Skip to content

Commit 6a1e8c4

Browse files
committed
Added some tests, added handling for licenses tucked away in *.dist-info/licenses, tidied up packaging a little bit, added thanks for contributors
1 parent 9ef3108 commit 6a1e8c4

File tree

13 files changed

+339
-80
lines changed

13 files changed

+339
-80
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
build
2+
**/__pycache__
3+
**/.pyc
4+
*.egg-info

Dockerfile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
ARG VERSION
2+
3+
FROM python:${VERSION:-3.12}
4+
5+
WORKDIR /srv/
6+
7+
RUN pip install twine setuptools
8+
9+
COPY ./requirements.txt /srv/python-third-party-license-file-generator/requirements.txt
10+
11+
RUN pip install -r /srv/python-third-party-license-file-generator/requirements.txt
12+
13+
COPY . /srv/python-third-party-license-file-generator
14+
15+
RUN pip install ./python-third-party-license-file-generator/
16+
17+
CMD ["/srv/python-third-party-license-file-generator/docker-entrypoint.sh"]

Dockerfile.dockerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
build
2+
**/__pycache__
3+
**/.pyc
4+
*.egg-info

README.md

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
The Python third_party_license_file_generator is aimed at distilling down the appropriate license for one or many pip "requirements" files into a single file; it supports Python2.7 and Python3.
44

