Skip to content

Commit 288532d

Browse files
committed
Add --init option to configure #33
* This is used for the case where we are starting off a project and have not yet generated requirements files Signed-off-by: Jono Yang <[email protected]>
1 parent 0e1f56b commit 288532d

6 files changed

+281
-23
lines changed

configure

+4-3
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,6 @@ CFG_BIN_DIR=$CFG_ROOT_DIR/$VIRTUALENV_DIR/bin
5353
# Find packages from the local thirdparty directory or from thirdparty.aboutcode.org
5454
PIP_EXTRA_ARGS="--find-links $CFG_ROOT_DIR/thirdparty --find-links https://thirdparty.aboutcode.org/pypi"
5555

56-
if [[ -f "$CFG_ROOT_DIR/requirements.txt" ]] && [[ -f "$CFG_ROOT_DIR/requirements-dev.txt" ]]; then
57-
PIP_EXTRA_ARGS+=" --no-index"
58-
fi
5956

6057
################################
6158
# Set the quiet flag to empty if not defined
@@ -161,13 +158,17 @@ install_packages() {
161158
# Main command line entry point
162159
CFG_DEV_MODE=0
163160
CFG_REQUIREMENTS=$REQUIREMENTS
161+
NO_INDEX="--no-index"
164162

165163
case "$CLI_ARGS" in
166164
--help) cli_help;;
167165
--clean) clean;;
168166
--dev) CFG_REQUIREMENTS="$DEV_REQUIREMENTS" && CFG_DEV_MODE=1;;
167+
--init) NO_INDEX="";;
169168
esac
170169

170+
PIP_EXTRA_ARGS="$PIP_EXTRA_ARGS $NO_INDEX"
171+
171172
create_virtualenv "$VIRTUALENV_DIR"
172173
install_packages "$CFG_REQUIREMENTS"
173174
. "$CFG_BIN_DIR/activate"

etc/scripts/gen_pypi_simple.py

