-
-
Notifications
You must be signed in to change notification settings - Fork 792
Automate the creation of requirement.txt and fetch deps #2118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
0308787
a52ab7a
2c7c27f
10ede31
da266a3
0a9db9f
979bfb0
996bd0b
c78b399
1dea23f
dc6c9a4
d6a63ce
b61a9db
c5ce300
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| # -*- coding: utf-8 -*- | ||
| # | ||
| # Copyright nexB Inc. and others. All rights reserved. | ||
| # http://nexb.com and https://github.com/nexB/scancode-toolkit/ | ||
| # The ScanCode software is licensed under the Apache License version 2.0. | ||
| # Data generated with ScanCode require an acknowledgment. | ||
| # ScanCode is a trademark of nexB Inc. | ||
| # | ||
| # You may not use this software except in compliance with the License. | ||
| # You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0 | ||
| # Unless required by applicable law or agreed to in writing, software distributed | ||
| # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | ||
| # CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
| # specific language governing permissions and limitations under the License. | ||
| # | ||
| # When you publish or redistribute any data created with ScanCode or any ScanCode | ||
| # derivative work, you must accompany this data with the following acknowledgment: | ||
| # | ||
| # Generated with ScanCode and provided on an "AS IS" BASIS, WITHOUT WARRANTIES | ||
| # OR CONDITIONS OF ANY KIND, either express or implied. No content created from | ||
| # ScanCode should be considered or used as legal advice. Consult an Attorney | ||
| # for any legal advice. | ||
| # ScanCode is a free software code scanning tool from nexB Inc. and others. | ||
| # Visit https://github.com/nexB/scancode-toolkit/ for support and download. | ||
|
|
||
| from __future__ import absolute_import | ||
| from __future__ import print_function | ||
|
|
||
| import argparse | ||
| import fnmatch | ||
| from commoncode.fileutils import resource_iter | ||
| import os | ||
| import subprocess | ||
| import shutil | ||
| import sys | ||
|
|
||
| python_version = str(sys.version_info[0]) + str(sys.version_info[1]) | ||
| py_abi = "{0}cp{1}{0}".format("*", python_version) | ||
|
|
||
|
|
||
| def generate_req_text(input_dir, output_file=False, package_name=False): | ||
| """ | ||
| Generate a requirement.txt file of all dependencies present in thirdparty. | ||
| """ | ||
| thirdparty = list(resource_iter(input_dir, with_dirs=False)) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The list() wrapper is not needed here
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
| # FIXME this code is for py 3.6 and later we will update for all version | ||
| dependencies = [ | ||
| files | ||
| for files in thirdparty | ||
| if fnmatch.fnmatchcase(files, "*py3*") | ||
| or fnmatch.fnmatchcase(files, py_abi) | ||
| or ( | ||
| fnmatch.fnmatchcase(files, "*tar.gz*") | ||
| and not fnmatch.fnmatchcase(files, "*py2-ipaddress-3.4.1.tar.gz*") | ||
| ) | ||
| ] | ||
|
Abhishek-Dev09-zz marked this conversation as resolved.
|
||
| if not (os.path.isdir("required_deps")): | ||
| os.mkdir("required_deps") | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you create that directory?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To filter the dependencies of specific python version we want because we have both py2 and py3 wheels in thirdparty. Don't worry it will deleted later by scripts itself.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, so please add a comment explaining that... and also this may not be created where you want. Make sure you use a well known location or better use some temp directory instead since this is temporary
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you mean to say
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use a temp dir instead
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
| for deps in dependencies: | ||
| shutil.copy(deps, "required_deps") | ||
| subprocess.run( | ||
| [ | ||
| "pip-compile", | ||
| "--generate-hashes", | ||
| "--find-links", | ||
| "required_deps", | ||
| "--upgrade", | ||
| "--output-file", | ||
| output_file, | ||
| "--verbose", | ||
| "--upgrade-package", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do you do this? we never want to do some unwanted
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this feature alow you to upgrade specfic package. See help by running this arg.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I known that but what is
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In any case why would I want to upgrade a package there? Please elaborate and explain in comments
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Package name may be intbitset, banal, urlpy . Anything deps that exist in thirdparty |
||
| "package_name", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, yeah it is function parameter through arguments . I have treated like |
||
| "--pip-args", | ||
| "--no-index", | ||
| ] | ||
| ) | ||
| shutil.rmtree("required_deps") | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would rather you use a temp file with a "with" context manager to avoid leaving dangling files
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is not a file , it is directory |
||
|
|
||
|
|
||
| def main_with_args(args: str) -> None: | ||
| parser = argparse.ArgumentParser( | ||
| description="""Creates a archive for specific OS and specific python. | ||
| EXAMPLE: | ||
| freeze_and_update_reqs.py \\ | ||
| --deps_directory DEPS_DIRECTORY \\ | ||
| --output OUTPUT \\ | ||
| --upgrade_package PACKAGE_NAME \\ | ||
| """, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove this example. |
||
| formatter_class=argparse.RawDescriptionHelpFormatter, | ||
| ) | ||
|
|
||
| parser.add_argument( | ||
| "--deps_directory", | ||
| help="Required: Thirdparty Dependencies directory to be archived. ", | ||
| type=str, | ||
| required=True, | ||
| ) | ||
|
|
||
| parser.add_argument( | ||
| "--output", | ||
| help="Output file name. Required if more than one input file is given. Will be derived from input file otherwise. ", | ||
| type=str, | ||
|
pombredanne marked this conversation as resolved.
|
||
| default="requirements.txt", | ||
| ) | ||
|
|
||
| parser.add_argument( | ||
| "--upgrade", | ||
| help="Upgrade all dependencies to new version. ", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: you have trailing whitespaces here and elsewhere
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
| action="store_true", | ||
| ) | ||
|
|
||
| parser.add_argument( | ||
| "--upgrade_package", | ||
| help="Specify particular packages to upgrade. ", | ||
| type=str, | ||
| default=None, | ||
| ) | ||
|
|
||
| args = parser.parse_args() | ||
|
|
||
| tpdir = args.deps_directory | ||
| output_file = args.output | ||
| package_name = args.upgrade_package | ||
| upgrade = args.upgrade or None | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This argument is not used at all... so what is it for?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. upgrade is for upgrading all packages whereas upgrade_package is for specific package,
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But where do you use it?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is not an argument used anywhere in your functions
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great catch .It is an option just like ON/OFF . It is used here only , i have tested it it works, if you want i will paste output here. |
||
| generate_req_text(tpdir, output_file, package_name) | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. prefer named keyword arguments for example: |
||
|
|
||
| def main() -> None: | ||
| main_with_args(sys.argv[1:]) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| # -*- coding: utf-8 -*- | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please do not name this scancode ;) that's confusing!
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggest the better name.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| # | ||
| # Copyright nexB Inc. and others. All rights reserved. | ||
| # http://nexb.com and https://github.com/nexB/scancode-toolkit/ | ||
| # The ScanCode software is licensed under the Apache License version 2.0. | ||
| # Data generated with ScanCode require an acknowledgment. | ||
| # ScanCode is a trademark of nexB Inc. | ||
| # | ||
| # You may not use this software except in compliance with the License. | ||
| # You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0 | ||
| # Unless required by applicable law or agreed to in writing, software distributed | ||
| # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR | ||
| # CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
| # specific language governing permissions and limitations under the License. | ||
| # | ||
| # When you publish or redistribute any data created with ScanCode or any ScanCode | ||
| # derivative work, you must accompany this data with the following acknowledgment: | ||
| # | ||
| # Generated with ScanCode and provided on an "AS IS" BASIS, WITHOUT WARRANTIES | ||
| # OR CONDITIONS OF ANY KIND, either express or implied. No content created from | ||
| # ScanCode should be considered or used as legal advice. Consult an Attorney | ||
| # for any legal advice. | ||
| # ScanCode is a free software code scanning tool from nexB Inc. and others. | ||
| # Visit https://github.com/nexB/scancode-toolkit/ for support and download. | ||
|
|
||
| from __future__ import absolute_import | ||
| from __future__ import print_function | ||
|
|
||
| import argparse | ||
| import fnmatch | ||
| from commoncode.fileutils import resource_iter | ||
| import sys | ||
|
|
||
|
|
||
| def search_package(package_name, target, version=False): | ||
| """ | ||
| Search specific package in given directory with all corresponding files. | ||
| """ | ||
|
|
||
| if version: | ||
| package_name = "*{}-{}*".format(package_name, version) | ||
| else: | ||
| package_name = "*{}*".format(package_name) | ||
| thirdparty = list(resource_iter(target, with_dirs=False)) | ||
| dependency = [ | ||
| files for files in thirdparty if fnmatch.fnmatchcase(files, package_name) | ||
| ] | ||
| if dependency: | ||
| whl = [ | ||
| files for files in dependency if files.endswith(".whl") | ||
| ] ## There are multiple version of same package So list of wheel will be considered. | ||
| sdist = [files for files in dependency if files.endswith(".tar.gz")] | ||
| about = [files for files in dependency if files.endswith(".ABOUT")] | ||
| notice = [files for files in dependency if files.endswith(".NOTICE")] | ||
| license = [files for files in dependency if files.endswith(".LICENSE")] | ||
| print(*whl, sep="\n") | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do you print all that ?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because scancode's developer want to fetch the deps in target directory. Script will know developer by printing the info of deps.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that's too verbose by default. Hide the prints behind an option
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it shows ONLY .ABOUT/.NOTICE/.LICENCE/.whl/.tar.gz . Not too verbose i have seen |
||
| print("\n") | ||
| if sdist: | ||
| print(*sdist, sep="\n") | ||
| else: | ||
| print("Corresponding sdist does not exits in target\n") | ||
| print("\n") | ||
| if about: | ||
| print(*about, sep="\n") | ||
| else: | ||
| print("Corresponding .ABOUT does not exits in target\n") | ||
| print("\n") | ||
| if license: | ||
| print(*licence, sep="\n") | ||
| else: | ||
| print("Corresponding .LICENSE does not exits in target\n") | ||
| print("\n") | ||
| if notice: | ||
| print(*notice, sep="\n") | ||
| else: | ||
| print("Corresponding .NOTICE does not exits in target\n") | ||
| print("\n") | ||
| else: | ||
| print("Specified package does not exist\n") | ||
|
|
||
|
|
||
| def main_with_args(args: str) -> None: | ||
| parser = argparse.ArgumentParser( | ||
| description="""Fetch a specific package with version in given target like thirdparty by default. | ||
| EXAMPLE: | ||
| scancode.py \\ | ||
| --fetch PACKAGE_NAME \\ | ||
| --target TARGET_DIR \\ | ||
| --version VERSION_OF_PACKAGE \\ | ||
| """, | ||
| formatter_class=argparse.RawDescriptionHelpFormatter, | ||
| ) | ||
|
|
||
| parser.add_argument( | ||
| "--fetch", | ||
| help="Required: Specific Dependencies to be fetched. ", | ||
| type=str, | ||
| required=True, | ||
| ) | ||
|
|
||
| parser.add_argument( | ||
| "--target", | ||
| help=" a target directory where the built wheels and tarballs would be fetched. ", | ||
| type=str, | ||
| default="thirdparty", | ||
| ) | ||
|
|
||
| parser.add_argument( | ||
| "--version", | ||
| help="Specify version of dependencies to be fetched. ", | ||
| type=str, | ||
| default=None, | ||
| ) | ||
|
|
||
| args = parser.parse_args() | ||
|
|
||
| package_name = args.fetch | ||
| target = args.target | ||
| version = args.version | ||
| search_package(package_name, target, version) | ||
|
|
||
|
|
||
| def main() -> None: | ||
| main_with_args(sys.argv[1:]) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| about_resource: setuptools-41.2.0-py2.py3-none-any.whl | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should already have setuptools..... good catch. But please do not commit it there, craft another PR instead just for that.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't worry, i already mentioned in PR description. FYI there is no deps named
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I get that, but please provide a different PR for adding that back (and FYI zopefoundation/zc.lockfile#22 )
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. removed and PR #2123 |
||
| name: setuptools | ||
| version: 41.2.0 | ||
| download_url: https://files.pythonhosted.org/packages/b2/86/095d2f7829badc207c893dd4ac767e871f6cd547145df797ea26baea4e2e/setuptools-41.2.0-py2.py3-none-any.whl#sha256=4380abcf2a4ffd1a5ba22d687c6d690dce83b2b51c70e9c6d09f7e8c7e8040dc | ||
| description: Easily download, build, install, upgrade, and uninstall Python packages | ||
| homepage_url: https://pypi.python.org/pypi/setuptools | ||
| license_expression: python AND mit | ||
| copyright: Copyright (c) Python Packaging Authority | ||
| attribute: yes | ||
| track_changes: yes | ||
| owner: Python Packaging Authority | ||
| owner_url: https://www.pypa.io/en/latest/ | ||
| contact: distutils-sig@python.org | ||
| checksum_md5: c339d06c65fe171f686b0ad76751f3bf | ||
| checksum_sha1: fd41702d63ed12ebb789c6dc52f1944e0bec0f33 | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and what are the args?
this should IMHO be something such as:
though I am not sure this is true for package_name
Also
output_file=False, package_name=Falseis weird. These should be None... and output_file should always be requiredAlso what is the base used there? the setup.py or some requirements.in file? I think we will need a requirements.in file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Base used here : setup.py and no need of requirements.in file. And by default output_file is
requirements.txtand it is default arguments.