Skip to content

Commit

Permalink
Merge pull request #4 from ZhengnanZhao/cli
Browse files Browse the repository at this point in the history
Use argparse to handle CLI
  • Loading branch information
zzhengnan authored Jun 8, 2020
2 parents ad89753 + 83baa86 commit 60784c8
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 14 deletions.
25 changes: 22 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,34 @@ Ever wondered which third-party dependencies your project relies on? `iscan` wil
$ pip install iscan
```

## Dependencies
`iscan` is light-weight and doesn't rely on anything outside the standard library. The core functionality leverages the built-in [ast](https://docs.python.org/3/library/ast.html) module. `pytest` is an optional dependency for running tests.

## Usage
Specify the path to the directory you wish to scan. Both absolute and relative paths are accepted.
```
$ iscan path/to/dir
```

Optionally, you can provide a second argument, specifying a directory to be _excluded_ when `iscan` looks for imported packages. For instance, the following command will scan all python files in the `foo` directory except those in `foo/tests`, which will be ignored.
Optionally, you can provide a second argument to specify a directory to be _excluded_ when `iscan` looks for imported packages. For instance, the following command will scan all python files in the `foo` directory except those in `foo/tests`, which will be ignored.
```
$ iscan foo -x foo/tests
```

The complete help message is shown below.
```
$ iscan foo foo/tests
$ iscan --help
usage: iscan [-h] [-x DIR_TO_EXCLUDE] DIR_TO_SCAN
Scan python files in a given directory for third-party
dependencies.
positional arguments:
DIR_TO_SCAN target directory to scan
optional arguments:
-h, --help show this help message and exit
-x DIR_TO_EXCLUDE directory to exclude during scanning
```

## Example output with `pandas`
Expand All @@ -27,7 +46,7 @@ Third-party packages imported across all python files in /Users/zhengnan/Desktop

If you are not interested in, say, packages imported during testing, you can specify the path to the tests directory for the entire directory to be ignored.
```
$ iscan ~/Desktop/pandas/pandas/ ~/Desktop/pandas/pandas/tests/
$ iscan ~/Desktop/pandas/pandas/ -x ~/Desktop/pandas/pandas/tests/
Third-party packages imported across all python files in /Users/zhengnan/Desktop/pandas/pandas/, EXCLUDING those in /Users/zhengnan/Desktop/pandas/pandas/tests/
['AppKit', 'Foundation', 'IPython', 'PyQt4', 'PyQt5', '_csv', 'botocore', 'bs4', 'cycler', 'dateutil', 'fastparquet', 'hypothesis', 'jedi', 'lxml', 'matplotlib', 'mpl_toolkits', 'numba', 'numexpr', 'numpy', 'odf', 'openpyxl', 'pandas', 'pg8000', 'pkg_resources', 'psycopg2', 'py', 'pyarrow', 'pylab', 'pymysql', 'pytest', 'pytz', 'pyxlsb', 'qtpy', 's3fs', 'scipy', 'sqlalchemy', 'tables', 'xarray', 'xlrd', 'xlsxwriter', 'xlwt']
```
1 change: 1 addition & 0 deletions iscan/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = '0.3.1'
29 changes: 22 additions & 7 deletions iscan/scan.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""This module provides functionality to scan a directory and aggregate
the names of packages imported across all python files in said directory.
"""
import argparse
import ast
import sys
from os import walk
Expand Down Expand Up @@ -116,14 +117,28 @@ def scan_directory(dir_to_scan: str, dir_to_exclude: str) -> list:
return sorted(set(map(get_base_name, all_imports)))


def cli() -> argparse.Namespace:
"""Command line interface."""
parser = argparse.ArgumentParser(
allow_abbrev=False,
description='Scan python files in a given directory for third-party dependencies.'
)
parser.add_argument(
'DIR_TO_SCAN',
help='target directory to scan'
)
parser.add_argument(
'-x',
default=None,
dest='DIR_TO_EXCLUDE',
help='directory to exclude during scanning'
)
return parser.parse_args()


def main():
args = sys.argv[1:]
if len(args) == 1:
dir_to_scan, dir_to_exclude = args[0], None
elif len(args) == 2:
dir_to_scan, dir_to_exclude = args
else:
raise ValueError('You may pass either one or two arguments.')
args = cli()
dir_to_scan, dir_to_exclude = args.DIR_TO_SCAN, args.DIR_TO_EXCLUDE

unique_imports = scan_directory(dir_to_scan, dir_to_exclude)
unique_imports = filter_out_std_lib(unique_imports)
Expand Down
19 changes: 15 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
import re
from pathlib import Path

import setuptools


PATH_TO_INIT = Path('iscan') / '__init__.py'
VERSION = re.search(
r'\'(.+?)\'',
PATH_TO_INIT.read_text()
).groups()[0]


with open('README.md', 'r') as f:
long_description = f.read()
LONG_DESCRIPTION = f.read()


setuptools.setup(
name='iscan',
version='0.3.0',
version=VERSION,
author='Zhengnan Zhao',
description='iscan helps you identify your project\'s third-party dependencies',
long_description=long_description,
long_description=LONG_DESCRIPTION,
long_description_content_type='text/markdown',
url='https://github.com/ZhengnanZhao/iscan',
packages=setuptools.find_packages(),
extras_require={
'dev': ['pytest', 'setuptools', 'twine', 'wheel']
'build': ['setuptools', 'twine', 'wheel'],
'dev': ['pytest']
},
entry_points={'console_scripts': ['iscan=iscan.scan:main']},
classifiers=[
Expand Down

0 comments on commit 60784c8

Please sign in to comment.