+191
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
# SPDX-License-Identifier: BSD-2-Clause-Views AND MIT
5+
# Copyright (c) 2010 David Wolever <[email protected]>. All rights reserved.
6+
# originally from https://github.com/wolever/pip2pi
7+
8+
import os
9+
import re
10+
import shutil
11+
12+
from html import escape
13+
from pathlib import Path
14+
15+
"""
16+
name: pip compatibility tags
17+
version: 20.3.1
18+
download_url: https://github.com/pypa/pip/blob/20.3.1/src/pip/_internal/models/wheel.py
19+
copyright: Copyright (c) 2008-2020 The pip developers (see AUTHORS.txt file)
20+
license_expression: mit
21+
notes: the weel name regex is copied from pip-20.3.1 pip/_internal/models/wheel.py
22+
23+
Copyright (c) 2008-2020 The pip developers (see AUTHORS.txt file)
24+
25+
Permission is hereby granted, free of charge, to any person obtaining
26+
a copy of this software and associated documentation files (the
27+
"Software"), to deal in the Software without restriction, including
28+
without limitation the rights to use, copy, modify, merge, publish,
29+
distribute, sublicense, and/or sell copies of the Software, and to
30+
permit persons to whom the Software is furnished to do so, subject to
31+
the following conditions:
32+
33+
The above copyright notice and this permission notice shall be
34+
included in all copies or substantial portions of the Software.
35+
36+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
37+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
38+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
39+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
40+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
41+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
42+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43+
"""
44+
get_wheel_from_filename = re.compile(
45+
r"""^(?P<namever>(?P<name>.+?)-(?P<version>.*?))
46+
((-(?P<build>\d[^-]*?))?-(?P<pyvers>.+?)-(?P<abis>.+?)-(?P<plats>.+?)
47+
\.whl)$""",
48+
re.VERBOSE
49+
).match
50+
51+
sdist_exts = ".tar.gz", ".tar.bz2", ".zip", ".tar.xz",
52+
wheel_ext = ".whl"
53+
app_ext = ".pyz"
54+
dist_exts = sdist_exts + (wheel_ext, app_ext)
55+
56+
57+
class InvalidDistributionFilename(Exception):
58+
pass
59+
60+
61+
def get_package_name_from_filename(filename, normalize=True):
62+
"""
63+
Return the package name extracted from a package ``filename``.
64+
Optionally ``normalize`` the name according to distribution name rules.
65+
Raise an ``InvalidDistributionFilename`` if the ``filename`` is invalid::
66+
67+
>>> get_package_name_from_filename("foo-1.2.3_rc1.tar.gz")
68+
'foo'
69+
>>> get_package_name_from_filename("foo-bar-1.2-py27-none-any.whl")
70+
'foo-bar'
71+
>>> get_package_name_from_filename("Cython-0.17.2-cp26-none-linux_x86_64.whl")
72+
'cython'
73+
>>> get_package_name_from_filename("python_ldap-2.4.19-cp27-none-macosx_10_10_x86_64.whl")
74+
'python-ldap'
75+
>>> get_package_name_from_filename("foo.whl")
76+
Traceback (most recent call last):
77+
...
78+
InvalidDistributionFilename: ...
79+
>>> get_package_name_from_filename("foo.png")
80+
Traceback (most recent call last):
81+
...
82+
InvalidFilePackageName: ...
83+
"""
84+
if not filename or not filename.endswith(dist_exts):
85+
raise InvalidDistributionFilename(filename)
86+
87+
filename = os.path.basename(filename)
88+
89+
if filename.endswith(sdist_exts):
90+
name_ver = None
91+
extension = None
92+
93+
for ext in sdist_exts:
94+
if filename.endswith(ext):
95+
name_ver, extension, _ = filename.rpartition(ext)
96+
break
97+
98+
if not extension or not name_ver:
99+
raise InvalidDistributionFilename(filename)
100+
101+
name, _, version = name_ver.rpartition('-')
102+
103+
if not (name and version):
104+
raise InvalidDistributionFilename(filename)
105+
106+
elif filename.endswith(wheel_ext):
107+
108+
wheel_info = get_wheel_from_filename(filename)
109+
110+
if not wheel_info:
111+
raise InvalidDistributionFilename(filename)
112+
113+
name = wheel_info.group('name')
114+
version = wheel_info.group('version')
115+
116+
if not (name and version):
117+
raise InvalidDistributionFilename(filename)
118+
119+
elif filename.endswith(app_ext):
120+
name_ver, extension, _ = filename.rpartition(".pyz")
121+
122+
if "-" in filename:
123+
name, _, version = name_ver.rpartition('-')
124+
else:
125+
name = name_ver
126+
127+
if not name:
128+
raise InvalidDistributionFilename(filename)
129+
130+
if normalize:
131+
name = name.lower().replace('_', '-')
132+
return name
133+
134+
135+
def build_pypi_index(directory, write_index=False):
136+
"""
137+
Using a ``directory`` directory of wheels and sdists, create the a PyPI simple
138+
directory index at ``directory``/simple/ populated with the proper PyPI simple
139+
index directory structure crafted using symlinks.
140+
141+
WARNING: The ``directory``/simple/ directory is removed if it exists.
142+
"""
143+
144+
directory = Path(directory)
145+
146+
index_dir = directory / "simple"
147+
if index_dir.exists():
148+
shutil.rmtree(str(index_dir), ignore_errors=True)
149+
150+
index_dir.mkdir(parents=True)
151+
152+
if write_index:
153+
simple_html_index = [
154+
"<html><head><title>PyPI Simple Index</title>",
155+
"<meta name='api-version' value='2' /></head><body>",
156+
]
157+
158+
package_names = set()
159+
for pkg_file in directory.iterdir():
160+
161+
pkg_filename = pkg_file.name
162+
163+
if (
164+
not pkg_file.is_file()
165+
or not pkg_filename.endswith(dist_exts)
166+
or pkg_filename.startswith(".")
167+
):
168+
continue
169+
170+
pkg_name = get_package_name_from_filename(pkg_filename)
171+
pkg_index_dir = index_dir / pkg_name
172+
pkg_index_dir.mkdir(parents=True, exist_ok=True)
173+
pkg_indexed_file = pkg_index_dir / pkg_filename
174+
link_target = Path("../..") / pkg_filename
175+
pkg_indexed_file.symlink_to(link_target)
176+
177+
if write_index and pkg_name not in package_names:
178+
esc_name = escape(pkg_name)
179+
simple_html_index.append(f'<a href="{esc_name}/">{esc_name}</a><br/>')
180+
package_names.add(pkg_name)
181+
182+
if write_index:
183+
simple_html_index.append("</body></html>")
184+
index_html = index_dir / "index.html"
185+
index_html.write_text("\n".join(simple_html_index))
186+
187+
188+
if __name__ == "__main__":
189+
import sys
190+
pkg_dir = sys.argv[1]
191+
build_pypi_index(pkg_dir)

