diff --git a/.github/workflows/docs-ci.yml b/.github/workflows/docs-ci.yml index 44b1352ccd9..a85ae2f3800 100644 --- a/.github/workflows/docs-ci.yml +++ b/.github/workflows/docs-ci.yml @@ -12,7 +12,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: [3.12] + python-version: [3.13] steps: - name: Checkout code @@ -24,14 +24,12 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install Dependencies - run: pip install -e .[docs] + run: ./configure --dev - - name: Check Sphinx Documentation build minimally - working-directory: ./docs - run: sphinx-build -E -W source build + - name: Check documentation and HTML for errors and dead links + run: make docs-check - - name: Check for documentation style errors - working-directory: ./docs - run: ./scripts/doc8_style_check.sh + - name: Check documentation for style errors + run: make doc8 diff --git a/.github/workflows/scancode-release.yml b/.github/workflows/scancode-release.yml index 5b3e5307023..d8b932463a2 100644 --- a/.github/workflows/scancode-release.yml +++ b/.github/workflows/scancode-release.yml @@ -5,7 +5,7 @@ name: Create ScanCode release archives, then test and publish to GH and PyPI # Summary of the steps: # - Build wheel and sdist for the "main" scancode, then build these for the "mini" flavor # - test each wheel and sdist on every possible OS x Python version combinations - # - Build release app archives, one for each of linux, windows, macos on Python 3.9 to 3.12 + # - Build release app archives, one for each of linux, windows, macos on Python 3.9 to 3.13 # - test each on its target OS and Python version # - Create gh-release and upload app archives to release # - Upload all wheels and sdist to PyPI @@ -34,7 +34,7 @@ jobs: strategy: fail-fast: true matrix: - pyver: ["3.9", "3.10", "3.11", "3.12"] + pyver: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 @@ -74,7 +74,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Install requirements then build main and mini sdist run: etc/release/scancode-create-pypi-sdist.sh @@ -100,7 +100,7 @@ jobs: strategy: fail-fast: true matrix: - pyver: ["3.9", "3.10", "3.11", "3.12"] + pyver: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 @@ -135,7 +135,7 @@ jobs: strategy: fail-fast: true matrix: - pyver: ["3.9", "3.10", "3.11", "3.12"] + pyver: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 @@ -170,7 +170,7 @@ jobs: strategy: fail-fast: true matrix: - pyver: ["3.9", "3.10", "3.11", "3.12"] + pyver: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 @@ -211,7 +211,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.12" + python-version: "3.13" - name: Build source archive with deps run: etc/release/scancode-create-release-app-sources.sh @@ -240,7 +240,7 @@ jobs: fail-fast: true matrix: os: [ubuntu-24.04, ubuntu-24.04, macos-13, macos-14] - pyver: ["3.9", "3.10", "3.11", "3.12"] + pyver: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 @@ -285,8 +285,8 @@ jobs: strategy: fail-fast: true matrix: - os: [windows-2019, windows-2022] - pyver: ["3.9", "3.10", "3.11", "3.12"] + os: [windows-2025, windows-2022] + pyver: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 @@ -331,7 +331,7 @@ jobs: fail-fast: true matrix: os: [ubuntu-24.04, ubuntu-24.04] - pyver: ["3.9", "3.10", "3.11", "3.12"] + pyver: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 @@ -349,7 +349,7 @@ jobs: - name: test install app archive run: | - for f in `find dist -type f -name "*.tar.gz"`; \ + for f in `find dist -type f -name "*.zip"`; \ do \ python etc/release/scancode_release_tests.py $f; \ done @@ -372,7 +372,7 @@ jobs: fail-fast: true matrix: os: [macos-13, macos-14] - pyver: ["3.9", "3.10", "3.11", "3.12"] + pyver: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 @@ -390,7 +390,7 @@ jobs: - name: test install app archive run: | - for f in `find dist -type f -name "*.tar.gz"`; \ + for f in `find dist -type f -name "*.zip"`; \ do \ python etc/release/scancode_release_tests.py $f; \ done @@ -412,8 +412,8 @@ jobs: strategy: fail-fast: true matrix: - os: [windows-2019, windows-2022] - pyver: ["3.9", "3.10", "3.11", "3.12"] + os: [windows-2025, windows-2022] + pyver: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v4 @@ -485,6 +485,12 @@ jobs: name: macos_app_py_3.12 path: dist + - name: Download a single artifact macos_app for python 3.13 + uses: actions/download-artifact@v4 + with: + name: macos_app_py_3.13 + path: dist + - name: Download a single artifact linux_app for python 3.9 uses: actions/download-artifact@v4 with: @@ -509,6 +515,12 @@ jobs: name: linux_app_py_3.12 path: dist + - name: Download a single artifact linux_app for python 3.13 + uses: actions/download-artifact@v4 + with: + name: linux_app_py_3.13 + path: dist + - name: Download a single artifact windows_app for python 3.9 uses: actions/download-artifact@v4 with: @@ -533,6 +545,12 @@ jobs: name: windows_app_py_3.12 path: dist + - name: Download a single artifact windows_app for python 3.13 + uses: actions/download-artifact@v4 + with: + name: windows_app_py_3.13 + path: dist + - name: Mock GH release run: | ls -al dist @@ -559,13 +577,13 @@ jobs: strategy: fail-fast: true matrix: - dist_names: ["wheels-3.9", "wheels-3.10", "wheels-3.11", "wheels-3.12", sdists] + dist_names: ["wheels-3.9", "wheels-3.10", "wheels-3.11", "wheels-3.12", "wheels-3.13", sdists] steps: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: 3.13 - name: Download a single artifact uses: actions/download-artifact@v4 diff --git a/.gitignore b/.gitignore index 24320ca9330..95df8c9d855 100644 --- a/.gitignore +++ b/.gitignore @@ -114,3 +114,5 @@ selenium # Ignore extra rpmdb sqlite stuff rpmdb.sqlite-* +/.ruff_cache/ +.env diff --git a/.readthedocs.yml b/.readthedocs.yml index 49dc506da7f..15beab53edf 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -32,4 +32,4 @@ python: - method: pip path: . extra_requirements: - - docs + - dev diff --git a/AUTHORS.rst b/AUTHORS.rst index 43e7ca97b0e..3ef1709b8af 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -48,7 +48,7 @@ The following organizations or individuals have contributed to ScanCode: - Mankaran Singh @MankaranSingh - Marc-Etienne Vargenau @vargenau - Martin Petkov @MartinPetkov -- Maximilian Huber @maxhbr +- Maximilian Huber @maxhbr - Michael Herzog @mjherzog - Michael Rupprecht @michaelrup - Mike Rombout @mrombout @@ -89,7 +89,7 @@ The following organizations or individuals have contributed to ScanCode: - Thomas Druez @tdruez - Thomas Steenbergen @tsteenbe - Thorsten Harter @ThorstenHarter -- Till Jaeger @LeChasseur +- Till Jaeger @LeChasseur - Tobias Furuholm @furuholm - Tushar Goel @TG1999 - Tushar Mittal @techytushar @@ -97,7 +97,7 @@ The following organizations or individuals have contributed to ScanCode: - Van Lindberg @VanL - Vibhu Agarwal @Vibhu-Agarwal - Viktor Tiulpin @tiulpin -- Vinay Kumar Singh @Vinay0001 +- Vinay Kumar Singh @Vinay0001 - Virag Umathe @viragumathe5 - Yash D. Saraf @yashdsaraf - Yash Nisar @yash-nisar diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 95056b8b3da..7cc1c61632e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -27,18 +27,6 @@ v33.0.0 (next next, roadmap) - `--unknown-licenses` is removed and this is always enabled and only used in case of improper detections automatically. -- All license rules have been tagged with required phrases to improve detection accuracy - and reduce false positives. See https://github.com/nexB/scancode-toolkit/issues/3300 - -- Equivalent words like license and licence, as well as plurals are now treated as the same in - license detection. With this, many redundant rules have been deprecated. - -- The license detection accuracy of Maven POMS has been improved fixing corner cases. - -- default value for `--processes` was previously 1. It was changed - to (number of CPUs)-1. - See https://github.com/aboutcode-org/scancode-toolkit/issues/2980 - - File categorization support added, a post scan plugin tagging files with priority levels for review, and also take advantage of these in other summary plugins. @@ -50,9 +38,72 @@ v33.0.0 (next next, roadmap) - Update ABOUT files to adapt the ABOUT File Specification. See https://github.com/aboutcode-org/scancode-toolkit/issues/4181 +v32.4.0 - 2025-06-26 +-------------------- + +This is a feature release with:: + + - python 3.13 support + - support added for adding required phrases to rules automatically + - misc license and package detection improvements + - new and updated license detection rules and new licenses + - misc bugfixes, dependency and documentation updates + +There are new data attributes, and we have a output format version bump +from ``4.0.0`` to ``4.1.0``. The changes in Output Data Structure are: + + - A new resource level attribute ``sha1_git`` is added, which has + the corresponding checksum value for files, and is empty for + directories. This is returned optionally with the ``--info`` plugin. + + - A new resource level attribute ``is_community`` is added, which is + True from commonly used files used for community/project maintainence. + This is returned optionally with the ``--classify`` plugin. + +These are the details for the most important changes introduced:: + +- Add support for adding required phrases in rules automatically using + some console scripts and CLI options using already marked required + phrases for the same license-expression and license field attributes + The new console scripts are: + - `add-required-phrases` to add required phrases from other rules or + license attributes + - `gen-new-required-phrases-rules` to add required phrase rules for + marked required phrase in rules + This improves detection accuracy and reduces false positives. + https://github.com/aboutcode-org/scancode-toolkit/pull/3924 + https://github.com/aboutcode-org/scancode-toolkit/pull/4237 + https://github.com/aboutcode-org/scancode-toolkit/pull/4241 + +- Default value of processes used for scancode scans is changed from + 1 to `N-1`, where N is the number of CPU processes available in the + system. https://github.com/aboutcode-org/scancode-toolkit/pull/4104 + - Also return sha1_git checksums for each files with ``--info`` plugin. https://github.com/aboutcode-org/scancode-toolkit/issues/624 +- Equivalent words like license and licence, as well as plurals are + now treated as the same in license detection. With this, + many redundant rules have been deprecated. + https://github.com/aboutcode-org/scancode-toolkit/pull/4215 + +- Support running scancode with python3.13 + Update and use latest native dependencies with py3.13 support, + update and test py3.13 usage in CI and other scripts, and + update other third-party dependencies, use latest skeleton + https://github.com/aboutcode-org/scancode-toolkit/pull/4430 + +- Misc license detection improvements, new licenses and license + detection rules. + https://github.com/aboutcode-org/scancode-toolkit/pull/4261 + https://github.com/aboutcode-org/scancode-toolkit/pull/4412 + https://github.com/aboutcode-org/scancode-toolkit/pull/4405 + https://github.com/aboutcode-org/scancode-toolkit/pull/4278 + https://github.com/aboutcode-org/scancode-toolkit/pull/4093 + +- Fix an issues where `pip install scancode-toolkit` was failing + because of a compatibility issue with Click + https://github.com/aboutcode-org/scancode-toolkit/pull/4427 v32.3.3 - 2025-03-06 -------------------- @@ -1795,14 +1846,16 @@ v3.2.0rc1 (2020-09-08) - Add new license rules for "bad" licenses #1899 @viragumathe5 - Improve copyright detection @WizardOhio24 - Improve tests @hanif-ali - - Add and improve support for package manifest for #2080 Go, Ruby gem gemspec, Cocoapod podspec, opam, Python PKG-INFO - Rohit Potter @rpotter12 - - Add and improve support for package lockfiles for Pipfile.lock, requirements.tx, Cargo.lock - Rohit Potter @rpotter12 + - Add and improve support for package manifest for #2080 Go, Ruby gem gemspec, + Cocoapod podspec, opam, Python PKG-INFO - Rohit Potter @rpotter12 + - Add and improve support for package lockfiles for Pipfile.lock, + requirements.tx, Cargo.lock - Rohit Potter @rpotter12 - Add new --max-depth option to limit sca depth - Hanif Ali @hanif-ali - Add initial Debian packaging - @aj4ayushjain - Add new documentation web site and documentation generation system - The "headers" attribute in JSON outputs now contains a 'duration' field. #1942 - Rework packaging and third-party support handling: Create new scripts and - process to provision, install and manage third-party dependencies - Abhishek Kumar @Abhishek-Dev09 + process to provision, install and manage third-party dependencies @Abhishek-Dev09 - Improve CSV output and fix manifest path bug #1718 Aditya Viki8 - Add new documentation, as well as tools and process. Ayan Sinha Mahapatra - Add new license detection rules - Ayan Sinha Mahapatra @@ -1830,9 +1883,12 @@ v3.2.0rc1 (2020-09-08) - Improve Documentation - Michael Herzog - Add new checksum type for sha256 - Nitish @nitish81299 - Improve documentation - Philippe Ombredanne - - Add new license detection rules and improve detection #1777 #1720 #1734 #1486 #1757 #1749 #1283 #1795 #2214 #1978 - - Add new license detection rules and improve detection #2187 #2188 #2189 #1904 #2207 #1905 #419 #2190 #1910 #1911 - - Add new license detection rules and improve detection #1841 #1913 #1795 #2124 #2145 #1800 #2200 #2206 #2186 + - Add new license detection rules and improve detection + #1777 #1720 #1734 #1486 #1757 #1749 #1283 #1795 #2214 #1978 + - Add new license detection rules and improve detection + #2187 #2188 #2189 #1904 #2207 #1905 #419 #2190 #1910 #1911 + - Add new license detection rules and improve detection + #1841 #1913 #1795 #2124 #2145 #1800 #2200 #2206 #2186 - Allow to call "run_scan" as a function #1780 - Update license data to SPDX 3.7 #1789 - Collect matched license text correctly including with Turkish diacritics #1872 @@ -1873,7 +1929,8 @@ Major new feature: New features: - - Improve package manifest support for #1643 RPMs, #1628 Cran, Python #1600, Maven #1649 Chef #1600 @licodeli @JonoYang + - Improve package manifest support for #1643 RPMs, #1628 Cran, Python #1600, + Maven #1649 Chef #1600 @licodeli @JonoYang - Add plugin to collect ELF and LKM clues #1685 @licodeli - Add runtime support for FreeBSD #1695 @knobix - Add support to extract lzip archives #245 #989 @@ -1950,15 +2007,18 @@ Other: v2.9.9 (2018-12-12) ------------------- -This is the penultimate pre-release of what will come up for 3.0 with some API change for packages. +This is the penultimate pre-release of what will come up for 3.0 +with some API change for packages. API changes: - - Streamline Package models #1226 #1324 and #1327. In particular the way checksums are managed has changed + - Streamline Package models #1226 #1324 and #1327. + In particular the way checksums are managed has changed Other changes: - Copyright detection improvements #1305 by @JonoYang - Correct CC-BY V3.0 and V4.0 license texts by correct one by @sschuberth #1320 - - Add new and improved licenses and license detection rules including the latest SPDX list 3.4 and #1322 #1324 + - Add new and improved licenses and license detection rules including + the latest SPDX list 3.4 and #1322 #1324 - Rename proprietary license key to proprietary-license - Rename commercial license key to commercial-license - Improve npm package.json handling #1308 and #1314 by @majurg @@ -1971,14 +2031,16 @@ This is a close-to-final pre-release of what will come up for 3.0 with some API API changes: - In Package models, rename normalized_license to license_expression and - add license detection on the declared_license to populate the license_expression #1092 #1268 #1278 + add license detection on the declared_license to populate + the license_expression #1092 #1268 #1278 Outputs: - Do not open output files until the command lines are validated as correct #1266 - The html-app output is marked as DEPRECATED. Use the AboutCode manager app instead # - Ensure HTML outputs can deal with non-ASCII file paths without crashsing #1292 - JSON outputs now use a "headers" attributes for top-level scan headers # - - SPDX output is now possible even without "--info" SHA1 checksums. This creates a partially valid document + - SPDX output is now possible even without "--info" SHA1 checksums. + This creates a partially valid document - LicenseRef for non-SPDX ScanCode licenses are named as "LicenseRef-scancode-" # - license_expression are correctly included in the CSV output #1238 - do not crash with multiple outputs #1199 @@ -1990,7 +2052,8 @@ License detection: - An optional "relevance" attribute has been added to the license YAML attributes. This is to store the relevance to e matched .LICENSE text when used as a rule. - - Licenses have been synchronized with the latest v3.3 SPDX license list and the latest DejaCode licenses #1242 + - Licenses have been synchronized with the latest v3.3 SPDX license list + and the latest DejaCode licenses #1242 - Duplicated SPDX keys have been fixed #1264 - Add new and improved license detection rules #1313 #1306 #1302 #1298 #1293 #1291 #1289 #1270 #1269 #1192 #1186 #1170 #1164 #1128 #1124 #1112 #1110 #1108 @@ -2000,7 +2063,8 @@ Packages: - Add support for haxe "haxelib" package manifests #1227 - Remove code_type attribute from Package models - In Package models, rename normalized_license to license_expression and - add license detection on the declared_license to populate the license_expression #1092 #1268 #1278 + add license detection on the declared_license to populate the + license_expression #1092 #1268 #1278 - Improve data returned for PHP Composer packages - Add PackageURL to top level output for packages - Report nuget as proper packages #1088 @@ -2126,7 +2190,8 @@ API change: - The returned copyright data structure has changed and is now simpler and less nested Licenses: - - Add new license and rules and improve licene rules #1186 #1108 #1124 #1171 #1173 #1039 #1098 #1111 + - Add new license and rules and improve licene rules + #1186 #1108 #1124 #1171 #1173 #1039 #1098 #1111 - Add new license clarity scoring #1180 This is also for use in the ClearlyDefined project - Add is_exception to license scan results #1159 diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 1ab35f0fb78..c16ecdeed9e 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -77,7 +77,7 @@ Documentation improvements ========================== Documentation can come in the form of new documentation pages/sections, tutorials/how-to documents, -any other general upgrades, etc. Even a minor typo fix is welcomed. +any other general upgrades, etc. Even a minor typo fix is welcomed. If something is missing in the documentation or if you found some part confusing, please file an issue with your suggestions for improvement. Use the “Documentation Improvement” @@ -104,25 +104,25 @@ To set up ScanCode for local development: git clone https://github.com/your_name_here/scancode-toolkit.git - See also GitHub docs for `SSH `_ + See also GitHub docs for `SSH `_ or `HTTPS `_ - + If you want to change the connection type, do following - + SSH to HTTPS :: - + git remote set-url https://github.com/your_name_here/scancode-toolkit.git - + HTTPS to SSH :: - + git remote set-url git@github.com:your_name_here/scancode-toolkit.git - + Generally is named origin, but in the case of multiple fetch/pull source of repository you can choose whatever name you want - + 3. Create a branch for local development:: git checkout -b name-of-your-bugfix-or-feature - + 4. Check out the Contributing to Code Development `documentation `_, as it contains more in-depth guide for contributing code and documentation. 5. To configure your local environment for development, locate to the main @@ -130,7 +130,7 @@ To set up ScanCode for local development: The configure script creates an isolated Python `virtual environment` in your checkout directory, the Python `pip` tool, and installs the third-party libraries (from the `thirdparty/ directory`), setup the paths, etc. - See https://virtualenv.pypa.io/en/latest/ for more details. + See https://virtualenv.pypa.io/en/latest/ for more details. Run this command to configure ScanCode:: @@ -160,15 +160,17 @@ To set up ScanCode for local development: 6. Now you can make your code changes in your local clone. Please create new unit tests for your code. We love tests! -7. An update to the ``CHANGELOG`` is required if any important changes are made that needs to be communicated such as: +7. An update to the ``CHANGELOG`` is required if any important changes are made + that needs to be communicated such as: * Changes in the API. * Addition or deletion of CLI options. * Addition of any new feature or any other miscellaneous changes to the program. - -8. If there is a code change, a significant document, or any other changes, you must update the ``AUTHORS`` to include your own name. + +8. If there is a code change, a significant document, or any other changes, + you must update the ``AUTHORS`` to include your own name. 9. When you are done with your changes, run all the tests. Use this command:: diff --git a/INSTALL.rst b/INSTALL.rst index 9e34a869e20..1aa9eb9ba8c 100644 --- a/INSTALL.rst +++ b/INSTALL.rst @@ -16,9 +16,10 @@ Prerequisites ------------- Before installing ScanCode make sure you have installed these prerequisites. -The main one is to have Python installed version 3.9, 3.10, 3.11 or 3.12 +The main one is to have Python installed version 3.9, 3.10, 3.11, 3.12 or 3.13. -- For Linux(Ubuntu): ``sudo apt install python3.9-dev bzip2 xz-utils zlib1g libxml2-dev libxslt1-dev`` +- For Linux(Ubuntu): + ``sudo apt install python3.9-dev bzip2 xz-utils zlib1g libxml2-dev libxslt1-dev`` - For MacOS: Install Python 3.x from https://www.python.org/ - For Windows: Install Python 3.x from https://www.python.org/ using the 64 bits amd64 variant - For FreeBSD: (this needs to be documented) @@ -34,7 +35,7 @@ Use a release download and install as an application https://github.com/nexB/scancode-toolkit/releases/ - Open a terminal window (or command prompt on Windows) and then `cd` to the - extracted ScanCode directory. + extracted ScanCode directory. - Run this command to self-configure and display the initial command line help: diff --git a/MANIFEST.in b/MANIFEST.in index 9334b861a6b..cc43a217419 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,6 @@ graft src +graft docs +graft etc graft thirdparty graft etc/thirdparty @@ -10,6 +12,7 @@ include *.ABOUT include *.toml include *.yml include *.rst +include *.png include setup.* include configure* include requirements* @@ -22,7 +25,14 @@ include scancode* include PYTHON_EXECUTABLE include Dockerfile +include .dockerignore +include .gitignore +include .readthedocs.yml +include manage.py +include Dockerfile* +include Makefile +include MANIFEST.in + include .VERSION global-exclude *.py[co] __pycache__ *.*~ - diff --git a/Makefile b/Makefile new file mode 100644 index 00000000000..9203d79201f --- /dev/null +++ b/Makefile @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# ScanCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/aboutcode-org/skeleton for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# + +# Python version can be specified with `$ PYTHON_EXE=python3.x make conf` +PYTHON_EXE?=python3 +VENV=venv +ACTIVATE?=. ${VENV}/bin/activate; + + +conf: + @echo "-> Install dependencies" + ./configure + +dev: + @echo "-> Configure and install development dependencies" + ./configure --dev + +doc8: + @echo "-> Run doc8 validation" + @${ACTIVATE} doc8 --max-line-length 100 --ignore D000 --quiet docs/ *.rst + +valid: + @echo "-> Run Ruff format" + @${ACTIVATE} ruff format + @echo "-> Run Ruff linter" + @${ACTIVATE} ruff check --fix + +check: + @echo "-> Run Ruff linter validation (pycodestyle, bandit, isort, and more)" + @${ACTIVATE} ruff check + @echo "-> Run Ruff format validation" + @${ACTIVATE} ruff format --check + @$(MAKE) doc8 + @echo "-> Run ABOUT files validation" + @${ACTIVATE} about check etc/ + +clean: + @echo "-> Clean the Python env" + ./configure --clean + +test: + @echo "-> Run the test suite" + ${VENV}/bin/pytest -vvs + +docs: + rm -rf docs/_build/ + @${ACTIVATE} sphinx-build docs/source docs/_build/ + +docs-check: + @${ACTIVATE} sphinx-build -E -W -b html docs/source docs/_build/ + +.PHONY: conf dev check valid clean test docs docs-check diff --git a/README.rst b/README.rst index b660c05473b..9bae910bdcd 100644 --- a/README.rst +++ b/README.rst @@ -14,7 +14,7 @@ Discover also: - The ScanCode.io server project here: https://scancodeio.readthedocs.io - The ScanCode Workbench project for visualization of scancode results data: - https://github.com/nexB/scancode-workbench + https://github.com/nexB/scancode-workbench - Other companion SCA projects for code origin, license and security analysis here: https://aboutcode.org @@ -44,7 +44,7 @@ Why use ScanCode? `OpenEmbedded.org `_, the `FSFE `_, the `FSF `_, - `OSS Review Toolkit `_, + `OSS Review Toolkit `_, `ClearlyDefined.io `_, `RedHat Fabric8 analytics `_, and many more. @@ -89,7 +89,7 @@ Why use ScanCode? InstallShield installers, iOS apps, ISO images, Apache IVY, JBoss Sar, R CRAN, Apache Maven, Meteor, Mozilla extensions, MSI installers, JavaScript npm packages, package-lock.json, yarn.lock, NSIS Installers, - NuGet, OPam, Cocoapods, Python PyPI setup.py, setup.cfg, and + NuGet, OPam, Cocoapods, Python PyPI setup.py, setup.cfg, and several related lockfile formats, semi structured README files such as README.android, README.chromium, README.facebook, README.google, README.thirdparty, RPMs, Shell Archives, Squashfs images, Java WAR, Windows @@ -110,13 +110,13 @@ The ScanCode documentation is hosted at If you are new to visualization of scancode results data, start with our `newcomer `_ page. -If you want to compare output changes between different versions of ScanCode, +If you want to compare output changes between different versions of ScanCode, or want to look at scans generated by ScanCode, review our `reference scans `_. Other Important Documentation Pages: -- A `synopsis `_ +- A `synopsis `_ of ScanCode command line options. - Tutorials on: @@ -139,15 +139,15 @@ Installation ============ Before installing ScanCode make sure that you have installed the prerequisites -properly. This means installing Python 3.9 for x86/64 architectures. -We support Python 3.9, 3.10, 3.11 and 3.12. +properly. This means installing Python 3.10 for x86/64 architectures. +We support Python 3.9, 3.10, 3.11, 3.12 and 3.13. See `prerequisites `_ for detailed information on the support platforms and Python versions. There are a few common ways to `install ScanCode `_. -- `**Installation as an application: Install Python 3.9, download a release archive, extract and run**. +- `**Installation as an application: Install Python 3.9, download a release archive, extract and run**. `_ This is the recommended installation method. @@ -271,19 +271,18 @@ This project is funded, supported and sponsored by: - Generous support and contributions from users like you! - the European Commission NGI programme -- the NLnet Foundation +- the NLnet Foundation - the Swiss State Secretariat for Education, Research and Innovation (SERI) - Google, including the Google Summer of Code and the Google Seasons of Doc programmes - Mercedes-Benz Group - Microsoft and Microsoft Azure - AboutCode ASBL -- nexB Inc. +- nexB Inc. +|europa| |dgconnect| -|europa| |dgconnect| - -|ngi| |nlnet| +|ngi| |nlnet| |aboutcode| |nexb| @@ -297,7 +296,7 @@ Communications Networks, Content and Technology under grant agreement No 825322. This project was funded through the NGI0 Entrust Fund, a fund established by NLnet with financial support from the European Commission's Next Generation Internet programme, under the aegis of DG -Communications Networks, Content and Technology under grant agreement No 101069594. +Communications Networks, Content and Technology under grant agreement No 101069594. |ngizeroentrust| https://nlnet.nl/project/Back2source/ @@ -311,7 +310,7 @@ Communications Networks, Content and Technology under grant agreement No 1010929 This project was funded through the NGI0 Core Fund, a fund established by NLnet with financial support from the European Commission's Next Generation Internet programme, under the aegis of DG -Communications Networks, Content and Technology under grant agreement No 101092990. +Communications Networks, Content and Technology under grant agreement No 101092990. |ngizerocore| https://nlnet.nl/project/FastScan/ @@ -326,7 +325,7 @@ funding is made available by the Swiss State Secretariat for Education, Research This project was funded through the NGI0 Entrust Fund, a fund established by NLnet with financial support from the European Commission's Next Generation Internet programme, under the aegis of DG -Communications Networks, Content and Technology under grant agreement No 101069594. +Communications Networks, Content and Technology under grant agreement No 101069594. |ngizeroentrust| https://nlnet.nl/project/purl2sym/ @@ -395,9 +394,3 @@ Communications Networks, Content and Technology under grant agreement No 1010695 :target: https://nlnet.nl/discovery/ :height: 40 :alt: NGI Discovery logo - - - - - - diff --git a/ROADMAP-ABOUTCODE.rst b/ROADMAP-ABOUTCODE.rst index 7e7fc15a0e2..be4800281ef 100644 --- a/ROADMAP-ABOUTCODE.rst +++ b/ROADMAP-ABOUTCODE.rst @@ -94,7 +94,7 @@ License detection quality improvements Improve package detection ~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Create synthethic, private packages from non-packaged files based on license and copyright +- Create synthethic, private packages from non-packaged files based on license and copyright - Create simplified purl-only lightweight package detection - Evolve model for dependencies towards requirements and true dependencies - Track private non-published packages @@ -102,7 +102,7 @@ Improve package detection Primary copyright detection for packages - This is closely tied to the primary license detection and should focus - on package manifests and key files. + on package manifests and key files. - Support copyright parsing from all package ecosystems. @@ -130,7 +130,7 @@ ABCTK: AboutCode Toolkit - add support for patterns for docoumented resources - add support for exclude for docoumented resources - document deployed resource for a development resource - + PURLDB: PurlDB ---------------- @@ -154,7 +154,7 @@ VCIO: VulnerableCode.io - Adopt VulnTotal model throughout - Log advisory history - Add vulnerable code reachability -- Add vulnerable code required context/config +- Add vulnerable code required context/config - Add more upstream resources - Deploy purlsync public pilot @@ -178,14 +178,14 @@ INSPECTORS: misc package and technology inspectors - Decompile and collect binary symbols. - Collect source symbols - - Resolve dependencies for Gradle, SBT and Maven. + - Resolve dependencies for Gradle, SBT and Maven. - Inspector for JavaScript, CSS - Decompile/deminify and collect bundled and minified symbols. - Analyze map files - Collect source symbols - - Resolve dependencies for npm, yarn and pnpm. + - Resolve dependencies for npm, yarn and pnpm. - Inspector for C/C++ - Collect source symbols diff --git a/ROADMAP.rst b/ROADMAP.rst index ebb58ce241c..4afd31d6cdf 100644 --- a/ROADMAP.rst +++ b/ROADMAP.rst @@ -1,7 +1,7 @@ ScanCode IO/TK Roadmap ======================== -SCIO: ScanCode.io +SCIO: ScanCode.io SCTK: ScanCode Toolkit Top Issues @@ -22,13 +22,13 @@ The goal of this improvement is to: - In a license detection, expose a primary license expression in addition to the complete, full license expression. - + - Make the logic of selection of the primary license visible, at the minimum with a log of combination and primary license selection operations. This is for SCTK first. -Status: +Status: This has been completed in SCTK and also included in SCIO. We use an updated --summary option and a new license clarity score for this. @@ -93,18 +93,18 @@ Roadmap - SCTK: add primary license field in package output and populate this based on package-type/ecosystem conventions. -- SCTK: also populate secondary license fields +- SCTK: also populate secondary license fields - SCIO: add primary license field in DiscoveredPackage models and feed it with the data from packages - SCIO: Do we track secondary? or is this just data aggregated on the fly. -- SCIO: Refine primary license based on license in "key files" +- SCIO: Refine primary license based on license in "key files" 2. Primary copyright detection for packages ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - This is closely tied to the primary license detection and should focus - on package manifests and key files. + on package manifests and key files. - Support copyright parsing from all package ecosystems. 3. Package files @@ -135,7 +135,8 @@ Roadmap 6. License detection quality improvements ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Finish and merge unknown license detection (this depends on completion of 4. Go to two-level reporting of detections for license) +- Finish and merge unknown license detection (this depends on completion of 4. + Go to two-level reporting of detections for license) - Update scancode-analyze to the new two-level reporting of license detections - Revamp how common list of suprrious licenses are detected (this is a bug) - Use important key phrases for license detection https://github.com/nexB/scancode-toolkit/issues/2637 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index eef4c1fbb39..97f9bae6290 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -15,7 +15,7 @@ jobs: parameters: job_name: core_tests image_name: ubuntu-24.04 - python_versions: ['3.10'] + python_versions: ['3.13'] test_suites: misc_and_scancode: | # cli tests are launched below on all OSes @@ -123,7 +123,7 @@ jobs: job_name: ubuntu24_cpython image_name: ubuntu-24.04 python_architecture: x64 - python_versions: ['3.9', '3.10', '3.11', '3.12'] + python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13'] test_suites: all: venv/bin/pytest -n 2 -vvs tests/scancode/test_cli.py --reruns 2 @@ -132,7 +132,7 @@ jobs: job_name: ubuntu22_cpython image_name: ubuntu-22.04 python_architecture: x64 - python_versions: ['3.9', '3.10', '3.11', '3.12'] + python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13'] test_suites: all: venv/bin/pytest -n 2 -vvs tests/scancode/test_cli.py --reruns 2 @@ -140,7 +140,7 @@ jobs: parameters: job_name: macos14_cpython image_name: macOS-14 - python_versions: ['3.9', '3.10', '3.11', '3.12'] + python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13'] python_architecture: x64 test_suites: all: venv/bin/pytest -n 2 -vvs tests/scancode/test_cli.py --reruns 2 @@ -149,14 +149,14 @@ jobs: parameters: job_name: macos13_cpython image_name: macOS-13 - python_versions: ['3.9', '3.10', '3.11', '3.12'] + python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13'] test_suites: all: venv/bin/pytest -n 2 -vvs tests/scancode/test_cli.py --reruns 2 - template: etc/ci/azure-win.yml parameters: - job_name: win2019_cpython_1 - image_name: windows-2019 + job_name: win2025_cpython + image_name: windows-2025 python_versions: ['3.9'] python_architecture: x64 test_suites: @@ -167,29 +167,10 @@ jobs: job_name: win2022_cpython image_name: windows-2022 python_architecture: x64 - python_versions: ['3.9', '3.10', '3.11', '3.12'] + python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13'] test_suites: all: venv\Scripts\pytest -n 2 -vvs tests\scancode\test_cli.py --reruns 2 - - template: etc/ci/azure-win.yml - parameters: - job_name: win2022_cpython_1 - image_name: windows-2022 - python_versions: ['3.9'] - python_architecture: x64 - test_suites: - all: venv\Scripts\pytest -n 2 -vvs tests\scancode\test_cli.py --reruns 2 - - - template: etc/ci/azure-win.yml - parameters: - job_name: win2022_cpython_2 - image_name: windows-2022 - python_versions: ['3.9', '3.10', '3.11', '3.12'] - python_architecture: x64 - test_suites: - all: venv\Scripts\pytest -n 2 -vvs tests\scancode\test_cli.py --reruns 2 - - ################################################################################ # Test using many version of Click to work around any regressions in their API ################################################################################ @@ -199,7 +180,7 @@ jobs: parameters: job_name: ubuntu22_test_all_supported_click_versions image_name: ubuntu-22.04 - python_versions: ['3.9', '3.10', '3.11', '3.12'] + python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13'] python_architecture: x64 test_suites: click_versions: | @@ -219,7 +200,7 @@ jobs: parameters: job_name: ubuntu22_cpython_latest_from_pip image_name: ubuntu-22.04 - python_versions: ['3.9', '3.10', '3.11', '3.12'] + python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13'] test_suites: all: venv/bin/pip install --upgrade-strategy eager --force-reinstall --upgrade -e .[testing] && venv/bin/pytest -n 2 -vvs tests/scancode/test_cli.py @@ -227,7 +208,7 @@ jobs: parameters: job_name: ubuntu24_cpython_latest_from_pip image_name: ubuntu-24.04 - python_versions: ['3.9', '3.10', '3.11', '3.12'] + python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13'] test_suites: all: venv/bin/pip install --upgrade-strategy eager --force-reinstall --upgrade -e .[testing] && venv/bin/pytest -n 2 -vvs tests/scancode/test_cli.py @@ -235,7 +216,7 @@ jobs: parameters: job_name: macos14_cpython_latest_from_pip image_name: macos-14 - python_versions: ['3.9', '3.10', '3.11', '3.12'] + python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13'] test_suites: all: venv/bin/pip install --upgrade-strategy eager --force-reinstall --upgrade -e .[testing] && venv/bin/pytest -n 2 -vvs tests/scancode/test_cli.py @@ -243,15 +224,15 @@ jobs: parameters: job_name: macos13_cpython_latest_from_pip image_name: macos-13 - python_versions: ['3.9', '3.10', '3.11', '3.12'] + python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13'] test_suites: all: venv/bin/pip install --upgrade-strategy eager --force-reinstall --upgrade -e .[testing] && venv/bin/pytest -n 2 -vvs tests/scancode/test_cli.py - template: etc/ci/azure-win.yml parameters: job_name: win2019_cpython_latest_from_pip - image_name: windows-2019 - python_versions: ['3.9', '3.10', '3.11', '3.12'] + image_name: windows-2025 + python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13'] test_suites: all: venv\Scripts\pip install --upgrade-strategy eager --force-reinstall --upgrade -e .[testing] && venv\Scripts\pytest -n 2 -vvs tests\scancode\test_cli.py @@ -259,7 +240,7 @@ jobs: parameters: job_name: win2022_cpython_latest_from_pip image_name: windows-2022 - python_versions: ['3.9', '3.10', '3.11', '3.12'] + python_versions: ['3.9', '3.10', '3.11', '3.12', '3.13'] test_suites: all: venv\Scripts\pip install --upgrade-strategy eager --force-reinstall --upgrade -e .[testing] && venv\Scripts\pytest -n 2 -vvs tests\scancode\test_cli.py @@ -270,5 +251,5 @@ jobs: - template: etc/ci/azure-posix-docker.yml parameters: - job_name: ubuntu22_build_container - image_name: ubuntu-22.04 + job_name: ubuntu24_build_container + image_name: ubuntu-24.04 diff --git a/configure b/configure index f20ec822eff..5c5c64adb71 100755 --- a/configure +++ b/configure @@ -149,17 +149,14 @@ if [[ $OSTYPE == 'darwin'* ]]; then fi # Requirement arguments passed to pip and used by default or with --dev. -REQUIREMENTS="--editable $BASE --constraint requirements.txt --constraint requirements-linux.txt" -DEV_REQUIREMENTS="--editable $BASE_DEV --constraint requirements.txt --constraint requirements-linux.txt --constraint requirements-dev.txt" -DOCS_REQUIREMENTS="--editable .[docs] --constraint requirements.txt" -REL_REQUIREMENTS="--requirement etc/scripts/requirements.txt" -PROD_REQUIREMENTS="scancode_toolkit*.whl" +REQUIREMENTS="--editable . --constraint requirements.txt" +DEV_REQUIREMENTS="--editable .[dev,packages] --constraint requirements.txt --constraint requirements-dev.txt" # where we create a virtualenv VIRTUALENV_DIR=venv # Cleanable files and directories to delete with the --clean option -CLEANABLE="tmp build dist venv .cache .eggs" +CLEANABLE="build dist venv .cache .eggs *.egg-info docs/_build/ pip-selfcheck.json" # extra arguments passed to pip PIP_EXTRA_ARGS=" " @@ -238,6 +235,7 @@ create_virtualenv() { $PYTHON_EXECUTABLE "$VIRTUALENV_PYZ" \ --wheel embed --pip embed --setuptools embed \ + --seeder pip \ --never-download \ --no-periodic-update \ --no-vcs-ignore \ @@ -293,6 +291,7 @@ clean() { for cln in $CLEANABLE; do rm -rf "${CFG_ROOT_DIR:?}/${cln:?}"; done + find . -type f -name '*.py[co]' -delete -o -type d -name __pycache__ -delete set +e exit } @@ -309,8 +308,6 @@ while getopts :-: optchar; do help ) cli_help;; clean ) find_python && clean;; dev ) CFG_REQUIREMENTS="$DEV_REQUIREMENTS";; - docs ) CFG_REQUIREMENTS="$DOCS_REQUIREMENTS";; - rel ) CFG_REQUIREMENTS="$REL_REQUIREMENTS";; esac;; esac done diff --git a/configure.bat b/configure.bat index 2421d350912..3314a31516e 100644 --- a/configure.bat +++ b/configure.bat @@ -27,9 +27,7 @@ @rem # Requirement arguments passed to pip and used by default or with --dev. set "REQUIREMENTS=--editable . --constraint requirements.txt" -set "DEV_REQUIREMENTS=--editable .[testing] --constraint requirements.txt --constraint requirements-dev.txt" -set "DOCS_REQUIREMENTS=--editable .[docs] --constraint requirements.txt" -set "REL_REQUIREMENTS=--requirement etc/scripts/requirements.txt" +set "DEV_REQUIREMENTS=--editable .[dev] --constraint requirements.txt --constraint requirements-dev.txt" @rem # where we create a virtualenv set "VIRTUALENV_DIR=venv" @@ -82,12 +80,6 @@ if not "%1" == "" ( if "%1" EQU "--dev" ( set "CFG_REQUIREMENTS=%DEV_REQUIREMENTS%" ) - if "%1" EQU "--docs" ( - set "CFG_REQUIREMENTS=%DOCS_REQUIREMENTS%" - ) - if "%1" EQU "--rel" ( - set "CFG_REQUIREMENTS=%REL_REQUIREMENTS%" - ) shift goto again ) diff --git a/docs/Makefile b/docs/Makefile index 4eeef58cf35..f9ba768b6c0 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -7,7 +7,7 @@ SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build SPHINXAUTOBUILD = sphinx-autobuild SOURCEDIR = source -BUILDDIR = build +BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: diff --git a/docs/scripts/doc8_style_check.sh b/docs/scripts/doc8_style_check.sh deleted file mode 100755 index 94163239416..00000000000 --- a/docs/scripts/doc8_style_check.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# halt script on error -set -e -# Check for Style Code Violations -doc8 --max-line-length 100 source --ignore D000 --quiet \ No newline at end of file diff --git a/docs/scripts/sphinx_build_link_check.sh b/docs/scripts/sphinx_build_link_check.sh deleted file mode 100755 index c5426863197..00000000000 --- a/docs/scripts/sphinx_build_link_check.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# halt script on error -set -e -# Build locally, and then check links -sphinx-build -E -W -b linkcheck source build \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index bfc53475592..cf0529c0a33 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -104,7 +104,8 @@ html_show_sphinx = True # Define CSS and HTML abbreviations used in .rst files. These are examples. -# .. role:: is used to refer to styles defined in _static/theme_overrides.css and is used like this: :red:`text` +# .. role:: is used to refer to styles defined in _static/theme_overrides.css +# and is used like this: :red:`text` rst_prolog = """ .. |psf| replace:: Python Software Foundation diff --git a/docs/source/contribute/contrib_doc.rst b/docs/source/contribute/contrib_doc.rst index e6c6b65a3e5..478783698c0 100644 --- a/docs/source/contribute/contrib_doc.rst +++ b/docs/source/contribute/contrib_doc.rst @@ -8,9 +8,7 @@ Contributing to the Documentation Setup Local Build ----------------- -To get started, create or identify a working directory on your local machine. - -Open that directory and execute the following command in a terminal session:: +To get started, check out and configure the repository for development:: git clone https://github.com/aboutcode-org/scancode-toolkit.git @@ -18,99 +16,54 @@ That will create an ``/scancode-toolkit`` directory in your working directory. Now you can install the dependencies in a virtualenv:: cd scancode-toolkit - ./configure --docs - -.. note:: - - In case of windows, run ``configure --docs`` instead of this. - -Now, this will install the following prerequisites: - -- Sphinx -- sphinx_rtd_theme (the format theme used by ReadTheDocs) -- docs8 (style linter) - -These requirements are already present in setup.cfg and `./configure --docs` installs them. - -Now you can build the HTML documents locally:: - - source venv/bin/activate - cd docs - make html - -Assuming that your Sphinx installation was successful, Sphinx should build a local instance of the -documentation .html files:: + ./configure --dev - open build/html/index.html +(Or use "make dev") .. note:: - In case this command did not work, for example on Ubuntu 18.04 you may get a message like “Couldn’t - get a file descriptor referring to the console”, try: + In case of windows, run ``configure --dev``. - :: - - see build/html/index.html - -You now have a local build of the AboutCode documents. +This will install and configure all requirements foer development including for docs development. -.. _contrib_doc_share_improvements: +Now you can build the HTML documentation locally:: -Share Document Improvements ---------------------------- - -Ensure that you have the latest files:: + source venv/bin/activate + make docs - git pull - git status +This will build a local instance of the ``docs/_build`` directory:: -Before commiting changes run Continious Integration Scripts locally to run tests. Refer -:ref:`doc_ci` for instructions on the same. + open docs/_build/index.html -Follow standard git procedures to upload your new and modified files. The following commands are -examples:: - git status - git add source/index.rst - git add source/how-to-scan.rst - git status - git commit -m "New how-to document that explains how to scan" - git status - git push - git status +To validate the documentation style and content, use:: -The ScanCode-Toolkit webhook with ReadTheDocs should rebuild the documentation after your -Pull Request is Merged. + source venv/bin/activate + make doc8 + make docs-check -Refer the `Pro Git Book `_ available online for Git tutorials -covering more complex topics on Branching, Merging, Rebasing etc. .. _doc_ci: Continuous Integration ---------------------- -The documentations are checked on every new commit through Travis-CI, so that common errors are -avoided and documentation standards are enforced. Travis-CI presently checks for these 3 aspects -of the documentation : +The documentations are checked on every new commit, so that common errors are avoided and +documentation standards are enforced. We checks for these aspects of the documentation: 1. Successful Builds (By using ``sphinx-build``) -2. No Broken Links (By Using ``link-check``) -3. Linting Errors (By Using ``Doc8``) - -So run these scripts at your local system before creating a Pull Request:: +2. No Broken Links (By Using ``linkcheck``) +3. Linting Errors (By Using ``doc8``) - cd docs - ./scripts/sphinx_build_link_check.sh - ./scripts/doc8_style_check.sh +You myst run these scripts locally before creating a pull request:: -If you don't have permission to run the scripts, run:: + make doc8 + make check-docs - chmod u+x ./scripts/doc8_style_check.sh .. _doc_style_docs8: -Style Checks Using ``Doc8`` +Style Checks Using ``doc8`` --------------------------- How To Run Style Tests @@ -118,8 +71,7 @@ How To Run Style Tests In the project root, run the following commands:: - $ cd docs - $ ./scripts/doc8_style_check.sh + make doc8 A sample output is:: @@ -143,11 +95,13 @@ A sample output is:: Now fix the errors and run again till there isn't any style error in the documentation. + What is Checked? ^^^^^^^^^^^^^^^^ PyCQA is an Organization for code quality tools (and plugins) for the Python programming language. -Doc8 is a sub-project of the same Organization. Refer this `README `_ for more details. +Doc8 is a sub-project of the same Organization. Refer this +`README `_ for more details. What is checked: @@ -164,16 +118,19 @@ What is checked: - no carriage returns (use UNIX newlines) - D004 - no newline at end of file - D005 + .. _doc_interspinx: Interspinx ---------- -ScanCode toolkit documentation uses `Intersphinx `_ +AboutCode documentation uses +`Intersphinx `_ to link to other Sphinx Documentations, to maintain links to other Aboutcode Projects. To link sections in the same documentation, standart reST labels are used. Refer -`Cross-Referencing `_ for more information. +`Cross-Referencing `_ +for more information. For example:: @@ -223,6 +180,7 @@ Intersphinx, and you link to that label, it will create a link to the local labe For more information, refer this tutorial named `Using Intersphinx `_. + .. _doc_style_conv: Style Conventions for the Documentaion @@ -230,7 +188,7 @@ Style Conventions for the Documentaion 1. Headings - (`Refer `_) + (`Refer `_) Normally, there are no heading levels assigned to certain characters as the structure is determined from the succession of headings. However, this convention is used in Python’s Style Guide for documenting which you may follow: @@ -312,9 +270,10 @@ Style Conventions for the Documentaion Converting from Markdown ------------------------ -If you want to convert a ``.md`` file to a ``.rst`` file, this `tool `_ -does it pretty well. You'd still have to clean up and check for errors as this contains a lot of -bugs. But this is definitely better than converting everything by yourself. +If you want to convert a ``.md`` file to a ``.rst`` file, this +`tool `_ does it pretty well. +You will still have to clean up and check for errors as this contains a lot of bugs. But this is +definitely better than converting everything by yourself. This will be helpful in converting GitHub wiki's (Markdown Files) to reStructuredtext files for Sphinx/ReadTheDocs hosting. diff --git a/docs/source/getting-started/install.rst b/docs/source/getting-started/install.rst index ed6ff448617..394b0a197db 100644 --- a/docs/source/getting-started/install.rst +++ b/docs/source/getting-started/install.rst @@ -44,7 +44,7 @@ For advanced usage and experienced users, you can also use any of these mode: Before Installing ----------------- -- ScanCode requires a Python version between 3.9 to 3.12 and is +- ScanCode requires a Python version between 3.9 to 3.13 and is tested on Linux, macOS, and Windows. It should work fine on FreeBSD. .. _system_requirements: diff --git a/etc/ci/azure-container-deb.yml b/etc/ci/azure-container-deb.yml index 85b611d3557..d80e8dfb819 100644 --- a/etc/ci/azure-container-deb.yml +++ b/etc/ci/azure-container-deb.yml @@ -21,7 +21,7 @@ jobs: - job: ${{ parameters.job_name }} pool: - vmImage: 'ubuntu-16.04' + vmImage: 'ubuntu-22.04' container: image: ${{ parameters.container }} diff --git a/etc/ci/azure-container-rpm.yml b/etc/ci/azure-container-rpm.yml index 1e6657d0f2b..a64138c9b85 100644 --- a/etc/ci/azure-container-rpm.yml +++ b/etc/ci/azure-container-rpm.yml @@ -1,6 +1,6 @@ parameters: job_name: '' - image_name: 'ubuntu-16.04' + image_name: 'ubuntu-22.04' container: '' python_path: '' python_version: '' diff --git a/etc/release/scancode-create-release-app-linux.sh b/etc/release/scancode-create-release-app-linux.sh index 94aa847ae47..fbe5951a937 100755 --- a/etc/release/scancode-create-release-app-linux.sh +++ b/etc/release/scancode-create-release-app-linux.sh @@ -33,7 +33,7 @@ thirdparty_src_dir=$release_dir/thirdparty-src mkdir -p $thirdparty_dir mkdir -p $thirdparty_src_dir -./configure --rel +./configure --dev venv/bin/python etc/scripts/fetch_thirdparty.py \ --requirements requirements-native.txt \ diff --git a/etc/release/scancode-create-release-app-macos.sh b/etc/release/scancode-create-release-app-macos.sh index e689f1f1b04..5f34bf88f28 100755 --- a/etc/release/scancode-create-release-app-macos.sh +++ b/etc/release/scancode-create-release-app-macos.sh @@ -33,7 +33,7 @@ thirdparty_src_dir=$release_dir/thirdparty-src mkdir -p $thirdparty_dir mkdir -p $thirdparty_src_dir -./configure --rel +./configure --dev venv/bin/python etc/scripts/fetch_thirdparty.py \ --requirements requirements-native.txt \ diff --git a/etc/release/scancode-create-release-app-sources.sh b/etc/release/scancode-create-release-app-sources.sh index 1a73aa7485b..c7fa0fb61e1 100755 --- a/etc/release/scancode-create-release-app-sources.sh +++ b/etc/release/scancode-create-release-app-sources.sh @@ -29,7 +29,7 @@ mkdir -p $thirdparty_dir venv/bin/python setup.py --quiet sdist mv dist/*.tar.gz $release_dir -./configure --rel +./configure --dev venv/bin/python etc/scripts/fetch_thirdparty.py \ --requirements requirements.txt \ diff --git a/etc/release/scancode-create-release-app-windows.sh b/etc/release/scancode-create-release-app-windows.sh index a7957ae15bb..03a22d7117a 100755 --- a/etc/release/scancode-create-release-app-windows.sh +++ b/etc/release/scancode-create-release-app-windows.sh @@ -32,7 +32,7 @@ thirdparty_src_dir=$release_dir/thirdparty-src mkdir -p $thirdparty_dir mkdir -p $thirdparty_src_dir -./configure --rel +./configure --dev venv/bin/python etc/scripts/fetch_thirdparty.py \ --requirements requirements-native.txt \ diff --git a/etc/scripts/check_thirdparty.py b/etc/scripts/check_thirdparty.py index 2daded948fa..65ae595edd0 100755 --- a/etc/scripts/check_thirdparty.py +++ b/etc/scripts/check_thirdparty.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # # Copyright (c) nexB Inc. and others. All rights reserved. # ScanCode is a trademark of nexB Inc. @@ -17,8 +16,7 @@ @click.option( "-d", "--dest", - type=click.Path(exists=True, readable=True, - path_type=str, file_okay=False), + type=click.Path(exists=True, readable=True, path_type=str, file_okay=False), required=True, help="Path to the thirdparty directory to check.", ) @@ -43,8 +41,7 @@ def check_thirdparty_dir( """ Check a thirdparty directory for problems and print these on screen. """ - # check for problems - print(f"==> CHECK FOR PROBLEMS") + print("==> CHECK FOR PROBLEMS") utils_thirdparty.find_problems( dest_dir=dest, report_missing_sources=sdists, diff --git a/etc/scripts/fetch_thirdparty.py b/etc/scripts/fetch_thirdparty.py index 3f9ff527a1e..454247e3667 100755 --- a/etc/scripts/fetch_thirdparty.py +++ b/etc/scripts/fetch_thirdparty.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # # Copyright (c) nexB Inc. and others. All rights reserved. # ScanCode is a trademark of nexB Inc. @@ -10,14 +9,13 @@ # import itertools -import os import sys from collections import defaultdict import click -import utils_thirdparty import utils_requirements +import utils_thirdparty TRACE = False TRACE_DEEP = False @@ -55,8 +53,7 @@ "-d", "--dest", "dest_dir", - type=click.Path(exists=True, readable=True, - path_type=str, file_okay=False), + type=click.Path(exists=True, readable=True, path_type=str, file_okay=False), metavar="DIR", default=utils_thirdparty.THIRDPARTY_DIR, show_default=True, @@ -110,7 +107,8 @@ @click.option( "--use-cached-index", is_flag=True, - help="Use on disk cached PyPI indexes list of packages and versions and do not refetch if present.", + help="Use on disk cached PyPI indexes list of packages and versions and " + "do not refetch if present.", ) @click.option( "--sdist-only", @@ -121,7 +119,7 @@ show_default=False, multiple=True, help="Package name(s) that come only in sdist format (no wheels). " - "The command will not fail and exit if no wheel exists for these names", + "The command will not fail and exit if no wheel exists for these names", ) @click.option( "--wheel-only", @@ -132,7 +130,7 @@ show_default=False, multiple=True, help="Package name(s) that come only in wheel format (no sdist). " - "The command will not fail and exit if no sdist exists for these names", + "The command will not fail and exit if no sdist exists for these names", ) @click.option( "--no-dist", @@ -143,7 +141,7 @@ show_default=False, multiple=True, help="Package name(s) that do not come either in wheel or sdist format. " - "The command will not fail and exit if no distribution exists for these names", + "The command will not fail and exit if no distribution exists for these names", ) @click.help_option("-h", "--help") def fetch_thirdparty( @@ -225,8 +223,7 @@ def fetch_thirdparty( environments = None if wheels: evts = itertools.product(python_versions, operating_systems) - environments = [utils_thirdparty.Environment.from_pyver_and_os( - pyv, os) for pyv, os in evts] + environments = [utils_thirdparty.Environment.from_pyver_and_os(pyv, os) for pyv, os in evts] # Collect PyPI repos repos = [] @@ -250,7 +247,6 @@ def fetch_thirdparty( print(f"Processing: {name} @ {version}") if wheels: for environment in environments: - if TRACE: print(f" ==> Fetching wheel for envt: {environment}") @@ -262,14 +258,11 @@ def fetch_thirdparty( repos=repos, ) if not fetched: - wheels_or_sdist_not_found[f"{name}=={version}"].append( - environment) + wheels_or_sdist_not_found[f"{name}=={version}"].append(environment) if TRACE: - print(f" NOT FOUND") + print(" NOT FOUND") - if (sdists or - (f"{name}=={version}" in wheels_or_sdist_not_found and name in sdist_only) - ): + if sdists or (f"{name}=={version}" in wheels_or_sdist_not_found and name in sdist_only): if TRACE: print(f" ==> Fetching sdist: {name}=={version}") @@ -282,18 +275,15 @@ def fetch_thirdparty( if not fetched: wheels_or_sdist_not_found[f"{name}=={version}"].append("sdist") if TRACE: - print(f" NOT FOUND") + print(" NOT FOUND") mia = [] for nv, dists in wheels_or_sdist_not_found.items(): name, _, version = nv.partition("==") if name in no_dist: continue - sdist_missing = sdists and "sdist" in dists and not name in wheel_only - if sdist_missing: - mia.append(f"SDist missing: {nv} {dists}") - wheels_missing = wheels and any( - d for d in dists if d != "sdist") and not name in sdist_only + sdist_missing = sdists and "sdist" in dists and name not in wheel_only + wheels_missing = wheels and any(d for d in dists if d != "sdist") and name not in sdist_only if wheels_missing: mia.append(f"Wheels missing: {nv} {dists}") @@ -302,13 +292,12 @@ def fetch_thirdparty( print(m) raise Exception(mia) - print(f"==> FETCHING OR CREATING ABOUT AND LICENSE FILES") - utils_thirdparty.fetch_abouts_and_licenses( - dest_dir=dest_dir, use_cached_index=use_cached_index) + print("==> FETCHING OR CREATING ABOUT AND LICENSE FILES") + utils_thirdparty.fetch_abouts_and_licenses(dest_dir=dest_dir, use_cached_index=use_cached_index) utils_thirdparty.clean_about_files(dest_dir=dest_dir) # check for problems - print(f"==> CHECK FOR PROBLEMS") + print("==> CHECK FOR PROBLEMS") utils_thirdparty.find_problems( dest_dir=dest_dir, report_missing_sources=sdists, diff --git a/etc/scripts/gen_pypi_simple.py b/etc/scripts/gen_pypi_simple.py index 214d90dc519..89d0626527c 100644 --- a/etc/scripts/gen_pypi_simple.py +++ b/etc/scripts/gen_pypi_simple.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # SPDX-License-Identifier: BSD-2-Clause-Views AND MIT # Copyright (c) 2010 David Wolever . All rights reserved. @@ -69,7 +68,6 @@ def get_package_name_from_filename(filename): raise InvalidDistributionFilename(filename) elif filename.endswith(wheel_ext): - wheel_info = get_wheel_from_filename(filename) if not wheel_info: @@ -133,7 +131,7 @@ def build_links_package_index(packages_by_package_name, base_url): Return an HTML document as string which is a links index of all packages """ document = [] - header = f""" + header = """ Links for all packages @@ -178,13 +176,13 @@ def simple_index_entry(self, base_url): def build_pypi_index(directory, base_url="https://thirdparty.aboutcode.org/pypi"): """ - Using a ``directory`` directory of wheels and sdists, create the a PyPI - simple directory index at ``directory``/simple/ populated with the proper - PyPI simple index directory structure crafted using symlinks. + Create the a PyPI simple directory index using a ``directory`` directory of wheels and sdists in + the direvctory at ``directory``/simple/ populated with the proper PyPI simple index directory + structure crafted using symlinks. - WARNING: The ``directory``/simple/ directory is removed if it exists. - NOTE: in addition to the a PyPI simple index.html there is also a links.html - index file generated which is suitable to use with pip's --find-links + WARNING: The ``directory``/simple/ directory is removed if it exists. NOTE: in addition to the a + PyPI simple index.html there is also a links.html index file generated which is suitable to use + with pip's --find-links """ directory = Path(directory) @@ -200,11 +198,10 @@ def build_pypi_index(directory, base_url="https://thirdparty.aboutcode.org/pypi" simple_html_index = [ "", "PyPI Simple Index", - '' '', + '', ] for pkg_file in directory.iterdir(): - pkg_filename = pkg_file.name if ( diff --git a/etc/scripts/gen_requirements.py b/etc/scripts/gen_requirements.py index 2b65ae807ef..1b87944239e 100755 --- a/etc/scripts/gen_requirements.py +++ b/etc/scripts/gen_requirements.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # # Copyright (c) nexB Inc. and others. All rights reserved. # ScanCode is a trademark of nexB Inc. @@ -34,7 +33,8 @@ def gen_requirements(): type=pathlib.Path, required=True, metavar="DIR", - help="Path to the 'site-packages' directory where wheels are installed such as lib/python3.6/site-packages", + help="Path to the 'site-packages' directory where wheels are installed " + "such as lib/python3.12/site-packages", ) parser.add_argument( "-r", diff --git a/etc/scripts/gen_requirements_dev.py b/etc/scripts/gen_requirements_dev.py index 5db1c48ed73..85482056598 100755 --- a/etc/scripts/gen_requirements_dev.py +++ b/etc/scripts/gen_requirements_dev.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # # Copyright (c) nexB Inc. and others. All rights reserved. # ScanCode is a trademark of nexB Inc. @@ -36,7 +35,8 @@ def gen_dev_requirements(): type=pathlib.Path, required=True, metavar="DIR", - help='Path to the "site-packages" directory where wheels are installed such as lib/python3.6/site-packages', + help="Path to the 'site-packages' directory where wheels are installed " + "such as lib/python3.12/site-packages", ) parser.add_argument( "-d", diff --git a/etc/scripts/test_utils_pip_compatibility_tags.py b/etc/scripts/test_utils_pip_compatibility_tags.py index 98187c56437..0e9c360ae7a 100644 --- a/etc/scripts/test_utils_pip_compatibility_tags.py +++ b/etc/scripts/test_utils_pip_compatibility_tags.py @@ -1,4 +1,5 @@ -"""Generate and work with PEP 425 Compatibility Tags. +""" +Generate and work with PEP 425 Compatibility Tags. copied from pip-20.3.1 pip/tests/unit/test_utils_compatibility_tags.py download_url: https://raw.githubusercontent.com/pypa/pip/20.3.1/tests/unit/test_utils_compatibility_tags.py @@ -25,8 +26,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ -from unittest.mock import patch import sysconfig +from unittest.mock import patch import pytest @@ -51,7 +52,7 @@ def test_version_info_to_nodot(version_info, expected): assert actual == expected -class Testcompatibility_tags(object): +class Testcompatibility_tags: def mock_get_config_var(self, **kwd): """ Patch sysconfig.get_config_var for arbitrary keys. @@ -82,7 +83,7 @@ def test_no_hyphen_tag(self): assert "-" not in tag.platform -class TestManylinux2010Tags(object): +class TestManylinux2010Tags: @pytest.mark.parametrize( "manylinux2010,manylinux1", [ @@ -105,7 +106,7 @@ def test_manylinux2010_implies_manylinux1(self, manylinux2010, manylinux1): assert arches[:2] == [manylinux2010, manylinux1] -class TestManylinux2014Tags(object): +class TestManylinux2014Tags: @pytest.mark.parametrize( "manylinuxA,manylinuxB", [ diff --git a/etc/scripts/update_skeleton.py b/etc/scripts/update_skeleton.py new file mode 100644 index 00000000000..374c06f24fe --- /dev/null +++ b/etc/scripts/update_skeleton.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python +# +# Copyright (c) nexB Inc. AboutCode, and others. All rights reserved. +# ScanCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/aboutcode-org/skeleton for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# + +from pathlib import Path +import os +import subprocess + +import click + + +ABOUTCODE_PUBLIC_REPO_NAMES = [ + "aboutcode-toolkit", + "ahocode", + "bitcode", + "clearcode-toolkit", + "commoncode", + "container-inspector", + "debian-inspector", + "deltacode", + "elf-inspector", + "extractcode", + "fetchcode", + "gemfileparser2", + "gh-issue-sandbox", + "go-inspector", + "heritedcode", + "license-expression", + "license_copyright_pipeline", + "nuget-inspector", + "pip-requirements-parser", + "plugincode", + "purldb", + "pygmars", + "python-inspector", + "sanexml", + "saneyaml", + "scancode-analyzer", + "scancode-toolkit-contrib", + "scancode-toolkit-reference-scans", + "thirdparty-toolkit", + "tracecode-toolkit", + "tracecode-toolkit-strace", + "turbo-spdx", + "typecode", + "univers", +] + + +@click.command() +@click.help_option("-h", "--help") +def update_skeleton_files(repo_names=ABOUTCODE_PUBLIC_REPO_NAMES): + """ + Update project files of AboutCode projects that use the skeleton + + This script will: + - Clone the repo + - Add the skeleton repo as a new origin + - Create a new branch named "update-skeleton-files" + - Merge in the new skeleton files into the "update-skeleton-files" branch + + The user will need to save merge commit messages that pop up when running + this script in addition to resolving the merge conflicts on repos that have + them. + """ + + # Create working directory + work_dir_path = Path("/tmp/update_skeleton/") + if not os.path.exists(work_dir_path): + os.makedirs(work_dir_path, exist_ok=True) + + for repo_name in repo_names: + # Move to work directory + os.chdir(work_dir_path) + + # Clone repo + repo_git = f"git@github.com:aboutcode-org/{repo_name}.git" + subprocess.run(["git", "clone", repo_git]) + + # Go into cloned repo + os.chdir(work_dir_path / repo_name) + + # Add skeleton as an origin + subprocess.run( + ["git", "remote", "add", "skeleton", "git@github.com:aboutcode-org/skeleton.git"] + ) + + # Fetch skeleton files + subprocess.run(["git", "fetch", "skeleton"]) + + # Create and checkout new branch + subprocess.run(["git", "checkout", "-b", "update-skeleton-files"]) + + # Merge skeleton files into the repo + subprocess.run(["git", "merge", "skeleton/main", "--allow-unrelated-histories"]) + + +if __name__ == "__main__": + update_skeleton_files() diff --git a/etc/scripts/utils_dejacode.py b/etc/scripts/utils_dejacode.py index 652252d48ed..b6bff5186c5 100644 --- a/etc/scripts/utils_dejacode.py +++ b/etc/scripts/utils_dejacode.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # # Copyright (c) nexB Inc. and others. All rights reserved. # ScanCode is a trademark of nexB Inc. @@ -14,7 +13,6 @@ import requests import saneyaml - from packvers import version as packaging_version """ @@ -26,15 +24,14 @@ DEJACODE_API_URL_PACKAGES = f"{DEJACODE_API_URL}packages/" DEJACODE_API_HEADERS = { - "Authorization": "Token {}".format(DEJACODE_API_KEY), + "Authorization": f"Token {DEJACODE_API_KEY}", "Accept": "application/json; indent=4", } def can_do_api_calls(): if not DEJACODE_API_KEY and DEJACODE_API_URL: - print( - "DejaCode DEJACODE_API_KEY and DEJACODE_API_URL not configured. Doing nothing") + print("DejaCode DEJACODE_API_KEY and DEJACODE_API_URL not configured. Doing nothing") return False else: return True @@ -52,6 +49,7 @@ def fetch_dejacode_packages(params): DEJACODE_API_URL_PACKAGES, params=params, headers=DEJACODE_API_HEADERS, + timeout=10, ) return response.json()["results"] @@ -69,8 +67,7 @@ def get_package_data(distribution): return results[0] elif len_results > 1: - print( - f"More than 1 entry exists, review at: {DEJACODE_API_URL_PACKAGES}") + print(f"More than 1 entry exists, review at: {DEJACODE_API_URL_PACKAGES}") else: print("Could not find package:", distribution.download_url) @@ -96,7 +93,7 @@ def update_with_dejacode_about_data(distribution): if package_data: package_api_url = package_data["api_url"] about_url = f"{package_api_url}about" - response = requests.get(about_url, headers=DEJACODE_API_HEADERS) + response = requests.get(about_url, headers=DEJACODE_API_HEADERS, timeout=10) # note that this is YAML-formatted about_text = response.json()["about_data"] about_data = saneyaml.load(about_text) @@ -116,7 +113,7 @@ def fetch_and_save_about_files(distribution, dest_dir="thirdparty"): if package_data: package_api_url = package_data["api_url"] about_url = f"{package_api_url}about_files" - response = requests.get(about_url, headers=DEJACODE_API_HEADERS) + response = requests.get(about_url, headers=DEJACODE_API_HEADERS, timeout=10) about_zip = response.content with io.BytesIO(about_zip) as zf: with zipfile.ZipFile(zf) as zi: @@ -151,12 +148,11 @@ def find_latest_dejacode_package(distribution): # there was no exact match, find the latest version # TODO: consider the closest version rather than the latest # or the version that has the best data - with_versions = [(packaging_version.parse(p["version"]), p) - for p in packages] + with_versions = [(packaging_version.parse(p["version"]), p) for p in packages] with_versions = sorted(with_versions) latest_version, latest_package_version = sorted(with_versions)[-1] print( - f"Found DejaCode latest version: {latest_version} " f"for dist: {distribution.package_url}", + f"Found DejaCode latest version: {latest_version} for dist: {distribution.package_url}", ) return latest_package_version @@ -182,7 +178,7 @@ def create_dejacode_package(distribution): } fields_to_carry_over = [ - "download_url" "type", + "download_urltype", "namespace", "name", "version", @@ -205,10 +201,11 @@ def create_dejacode_package(distribution): DEJACODE_API_URL_PACKAGES, data=new_package_payload, headers=DEJACODE_API_HEADERS, + timeout=10, ) new_package_data = response.json() if response.status_code != 201: raise Exception(f"Error, cannot create package for: {distribution}") - print(f'New Package created at: {new_package_data["absolute_url"]}') + print(f"New Package created at: {new_package_data['absolute_url']}") return new_package_data diff --git a/etc/scripts/utils_pip_compatibility_tags.py b/etc/scripts/utils_pip_compatibility_tags.py index af42a0cdd25..dd954bca74b 100644 --- a/etc/scripts/utils_pip_compatibility_tags.py +++ b/etc/scripts/utils_pip_compatibility_tags.py @@ -1,4 +1,5 @@ -"""Generate and work with PEP 425 Compatibility Tags. +""" +Generate and work with PEP 425 Compatibility Tags. copied from pip-20.3.1 pip/_internal/utils/compatibility_tags.py download_url: https://github.com/pypa/pip/blob/20.3.1/src/pip/_internal/utils/compatibility_tags.py @@ -27,14 +28,12 @@ import re -from packvers.tags import ( - compatible_tags, - cpython_tags, - generic_tags, - interpreter_name, - interpreter_version, - mac_platforms, -) +from packvers.tags import compatible_tags +from packvers.tags import cpython_tags +from packvers.tags import generic_tags +from packvers.tags import interpreter_name +from packvers.tags import interpreter_version +from packvers.tags import mac_platforms _osx_arch_pat = re.compile(r"(.+)_(\d+)_(\d+)_(.+)") @@ -132,7 +131,7 @@ def _get_custom_interpreter(implementation=None, version=None): implementation = interpreter_name() if version is None: version = interpreter_version() - return "{}{}".format(implementation, version) + return f"{implementation}{version}" def get_supported( @@ -142,7 +141,8 @@ def get_supported( abis=None, # type: Optional[List[str]] ): # type: (...) -> List[Tag] - """Return a list of supported tags for each version specified in + """ + Return a list of supported tags for each version specified in `versions`. :param version: a string version, of the form "33" or "32", diff --git a/etc/scripts/utils_requirements.py b/etc/scripts/utils_requirements.py index 1c502390f2c..4bdc96c6978 100755 --- a/etc/scripts/utils_requirements.py +++ b/etc/scripts/utils_requirements.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # # Copyright (c) nexB Inc. and others. All rights reserved. # ScanCode is a trademark of nexB Inc. @@ -40,7 +39,7 @@ def get_required_name_versions(requirement_lines, with_unpinned=False): req_line = req_line.strip() if not req_line or req_line.startswith("#"): continue - if req_line.startswith("-") or (not with_unpinned and not "==" in req_line): + if req_line.startswith("-") or (not with_unpinned and "==" not in req_line): print(f"Requirement line is not supported: ignored: {req_line}") continue yield get_required_name_version(requirement=req_line, with_unpinned=with_unpinned) @@ -57,21 +56,25 @@ def get_required_name_version(requirement, with_unpinned=False): >>> assert get_required_name_version("fooA==1.2.3.DEV1") == ("fooa", "1.2.3.dev1") >>> assert get_required_name_version("foo==1.2.3", with_unpinned=False) == ("foo", "1.2.3") >>> assert get_required_name_version("foo", with_unpinned=True) == ("foo", "") - >>> assert get_required_name_version("foo>=1.2", with_unpinned=True) == ("foo", ""), get_required_name_version("foo>=1.2") + >>> expected = ("foo", ""), get_required_name_version("foo>=1.2") + >>> assert get_required_name_version("foo>=1.2", with_unpinned=True) == expected >>> try: ... assert not get_required_name_version("foo", with_unpinned=False) ... except Exception as e: ... assert "Requirement version must be pinned" in str(e) """ requirement = requirement and "".join(requirement.lower().split()) - assert requirement, f"specifier is required is empty:{requirement!r}" + if not requirement: + raise ValueError(f"specifier is required is empty:{requirement!r}") name, operator, version = split_req(requirement) - assert name, f"Name is required: {requirement}" + if not name: + raise ValueError(f"Name is required: {requirement}") is_pinned = operator == "==" if with_unpinned: version = "" else: - assert is_pinned and version, f"Requirement version must be pinned: {requirement}" + if not is_pinned and version: + raise ValueError(f"Requirement version must be pinned: {requirement}") return name, version @@ -102,8 +105,7 @@ def lock_dev_requirements( all_req_nvs = get_required_name_versions(all_req_lines) dev_only_req_nvs = {n: v for n, v in all_req_nvs if n not in main_names} - new_reqs = "\n".join( - f"{n}=={v}" for n, v in sorted(dev_only_req_nvs.items())) + new_reqs = "\n".join(f"{n}=={v}" for n, v in sorted(dev_only_req_nvs.items())) with open(dev_requirements_file, "w") as fo: fo.write(new_reqs) @@ -114,13 +116,11 @@ def get_installed_reqs(site_packages_dir): as a text. """ if not os.path.exists(site_packages_dir): - raise Exception( - f"site_packages directory: {site_packages_dir!r} does not exists") + raise Exception(f"site_packages directory: {site_packages_dir!r} does not exists") # Also include these packages in the output with --all: wheel, distribute, # setuptools, pip - args = ["pip", "freeze", "--exclude-editable", - "--all", "--path", site_packages_dir] - return subprocess.check_output(args, encoding="utf-8") + args = ["pip", "freeze", "--exclude-editable", "--all", "--path", site_packages_dir] + return subprocess.check_output(args, encoding="utf-8") # noqa: S603 comparators = ( @@ -150,9 +150,13 @@ def split_req(req): >>> assert split_req("foo >= 1.2.3 ") == ("foo", ">=", "1.2.3"), split_req("foo >= 1.2.3 ") >>> assert split_req("foo>=1.2") == ("foo", ">=", "1.2"), split_req("foo>=1.2") """ - assert req + if not req: + raise ValueError("req is required") # do not allow multiple constraints and tags - assert not any(c in req for c in ",;") + if ";" in req: + req = req.split(";")[0] + if any(c in req for c in ",:"): + raise Exception(f"complex requirements with : or ; not supported: {req}") req = "".join(req.split()) if not any(c in req for c in comparators): return req, "", "" diff --git a/etc/scripts/utils_thirdparty.py b/etc/scripts/utils_thirdparty.py index 25b8d5eda72..6f812f090e4 100755 --- a/etc/scripts/utils_thirdparty.py +++ b/etc/scripts/utils_thirdparty.py @@ -115,14 +115,14 @@ TRACE_ULTRA_DEEP = False # Supported environments -PYTHON_VERSIONS = "38", "39", "310", "311", "312" +PYTHON_VERSIONS = "39", "310", "311", "312", "313" PYTHON_DOT_VERSIONS_BY_VER = { - "38": "3.8", "39": "3.9", "310": "3.10", "311": "3.11", "312": "3.12", + "313": "3.13", } @@ -134,11 +134,11 @@ def get_python_dot_version(version): ABIS_BY_PYTHON_VERSION = { - "38": ["cp38", "cp38m", "abi3"], "39": ["cp39", "cp39m", "abi3"], "310": ["cp310", "cp310m", "abi3"], "311": ["cp311", "cp311m", "abi3"], "312": ["cp312", "cp312m", "abi3"], + "313": ["cp313", "cp313m", "abi3"], } PLATFORMS_BY_OS = { @@ -247,11 +247,9 @@ def download_wheel(name, version, environment, dest_dir=THIRDPARTY_DIR, repos=tu package = repo.get_package_version(name=name, version=version) if not package: if TRACE_DEEP: - print( - f" download_wheel: No package in {repo.index_url} for {name}=={version}") + print(f" download_wheel: No package in {repo.index_url} for {name}=={version}") continue - supported_wheels = list( - package.get_supported_wheels(environment=environment)) + supported_wheels = list(package.get_supported_wheels(environment=environment)) if not supported_wheels: if TRACE_DEEP: print( @@ -295,8 +293,7 @@ def download_sdist(name, version, dest_dir=THIRDPARTY_DIR, repos=tuple()): if not package: if TRACE_DEEP: - print( - f" download_sdist: No package in {repo.index_url} for {name}=={version}") + print(f" download_sdist: No package in {repo.index_url} for {name}=={version}") continue sdist = package.sdist if not sdist: @@ -305,8 +302,7 @@ def download_sdist(name, version, dest_dir=THIRDPARTY_DIR, repos=tuple()): continue if TRACE_DEEP: - print( - f" download_sdist: Getting sdist from index (or cache): {sdist.download_url}") + print(f" download_sdist: Getting sdist from index (or cache): {sdist.download_url}") fetched_sdist_filename = package.sdist.download(dest_dir=dest_dir) if fetched_sdist_filename: @@ -361,7 +357,6 @@ def sorted(cls, namevers): @attr.attributes class Distribution(NameVer): - # field names that can be updated from another Distribution or mapping updatable_fields = [ "license_expression", @@ -539,8 +534,7 @@ def get_best_download_url(self, repos=tuple()): repos = DEFAULT_PYPI_REPOS for repo in repos: - package = repo.get_package_version( - name=self.name, version=self.version) + package = repo.get_package_version(name=self.name, version=self.version) if not package: if TRACE: print( @@ -779,8 +773,7 @@ def load_remote_about_data(self): if notice_text: about_data["notice_text"] = notice_text except RemoteNotFetchedException: - print( - f"Failed to fetch NOTICE file: {self.notice_download_url}") + print(f"Failed to fetch NOTICE file: {self.notice_download_url}") return self.load_about_data(about_data) def get_checksums(self, dest_dir=THIRDPARTY_DIR): @@ -829,11 +822,9 @@ def fetch_license_files(self, dest_dir=THIRDPARTY_DIR, use_cached_index=False): Fetch license files if missing in `dest_dir`. Return True if license files were fetched. """ - urls = LinksRepository.from_url( - use_cached_index=use_cached_index).links + urls = LinksRepository.from_url(use_cached_index=use_cached_index).links errors = [] - extra_lic_names = [l.get("file") - for l in self.extra_data.get("licenses", {})] + extra_lic_names = [l.get("file") for l in self.extra_data.get("licenses", {})] extra_lic_names += [self.extra_data.get("license_file")] extra_lic_names = [ln for ln in extra_lic_names if ln] lic_names = [f"{key}.LICENSE" for key in self.get_license_keys()] @@ -844,8 +835,7 @@ def fetch_license_files(self, dest_dir=THIRDPARTY_DIR, use_cached_index=False): try: # try remotely first - lic_url = get_license_link_for_filename( - filename=filename, urls=urls) + lic_url = get_license_link_for_filename(filename=filename, urls=urls) fetch_and_save( path_or_url=lic_url, @@ -922,8 +912,7 @@ def load_pkginfo_data(self, dest_dir=THIRDPARTY_DIR): c for c in classifiers if c.startswith("License") ] license_expression = get_license_expression(declared_license) - other_classifiers = [ - c for c in classifiers if not c.startswith("License")] + other_classifiers = [c for c in classifiers if not c.startswith("License")] holder = raw_data["Author"] holder_contact = raw_data["Author-email"] @@ -965,8 +954,7 @@ def update(self, data, overwrite=False, keep_extra=True): package_url = data.get("package_url") if package_url: purl_from_data = packageurl.PackageURL.from_string(package_url) - purl_from_self = packageurl.PackageURL.from_string( - self.package_url) + purl_from_self = packageurl.PackageURL.from_string(self.package_url) if purl_from_data != purl_from_self: print( f"Invalid dist update attempt, no same same purl with dist: " @@ -1016,8 +1004,7 @@ def get_license_link_for_filename(filename, urls): if not path_or_url: raise Exception(f"Missing link to file: {filename}") if not len(path_or_url) == 1: - raise Exception( - f"Multiple links to file: {filename}: \n" + "\n".join(path_or_url)) + raise Exception(f"Multiple links to file: {filename}: \n" + "\n".join(path_or_url)) return path_or_url[0] @@ -1105,7 +1092,6 @@ def get_sdist_name_ver_ext(filename): @attr.attributes class Sdist(Distribution): - extension = attr.ib( repr=False, type=str, @@ -1143,7 +1129,6 @@ def to_filename(self): @attr.attributes class Wheel(Distribution): - """ Represents a wheel file. @@ -1411,8 +1396,7 @@ def packages_from_dir(cls, directory): """ base = os.path.abspath(directory) - paths = [os.path.join(base, f) - for f in os.listdir(base) if f.endswith(EXTENSIONS)] + paths = [os.path.join(base, f) for f in os.listdir(base) if f.endswith(EXTENSIONS)] if TRACE_ULTRA_DEEP: print("packages_from_dir: paths:", paths) @@ -1473,8 +1457,7 @@ def dists_from_paths_or_urls(cls, paths_or_urls): dists = [] if TRACE_ULTRA_DEEP: print(" ###paths_or_urls:", paths_or_urls) - installable = [f for f in paths_or_urls if f.endswith( - EXTENSIONS_INSTALLABLE)] + installable = [f for f in paths_or_urls if f.endswith(EXTENSIONS_INSTALLABLE)] for path_or_url in installable: try: dist = Distribution.from_path_or_url(path_or_url) @@ -1492,8 +1475,7 @@ def dists_from_paths_or_urls(cls, paths_or_urls): ) except InvalidDistributionFilename: if TRACE_DEEP: - print( - f" Skipping invalid distribution from: {path_or_url}") + print(f" Skipping invalid distribution from: {path_or_url}") continue return dists @@ -1542,8 +1524,7 @@ class Environment: implementation = attr.ib( type=str, default="cp", - metadata=dict( - help="Python implementation supported by this environment."), + metadata=dict(help="Python implementation supported by this environment."), repr=False, ) @@ -1557,8 +1538,7 @@ class Environment: platforms = attr.ib( type=list, default=attr.Factory(list), - metadata=dict( - help="List of platform tags supported by this environment."), + metadata=dict(help="List of platform tags supported by this environment."), repr=False, ) @@ -1642,8 +1622,7 @@ class PypiSimpleRepository: fetched_package_normalized_names = attr.ib( type=set, default=attr.Factory(set), - metadata=dict( - help="A set of already fetched package normalized names."), + metadata=dict(help="A set of already fetched package normalized names."), ) use_cached_index = attr.ib( @@ -1674,12 +1653,10 @@ def _get_package_versions_map(self, name): self.packages[normalized_name] = versions except RemoteNotFetchedException as e: if TRACE: - print( - f"failed to fetch package name: {name} from: {self.index_url}:\n{e}") + print(f"failed to fetch package name: {name} from: {self.index_url}:\n{e}") if not versions and TRACE: - print( - f"WARNING: package {name} not found in repo: {self.index_url}") + print(f"WARNING: package {name} not found in repo: {self.index_url}") return versions @@ -1864,8 +1841,7 @@ def get(self, path_or_url, as_text=True, force=False): if force or not os.path.exists(cached): if TRACE_DEEP: print(f" FILE CACHE MISS: {path_or_url}") - content = get_file_content( - path_or_url=path_or_url, as_text=as_text) + content = get_file_content(path_or_url=path_or_url, as_text=as_text) wmode = "w" if as_text else "wb" with open(cached, wmode) as fo: fo.write(content) @@ -1887,8 +1863,7 @@ def get_file_content(path_or_url, as_text=True): if path_or_url.startswith("https://"): if TRACE_DEEP: print(f"Fetching: {path_or_url}") - _headers, content = get_remote_file_content( - url=path_or_url, as_text=as_text) + _headers, content = get_remote_file_content(url=path_or_url, as_text=as_text) return content elif path_or_url.startswith("file://") or ( @@ -1954,8 +1929,7 @@ def get_remote_file_content( ) else: - raise RemoteNotFetchedException( - f"Failed HTTP request from {url} with {status}") + raise RemoteNotFetchedException(f"Failed HTTP request from {url} with {status}") if headers_only: return response.headers, None @@ -2046,8 +2020,7 @@ def get_other_dists(_package, _dist): # if has key data we may look to improve later, but we can move on if local_dist.has_key_metadata(): local_dist.save_about_and_notice_files(dest_dir=dest_dir) - local_dist.fetch_license_files( - dest_dir=dest_dir, use_cached_index=use_cached_index) + local_dist.fetch_license_files(dest_dir=dest_dir, use_cached_index=use_cached_index) continue # lets try to get from another dist of the same local package @@ -2059,8 +2032,7 @@ def get_other_dists(_package, _dist): # if has key data we may look to improve later, but we can move on if local_dist.has_key_metadata(): local_dist.save_about_and_notice_files(dest_dir=dest_dir) - local_dist.fetch_license_files( - dest_dir=dest_dir, use_cached_index=use_cached_index) + local_dist.fetch_license_files(dest_dir=dest_dir, use_cached_index=use_cached_index) continue # try to get another version of the same package that is not our version @@ -2071,8 +2043,7 @@ def get_other_dists(_package, _dist): ] other_local_version = other_local_packages and other_local_packages[-1] if other_local_version: - latest_local_dists = list( - other_local_version.get_distributions()) + latest_local_dists = list(other_local_version.get_distributions()) for latest_local_dist in latest_local_dists: latest_local_dist.load_about_data(dest_dir=dest_dir) if not latest_local_dist.has_key_metadata(): @@ -2098,8 +2069,7 @@ def get_other_dists(_package, _dist): # if has key data we may look to improve later, but we can move on if local_dist.has_key_metadata(): local_dist.save_about_and_notice_files(dest_dir=dest_dir) - local_dist.fetch_license_files( - dest_dir=dest_dir, use_cached_index=use_cached_index) + local_dist.fetch_license_files(dest_dir=dest_dir, use_cached_index=use_cached_index) continue # try to get a latest version of the same package that is not our version @@ -2140,8 +2110,7 @@ def get_other_dists(_package, _dist): # if local_dist.has_key_metadata() or not local_dist.has_key_metadata(): local_dist.save_about_and_notice_files(dest_dir) - lic_errs = local_dist.fetch_license_files( - dest_dir, use_cached_index=use_cached_index) + lic_errs = local_dist.fetch_license_files(dest_dir, use_cached_index=use_cached_index) if not local_dist.has_key_metadata(): print(f"Unable to add essential ABOUT data for: {local_dist}") @@ -2167,7 +2136,6 @@ def call(args, verbose=TRACE): with subprocess.Popen( args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8" ) as process: - stdouts = [] while True: line = process.stdout.readline() @@ -2289,8 +2257,7 @@ def find_problems( for dist in package.get_distributions(): dist.load_about_data(dest_dir=dest_dir) - abpth = os.path.abspath(os.path.join( - dest_dir, dist.about_filename)) + abpth = os.path.abspath(os.path.join(dest_dir, dist.about_filename)) if not dist.has_key_metadata(): print(f" Missing key ABOUT data in file://{abpth}") if "classifiers" in dist.extra_data: diff --git a/pyproject.toml b/pyproject.toml index eeb168eb668..8af0e040a8b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,6 @@ norecursedirs = [ "dist", "build", "_build", - "dist", "etc", "local", "ci", @@ -34,7 +33,9 @@ norecursedirs = [ "thirdparty", "tmp", "venv", + ".venv", "tests/data", + "*/tests/test_data", ".eggs", "src/*/data", "tests/*/data", @@ -51,3 +52,79 @@ addopts = [ "--strict-markers", "--doctest-modules" ] + +[tool.ruff] +line-length = 100 +extend-exclude = [] +target-version = "py310" +include = [ + "pyproject.toml", + "src/**/*.py", + "etc/**/*.py", + "test/**/*.py", + "tests/**/*.py", + "doc/**/*.py", + "docs/**/*.py", + "*.py", + "." + +] +# ignore test data and testfiles: they should never be linted nor formatted +exclude = [ +# main style + "**/tests/data/**/*", +# scancode-toolkit + "**/tests/*/data/**/*", +# dejacode, purldb + "**/tests/testfiles/**/*", +# vulnerablecode, fetchcode + "**/tests/*/test_data/**/*", + "**/tests/test_data/**/*", +# django migrations + "**/migrations/**/*" +] + +[tool.ruff.lint] +# Rules: https://docs.astral.sh/ruff/rules/ +select = [ +# "E", # pycodestyle +# "W", # pycodestyle warnings + "D", # pydocstyle +# "F", # Pyflakes +# "UP", # pyupgrade +# "S", # flake8-bandit + "I", # isort +# "C9", # McCabe complexity +] +ignore = ["D1", "D200", "D202", "D203", "D205", "D212", "D400", "D415", "I001"] + + +[tool.ruff.lint.isort] +force-single-line = true +lines-after-imports = 1 +default-section = "first-party" +known-first-party = ["src", "tests", "etc/scripts/**/*.py"] +known-third-party = ["click", "pytest"] + +sections = { django = ["django"] } +section-order = [ + "future", + "standard-library", + "django", + "third-party", + "first-party", + "local-folder", +] + +[tool.ruff.lint.mccabe] +max-complexity = 10 + +[tool.ruff.lint.per-file-ignores] +# Place paths of files to be ignored by ruff here +"tests/*" = ["S101"] +"test_*.py" = ["S101"] + + +[tool.doc8] +ignore-path = ["docs/build", "doc/build", "docs/_build", "doc/_build"] +max-line-length=100 diff --git a/requirements-dev.txt b/requirements-dev.txt index 6b74f9fc1cb..b995b2305b4 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,7 +1,7 @@ -aboutcode-toolkit==7.0.2 +aboutcode-toolkit==11.1.1 black==22.6.0 bleach==5.0.1 -build==0.7.0 +build==1.2.2.post1 commonmark==0.9.1 docutils==0.19 et-xmlfile==1.1.0 @@ -14,7 +14,7 @@ mypy-extensions==0.4.3 openpyxl==3.0.10 pathspec==0.9.0 pep517==0.12.0 -pkginfo==1.8.3 +pkginfo==1.12.1.2 platformdirs==2.5.2 py==1.11.0 pytest==7.1.2 @@ -27,7 +27,7 @@ rich==12.5.1 secretstorage==3.3.2 tomli==2.0.1 tqdm==4.64.0 -twine==4.0.1 -typing_extensions==4.3.0 +twine==6.1.0 +typing_extensions==4.14.0 vendorize==0.3.0 diff --git a/requirements-native.txt b/requirements-native.txt index f1f2b09b80e..aee3901fbb8 100644 --- a/requirements-native.txt +++ b/requirements-native.txt @@ -1,6 +1,6 @@ -cffi==1.16.0 -intbitset==3.1.0 -lxml==5.1.0 -MarkupSafe==2.1.5 -pyahocorasick==2.1.0 -PyYAML==6.0.1 +cffi==1.17.1 +intbitset==4.0.0 +lxml==5.4.0 +MarkupSafe==3.0.2 +pyahocorasick==2.2.0 +PyYAML==6.0.2 diff --git a/requirements.txt b/requirements.txt index 358fa3ff257..c64daff856e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,82 +1,82 @@ -attrs==23.2.0 +attrs==25.3.0 banal==1.0.6 -beautifulsoup4==4.13.3 +beautifulsoup4==4.13.4 binaryornot==0.4.4 -beartype==0.17.2 -boolean.py==4.0 -certifi==2024.2.2 -cffi==1.16.0 -chardet==5.0.0 -charset-normalizer==2.1.0 +beartype==0.21.0 +boolean.py==5.0 +certifi==2025.6.15 +cffi==1.17.1 +chardet==5.2.0 +charset-normalizer==3.4.2 click==8.2.1;python_version>='3.10' click==8.1.7;python_version<'3.10' -colorama==0.4.5 +colorama==0.4.6 commoncode==32.3.0 -construct==2.10.68 -container-inspector==31.1.0 -cryptography==42.0.5 +construct==2.10.70 +container-inspector==33.0.0 +cryptography==45.0.4 debian-inspector==31.1.0 -dockerfile-parse==1.2.0 +dockerfile-parse==2.0.1 dparse2==0.7.0 extractcode==31.0.0 extractcode-7z==16.5.210531 extractcode-libarchive==3.5.1.210531 -fasteners==0.17.3 -fingerprints==1.0.3 -ftfy==6.1.1 -future==0.18.2 -gemfileparser2==0.9.0 +fasteners==0.19 +fingerprints==1.2.3 +ftfy==6.3.1 +future==1.0.0 +gemfileparser2==0.9.4 html5lib==1.1 -idna==3.3 -importlib-metadata==4.12.0 +idna==3.10 +importlib-metadata==6.2.1 inflection==0.5.1 -intbitset==3.1.0 -isodate==0.6.1 -jaraco.functools==4.1.0 -javaproperties==0.8.1 -Jinja2==3.1.3 +intbitset==4.0.0 +isodate==0.7.2 +jaraco.functools==4.2.1 +javaproperties==0.8.2 +Jinja2==3.1.6 jsonstreams==0.6.0 -license-expression==30.4.1 -lxml==5.1.0 -MarkupSafe==2.1.5 -more-itertools==8.13.0 -normality==2.3.3 -packageurl-python==0.15.0 -packaging==24.1 +license-expression==30.4.3 +lxml==5.4.0 +MarkupSafe==3.0.2 +more-itertools==10.7.0 +normality==2.6.1 +packageurl-python==0.17.1 +packaging==25.0 packvers==21.5 parameter-expansion-patched==0.3.1 -pdfminer.six==20220524 -pefile==2022.5.30 +pdfminer.six==20250506 +pefile==2024.8.26 pip-requirements-parser==32.0.1 pkginfo2==30.0.0 -pluggy==1.0.0 +pluggy==1.6.0 plugincode==32.0.0 ply==3.11 publicsuffix2==2.20191221 -pyahocorasick==2.1.0 -pycparser==2.21 +pyahocorasick==2.2.0 +pycparser==2.22 pygmars==0.9.0 Pygments==2.13.0 pymaven-patch==0.3.2 -pyparsing==3.0.9 +pyparsing==3.2.3 pytz==2022.1 -PyYAML==6.0.1 -rdflib==6.2.0 -requests==2.31.0 -saneyaml==0.6.0 -semantic-version==2.8.5 -six==1.16.0 -soupsieve==2.3.2.post1 +PyYAML==6.0.2 +rdflib==7.1.4 +requests==2.32.4 +saneyaml==0.6.1 +semantic-version==2.10.0 +six==1.17.0 +soupsieve==2.7 spdx-tools==0.8.2 text-unidecode==1.3 toml==0.10.2 -typecode==30.0.1 +typecode==30.0.2 typecode-libmagic==5.39.210531 -typing-extensions==4.3.0 -uritools==4.0.2 -urllib3==2.2.1 +typing-extensions==4.14.0 +uritools==5.0.0 +urllib3==2.5.0 urlpy==0.5 -wcwidth==0.2.5 +wcwidth==0.2.13 webencodings==0.5.1 -xmltodict==0.13.0 -zipp==3.8.1 +xmltodict==0.14.2 +zipp==3.23.0 diff --git a/setup-mini.cfg b/setup-mini.cfg index 59fbf90b014..8fe61f4e2b3 100644 --- a/setup-mini.cfg +++ b/setup-mini.cfg @@ -1,6 +1,6 @@ [metadata] name = scancode-toolkit-mini -version = 32.3.3 +version = 32.4.0 license = Apache-2.0 AND CC-BY-4.0 AND LicenseRef-scancode-other-permissive AND LicenseRef-scancode-other-copyleft # description must be on ONE line https://github.com/pypa/setuptools/issues/1390 @@ -21,6 +21,7 @@ classifiers = Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 Programming Language :: Python :: 3.12 + Programming Language :: Python :: 3.13 Topic :: Software Development Topic :: Utilities @@ -48,8 +49,10 @@ license_files = CHANGELOG.rst CODE_OF_CONDUCT.rst cc-by-4.0.LICENSE + README.rst [options] +python_requires = >=3.9 package_dir = =src packages = find: @@ -59,7 +62,6 @@ zip_safe = false py_modules = scancode_config -python_requires = >=3.9 install_requires = attrs >= 18.1,!=20.1.0;python_version<'3.11' @@ -86,7 +88,7 @@ install_requires = jinja2 >= 2.7.0 jsonstreams >= 0.5.0 license_expression >= 30.4.1 - lxml >= 4.9.2 + lxml >= 5.4.0 MarkupSafe >= 2.1.2 packageurl_python >= 0.9.0 packvers >= 21.0.0 @@ -125,20 +127,18 @@ full = typecode[full] >= 30.0.0 extractcode[full] >= 31.0.0 -testing = +dev = pytest >= 6, != 7.0.0 pytest-xdist >= 2 aboutcode-toolkit >= 7.0.2 - pycodestyle >= 2.8.0 twine black isort vendorize >= 0.3.0 pytest-rerunfailures - -docs = - Sphinx == 5.1.0 - sphinx_rtd_theme >= 0.5.1 + ruff + Sphinx>=5.0.2 + sphinx-rtd-theme>=1.0.0 sphinx-reredirects >= 0.1.2 doc8 >= 0.8.1 sphinx-autobuild @@ -160,6 +160,7 @@ console_scripts = scancode-license-data = licensedcode.license_db:dump_scancode_license_data regen-package-docs = packagedcode.regen_package_docs:regen_package_docs add-required-phrases = licensedcode.required_phrases:add_required_phrases + gen-new-required-phrases-rules = licensedcode.required_phrases:gen_required_phrases_rules # These are configurations for ScanCode plugins as setuptools entry points. # Each plugin entry hast this form: diff --git a/setup.cfg b/setup.cfg index 960a1613d79..426ae21fef8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = scancode-toolkit -version = 32.3.3 +version = 32.4.0 license = Apache-2.0 AND CC-BY-4.0 AND LicenseRef-scancode-other-permissive AND LicenseRef-scancode-other-copyleft # description must be on ONE line https://github.com/pypa/setuptools/issues/1390 @@ -21,6 +21,7 @@ classifiers = Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 Programming Language :: Python :: 3.12 + Programming Language :: Python :: 3.13 Topic :: Software Development Topic :: Utilities @@ -48,8 +49,11 @@ license_files = CHANGELOG.rst CODE_OF_CONDUCT.rst cc-by-4.0.LICENSE + README.rst [options] +python_requires = >=3.9 + package_dir = =src packages = find: @@ -59,7 +63,6 @@ zip_safe = false py_modules = scancode_config -python_requires = >=3.9 install_requires = attrs >= 18.1,!=20.1.0;python_version<'3.11' @@ -86,7 +89,7 @@ install_requires = jinja2 >= 2.7.0 jsonstreams >= 0.5.0 license_expression >= 30.4.1 - lxml >= 4.9.2 + lxml >= 5.4.0 MarkupSafe >= 2.1.2 packageurl_python >= 0.9.0 packvers >= 21.0.0 @@ -125,20 +128,18 @@ full = typecode[full] >= 30.0.0 extractcode[full] >= 31.0.0 -testing = +dev = pytest >= 6, != 7.0.0 pytest-xdist >= 2 aboutcode-toolkit >= 7.0.2 - pycodestyle >= 2.8.0 twine black isort vendorize >= 0.3.0 pytest-rerunfailures - -docs = - Sphinx == 5.1.0 - sphinx_rtd_theme >= 0.5.1 + ruff + Sphinx>=5.0.2 + sphinx-rtd-theme>=1.0.0 sphinx-reredirects >= 0.1.2 doc8 >= 0.8.1 sphinx-autobuild diff --git a/src/scancode_config.py b/src/scancode_config.py index cfe24d5def7..d1da047b2cc 100644 --- a/src/scancode_config.py +++ b/src/scancode_config.py @@ -131,20 +131,22 @@ def _create_dir(location): # 4. hardcoded This is the default, fallback version in case package is not installed or we # do not have a proper version otherwise. +# See https://scancode-toolkit.readthedocs.io/en/latest/misc/versioning.html for +# more information on versioning if not __version__: - __version__ = '32.3.3' + __version__ = '32.4.0' ####################### # used to warn user when the version is out of date # this is (year, month, day) -__release_date__ = datetime.datetime(2025, 1, 20) +__release_date__ = datetime.datetime(2025, 6, 26) -# See https://github.com/nexB/scancode-toolkit/issues/2653 for more information -# on the data format version -__output_format_version__ = '4.0.0' +# See https://scancode-toolkit.readthedocs.io/en/latest/misc/versioning.html +# for more information on the data format version +__output_format_version__ = '4.1.0' # see https://github.com/spdx/tools-python/issues/820 -# this is actually `3.25.0` +# this is actually `3.26.0` spdx_license_list_version = '3.26' ################################################################################ diff --git a/tests/packagedcode/data/m2/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom.json b/tests/packagedcode/data/m2/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom.json index 785d40ea381..cfbf574d3bf 100644 --- a/tests/packagedcode/data/m2/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom.json +++ b/tests/packagedcode/data/m2/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom.json @@ -116,7 +116,7 @@ }, { "id": "trygvis", - "name": "Trygve Laugstl", + "name": "Trygve Laugst", "email": "trygvis@codehaus.org", "url": null, "organization": null, diff --git a/tests/packagedcode/data/m2/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom.package.json b/tests/packagedcode/data/m2/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom.package.json index c687d0c4262..48a9910b926 100644 --- a/tests/packagedcode/data/m2/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom.package.json +++ b/tests/packagedcode/data/m2/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom.package.json @@ -75,7 +75,7 @@ { "type": "person", "role": "developer", - "name": "Trygve Laugstl", + "name": "Trygve Laugst", "email": "trygvis@codehaus.org", "url": null }, diff --git a/tests/packagedcode/data/m2/org/codehaus/plexus/plexus/1.0.5/plexus-1.0.5.pom.json b/tests/packagedcode/data/m2/org/codehaus/plexus/plexus/1.0.5/plexus-1.0.5.pom.json index abb2e8cd171..5dc0bd3d2a5 100644 --- a/tests/packagedcode/data/m2/org/codehaus/plexus/plexus/1.0.5/plexus-1.0.5.pom.json +++ b/tests/packagedcode/data/m2/org/codehaus/plexus/plexus/1.0.5/plexus-1.0.5.pom.json @@ -116,7 +116,7 @@ }, { "id": "trygvis", - "name": "Trygve Laugstl", + "name": "Trygve Laugst", "email": "trygvis@codehaus.org", "url": null, "organization": null, diff --git a/tests/packagedcode/data/m2/org/codehaus/plexus/plexus/1.0.5/plexus-1.0.5.pom.package.json b/tests/packagedcode/data/m2/org/codehaus/plexus/plexus/1.0.5/plexus-1.0.5.pom.package.json index 3bef77f7890..2db8c834a73 100644 --- a/tests/packagedcode/data/m2/org/codehaus/plexus/plexus/1.0.5/plexus-1.0.5.pom.package.json +++ b/tests/packagedcode/data/m2/org/codehaus/plexus/plexus/1.0.5/plexus-1.0.5.pom.package.json @@ -75,7 +75,7 @@ { "type": "person", "role": "developer", - "name": "Trygve Laugstl", + "name": "Trygve Laugst", "email": "trygvis@codehaus.org", "url": null }, diff --git a/tests/packagedcode/data/m2/plexus/plexus-root/1.0.3/plexus-root-1.0.3.pom.json b/tests/packagedcode/data/m2/plexus/plexus-root/1.0.3/plexus-root-1.0.3.pom.json index 598e4b3955c..c43b7c2dadc 100644 --- a/tests/packagedcode/data/m2/plexus/plexus-root/1.0.3/plexus-root-1.0.3.pom.json +++ b/tests/packagedcode/data/m2/plexus/plexus-root/1.0.3/plexus-root-1.0.3.pom.json @@ -116,7 +116,7 @@ }, { "id": "trygvis", - "name": "Trygve Laugstl", + "name": "Trygve Laugst", "email": "trygvis@codehaus.org", "url": null, "organization": null, diff --git a/tests/packagedcode/data/m2/plexus/plexus-root/1.0.3/plexus-root-1.0.3.pom.package.json b/tests/packagedcode/data/m2/plexus/plexus-root/1.0.3/plexus-root-1.0.3.pom.package.json index 20b1518aabc..9e0f18b2929 100644 --- a/tests/packagedcode/data/m2/plexus/plexus-root/1.0.3/plexus-root-1.0.3.pom.package.json +++ b/tests/packagedcode/data/m2/plexus/plexus-root/1.0.3/plexus-root-1.0.3.pom.package.json @@ -75,7 +75,7 @@ { "type": "person", "role": "developer", - "name": "Trygve Laugstl", + "name": "Trygve Laugst", "email": "trygvis@codehaus.org", "url": null }, diff --git a/tests/packagedcode/test_pypi.py b/tests/packagedcode/test_pypi.py index acbd47e255b..3dcfa7d4268 100644 --- a/tests/packagedcode/test_pypi.py +++ b/tests/packagedcode/test_pypi.py @@ -100,12 +100,6 @@ def test_develop_with_parse_metadata(self): expected_loc = self.get_test_loc('pypi/develop/scancode_toolkit.egg-info-expected.json') self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) - def test_develop_with_parse(self): - test_file = self.get_test_loc('pypi/develop/scancode_toolkit.egg-info/PKG-INFO') - package = pypi.PythonEditableInstallationPkgInfoFile.parse(test_file) - expected_loc = self.get_test_loc('pypi/develop/scancode_toolkit.egg-info-expected.json') - self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) - class TestPyPiPkgInfoAndMetadata(PackageTester): test_data_dir = os.path.join(os.path.dirname(__file__), 'data')