Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions etc/scripts/freeze_and_update_reqs.py
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.

Copy link
Copy Markdown
Member

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:

Generate a requirement file at `output_file` of all dependencies wheels and sdists present in the `input_dir` directory.
If a `package_name` is provided it will be updated to its latest version.

though I am not sure this is true for package_name
Also output_file=False, package_name=False is weird. These should be None... and output_file should always be required

Also what is the base used there? the setup.py or some requirements.in file? I think we will need a requirements.in file

Copy link
Copy Markdown
Author

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.txt and it is default arguments.

"""
thirdparty = list(resource_iter(input_dir, with_dirs=False))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The list() wrapper is not needed here

@Abhishek-Dev09-zz Abhishek-Dev09-zz Jul 22, 2020

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The 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*")
)
]
Comment thread
Abhishek-Dev09-zz marked this conversation as resolved.
if not (os.path.isdir("required_deps")):
os.mkdir("required_deps")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you create that directory?

@Abhishek-Dev09-zz Abhishek-Dev09-zz Jul 21, 2020

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you mean to say bin

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use a temp dir instead

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The 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",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you do this? we never want to do some unwanted upgrade-package IMHO and what is "package_name", below about?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I known that but what is "package_name" I know of no package whose name is "package_name"
If this is some kind of magic, explain it in comments, do not make me chase down the help of that command

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The 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",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"package_name" is NOT a variable here ... but a plain string. This cannot work as it is... you need to test your code.

@Abhishek-Dev09-zz Abhishek-Dev09-zz Jul 24, 2020

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yeah it is function parameter through arguments . I have treated like temp dir as That is also also in double quotes but it is dir not variable . Same issue with upgrade parameter also.

"--pip-args",
"--no-index",
]
)
shutil.rmtree("required_deps")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The 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 \\
""",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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,
Comment thread
pombredanne marked this conversation as resolved.
default="requirements.txt",
)

parser.add_argument(
"--upgrade",
help="Upgrade all dependencies to new version. ",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: you have trailing whitespaces here and elsewhere

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The 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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This argument is not used at all... so what is it for?

@Abhishek-Dev09-zz Abhishek-Dev09-zz Jul 23, 2020

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The 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,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But where do you use it?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is not an argument used anywhere in your functions

@Abhishek-Dev09-zz Abhishek-Dev09-zz Jul 23, 2020

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The 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)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer named keyword arguments for example:
(tpdir=tpdir, requirement_file=requirement_file, package_name=package_name, upgrade=upgrade) But do not use these names... use the same variable names on both sides: e.g. if you use args.deps_directory then usedeps_directoryand nottpdir`


def main() -> None:
main_with_args(sys.argv[1:])


if __name__ == "__main__":
main()
128 changes: 128 additions & 0 deletions etc/scripts/scancode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# -*- coding: utf-8 -*-

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not name this scancode ;) that's confusing!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest the better name.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deps_info.py

#
# 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")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you print all that ?

@Abhishek-Dev09-zz Abhishek-Dev09-zz Jul 21, 2020

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's too verbose by default. Hide the prints behind an option

@Abhishek-Dev09-zz Abhishek-Dev09-zz Jul 23, 2020

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The 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()
Binary file not shown.
15 changes: 15 additions & 0 deletions thirdparty/setuptools-41.2.0-py2.py3-none-any.whl.ABOUT
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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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.

@Abhishek-Dev09-zz Abhishek-Dev09-zz Jul 21, 2020

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The 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 setuptools . That's why i added wheels setuptools also here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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 )

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The 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