Skip to content

Commit

Permalink
argparse (#4)
Browse files Browse the repository at this point in the history
* implement an initial arg parser.
* argparse support.
  • Loading branch information
isidentical committed Dec 20, 2019
2 parents 0fa3f80 + 837af61 commit 90cfab7
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 52 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
15 changes: 6 additions & 9 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,15 @@
TEST_DIR = pathlib.Path(__file__).parent
TEST_DATA = [
{
"config_dir": TEST_DIR / "samples" / "unimport_cfg",
"config_path": TEST_DIR / "samples" / "unimport_cfg" / ".unimport.cfg",
"config_file": TEST_DIR / "samples" / ".unimport.cfg",
"section": None,
},
{
"config_dir": TEST_DIR / "samples" / "pyproject_toml",
"config_path": TEST_DIR / "samples" / "pyproject_toml" / "pyproject.toml",
"config_file": TEST_DIR / "samples" / "pyproject.toml",
"section": "tool.unimport",
},
{
"config_dir": TEST_DIR / "samples" / "setup_cfg",
"config_path": TEST_DIR / "samples" / "setup_cfg" / "setup.cfg",
"config_file": TEST_DIR / "samples" / "setup.cfg",
"section": "unimport",
},
]
Expand All @@ -26,9 +23,9 @@
class ConfigTest(TestCase):
def test_find_config(self):
for datum in TEST_DATA:
config = Config(config_dir=datum["config_dir"])
config = Config(config_file=datum["config_file"])
actual_path, actual_section = config.find_config()
self.assertEqual(actual_path, datum["config_path"])
self.assertEqual(actual_path, datum["config_file"])
self.assertEqual(actual_section, datum["section"])

def test_parse_config(self):
Expand All @@ -40,6 +37,6 @@ def test_parse_config(self):

for datum in TEST_DATA:
print(datum["section"])
config = Config(config_dir=datum["config_dir"])
config = Config(config_file=datum["config_file"])
self.assertSetEqual(config.ignored_folders, expected_folders)
self.assertSetEqual(config.ignored_files, expected_files)
28 changes: 6 additions & 22 deletions unimport/config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import configparser
import pathlib
import re
import sys

try:
import toml
Expand Down Expand Up @@ -54,8 +52,8 @@ class Config(object):
ignored_folders = set()
ignored_files = set()

def __init__(self, config_dir=None):
self.config_dir = config_dir
def __init__(self, config_file=None):
self.config_file = config_file
self.config_path, self.section = self.find_config()
if self.config_path is not None:
self.parse()
Expand All @@ -71,12 +69,11 @@ def is_available_to_parse(config_path):

def find_config(self):
for file_name, section in CONFIG_FILES:
if self.config_file is not None and file_name == self.config_file.name:
return self.config_file, section

current_dir = pathlib.Path().cwd()
if self.config_dir is None:
search_depth = len(current_dir.parts)
else:
current_dir /= self.config_dir
search_depth = 1
search_depth = len(current_dir.parts)

for _ in range(search_depth):
config_path = current_dir / file_name
Expand Down Expand Up @@ -111,16 +108,3 @@ def parse_toml(self):
config = parsed_toml.get("tool", {}).get("unimport", {})
self.ignored_folders.update(set(config.get("folders", [])))
self.ignored_files.update(set(config.get("files", [])))


config = Config(config_dir=sys.argv[1] if len(sys.argv) >= 2 else None)


def is_ignore_folder(path):
regex = re.compile("|".join(set(config.ignored_folders)))
return regex.match(path) is not None


def is_ignore_files(path):
regex = re.compile("|".join(set(config.ignored_files)))
return regex.match(path) is not None
65 changes: 49 additions & 16 deletions unimport/console.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,57 @@
import argparse
import os
import sys
import pathlib
import tokenize

from unimport.config import Config
from unimport.files import get_files
from unimport.unused import get_unused


class CLI:
def parse_args(self):
parser = argparse.ArgumentParser(
description="Detect or remove unused Python imports."
)
parser.add_argument(
"source",
default=".",
nargs="?",
help="include file or folder to find the unused imports",
type=pathlib.Path,
)
parser.add_argument(
"-c",
"--config",
help="read configuration from PATH",
metavar="PATH",
type=pathlib.Path,
)
parser.add_argument(
"-w",
"--write",
action="store_true",
help="remove unused imports automatically",
)
return parser.parse_args()

def run(self):
args = self.parse_args()
config = Config(config_file=args.config)
py_files = get_files(args.source, config=config)
if args.write:
# TODO: not ready yet.
for py_file in py_files:
self.overwrite(get_unused_imports(py_file))
else:
for py_file in py_files:
for unused_import in get_unused_imports(py_file):
print(unused_import)

def overwrite(self, unused_import):
print("not ready")


def get_unused_imports(file_path):
try:
with tokenize.open(file_path) as f:
Expand All @@ -19,21 +65,8 @@ def get_unused_imports(file_path):


def console_scripts():
try:
source_file_or_directory = sys.argv[1]
except IndexError:
source_file_or_directory = "."
if os.path.isdir(source_file_or_directory):
# folder
for file in get_files(source_file_or_directory):
for un_used in get_unused_imports(file):
print(un_used)
else:
# file
file_path = os.path.join(os.getcwd(), source_file_or_directory)
if file_path.endswith(".py"):
for un_used in get_unused_imports(file_path):
print(un_used)
cli = CLI()
cli.run()


if __name__ == "__main__":
Expand Down
22 changes: 17 additions & 5 deletions unimport/files.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import os
import re

from unimport.config import is_ignore_files, is_ignore_folder

def get_files(src, config):
ignored_folders = re.compile("|".join(set(config.ignored_folders)))
ignored_files = re.compile("|".join(set(config.ignored_files)))

def get_files(direction):
for root, dirs, files in os.walk(direction):
if is_ignore_folder(root):
def _is_ignored_folder(path):
return ignored_folders.match(path) is not None

def _is_ignored_file(path):
return not path.endswith(".py") or ignored_files.match(path) is not None

if not src.is_dir():
return str(src) if not _is_ignored_file(src.name) else None

for root, dirs, files in os.walk(str(src.absolute())):
if _is_ignored_folder(root):
continue

for name in files:
file_path = os.path.join(root, name)
if file_path.endswith(".py") and not is_ignore_files(file_path):
if not _is_ignored_file(file_path):
yield file_path

0 comments on commit 90cfab7

Please sign in to comment.