diff --git a/README.rst b/README.rst index 25867f6..c23c795 100644 --- a/README.rst +++ b/README.rst @@ -37,6 +37,7 @@ Usage pipreqs [options] Options: + --use-local Use ONLY local package information instead of querying PyPI --debug Print debug information --savepath Save the list of requirements in the given file diff --git a/pipreqs/pipreqs.py b/pipreqs/pipreqs.py index 14a0d54..252265e 100755 --- a/pipreqs/pipreqs.py +++ b/pipreqs/pipreqs.py @@ -6,12 +6,14 @@ Usage: pipreqs [options] Options: + --use-local Use ONLY local package information instead of querying PyPI --debug Print debug information --savepath Save the list of requirements in the given file """ from __future__ import print_function import os import sys +from distutils.sysconfig import get_python_lib import re import logging @@ -84,13 +86,52 @@ def get_imports_info(imports): result.append({'name': item, 'version': last_release}) return result +def get_locally_installed_packages(): + path = get_python_lib() + packages = {} + for root, dirs, files in os.walk(path): + for item in files: + if "top_level" in item: + with open(os.path.join(root,item), "r") as f: + package = root.split("/")[-1].split("-") + package_import = f.read().strip().split("\n") + package_import_name = "" + for item in package_import: + if item not in ["tests","_tests"]: + package_import_name = item + break + if package_import_name == "": + logging.debug('Could not determine import name for package ' + package_import) + else: + packages[package_import_name] = { + 'version':package[1].replace(".dist",""), + 'name': package[0] + } + return packages + +def get_import_local(imports): + local = get_locally_installed_packages() + result = [] + for item in imports: + if item in local: + result.append(local[item]) + return result + def init(args): print("Looking for imports") imports = get_all_imports(args['']) - print("Getting latest information about packages from PyPI") - imports_with_info = get_imports_info(imports) print("Found third-party imports: " + ", ".join(imports)) + if args['--use-local']: + print("Getting package version information ONLY from local installation.") + imports_with_info = get_import_local(imports) + else: + print("Getting latest version information about packages from Local/PyPI") + imports_local = get_import_local(imports) + difference = [x for x in imports if x not in [z['name'] for z in imports_local]] + imports_pypi = get_imports_info(difference) + imports_with_info = imports_local + imports_pypi + print("Imports written to requirements file:", ", ".join([x['name'] for x in imports_with_info])) path = args["--savepath"] if args["--savepath"] else os.path.join(args[''], "requirements.txt") generate_requirements_file(path, imports_with_info) print("Successfully saved requirements file in " + path) diff --git a/setup.py b/setup.py index feb645c..6856eaf 100755 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ test_requirements = [ setup( name='pipreqs', - version='0.1.9', + version='0.2.0', description="Pip requirements.txt generator based on imports in project", long_description=readme + '\n\n' + history, author="Vadim Kravcenko", @@ -42,7 +42,7 @@ setup( zip_safe=False, keywords='pip requirements imports', classifiers=[ - 'Development Status :: 2 - Pre-Alpha', + 'Development Status :: 4 - Beta', 'Intended Audience :: Developers', 'License :: OSI Approved :: Apache Software License', 'Natural Language :: English', diff --git a/tests/test_pipreqs.py b/tests/test_pipreqs.py index a2001dd..bf3f880 100755 --- a/tests/test_pipreqs.py +++ b/tests/test_pipreqs.py @@ -38,9 +38,14 @@ class TestPipreqs(unittest.TestCase): self.assertEqual(len(with_info), 5, "Length of imports array with info is wrong") for item in with_info: self.assertTrue(item['name'] in self.modules, "Import item appears to be missing") + + def test_get_use_local_only(self): + # should find only docopt and requests + imports_with_info = pipreqs.get_import_local(self.modules) + self.assertTrue(len(imports_with_info) == 2) def test_init(self): - pipreqs.init({'': self.project, '--savepath': None}) + pipreqs.init({'': self.project, '--savepath': None,'--use-local':None}) assert os.path.exists(self.requirements_path) == 1 with open(self.requirements_path, "r") as f: data = f.read()