etc/scripts/gen_pypi_simple.py.ABOUT

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
about_resource: gen_pypi_simple.py
2+
name: gen_pypi_simple.py
3+
license_expression: bsd-2-clause-views and mit
4+
copyright: Copyright (c) nexB Inc.
5+
Copyright (c) 2010 David Wolever <[email protected]>
6+
Copyright (c) The pip developers
7+
notes: Originally from https://github.com/wolever/pip2pi and modified extensivley
8+
Also partially derived from pip code

etc/scripts/gen_pypi_simple.py.NOTICE

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
SPDX-License-Identifier: BSD-2-Clause-Views AND mit
2+
3+
Copyright (c) nexB Inc.
4+
Copyright (c) 2010 David Wolever <[email protected]>
5+
Copyright (c) The pip developers
6+
7+
8+
Original code: copyright 2010 David Wolever <[email protected]>. All rights reserved.
9+
10+
Redistribution and use in source and binary forms, with or without
11+
modification, are permitted provided that the following conditions are met:
12+
13+
1. Redistributions of source code must retain the above copyright notice,
14+
this list of conditions and the following disclaimer.
15+
16+
2. Redistributions in binary form must reproduce the above copyright notice,
17+
this list of conditions and the following disclaimer in the documentation
18+
and/or other materials provided with the distribution.
19+
20+
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY EXPRESS OR
21+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
23+
EVENT SHALL <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28+
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
31+
The views and conclusions contained in the software and documentation are those
32+
of the authors and should not be interpreted as representing official policies,
33+
either expressed or implied, of David Wolever.
34+
35+
36+
Original code: Copyright (c) 2008-2020 The pip developers
37+
38+
Permission is hereby granted, free of charge, to any person obtaining
39+
a copy of this software and associated documentation files (the
40+
"Software"), to deal in the Software without restriction, including
41+
without limitation the rights to use, copy, modify, merge, publish,
42+
distribute, sublicense, and/or sell copies of the Software, and to
43+
permit persons to whom the Software is furnished to do so, subject to
44+
the following conditions:
45+
46+
The above copyright notice and this permission notice shall be
47+
included in all copies or substantial portions of the Software.
48+
49+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
50+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
51+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
52+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
53+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
54+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
55+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
56+

etc/scripts/requirements.txt

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
aboutcode_toolkit
2+
github-release-retry2
3+
attrs
4+
commoncode
5+
click
6+
requests
7+
saneyaml
8+
romp
9+
pip
10+
setuptools
11+
twine
12+
wheel

etc/scripts/utils_thirdparty.py

+10-20
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,8 @@ def load_pkginfo_data(self, dest_dir=THIRDPARTY_DIR):
899899

900900
holder = raw_data['Author']
901901
holder_contact=raw_data['Author-email']
902-
copyright = f'Copyright {holder} <{holder_contact}>'
902+
copyright = f'Copyright (c) {holder} <{holder_contact}>'
903+
903904
pkginfo_data = dict(
904905
name=raw_data['Name'],
905906
declared_license=declared_license,
@@ -908,8 +909,8 @@ def load_pkginfo_data(self, dest_dir=THIRDPARTY_DIR):
908909
homepage_url=raw_data['Home-page'],
909910
copyright=copyright,
910911
license_expression=license_expression,
911-
holder=raw_data['Author'],
912-
holder_contact=raw_data['Author-email'],
912+
holder=holder,
913+
holder_contact=holder_contact,
913914
keywords=raw_data['Keywords'],
914915
classifiers=other_classifiers,
915916
)
@@ -2949,20 +2950,9 @@ def find_problems(
29492950
def compute_normalized_license_expression(declared_licenses):
29502951
if not declared_licenses:
29512952
return
2952-
2953-
from packagedcode import licensing
2954-
from packagedcode.utils import combine_expressions
2955-
2956-
detected_licenses = []
2957-
for declared in declared_licenses:
2958-
try:
2959-
license_expression = licensing.get_normalized_expression(
2960-
query_string=declared
2961-
)
2962-
except Exception:
2963-
return 'unknown'
2964-
if not license_expression:
2965-
continue
2966-
detected_licenses.append(license_expression)
2967-
if detected_licenses:
2968-
return combine_expressions(detected_licenses)
2953+
try:
2954+
from packagedcode import pypi
2955+
return pypi.compute_normalized_license(declared_licenses)
2956+
except ImportError:
2957+
# Scancode is not installed, we join all license strings and return it
2958+
return ' '.join(declared_licenses)

0 commit comments

Comments
 (0)