5+
## Thanks to everyone who has contributed over the years!
6+
7+
- [fredvisser](https://github.com/fredvisser)
8+
- [Brian-Williams](https://github.com/Brian-Williams)
9+
- [andzn](https://github.com/andzn)
10+
- [dave-v](https://github.com/dave-v)
11+
- [j-b-d](https://github.com/j-b-d)
12+
- [malesh](https://github.com/malesh)
13+
- [lowaa](https://github.com/lowaa)
14+
515
## How do I install it?
616

717
$ pip install third-party-license-file-generator
@@ -16,12 +26,12 @@ With no arguments (other than a pip "requirements" file and a Python executable
1626

1727
- walk the given Python executable's site-packages folder and build up package metadata (and license files, if present)
1828
- filter down by packages that are listed in the pip "requirements" file (and those packages dependencies, and their dependencies, and their dependencies... you get the gist)
19-
- note: it follows "-r some_file.txt" references found in the pip "requirements" files
29+
- note: it follows "-r some_file.txt" references found in the pip "requirements" files
2030
- if a license name could not be secured for a package, try to gather that from the package's PyPI web page
21-
- if a license name has still not been secured and the package lists a GitHub home page, try to find a license from there
22-
- otherwise, assume the package to be commercially licensed (as it is legally understood that is the case)
31+
- if a license name has still not been secured and the package lists a GitHub home page, try to find a license from there
32+
- otherwise, assume the package to be commercially licensed (as it is legally understood that is the case)
2333
- if a license file could not be secured for a package and the package lists a GitHub home page, try to find a license from there
24-
- otherwise, create a license (for the known license name) from a local collection of licenses (within the Python Third Party License Generator)
34+
- otherwise, create a license (for the known license name) from a local collection of licenses (within the Python Third Party License Generator)
2535
- show a summary of packages against licenses to the user
2636
- build a THIRDPARTYLICENSES file in the current folder
2737
- give a return code of zero for success or non-zero for failures (e.g. GPL-licensed packages detected when specified to not permit GPL)
@@ -62,13 +72,13 @@ Three different pip "requirements" files, two different Python paths (need to re
6272
-p ~/.virtualenvs/api_pypy/bin/python \
6373
-r cpython_requirements.txt \
6474
-p ~/.virtualenvs/api_py/bin/python \
65-
-x uWSGI \
75+
-x uWSGI \
6676
-o ThirdPartyLicenses.txt
6777

6878
Three different pip "requirements" files, two different Python paths (need to repeat), a GPL exception, a custom output file and a license override file:
6979

7080
# contents of license_override_file.yml
71-
uWSGI:
81+
uWSGI:
7282
license_name: GPL-2.0 w/ linking exception
7383
license_file: https://raw.githubusercontent.com/unbit/uwsgi/master/LICENSE
7484

@@ -79,7 +89,7 @@ Three different pip "requirements" files, two different Python paths (need to re
7989
-p ~/.virtualenvs/api_pypy/bin/python \
8090
-r cpython_requirements.txt \
8191
-p ~/.virtualenvs/api_py/bin/python \
82-
-x uWSGI \
92+
-x uWSGI \
8393
-o ThirdPartyLicenses.txt \
8494
-l license_override_file.yml
8595

@@ -100,3 +110,25 @@ An example of the structure of the generated third party license file is as foll
100110
----------------------------------------
101111

102112
End of 'ThirdPartyLicenses.txt' generated by Python third_party_license_generator at 2018-04-19 12:36:58.627825
113+
114+
## Packaging notes
115+
116+
### Testing
117+
118+
If you're making any changes you can run the tests:
119+
120+
```bash
121+
./test.sh
122+
```
123+
124+
### Publishing
125+
126+
NOTE: This probably only applies to folks that work at [FTP Solutions](https://github.com/ftpsolutions/) (maintainers of this package).
127+
128+
This will test a few Python versions, operating the tool against this repo's `requirements.txt`.
129+
130+
When you're ready to push to PyPI, as long as you have a `~/.pypirc` and you have permissions to push to the repo:
131+
132+
```bash
133+
./build-tag-and-push.sh
134+
```

THIRDPARTYLICENSES

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Start of 'THIRDPARTYLICENSES' generated by Python third_party_license_generator at 2023-02-22 21:58:48.921278
1+
Start of 'THIRDPARTYLICENSES' generated by Python third_party_license_generator at 2025-06-18 04:59:56.875233
22

33
----------------------------------------
44

@@ -41,7 +41,6 @@ This package contains a modified version of ca-bundle.crt:
4141

4242
ca-bundle.crt -- Bundle of CA Root Certificates
4343

44-
Certificate data from Mozilla as of: Thu Nov 3 19:04:19 2011#
4544
This is a bundle of X.509 certificates of public Certificate Authorities
4645
(CA). These were automatically extracted from Mozilla's root certificates
4746
file (certdata.txt). This file can be found in the mozilla source tree:
@@ -64,12 +63,12 @@ one at http://mozilla.org/MPL/2.0/.
6463
Package: charset-normalizer
6564
License: MIT
6665
Requires: n/a
67-
Author: Ahmed TAHRI <ahmed.tahri@cloudnursery.dev>
68-
Home page: https://github.com/Ousret/charset_normalizer
66+
Author: (unknown) <"Ahmed R. TAHRI" <tahri.ahmed@proton.me>>
67+
Home page: None
6968

7069
MIT License
7170

72-
Copyright (c) 2019 TAHRI Ahmed R.
71+
Copyright (c) 2025 TAHRI Ahmed R.
7372

7473
Permission is hereby granted, free of charge, to any person obtaining a copy
7574
of this software and associated documentation files (the "Software"), to deal
@@ -94,38 +93,40 @@ SOFTWARE.
9493
Package: idna
9594
License: BSD-3-clause
9695
Requires: n/a
97-
Author: (unknown) <Kim Davies <kim@cynosure.com.au>>
96+
Author: (unknown) <Kim Davies <kim+pypi@gumleaf.org>>
9897
Home page: None
9998

10099
BSD 3-Clause License
101100

102-
Copyright (c) 2013-2021, Kim Davies
101+
Copyright (c) 2013-2024, Kim Davies and contributors.
103102
All rights reserved.
104103

105104
Redistribution and use in source and binary forms, with or without
106-
modification, are permitted provided that the following conditions are met:
105+
modification, are permitted provided that the following conditions are
106+
met:
107107

108-
1. Redistributions of source code must retain the above copyright notice, this
109-
list of conditions and the following disclaimer.
108+
1. Redistributions of source code must retain the above copyright
109+
notice, this list of conditions and the following disclaimer.
110110

111-
2. Redistributions in binary form must reproduce the above copyright notice,
112-
this list of conditions and the following disclaimer in the documentation
113-
and/or other materials provided with the distribution.
111+
2. Redistributions in binary form must reproduce the above copyright
112+
notice, this list of conditions and the following disclaimer in the
113+
documentation and/or other materials provided with the distribution.
114114

115115
3. Neither the name of the copyright holder nor the names of its
116116
contributors may be used to endorse or promote products derived from
117117
this software without specific prior written permission.
118118

119-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
120-
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
121-
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122-
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
123-
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
124-
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
125-
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
126-
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
127-
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
128-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
120+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
121+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
122+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
123+
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
124+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
125+
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
126+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
127+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
128+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129130

130131
----------------------------------------
131132

@@ -160,7 +161,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
160161

161162
Package: requests
162163
License: Apache-2.0
163-
Requires: charset-normalizer, idna, urllib3, certifi
164+
Requires: charset_normalizer, idna, urllib3, certifi
164165
Author: Kenneth Reitz <me@kennethreitz.org>
165166
Home page: https://requests.readthedocs.io
166167

@@ -372,12 +373,12 @@ IN THE SOFTWARE.
372373
Package: urllib3
373374
License: MIT
374375
Requires: n/a
375-
Author: Andrey Petrov <andrey.petrov@shazow.net>
376-
Home page: https://urllib3.readthedocs.io/
376+
Author: (unknown) <Andrey Petrov <andrey.petrov@shazow.net>>
377+
Home page: None
377378

378379
MIT License
379380

380-
Copyright (c) 2008-2020 Andrey Petrov and contributors (see CONTRIBUTORS.txt)
381+
Copyright (c) 2008-2020 Andrey Petrov and contributors.
381382

382383
Permission is hereby granted, free of charge, to any person obtaining a copy
383384
of this software and associated documentation files (the "Software"), to deal
@@ -402,8 +403,8 @@ SOFTWARE.
402403
Package: wheel
403404
License: MIT
404405
Requires: n/a
405-
Author: Daniel Holth <dholth@fastmail.fm>
406-
Home page: https://github.com/pypa/wheel
406+
Author: (unknown) <Daniel Holth <dholth@fastmail.fm>>
407+
Home page: None
407408

408409
MIT License
409410

@@ -429,4 +430,4 @@ OTHER DEALINGS IN THE SOFTWARE.
429430

430431
----------------------------------------
431432

432-
End of 'THIRDPARTYLICENSES' generated by Python third_party_license_generator at 2023-02-22 21:58:48.921301
433+
End of 'THIRDPARTYLICENSES' generated by Python third_party_license_generator at 2025-06-18 04:59:56.875292

build-tag-and-push.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
python_version="3.12"
6+
image_base="$(basename "$(pwd)")-build-tag-and-push"
7+
image="${image_base}:${python_version}"
8+
container="${image_base}-${python_version}"
9+
10+
if ! test -e "${HOME}/.pypirc"; then
11+
echo "error: failed to find ${HOME}/.pypirc"
12+
exit 1
13+
fi
14+
15+
docker build --build-arg "VERSION=${python_version}" -f ./Dockerfile -t "${image}" .
16+
17+
docker run --rm --name "${container}" -v "${HOME}/.pypirc:/root/.pypirc" --workdir "/srv/python-third-party-license-file-generator" --entrypoint bash "${image}" -c "python setup.py sdist && twine upload dist/*"

docker-entrypoint.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
python -u -m third_party_license_file_generator \
6+
-r /srv/python-third-party-license-file-generator/requirements.txt \
7+
-p "$(which python)" \
8+
--do-not-skip-not-required-packages \
9+
--permit-gpl
10+
11+
echo ""
12+
13+
if ! test -e THIRDPARTYLICENSES; then
14+
echo "error: couldn't find THIRDPARTYLICENSES- something has gone badly wrong"
15+
16+
exit 1
17+
fi
18+
19+
cat THIRDPARTYLICENSES
20+
21+
echo ""

requirements.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
1-
requests>=2.25
2-
PyYAML>=5.4
1+
requests>=2.25; python_version>="3.0"
2+
PyYAML>=5.4; python_version>="3.0"
3+
4+
# just hope for the best w/ Python2
5+
requests>=2.25; python_version<"3.0"
6+
PyYAML<5.4; python_version<"3.0"

setup.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,27 @@
44
https://github.com/pypa/sampleproject
55
"""
66

7+
import datetime
8+
79
# To use a consistent encoding
810
from codecs import open
911
from os import path
1012

1113
# Always prefer setuptools over distutils
1214
from setuptools import find_packages, setup
1315

16+
python3 = True
17+
18+
try:
19+
import sys
20+
21+
if sys.version_info < (3, 0):
22+
python3 = False
23+
except Exception:
24+
pass
25+
26+
now = datetime.datetime.now()
27+
1428
here = path.abspath(path.dirname(__file__))
1529

1630
# Get the long description from the README file
@@ -22,7 +36,11 @@
2236
# Versions should comply with PEP440. For a discussion on single-sourcing
2337
# the version across setup.py and the project code, see
2438
# https://packaging.python.org/en/latest/single_source_version.html
25-
version="2024.8.23",
39+
version="{}.{}.{}".format(
40+
now.year,
41+
now.month,
42+
now.day,
43+
),
2644
description='The Python third_party_license_file_generator is aimed at distilling down the appropriate license for one or many pip "requirements" files into a single file; it supports Python2.7 and Python3.',
2745
long_description=long_description,
2846
long_description_content_type="text/markdown",
@@ -62,10 +80,17 @@
6280
# your project is installed. For an analysis of "install_requires" vs pip's
6381
# requirements files see:
6482
# https://packaging.python.org/en/latest/requirements.html
65-
install_requires=[
66-
"requests>=2.25",
67-
"PyYAML>=5.4",
68-
],
83+
install_requires=(
84+
[
85+
"requests>=2.25",
86+
"PyYAML>=5.4",
87+
]
88+
if python3
89+
else [
90+
"requests>=2.25",
91+
"PyYAML<5.4",
92+
]
93+
),
6994
# List additional groups of dependencies here (e.g. development
7095
# dependencies). You can install these using the following syntax,
7196
# for example:

test.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
image_base="$(basename "$(pwd)")-test"
6+
7+
VERSIONS=${VERSIONS:-"2.7 3.9 3.12 3.13"}
8+
9+
for version in ${VERSIONS}; do
10+
image="${image_base}:${version}"
11+
12+
echo ""
13+
echo "!!!!"
14+
echo "!!!! building ${image}"
15+
echo "!!!!"
16+
echo ""
17+
18+
if ! docker build --build-arg "VERSION=${version}" -f ./Dockerfile -t "${image}" .; then
19+
echo "error: failed to build ${image}"
20+
exit 1
21+
fi
22+
done
23+
24+
for version in ${VERSIONS}; do
25+
container="${image_base}-${version}"
26+
image="${image_base}:${version}"
27+
28+
echo ""
29+
echo "!!!!"
30+
echo "!!!! running ${image}"
31+
echo "!!!!"
32+
echo ""
33+
34+
if ! docker run --rm --name "${container}" --workdir /test "${image}"; then
35+
echo "error: failed to run ${image}"
36+
exit 1
37+
fi
38+
done

0 commit comments

Comments
 (0)