Skip to content

Commit

Permalink
Feature additions – unused imports (#1180)
Browse files Browse the repository at this point in the history
- Make unused imports remover order files by git history to check the
most relevant files first, even when moving between local branches
- Add ability to search specified files or folders
- Add vscode task to remove unused imports in current file
  • Loading branch information
fredrik-bakke authored Sep 7, 2024
1 parent c22dba0 commit eedb271
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 8 deletions.
20 changes: 19 additions & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
"type": "shell",
"command": "python3",
"args": ["${workspaceFolder}/scripts/demote_foundation_imports.py"],
"problemMatcher": []
"problemMatcher": [],
"hide": true
},
{
"label": "unused-imports",
Expand All @@ -48,6 +49,23 @@
"problemMatcher": [],
"dependsOn": ["remove-unused-imports", "demote-foundation-imports"],
"dependsOrder": "sequence"
},
{
"label": "remove-unused-imports-current-file",
"detail": "Remove unused imports in current file",
"type": "shell",
"command": "${workspaceFolder}/scripts/remove_unused_imports.py",
"args": ["${relativeFile}"],
"problemMatcher": [],
// "hide": true,
"presentation": {
"reveal": "silent",
"revealProblems": "onProblem",
"close": true
},
"runOptions": {
"runOn": "default"
}
}
],
"statusbar.default.hide": false
Expand Down
42 changes: 35 additions & 7 deletions scripts/remove_unused_imports.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#!/usr/bin/env python3
# Run this script:
# $ ./scripts/remove_unused_imports.py
# $ ./scripts/remove_unused_imports.py [optional: path_to_file_or_folder ...]

import os
import sys
import pathlib
import shutil
import utils
Expand Down Expand Up @@ -91,25 +92,52 @@ def process_agda_file(agda_file, agda_options, root, temp_dir):
f"'{agda_module}' No unused imports.")


def get_agda_files(path):
if os.path.isfile(path):
return [path] if utils.is_agda_file(pathlib.Path(path)) else []
elif os.path.isdir(path):
def filter_agda_files(f): return utils.is_agda_file(pathlib.Path(f)) and os.path.dirname(f) != path
return list(filter(filter_agda_files, utils.get_files_recursive(path)))
else:
utils.multithread.thread_safe_print(f"Warning: '{path}' is not a valid file or directory. Skipping.")
return []


if __name__ == '__main__':
root = 'src'
if len(sys.argv) > 1:
input_paths = sys.argv[1:]
# root = os.path.commonpath(input_paths) # Find common root for all inputs
else:
# Default behavior when no argument is provided
root = 'src'
input_paths = [root]

temp_dir = 'temp'
status = 0
agda_options = '--without-K --exact-split --no-import-sorts --auto-inline --no-caching'

temp_root = os.path.join(root, temp_dir)
shutil.rmtree(temp_root, ignore_errors=True)

def filter_agda_files(f): return utils.is_agda_file(
pathlib.Path(f)) and os.path.dirname(f) != root
# Get Agda files based on the inputs
agda_files = []
for path in input_paths:
agda_files.extend(get_agda_files(path))

if not agda_files:
utils.multithread.thread_safe_print("No Agda files found in the specified paths.")
sys.exit(1)

# Sort the files by Git modification status and last commit date
def sort_key(file):
return (-int(utils.is_file_modified(file)), -utils.get_git_last_modified(file))

# Sort the files by most recently changed
agda_files = sorted(
filter(filter_agda_files, utils.get_files_recursive(root)), key=lambda t: -os.stat(t).st_mtime)
sorted_agda_files = sorted(agda_files, key=sort_key)

with ThreadPoolExecutor() as executor:
executor.map(lambda file: process_agda_file(
file, agda_options, root, temp_dir), agda_files)
file, agda_options, root, temp_dir), sorted_agda_files)

shutil.rmtree(temp_root)
sys.exit(status)
17 changes: 17 additions & 0 deletions scripts/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,20 @@ def get_git_tracked_files():
git_output = subprocess.check_output(['git', 'ls-files'], text=True)
git_tracked_files = map(pathlib.Path, git_output.strip().split('\n'))
return git_tracked_files


def get_git_last_modified(file_path):
try:
# Get the last commit date for the file
output = subprocess.check_output(['git', 'log', '-1', '--format=%at', file_path], stderr=subprocess.DEVNULL)
return int(output.strip())
except subprocess.CalledProcessError:
# If the file is not in git or there's an error, return last modified time according to OS
return os.path.getmtime(file_path)

def is_file_modified(file_path):
try:
subprocess.check_output(['git', 'diff', '--quiet', file_path], stderr=subprocess.DEVNULL)
return False
except subprocess.CalledProcessError:
return True

0 comments on commit eedb271

Please sign in to comment.