├── .gitattributes
├── .github
└── workflows
│ ├── docs-ci.yml
│ └── pypi-release.yml
├── .gitignore
├── .readthedocs.yml
├── AUTHORS.rst
├── CHANGELOG.rst
├── CODE_OF_CONDUCT.rst
├── MANIFEST.in
├── Makefile
├── NOTICE
├── README.rst
├── apache-2.0.LICENSE
├── azure-pipelines.yml
├── bsd-new.LICENSE
├── configure
├── configure.bat
├── conftest.py
├── default.nix
├── docs
├── Makefile
├── make.bat
├── scripts
│ ├── doc8_style_check.sh
│ └── sphinx_build_link_check.sh
└── source
│ ├── _static
│ └── theme_overrides.css
│ ├── conf.py
│ ├── contribute
│ └── contrib_doc.rst
│ ├── index.rst
│ └── skeleton-usage.rst
├── etc
├── ci
│ ├── azure-container-deb.yml
│ ├── azure-container-rpm.yml
│ ├── azure-posix.yml
│ ├── azure-win.yml
│ ├── install_sudo.sh
│ ├── macports-ci
│ ├── macports-ci.ABOUT
│ └── mit.LICENSE
└── scripts
│ ├── README.rst
│ ├── check_thirdparty.py
│ ├── fetch_thirdparty.py
│ ├── gen_pypi_simple.py
│ ├── gen_pypi_simple.py.ABOUT
│ ├── gen_pypi_simple.py.NOTICE
│ ├── gen_requirements.py
│ ├── gen_requirements_dev.py
│ ├── requirements.txt
│ ├── test_utils_pip_compatibility_tags.py
│ ├── test_utils_pip_compatibility_tags.py.ABOUT
│ ├── test_utils_pypi_supported_tags.py
│ ├── test_utils_pypi_supported_tags.py.ABOUT
│ ├── utils_dejacode.py
│ ├── utils_pip_compatibility_tags.py
│ ├── utils_pip_compatibility_tags.py.ABOUT
│ ├── utils_pypi_supported_tags.py
│ ├── utils_pypi_supported_tags.py.ABOUT
│ ├── utils_requirements.py
│ ├── utils_thirdparty.py
│ └── utils_thirdparty.py.ABOUT
├── flake.lock
├── flake.nix
├── mit.LICENSE
├── overlay.nix
├── pyproject.toml
├── requirements-dev.txt
├── requirements.txt
├── setup.cfg
├── setup.py
├── shell.nix
├── src
└── univers
│ ├── __init__.py
│ ├── arch.py
│ ├── arch.py.ABOUT
│ ├── arch.py.NOTICE
│ ├── bsd-new.LICENSE
│ ├── conan
│ ├── __init__.py
│ ├── errors.py
│ ├── errors.py.ABOUT
│ ├── errors.py.NOTICE
│ ├── version.py
│ ├── version.py.ABOUT
│ ├── version.py.NOTICE
│ ├── version_range.py
│ ├── version_range.py.ABOUT
│ └── version_range.py.NOTICE
│ ├── debian.py
│ ├── debian.py.ABOUT
│ ├── debian.py.NOTICE
│ ├── gem.py
│ ├── gem.py.ABOUT
│ ├── gem.py.NOTICE
│ ├── gentoo.py
│ ├── gentoo.py.ABOUT
│ ├── gentoo.py.NOTICE
│ ├── maven.py
│ ├── maven.py.ABOUT
│ ├── maven.py.NOTICE
│ ├── nuget.py
│ ├── nuget.py.ABOUT
│ ├── nuget.py.NOTICE
│ ├── rpm.py
│ ├── rpm.py.ABOUT
│ ├── rpm.py.NOTICE
│ ├── rpm.py.README
│ ├── rpm.py.antlir.ABOUT
│ ├── rpm.py.antlir.LICENSE
│ ├── rpm.py.antlir.NOTICE
│ ├── univers_semver.py
│ ├── utils.py
│ ├── version_constraint.py
│ ├── version_range.py
│ └── versions.py
└── tests
├── apache-2.0.LICENSE
├── bsd-new.LICENSE
├── data
├── alpine_test.txt
├── alpine_test.txt.ABOUT
├── alpine_test.txt.NOTICE
├── apache-2.0.LICENSE
├── composer_gitlab.json
├── conan_advisory.json
├── gem_gitlab.json
├── go_gitlab.json
├── gpl-2.0.LICENSE
├── npm_advisory.json
├── npm_gitlab.json
├── openssl
│ ├── openssl_all_versions.txt
│ └── openssl_versort_expected.json
├── pypi_gitlab.json
├── rpmvercmp.at
├── rpmvercmp.at.ABOUT
├── rpmvercmp.at.NOTICE
└── test-suite-data.json
├── gpl-2.0.LICENSE
├── nuget
├── test_nuget_floating_range.py
├── test_nuget_semver_201_spec.py
├── test_nuget_version.py
├── test_nuget_version_comparer.py
├── test_nuget_version_parsing.py
├── test_nuget_version_range.py
├── test_nuget_version_range_float_parsing.py
└── test_nuget_version_range_operation.py
├── nuget_versioning_tests.ABOUT
├── nuget_versioning_tests.NOTICE
├── nuget_versioning_tests.README.md
├── test_alpine.py
├── test_bundler_version_ranges_spec.py
├── test_bundler_version_ranges_spec.py.ABOUT
├── test_bundler_version_ranges_spec.py.NOTICE
├── test_codestyle.py
├── test_conan_version_bump.py
├── test_conan_version_bump.py.ABOUT
├── test_conan_version_bump.py.NOTICE
├── test_conan_version_comparison.py
├── test_conan_version_comparison.py.ABOUT
├── test_conan_version_comparison.py.NOTICE
├── test_conan_version_range.py
├── test_conan_version_range.py.ABOUT
├── test_conan_version_range.py.NOTICE
├── test_debian_version.py
├── test_debian_version.py.ABOUT
├── test_debian_version.py.NOTICE
├── test_debian_version_python_deb_pkg_tools.py
├── test_debian_version_python_deb_pkg_tools.py.ABOUT
├── test_gem.py
├── test_gem.py.ABOUT
├── test_gem.py.NOTICE
├── test_gentoo.py
├── test_gentoo.py.ABOUT
├── test_gentoo.py.NOTICE
├── test_gentoo_pkgcore.py
├── test_gentoo_pkgcore.py.ABOUT
├── test_gentoo_pkgcore.py.NOTICE
├── test_maven_version.py
├── test_maven_version.py.ABOUT
├── test_maven_version.py.NOTICE
├── test_maven_version_range.py
├── test_nuget.py
├── test_nuget.py.ABOUT
├── test_nuget.py.NOTICE
├── test_openssl_vercmp.py
├── test_openssl_versort.py
├── test_pacman_vercmp.py
├── test_pacman_vercmp.py.ABOUT
├── test_pacman_vercmp.py.NOTICE
├── test_pypi_version.py
├── test_python_semver.py
├── test_rpm.py
├── test_rpm.py.antlir.ABOUT
├── test_rpm.py.mit.NOTICE
├── test_rpm_vercmp.py
├── test_rpm_vercmp.py.ABOUT
├── test_rpm_vercmp.py.NOTICE
├── test_rubygems_gem_requirement.py
├── test_rubygems_gem_requirement.py.ABOUT
├── test_rubygems_gem_requirement.py.NOTICE
├── test_rubygems_gem_version.py
├── test_rubygems_gem_version.py.ABOUT
├── test_rubygems_gem_version.py.NOTICE
├── test_skeleton_codestyle.py
├── test_vers.py
├── test_version_comparison.py
├── test_version_constraint.py
├── test_version_range.py
├── test_versions.py
└── util_tests.py
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Ignore all Git auto CR/LF line endings conversions
2 | * -text
3 | pyproject.toml export-subst
4 |
--------------------------------------------------------------------------------
/.github/workflows/docs-ci.yml:
--------------------------------------------------------------------------------
1 | name: CI Documentation
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-22.04
8 |
9 | strategy:
10 | max-parallel: 4
11 | matrix:
12 | python-version: [3.9]
13 |
14 | steps:
15 | - name: Checkout code
16 | uses: actions/checkout@v3
17 |
18 | - name: Set up Python ${{ matrix.python-version }}
19 | uses: actions/setup-python@v4
20 | with:
21 | python-version: ${{ matrix.python-version }}
22 |
23 | - name: Install Dependencies
24 | run: pip install -e .[docs]
25 |
26 | - name: Check Sphinx Documentation build minimally
27 | working-directory: ./docs
28 | run: sphinx-build -E -W source build
29 |
30 | - name: Check for documentation style errors
31 | working-directory: ./docs
32 | run: ./scripts/doc8_style_check.sh
33 |
34 |
35 |
--------------------------------------------------------------------------------
/.github/workflows/pypi-release.yml:
--------------------------------------------------------------------------------
1 | name: Release library as a PyPI wheel and sdist on tag
2 |
3 | on:
4 | release:
5 | types: [created]
6 |
7 | jobs:
8 | build-and-publish-to-pypi:
9 | name: Build and publish library to PyPI
10 | runs-on: ubuntu-20.04
11 | steps:
12 | - uses: actions/checkout@master
13 | - name: Set up Python
14 | uses: actions/setup-python@v1
15 | with:
16 | python-version: 3.9
17 | - name: Install pypa/build
18 | run: python -m pip install build --user
19 | - name: Build a binary wheel and a source tarball
20 | run: python -m build --sdist --wheel --outdir dist/
21 | .
22 | - name: Publish distribution to PyPI
23 | if: startsWith(github.ref, 'refs/tags')
24 | uses: pypa/gh-action-pypi-publish@master
25 | with:
26 | password: ${{ secrets.PYPI_API_TOKEN }}
27 |
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Python compiled files
2 | *.py[cod]
3 |
4 | # virtualenv and other misc bits
5 | /src/*.egg-info
6 | *.egg-info
7 | /dist
8 | /build
9 | /bin
10 | /lib
11 | /scripts
12 | /Scripts
13 | /Lib
14 | /pip-selfcheck.json
15 | /tmp
16 | /venv
17 | .Python
18 | /include
19 | /Include
20 | /local
21 | */local/*
22 | /local/
23 | /share/
24 | /tcl/
25 | /.eggs/
26 |
27 | # Installer logs
28 | pip-log.txt
29 |
30 | # Unit test / coverage reports
31 | .cache
32 | .coverage
33 | .coverage.*
34 | nosetests.xml
35 | htmlcov
36 |
37 | # Translations
38 | *.mo
39 |
40 | # IDEs
41 | .project
42 | .pydevproject
43 | .idea
44 | org.eclipse.core.resources.prefs
45 | .vscode
46 | .vs
47 |
48 | # Sphinx
49 | docs/_build
50 | docs/bin
51 | docs/build
52 | docs/include
53 | docs/Lib
54 | doc/pyvenv.cfg
55 | pyvenv.cfg
56 |
57 | # Various junk and temp files
58 | .DS_Store
59 | *~
60 | .*.sw[po]
61 | .build
62 | .ve
63 | *.bak
64 | /.cache/
65 |
66 | # pyenv
67 | /.python-version
68 | /man/
69 | /.pytest_cache/
70 | lib64
71 | tcl
72 |
73 | # Ignore Jupyter Notebook related temp files
74 | .ipynb_checkpoints/
75 |
76 | # Nix
77 | /result*
78 |
--------------------------------------------------------------------------------
/.readthedocs.yml:
--------------------------------------------------------------------------------
1 | # .readthedocs.yml
2 | # Read the Docs configuration file
3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4 |
5 | # Required
6 | version: 2
7 |
8 | # Build in latest ubuntu/python
9 | build:
10 | os: ubuntu-22.04
11 | tools:
12 | python: "3.11"
13 |
14 | # Build PDF & ePub
15 | formats:
16 | - epub
17 | - pdf
18 |
19 | # Where the Sphinx conf.py file is located
20 | sphinx:
21 | configuration: docs/source/conf.py
22 |
23 | # Setting the python version and doc build requirements
24 | python:
25 | install:
26 | - method: pip
27 | path: .
28 | extra_requirements:
29 | - docs
30 |
--------------------------------------------------------------------------------
/AUTHORS.rst:
--------------------------------------------------------------------------------
1 | The following organizations or individuals have contributed to this repo:
2 |
3 | - Shivam Sandbhor @sbs2001
4 | - Philippe Ombredanne @pombredanne
5 | - Hritik Vijay @Hritik14
6 | - Tushar Goel @TG1999
7 | - Keshav Priyadarshi @keshav-space
8 | - Chin-Yeung Li @chinyeungli
9 | - Ayan Sinha Mahapatra @AyanSinhaMahapatra
10 | - Jono Yang @JonoYang
11 |
12 | Plus 100+ contributors that created the underlying and bundled version handling
13 | utilities.
--------------------------------------------------------------------------------
/CHANGELOG.rst:
--------------------------------------------------------------------------------
1 | Changelog
2 | =========
3 |
4 | Version v30.12.1
5 | ----------------
6 |
7 | - Update link references of ownership from nexB to aboutcode-org. https://github.com/aboutcode-org/univers/issues/140
8 |
9 |
10 | Version v30.12.0
11 | ----------------
12 |
13 | - Support VersionRange normalization using known versions. https://github.com/nexB/univers/pull/108
14 | - Fix the edge case resulting in incorrect ``contains`` resolution in VersionRange. https://github.com/nexB/univers/issues/137 https://github.com/nexB/univers/pull/108
15 | - Use native impl to parse Maven and NuGet range expression in ``from_gitlab_native``. https://github.com/nexB/univers/issues/136 https://github.com/nexB/univers/pull/108
16 | - Fix incorrect parsing of composer range in ``from_gitlab_native``. https://github.com/nexB/univers/issues/136 https://github.com/nexB/univers/pull/108
17 |
18 |
19 | Version v30.11.0
20 | ----------------
21 |
22 | - Use proper exception subclass for invalid constraints error.
23 |
24 |
25 | Version v30.10.1
26 | ----------------
27 |
28 | - Add Nix flake as a build system.
29 | - Refactor gem and make nuget hashable.
30 | - Update skeleton.
31 | - Handle NoneType in VersionRange.from_string.
32 | - Handle npm prerelease caret range expression.
33 |
34 |
35 | Version v30.10.0
36 | ----------------
37 |
38 | - Add support for conan version and version range.
39 | - Fix version comparison for all the versions.
40 |
41 |
42 | Version v30.9.2
43 | ----------------
44 |
45 | - Fix unhashable error in GemVersion.
46 |
47 |
48 | Version v30.9.1
49 | ----------------
50 |
51 | - Add invert function to VersionRange.
52 |
53 |
54 | Version v30.9.0
55 | ----------------
56 |
57 | - Change type of archlinux version ranges to alpm.
58 |
59 |
60 | Version v30.8.0
61 | ----------------
62 |
63 | - Fix npm version ranges
64 |
65 |
66 | Version v30.7.0
67 | ----------------
68 |
69 | - Add composer and golang versions and also support gitlab native ranges for them
70 |
71 |
72 | Version v30.6.0
73 | ----------------
74 |
75 | - Add support for gitlab in pypi, npm, gem version ranges
76 | - Subclass semver for nginx
77 |
78 |
79 | Version v30.5.1
80 | ----------------
81 |
82 | - Fix Nuget string representation
83 | - Test sorting of all the OpenSSL versions ever released
84 |
85 |
86 | Version v30.5.0
87 | ----------------
88 |
89 | - Add version range support for maven
90 | - Remove unsupported characters in Pypi from_native implementation
91 | - Add Nuget Version support in Univers
92 |
93 |
94 | Version v30.4.0
95 | ----------------
96 |
97 | - Add support for forming VersionRange from a list of versions.Thank you
98 | to Keshav Priyadarshi @keshav-space for this.
99 |
100 |
101 | Version v30.3.1
102 | ----------------
103 |
104 | - Change equal comparator for github native ranges
105 |
106 |
107 | Version v30.3.0
108 | ----------------
109 |
110 | - New support for native GitHub version ranges. GitHub native version range is different from
111 | other native ranges. For example:
112 | Maven native version range looks like:
113 | `[1.0.0,1.0.1)`
114 | Github native version range looks like:
115 | `>= 1.0.0, < 1.0.1`
116 |
117 |
118 | Version v30.2.0
119 | ----------------
120 |
121 | - New support for OpenSSL version(s). These are peculiar because there are two
122 | epochs in the versioning: the versioning scheme is custom before version 3
123 | and is based on semver from version 3 onwards. Thank you to Keshav Priyadarshi
124 | @keshav-space for this.
125 |
126 |
127 | Version v30.1.0
128 | -----------------
129 |
130 | - New support for Alpine package versions. These are based loosely on Gentoo
131 | versions with some variations. We do not support all the version styles yet.
132 | The unit tests are based on the upstream apk-tools tests and this brings in
133 | 700 new unit tests.
134 | - Fix handling of caret and tilde version in npm version ranges.
135 | - Enable automated build of wheels on release
136 | - Adopt latest skeleton, droping support for tests on macOS 10.14
137 |
138 |
139 | Version v30.0.0
140 | -----------------
141 |
142 | - Implement the new "vers" spec. This is a major incomplatible change.
143 | - Add support for nginx version scheme
144 | - Switching back to semver
145 | - Improve origin and license documentation
146 | - Add tests for carets in RPMs
147 | - Format, streamline and refactor code
148 | - Improve testing
149 |
150 |
151 | Version v21.4.9
152 | -----------------
153 |
154 | - Add support Gentoo style versions.
155 |
156 |
157 | Version v21.4.8
158 | -----------------
159 |
160 | - Add support for more package types.
161 | - Version classes are now hashable and frozen
162 |
163 |
164 | Version v21.4.6
165 | -----------------
166 |
167 | - Initial Release
168 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.rst:
--------------------------------------------------------------------------------
1 | Contributor Covenant Code of Conduct
2 | ====================================
3 |
4 | Our Pledge
5 | ----------
6 |
7 | In the interest of fostering an open and welcoming environment, we as
8 | contributors and maintainers pledge to making participation in our
9 | project and our community a harassment-free experience for everyone,
10 | regardless of age, body size, disability, ethnicity, gender identity and
11 | expression, level of experience, education, socio-economic status,
12 | nationality, personal appearance, race, religion, or sexual identity and
13 | orientation.
14 |
15 | Our Standards
16 | -------------
17 |
18 | Examples of behavior that contributes to creating a positive environment
19 | include:
20 |
21 | - Using welcoming and inclusive language
22 | - Being respectful of differing viewpoints and experiences
23 | - Gracefully accepting constructive criticism
24 | - Focusing on what is best for the community
25 | - Showing empathy towards other community members
26 |
27 | Examples of unacceptable behavior by participants include:
28 |
29 | - The use of sexualized language or imagery and unwelcome sexual
30 | attention or advances
31 | - Trolling, insulting/derogatory comments, and personal or political
32 | attacks
33 | - Public or private harassment
34 | - Publishing others’ private information, such as a physical or
35 | electronic address, without explicit permission
36 | - Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | Our Responsibilities
40 | --------------------
41 |
42 | Project maintainers are responsible for clarifying the standards of
43 | acceptable behavior and are expected to take appropriate and fair
44 | corrective action in response to any instances of unacceptable behavior.
45 |
46 | Project maintainers have the right and responsibility to remove, edit,
47 | or reject comments, commits, code, wiki edits, issues, and other
48 | contributions that are not aligned to this Code of Conduct, or to ban
49 | temporarily or permanently any contributor for other behaviors that they
50 | deem inappropriate, threatening, offensive, or harmful.
51 |
52 | Scope
53 | -----
54 |
55 | This Code of Conduct applies both within project spaces and in public
56 | spaces when an individual is representing the project or its community.
57 | Examples of representing a project or community include using an
58 | official project e-mail address, posting via an official social media
59 | account, or acting as an appointed representative at an online or
60 | offline event. Representation of a project may be further defined and
61 | clarified by project maintainers.
62 |
63 | Enforcement
64 | -----------
65 |
66 | Instances of abusive, harassing, or otherwise unacceptable behavior may
67 | be reported by contacting the project team at pombredanne@gmail.com
68 | or on the Gitter chat channel at https://gitter.im/aboutcode-org/discuss .
69 | All complaints will be reviewed and investigated and will result in a
70 | response that is deemed necessary and appropriate to the circumstances.
71 | The project team is obligated to maintain confidentiality with regard to
72 | the reporter of an incident. Further details of specific enforcement
73 | policies may be posted separately.
74 |
75 | Project maintainers who do not follow or enforce the Code of Conduct in
76 | good faith may face temporary or permanent repercussions as determined
77 | by other members of the project’s leadership.
78 |
79 | Attribution
80 | -----------
81 |
82 | This Code of Conduct is adapted from the `Contributor Covenant`_ ,
83 | version 1.4, available at
84 | https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
85 |
86 | .. _Contributor Covenant: https://www.contributor-covenant.org
87 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | graft src
2 |
3 | include *.LICENSE
4 | include NOTICE
5 | include *.ABOUT
6 | include *.toml
7 | include *.yml
8 | include *.rst
9 | include setup.*
10 | include configure*
11 | include requirements*
12 | include .git*
13 |
14 | global-exclude *.py[co] __pycache__ *.*~
15 |
16 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: Apache-2.0
2 | #
3 | # Copyright (c) nexB Inc. and others. All rights reserved.
4 | # ScanCode is a trademark of nexB Inc.
5 | # SPDX-License-Identifier: Apache-2.0
6 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
7 | # See https://github.com/aboutcode-org/skeleton for support or download.
8 | # See https://aboutcode.org for more information about nexB OSS projects.
9 | #
10 |
11 | # Python version can be specified with `$ PYTHON_EXE=python3.x make conf`
12 | PYTHON_EXE?=python3
13 | VENV=venv
14 | ACTIVATE?=. ${VENV}/bin/activate;
15 |
16 | dev:
17 | @echo "-> Configure the development envt."
18 | ./configure --dev
19 |
20 | isort:
21 | @echo "-> Apply isort changes to ensure proper imports ordering"
22 | ${VENV}/bin/isort --sl -l 100 src tests setup.py
23 |
24 | black:
25 | @echo "-> Apply black code formatter"
26 | ${VENV}/bin/black -l 100 src tests setup.py
27 |
28 | doc8:
29 | @echo "-> Run doc8 validation"
30 | @${ACTIVATE} doc8 --max-line-length 100 --ignore-path docs/_build/ --quiet docs/
31 |
32 | valid: isort black
33 |
34 | check:
35 | @echo "-> Run pycodestyle (PEP8) validation"
36 | @${ACTIVATE} pycodestyle --max-line-length=100 --exclude=.eggs,venv,lib,thirdparty,docs,migrations,settings.py,.cache .
37 | @echo "-> Run isort imports ordering validation"
38 | @${ACTIVATE} isort --sl --check-only -l 100 setup.py src tests .
39 | @echo "-> Run black validation"
40 | @${ACTIVATE} black --check --check -l 100 src tests setup.py
41 |
42 | clean:
43 | @echo "-> Clean the Python env"
44 | ./configure --clean
45 |
46 | test:
47 | @echo "-> Run the test suite"
48 | ${VENV}/bin/pytest -vvs
49 |
50 | docs:
51 | rm -rf docs/_build/
52 | @${ACTIVATE} sphinx-build docs/ docs/_build/
53 |
54 | .PHONY: conf dev check valid black isort clean test docs
55 |
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) nexB Inc. and others.
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/vulnerablecode
6 | # for support and download.
7 | #
8 | # Licensed under the Apache License, Version 2.0 (the "License");
9 | # you may not use this file except in compliance with the License.
10 | # You may obtain a copy of the License at
11 | #
12 | # http://www.apache.org/licenses/LICENSE-2.0
13 | #
14 | # Unless required by applicable law or agreed to in writing, software
15 | # distributed under the License is distributed on an "AS IS" BASIS,
16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 | # See the License for the specific language governing permissions and
18 | # limitations under the License.
19 | #
20 |
--------------------------------------------------------------------------------
/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 |
2 | ################################################################################
3 | # We use Azure to run the full tests suites on multiple Python 3.x
4 | # on multiple Windows, macOS and Linux versions all on 64 bits
5 | # These jobs are using VMs with Azure-provided Python builds
6 | ################################################################################
7 |
8 | jobs:
9 |
10 | - template: etc/ci/azure-posix.yml
11 | parameters:
12 | job_name: ubuntu20_cpython
13 | image_name: ubuntu-20.04
14 | python_versions: ['3.8', '3.9', '3.10', '3.11', '3.12']
15 | test_suites:
16 | all: |
17 | source venv/bin/activate
18 | pytest -n 2 -vvs
19 |
20 | - template: etc/ci/azure-posix.yml
21 | parameters:
22 | job_name: ubuntu22_cpython
23 | image_name: ubuntu-22.04
24 | python_versions: ['3.8', '3.9', '3.10', '3.11', '3.12']
25 | test_suites:
26 | all: |
27 | source venv/bin/activate
28 | pytest -n 2 -vvs
29 |
30 | - template: etc/ci/azure-posix.yml
31 | parameters:
32 | job_name: macos12_cpython
33 | image_name: macOS-12
34 | python_versions: ['3.8', '3.9', '3.10', '3.11', '3.12']
35 | test_suites:
36 | all: |
37 | source venv/bin/activate
38 | pytest -n 2 -vvs
39 |
40 | - template: etc/ci/azure-posix.yml
41 | parameters:
42 | job_name: macos13_cpython
43 | image_name: macOS-13
44 | python_versions: ['3.8', '3.9', '3.10', '3.11', '3.12']
45 | test_suites:
46 | all: venv/bin/pytest -n 2 -vvs
47 |
48 | - template: etc/ci/azure-posix.yml
49 | parameters:
50 | job_name: macos14_cpython_arm64
51 | image_name: macOS-14
52 | python_versions: ['3.8', '3.9', '3.10', '3.11', '3.12']
53 | test_suites:
54 | all: venv/bin/pytest -n 2 -vvs
55 |
56 | - template: etc/ci/azure-win.yml
57 | parameters:
58 | job_name: win2019_cpython
59 | image_name: windows-2019
60 | python_versions: ['3.8', '3.9', '3.10', '3.11', '3.12']
61 | test_suites:
62 | all: |
63 | call venv\Scripts\activate.bat
64 | pytest -n 2 -vvs
65 |
66 | - template: etc/ci/azure-win.yml
67 | parameters:
68 | job_name: win2022_cpython
69 | image_name: windows-2022
70 | python_versions: ['3.8', '3.9', '3.10', '3.11', '3.12']
71 | test_suites:
72 | all: |
73 | call venv\Scripts\activate.bat
74 | pytest -n 2 -vvs
75 |
--------------------------------------------------------------------------------
/bsd-new.LICENSE:
--------------------------------------------------------------------------------
1 | Redistribution and use in source and binary forms, with or without modification,
2 | are permitted provided that the following conditions are met:
3 |
4 | Redistributions of source code must retain the above copyright notice, this list
5 | of conditions and the following disclaimer.
6 |
7 | Redistributions in binary form must reproduce the above copyright notice, this
8 | list of conditions and the following disclaimer in the documentation and/or
9 | other materials provided with the distribution.
10 |
11 | Neither the name of the ORGANIZATION nor the names of its contributors may be
12 | used to endorse or promote products derived from this software without specific
13 | prior written permission.
14 |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
19 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
24 | THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/conftest.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) nexB Inc. and others.
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 | collect_ignore = ["setup.py"]
8 |
--------------------------------------------------------------------------------
/default.nix:
--------------------------------------------------------------------------------
1 | (import (fetchTarball https://github.com/edolstra/flake-compat/archive/b4a34015c698c7793d592d66adbab377907a2be8.tar.gz) {
2 | src = builtins.fetchGit ./.;
3 | }).defaultNix
4 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?=
7 | SPHINXBUILD ?= sphinx-build
8 | SPHINXAUTOBUILD = sphinx-autobuild
9 | SOURCEDIR = source
10 | BUILDDIR = build
11 |
12 | # Put it first so that "make" without argument is like "make help".
13 | help:
14 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
15 |
16 | .PHONY: help Makefile
17 |
18 | # Run the development server using sphinx-autobuild
19 | docs:
20 | @echo
21 | @echo "Starting up the docs server..."
22 | @echo
23 | $(SPHINXAUTOBUILD) --port 8000 --watch ${SOURCEDIR} $(SOURCEDIR) "$(BUILDDIR)/html" $(SPHINXOPTS) $(O)
24 |
25 | # Catch-all target: route all unknown targets to Sphinx using the new
26 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
27 | %: Makefile
28 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
29 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | if "%SPHINXAUTOBUILD%" == "" (
11 | set SPHINXAUTOBUILD=sphinx-autobuild
12 | )
13 | set SOURCEDIR=source
14 | set BUILDDIR=build
15 |
16 | if "%1" == "" goto help
17 |
18 | if "%1" == "docs" goto docs
19 |
20 | %SPHINXBUILD% >NUL 2>NUL
21 | if errorlevel 9009 (
22 | echo.
23 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
24 | echo.installed, then set the SPHINXBUILD environment variable to point
25 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
26 | echo.may add the Sphinx directory to PATH.
27 | echo.
28 | echo.If you don't have Sphinx installed, grab it from
29 | echo.http://sphinx-doc.org/
30 | exit /b 1
31 | )
32 |
33 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
34 | goto end
35 |
36 | :docs
37 | @echo
38 | @echo Starting up the docs server...
39 | @echo
40 | %SPHINXAUTOBUILD% --port 8000 --watch %SOURCEDIR% %SOURCEDIR% %BUILDDIR%\html %SPHINXOPTS% %O%
41 | goto end
42 |
43 | :help
44 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
45 |
46 | :end
47 | popd
48 |
--------------------------------------------------------------------------------
/docs/scripts/doc8_style_check.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # halt script on error
3 | set -e
4 | # Check for Style Code Violations
5 | doc8 --max-line-length 100 source --ignore D000 --quiet
--------------------------------------------------------------------------------
/docs/scripts/sphinx_build_link_check.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # halt script on error
3 | set -e
4 | # Build locally, and then check links
5 | sphinx-build -E -W -b linkcheck source build
--------------------------------------------------------------------------------
/docs/source/_static/theme_overrides.css:
--------------------------------------------------------------------------------
1 | /* this is the container for the pages */
2 | .wy-nav-content {
3 | max-width: 100%;
4 | padding: 0px 40px 0px 0px;
5 | margin-top: 0px;
6 | }
7 |
8 | .wy-nav-content-wrap {
9 | border-right: solid 1px;
10 | }
11 |
12 | div.rst-content {
13 | max-width: 1300px;
14 | border: 0;
15 | padding: 10px 80px 10px 80px;
16 | margin-left: 50px;
17 | }
18 |
19 | @media (max-width: 768px) {
20 | div.rst-content {
21 | max-width: 1300px;
22 | border: 0;
23 | padding: 0px 10px 10px 10px;
24 | margin-left: 0px;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/docs/source/conf.py:
--------------------------------------------------------------------------------
1 | # Configuration file for the Sphinx documentation builder.
2 | #
3 | # This file only contains a selection of the most common options. For a full
4 | # list see the documentation:
5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html
6 |
7 | # -- Path setup --------------------------------------------------------------
8 |
9 | # If extensions (or modules to document with autodoc) are in another directory,
10 | # add these directories to sys.path here. If the directory is relative to the
11 | # documentation root, use os.path.abspath to make it absolute, like shown here.
12 | #
13 | # import os
14 | # import sys
15 | # sys.path.insert(0, os.path.abspath('.'))
16 |
17 |
18 | # -- Project information -----------------------------------------------------
19 |
20 | project = "nexb-skeleton"
21 | copyright = "nexB Inc. and others."
22 | author = "AboutCode.org authors and contributors"
23 |
24 |
25 | # -- General configuration ---------------------------------------------------
26 |
27 | # Add any Sphinx extension module names here, as strings. They can be
28 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
29 | # ones.
30 | extensions = [
31 | "sphinx.ext.intersphinx",
32 | "sphinx_reredirects",
33 | "sphinx_rtd_theme",
34 | "sphinx_rtd_dark_mode",
35 | "sphinx.ext.extlinks",
36 | "sphinx_copybutton",
37 | ]
38 |
39 |
40 | # Redirects for olds pages
41 | # See https://documatt.gitlab.io/sphinx-reredirects/usage.html
42 | redirects = {}
43 |
44 | # This points to aboutcode.readthedocs.io
45 | # In case of "undefined label" ERRORS check docs on intersphinx to troubleshoot
46 | # Link was created at commit - https://github.com/aboutcode-org/aboutcode/commit/faea9fcf3248f8f198844fe34d43833224ac4a83
47 |
48 | intersphinx_mapping = {
49 | "aboutcode": ("https://aboutcode.readthedocs.io/en/latest/", None),
50 | "scancode-workbench": (
51 | "https://scancode-workbench.readthedocs.io/en/develop/",
52 | None,
53 | ),
54 | }
55 |
56 |
57 | # Add any paths that contain templates here, relative to this directory.
58 | templates_path = ["_templates"]
59 |
60 | # List of patterns, relative to source directory, that match files and
61 | # directories to ignore when looking for source files.
62 | # This pattern also affects html_static_path and html_extra_path.
63 | exclude_patterns = []
64 |
65 |
66 | # -- Options for HTML output -------------------------------------------------
67 |
68 | # The theme to use for HTML and HTML Help pages. See the documentation for
69 | # a list of builtin themes.
70 | #
71 | html_theme = "sphinx_rtd_theme"
72 |
73 | # Add any paths that contain custom static files (such as style sheets) here,
74 | # relative to this directory. They are copied after the builtin static files,
75 | # so a file named "default.css" will overwrite the builtin "default.css".
76 | html_static_path = ["_static"]
77 |
78 | master_doc = "index"
79 |
80 | html_context = {
81 | "display_github": True,
82 | "github_user": "nexB",
83 | "github_repo": "nexb-skeleton",
84 | "github_version": "develop", # branch
85 | "conf_py_path": "/docs/source/", # path in the checkout to the docs root
86 | }
87 |
88 | html_css_files = [
89 | "theme_overrides.css",
90 | ]
91 |
92 |
93 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
94 | html_show_sphinx = True
95 |
96 | # Define CSS and HTML abbreviations used in .rst files. These are examples.
97 | # .. role:: is used to refer to styles defined in _static/theme_overrides.css and is used like this: :red:`text`
98 | rst_prolog = """
99 | .. |psf| replace:: Python Software Foundation
100 |
101 | .. # define a hard line break for HTML
102 | .. |br| raw:: html
103 |
104 |
105 |
106 | .. role:: red
107 |
108 | .. role:: img-title
109 |
110 | .. role:: img-title-para
111 |
112 | """
113 |
114 | # -- Options for LaTeX output -------------------------------------------------
115 |
116 | latex_elements = {"classoptions": ",openany,oneside"}
117 |
--------------------------------------------------------------------------------
/docs/source/index.rst:
--------------------------------------------------------------------------------
1 | Welcome to nexb-skeleton's documentation!
2 | =========================================
3 |
4 | .. toctree::
5 | :maxdepth: 2
6 | :caption: Contents:
7 |
8 | skeleton-usage
9 | contribute/contrib_doc
10 |
11 | Indices and tables
12 | ==================
13 |
14 | * :ref:`genindex`
15 | * :ref:`modindex`
16 | * :ref:`search`
17 |
--------------------------------------------------------------------------------
/docs/source/skeleton-usage.rst:
--------------------------------------------------------------------------------
1 | Usage
2 | =====
3 | A brand new project
4 | -------------------
5 | .. code-block:: bash
6 |
7 | git init my-new-repo
8 | cd my-new-repo
9 | git pull git@github.com:nexB/skeleton
10 |
11 | # Create the new repo on GitHub, then update your remote
12 | git remote set-url origin git@github.com:nexB/your-new-repo.git
13 |
14 | From here, you can make the appropriate changes to the files for your specific project.
15 |
16 | Update an existing project
17 | ---------------------------
18 | .. code-block:: bash
19 |
20 | cd my-existing-project
21 | git remote add skeleton git@github.com:nexB/skeleton
22 | git fetch skeleton
23 | git merge skeleton/main --allow-unrelated-histories
24 |
25 | This is also the workflow to use when updating the skeleton files in any given repository.
26 |
27 | Customizing
28 | -----------
29 |
30 | You typically want to perform these customizations:
31 |
32 | - remove or update the src/README.rst and tests/README.rst files
33 | - set project info and dependencies in setup.cfg
34 | - check the configure and configure.bat defaults
35 |
36 | Initializing a project
37 | ----------------------
38 |
39 | All projects using the skeleton will be expected to pull all of it dependencies
40 | from thirdparty.aboutcode.org/pypi or the local thirdparty directory, using
41 | requirements.txt and/or requirements-dev.txt to determine what version of a
42 | package to collect. By default, PyPI will not be used to find and collect
43 | packages from.
44 |
45 | In the case where we are starting a new project where we do not have
46 | requirements.txt and requirements-dev.txt and whose dependencies are not yet on
47 | thirdparty.aboutcode.org/pypi, we run the following command after adding and
48 | customizing the skeleton files to your project:
49 |
50 | .. code-block:: bash
51 |
52 | ./configure
53 |
54 | This will initialize the virtual environment for the project, pull in the
55 | dependencies from PyPI and add them to the virtual environment.
56 |
57 |
58 | Generating requirements.txt and requirements-dev.txt
59 | ----------------------------------------------------
60 |
61 | After the project has been initialized, we can generate the requirements.txt and
62 | requirements-dev.txt files.
63 |
64 | Ensure the virtual environment is enabled.
65 |
66 | .. code-block:: bash
67 |
68 | source venv/bin/activate
69 |
70 | To generate requirements.txt:
71 |
72 | .. code-block:: bash
73 |
74 | python etc/scripts/gen_requirements.py -s venv/lib/python/site-packages/
75 |
76 | Replace \ with the version number of the Python being used, for example:
77 | ``venv/lib/python3.6/site-packages/``
78 |
79 | To generate requirements-dev.txt after requirements.txt has been generated:
80 |
81 | .. code-block:: bash
82 |
83 | ./configure --dev
84 | python etc/scripts/gen_requirements_dev.py -s venv/lib/python/site-packages/
85 |
86 | Note: on Windows, the ``site-packages`` directory is located at ``venv\Lib\site-packages\``
87 |
88 | .. code-block:: bash
89 |
90 | python .\\etc\\scripts\\gen_requirements.py -s .\\venv\\Lib\\site-packages\\
91 | .\configure --dev
92 | python .\\etc\\scripts\\gen_requirements_dev.py -s .\\venv\\Lib\\site-packages\\
93 |
94 |
95 | Collecting and generating ABOUT files for dependencies
96 | ------------------------------------------------------
97 |
98 | Ensure that the dependencies used by ``etc/scripts/fetch_thirdparty.py`` are installed:
99 |
100 | .. code-block:: bash
101 |
102 | pip install -r etc/scripts/requirements.txt
103 |
104 | Once we have requirements.txt and requirements-dev.txt, we can fetch the project
105 | dependencies as wheels and generate ABOUT files for them:
106 |
107 | .. code-block:: bash
108 |
109 | python etc/scripts/fetch_thirdparty.py -r requirements.txt -r requirements-dev.txt
110 |
111 | There may be issues with the generated ABOUT files, which will have to be
112 | corrected. You can check to see if your corrections are valid by running:
113 |
114 | .. code-block:: bash
115 |
116 | python etc/scripts/check_thirdparty.py -d thirdparty
117 |
118 | Once the wheels are collected and the ABOUT files are generated and correct,
119 | upload them to thirdparty.aboutcode.org/pypi by placing the wheels and ABOUT
120 | files from the thirdparty directory to the pypi directory at
121 | https://github.com/aboutcode-org/thirdparty-packages
122 |
123 |
124 | Usage after project initialization
125 | ----------------------------------
126 |
127 | Once the ``requirements.txt`` and ``requirements-dev.txt`` have been generated
128 | and the project dependencies and their ABOUT files have been uploaded to
129 | thirdparty.aboutcode.org/pypi, you can configure the project as needed, typically
130 | when you update dependencies or use a new checkout.
131 |
132 | If the virtual env for the project becomes polluted, or you would like to remove
133 | it, use the ``--clean`` option:
134 |
135 | .. code-block:: bash
136 |
137 | ./configure --clean
138 |
139 | Then you can run ``./configure`` again to set up the project virtual environment.
140 |
141 | To set up the project for development use:
142 |
143 | .. code-block:: bash
144 |
145 | ./configure --dev
146 |
147 | To update the project dependencies (adding, removing, updating packages, etc.),
148 | update the dependencies in ``setup.cfg``, then run:
149 |
150 | .. code-block:: bash
151 |
152 | ./configure --clean # Remove existing virtual environment
153 | source venv/bin/activate # Ensure virtual environment is activated
154 | python etc/scripts/gen_requirements.py -s venv/lib/python/site-packages/ # Regenerate requirements.txt
155 | python etc/scripts/gen_requirements_dev.py -s venv/lib/python/site-packages/ # Regenerate requirements-dev.txt
156 | pip install -r etc/scripts/requirements.txt # Install dependencies needed by etc/scripts/bootstrap.py
157 | python etc/scripts/fetch_thirdparty.py -r requirements.txt -r requirements-dev.txt # Collect dependency wheels and their ABOUT files
158 |
159 | Ensure that the generated ABOUT files are valid, then take the dependency wheels
160 | and ABOUT files and upload them to thirdparty.aboutcode.org/pypi.
161 |
--------------------------------------------------------------------------------
/etc/ci/azure-container-deb.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | job_name: ''
3 | container: ''
4 | python_path: ''
5 | python_version: ''
6 | package_manager: apt-get
7 | install_python: ''
8 | install_packages: |
9 | set -e -x
10 | sudo apt-get -y update
11 | sudo apt-get -y install \
12 | build-essential \
13 | xz-utils zlib1g bzip2 libbz2-1.0 tar \
14 | sqlite3 libxml2-dev libxslt1-dev \
15 | software-properties-common openssl
16 | test_suite: ''
17 | test_suite_label: ''
18 |
19 |
20 | jobs:
21 | - job: ${{ parameters.job_name }}
22 |
23 | pool:
24 | vmImage: 'ubuntu-16.04'
25 |
26 | container:
27 | image: ${{ parameters.container }}
28 | options: '--name ${{ parameters.job_name }} -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 -v /usr/bin/docker:/tmp/docker:ro'
29 |
30 | steps:
31 | - checkout: self
32 | fetchDepth: 10
33 |
34 | - script: /tmp/docker exec -t -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 -u 0 ${{ parameters.job_name }} $(Build.SourcesDirectory)/etc/ci/install_sudo.sh ${{ parameters.package_manager }}
35 | displayName: Install sudo
36 |
37 | - script: ${{ parameters.install_packages }}
38 | displayName: Install required packages
39 |
40 | - script: ${{ parameters.install_python }}
41 | displayName: 'Install Python ${{ parameters.python_version }}'
42 |
43 | - script: ${{ parameters.python_path }} --version
44 | displayName: 'Show Python version'
45 |
46 | - script: PYTHON_EXE=${{ parameters.python_path }} ./configure --dev
47 | displayName: 'Run Configure'
48 |
49 | - script: ${{ parameters.test_suite }}
50 | displayName: 'Run ${{ parameters.test_suite_label }} tests with py${{ parameters.python_version }} on ${{ parameters.job_name }}'
51 |
--------------------------------------------------------------------------------
/etc/ci/azure-container-rpm.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | job_name: ''
3 | image_name: 'ubuntu-16.04'
4 | container: ''
5 | python_path: ''
6 | python_version: ''
7 | package_manager: yum
8 | install_python: ''
9 | install_packages: |
10 | set -e -x
11 | sudo yum groupinstall -y "Development Tools"
12 | sudo yum install -y \
13 | openssl openssl-devel \
14 | sqlite-devel zlib-devel xz-devel bzip2-devel \
15 | bzip2 tar unzip zip \
16 | libxml2-devel libxslt-devel
17 | test_suite: ''
18 | test_suite_label: ''
19 |
20 |
21 | jobs:
22 | - job: ${{ parameters.job_name }}
23 |
24 | pool:
25 | vmImage: ${{ parameters.image_name }}
26 |
27 | container:
28 | image: ${{ parameters.container }}
29 | options: '--name ${{ parameters.job_name }} -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 -v /usr/bin/docker:/tmp/docker:ro'
30 |
31 | steps:
32 | - checkout: self
33 | fetchDepth: 10
34 |
35 | - script: /tmp/docker exec -t -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 -u 0 ${{ parameters.job_name }} $(Build.SourcesDirectory)/etc/ci/install_sudo.sh ${{ parameters.package_manager }}
36 | displayName: Install sudo
37 |
38 | - script: ${{ parameters.install_packages }}
39 | displayName: Install required packages
40 |
41 | - script: ${{ parameters.install_python }}
42 | displayName: 'Install Python ${{ parameters.python_version }}'
43 |
44 | - script: ${{ parameters.python_path }} --version
45 | displayName: 'Show Python version'
46 |
47 | - script: PYTHON_EXE=${{ parameters.python_path }} ./configure --dev
48 | displayName: 'Run Configure'
49 |
50 | - script: ${{ parameters.test_suite }}
51 | displayName: 'Run ${{ parameters.test_suite_label }} tests with py${{ parameters.python_version }} on ${{ parameters.job_name }}'
52 |
--------------------------------------------------------------------------------
/etc/ci/azure-posix.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | job_name: ''
3 | image_name: ''
4 | python_versions: []
5 | test_suites: {}
6 | python_architecture: x64
7 |
8 | jobs:
9 | - job: ${{ parameters.job_name }}
10 |
11 | pool:
12 | vmImage: ${{ parameters.image_name }}
13 |
14 | strategy:
15 | matrix:
16 | ${{ each tsuite in parameters.test_suites }}:
17 | ${{ tsuite.key }}:
18 | test_suite_label: ${{ tsuite.key }}
19 | test_suite: ${{ tsuite.value }}
20 |
21 | steps:
22 | - checkout: self
23 | fetchDepth: 10
24 |
25 | - ${{ each pyver in parameters.python_versions }}:
26 | - task: UsePythonVersion@0
27 | inputs:
28 | versionSpec: '${{ pyver }}'
29 | architecture: '${{ parameters.python_architecture }}'
30 | displayName: '${{ pyver }} - Install Python'
31 |
32 | - script: |
33 | python${{ pyver }} --version
34 | echo "python${{ pyver }}" > PYTHON_EXECUTABLE
35 | ./configure --clean && ./configure --dev
36 | displayName: '${{ pyver }} - Configure'
37 |
38 | - script: $(test_suite)
39 | displayName: '${{ pyver }} - $(test_suite_label) on ${{ parameters.job_name }}'
40 |
--------------------------------------------------------------------------------
/etc/ci/azure-win.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | job_name: ''
3 | image_name: ''
4 | python_versions: []
5 | test_suites: {}
6 | python_architecture: x64
7 |
8 | jobs:
9 | - job: ${{ parameters.job_name }}
10 |
11 | pool:
12 | vmImage: ${{ parameters.image_name }}
13 |
14 | strategy:
15 | matrix:
16 | ${{ each tsuite in parameters.test_suites }}:
17 | ${{ tsuite.key }}:
18 | test_suite_label: ${{ tsuite.key }}
19 | test_suite: ${{ tsuite.value }}
20 |
21 | steps:
22 | - checkout: self
23 | fetchDepth: 10
24 |
25 | - ${{ each pyver in parameters.python_versions }}:
26 | - task: UsePythonVersion@0
27 | inputs:
28 | versionSpec: '${{ pyver }}'
29 | architecture: '${{ parameters.python_architecture }}'
30 | displayName: '${{ pyver }} - Install Python'
31 |
32 | - script: |
33 | python --version
34 | echo | set /p=python> PYTHON_EXECUTABLE
35 | configure --clean && configure --dev
36 | displayName: '${{ pyver }} - Configure'
37 |
38 | - script: $(test_suite)
39 | displayName: '${{ pyver }} - $(test_suite_label) on ${{ parameters.job_name }}'
40 |
--------------------------------------------------------------------------------
/etc/ci/install_sudo.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 |
5 | if [[ "$1" == "apt-get" ]]; then
6 | apt-get update -y
7 | apt-get -o DPkg::Options::="--force-confold" install -y sudo
8 |
9 | elif [[ "$1" == "yum" ]]; then
10 | yum install -y sudo
11 |
12 | elif [[ "$1" == "dnf" ]]; then
13 | dnf install -y sudo
14 |
15 | fi
16 |
--------------------------------------------------------------------------------
/etc/ci/macports-ci.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: macports-ci
2 | name: macports-ci
3 | version: c9676e67351a3a519e37437e196cd0ee9c2180b8
4 | download_url: https://raw.githubusercontent.com/GiovanniBussi/macports-ci/c9676e67351a3a519e37437e196cd0ee9c2180b8/macports-ci
5 | description: Simplify MacPorts setup on Travis-CI
6 | homepage_url: https://github.com/GiovanniBussi/macports-ci
7 | license_expression: mit
8 | copyright: Copyright (c) Giovanni Bussi
9 | attribute: yes
10 | checksum_md5: 5d31d479132502f80acdaed78bed9e23
11 | checksum_sha1: 74b15643bd1a528d91b4a7c2169c6fc656f549c2
12 | package_url: pkg:github/giovannibussi/macports-ci@c9676e67351a3a519e37437e196cd0ee9c2180b8#macports-ci
13 | licenses:
14 | - key: mit
15 | name: MIT License
16 | file: mit.LICENSE
17 |
--------------------------------------------------------------------------------
/etc/ci/mit.LICENSE:
--------------------------------------------------------------------------------
1 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
2 |
3 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
4 |
5 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/etc/scripts/README.rst:
--------------------------------------------------------------------------------
1 | This directory contains the tools to manage a directory of thirdparty Python
2 | package source, wheels and metadata pin, build, update, document and publish to
3 | a PyPI-like repo (GitHub release).
4 |
5 | NOTE: These are tested to run ONLY on Linux.
6 |
7 |
8 | Thirdparty packages management scripts
9 | ======================================
10 |
11 | Pre-requisites
12 | --------------
13 |
14 | * There are two run "modes":
15 |
16 | * To generate or update pip requirement files, you need to start with a clean
17 | virtualenv as instructed below (This is to avoid injecting requirements
18 | specific to the tools used here in the main requirements).
19 |
20 | * For other usages, the tools here can run either in their own isolated
21 | virtualenv or in the the main configured development virtualenv.
22 | These requireements need to be installed::
23 |
24 | pip install --requirement etc/scripts/requirements.txt
25 |
26 | TODO: we need to pin the versions of these tools
27 |
28 |
29 |
30 | Generate or update pip requirement files
31 | ----------------------------------------
32 |
33 | Scripts
34 | ~~~~~~~
35 |
36 | **gen_requirements.py**: create/update requirements files from currently
37 | installed requirements.
38 |
39 | **gen_requirements_dev.py** does the same but can subtract the main requirements
40 | to get extra requirements used in only development.
41 |
42 |
43 | Usage
44 | ~~~~~
45 |
46 | The sequence of commands to run are:
47 |
48 |
49 | * Start with these to generate the main pip requirements file::
50 |
51 | ./configure --clean
52 | ./configure
53 | python etc/scripts/gen_requirements.py --site-packages-dir
54 |
55 | * You can optionally install or update extra main requirements after the
56 | ./configure step such that these are included in the generated main requirements.
57 |
58 | * Optionally, generate a development pip requirements file by running these::
59 |
60 | ./configure --clean
61 | ./configure --dev
62 | python etc/scripts/gen_requirements_dev.py --site-packages-dir
63 |
64 | * You can optionally install or update extra dev requirements after the
65 | ./configure step such that these are included in the generated dev
66 | requirements.
67 |
68 | Notes: we generate development requirements after the main as this step requires
69 | the main requirements.txt to be up-to-date first. See **gen_requirements.py and
70 | gen_requirements_dev.py** --help for details.
71 |
72 | Note: this does NOT hash requirements for now.
73 |
74 | Note: Be aware that if you are using "conditional" requirements (e.g. only for
75 | OS or Python versions) in setup.py/setp.cfg/requirements.txt as these are NOT
76 | yet supported.
77 |
78 |
79 | Populate a thirdparty directory with wheels, sources, .ABOUT and license files
80 | ------------------------------------------------------------------------------
81 |
82 | Scripts
83 | ~~~~~~~
84 |
85 | * **fetch_thirdparty.py** will fetch package wheels, source sdist tarballs
86 | and their ABOUT, LICENSE and NOTICE files to populate a local directory from
87 | a list of PyPI simple URLs (typically PyPI.org proper and our self-hosted PyPI)
88 | using pip requirements file(s), specifiers or pre-existing packages files.
89 | Fetch wheels for specific python version and operating system combinations.
90 |
91 | * **check_thirdparty.py** will check a thirdparty directory for errors.
92 |
93 |
94 | Upgrade virtualenv app
95 | ----------------------
96 |
97 | The bundled virtualenv.pyz has to be upgraded by hand and is stored under
98 | etc/thirdparty
99 |
100 | * Fetch https://github.com/pypa/get-virtualenv/raw//public/virtualenv.pyz
101 | for instance https://github.com/pypa/get-virtualenv/raw/20.2.2/public/virtualenv.pyz
102 | and save to thirdparty and update the ABOUT and LICENSE files as needed.
103 |
104 | * This virtualenv app contains also bundled pip, wheel and setuptools that are
105 | essential for the installation to work.
106 |
107 |
108 | Other files
109 | ===========
110 |
111 | The other files and scripts are test, support and utility modules used by the
112 | main scripts documented here.
113 |
--------------------------------------------------------------------------------
/etc/scripts/check_thirdparty.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) nexB Inc. and others. All rights reserved.
5 | # ScanCode is a trademark of nexB Inc.
6 | # SPDX-License-Identifier: Apache-2.0
7 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
8 | # See https://github.com/aboutcode-org/skeleton for support or download.
9 | # See https://aboutcode.org for more information about nexB OSS projects.
10 | #
11 | import click
12 |
13 | import utils_thirdparty
14 |
15 |
16 | @click.command()
17 | @click.option(
18 | "-d",
19 | "--dest",
20 | type=click.Path(exists=True, readable=True,
21 | path_type=str, file_okay=False),
22 | required=True,
23 | help="Path to the thirdparty directory to check.",
24 | )
25 | @click.option(
26 | "-w",
27 | "--wheels",
28 | is_flag=True,
29 | help="Check missing wheels.",
30 | )
31 | @click.option(
32 | "-s",
33 | "--sdists",
34 | is_flag=True,
35 | help="Check missing source sdists tarballs.",
36 | )
37 | @click.help_option("-h", "--help")
38 | def check_thirdparty_dir(
39 | dest,
40 | wheels,
41 | sdists,
42 | ):
43 | """
44 | Check a thirdparty directory for problems and print these on screen.
45 | """
46 | # check for problems
47 | print(f"==> CHECK FOR PROBLEMS")
48 | utils_thirdparty.find_problems(
49 | dest_dir=dest,
50 | report_missing_sources=sdists,
51 | report_missing_wheels=wheels,
52 | )
53 |
54 |
55 | if __name__ == "__main__":
56 | check_thirdparty_dir()
57 |
--------------------------------------------------------------------------------
/etc/scripts/gen_pypi_simple.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: gen_pypi_simple.py
2 | name: gen_pypi_simple.py
3 | license_expression: bsd-2-clause-views and mit
4 | copyright: Copyright (c) nexB Inc.
5 | Copyright (c) 2010 David Wolever
6 | Copyright (c) The pip developers
7 | notes: Originally from https://github.com/wolever/pip2pi and modified extensivley
8 | Also partially derived from pip code
9 |
--------------------------------------------------------------------------------
/etc/scripts/gen_pypi_simple.py.NOTICE:
--------------------------------------------------------------------------------
1 | SPDX-License-Identifier: BSD-2-Clause-Views AND mit
2 |
3 | Copyright (c) nexB Inc.
4 | Copyright (c) 2010 David Wolever
5 | Copyright (c) The pip developers
6 |
7 |
8 | Original code: copyright 2010 David Wolever . All rights reserved.
9 |
10 | Redistribution and use in source and binary forms, with or without
11 | modification, are permitted provided that the following conditions are met:
12 |
13 | 1. Redistributions of source code must retain the above copyright notice,
14 | this list of conditions and the following disclaimer.
15 |
16 | 2. Redistributions in binary form must reproduce the above copyright notice,
17 | this list of conditions and the following disclaimer in the documentation
18 | and/or other materials provided with the distribution.
19 |
20 | THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR
21 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
23 | EVENT SHALL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
31 | The views and conclusions contained in the software and documentation are those
32 | of the authors and should not be interpreted as representing official policies,
33 | either expressed or implied, of David Wolever.
34 |
35 |
36 | Original code: Copyright (c) 2008-2020 The pip developers
37 |
38 | Permission is hereby granted, free of charge, to any person obtaining
39 | a copy of this software and associated documentation files (the
40 | "Software"), to deal in the Software without restriction, including
41 | without limitation the rights to use, copy, modify, merge, publish,
42 | distribute, sublicense, and/or sell copies of the Software, and to
43 | permit persons to whom the Software is furnished to do so, subject to
44 | the following conditions:
45 |
46 | The above copyright notice and this permission notice shall be
47 | included in all copies or substantial portions of the Software.
48 |
49 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
50 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
51 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
52 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
53 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
54 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
55 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
56 |
57 |
--------------------------------------------------------------------------------
/etc/scripts/gen_requirements.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) nexB Inc. and others. All rights reserved.
5 | # ScanCode is a trademark of nexB Inc.
6 | # SPDX-License-Identifier: Apache-2.0
7 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
8 | # See https://github.com/aboutcode-org/skeleton for support or download.
9 | # See https://aboutcode.org for more information about nexB OSS projects.
10 | #
11 | import argparse
12 | import pathlib
13 |
14 | import utils_requirements
15 |
16 | """
17 | Utilities to manage requirements files.
18 | NOTE: this should use ONLY the standard library and not import anything else
19 | because this is used for boostrapping with no requirements installed.
20 | """
21 |
22 |
23 | def gen_requirements():
24 | description = """
25 | Create or replace the `--requirements-file` file FILE requirements file with all
26 | locally installed Python packages.all Python packages found installed in `--site-packages-dir`
27 | """
28 | parser = argparse.ArgumentParser(description=description)
29 |
30 | parser.add_argument(
31 | "-s",
32 | "--site-packages-dir",
33 | dest="site_packages_dir",
34 | type=pathlib.Path,
35 | required=True,
36 | metavar="DIR",
37 | help="Path to the 'site-packages' directory where wheels are installed such as lib/python3.6/site-packages",
38 | )
39 | parser.add_argument(
40 | "-r",
41 | "--requirements-file",
42 | type=pathlib.Path,
43 | metavar="FILE",
44 | default="requirements.txt",
45 | help="Path to the requirements file to update or create.",
46 | )
47 |
48 | args = parser.parse_args()
49 |
50 | utils_requirements.lock_requirements(
51 | site_packages_dir=args.site_packages_dir,
52 | requirements_file=args.requirements_file,
53 | )
54 |
55 |
56 | if __name__ == "__main__":
57 | gen_requirements()
58 |
--------------------------------------------------------------------------------
/etc/scripts/gen_requirements_dev.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Copyright (c) nexB Inc. and others. All rights reserved.
5 | # ScanCode is a trademark of nexB Inc.
6 | # SPDX-License-Identifier: Apache-2.0
7 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
8 | # See https://github.com/aboutcode-org/skeleton for support or download.
9 | # See https://aboutcode.org for more information about nexB OSS projects.
10 | #
11 | import argparse
12 | import pathlib
13 |
14 | import utils_requirements
15 |
16 | """
17 | Utilities to manage requirements files.
18 | NOTE: this should use ONLY the standard library and not import anything else
19 | because this is used for boostrapping with no requirements installed.
20 | """
21 |
22 |
23 | def gen_dev_requirements():
24 | description = """
25 | Create or overwrite the `--dev-requirements-file` pip requirements FILE with
26 | all Python packages found installed in `--site-packages-dir`. Exclude
27 | package names also listed in the --main-requirements-file pip requirements
28 | FILE (that are assume to the production requirements and therefore to always
29 | be present in addition to the development requirements).
30 | """
31 | parser = argparse.ArgumentParser(description=description)
32 |
33 | parser.add_argument(
34 | "-s",
35 | "--site-packages-dir",
36 | type=pathlib.Path,
37 | required=True,
38 | metavar="DIR",
39 | help='Path to the "site-packages" directory where wheels are installed such as lib/python3.6/site-packages',
40 | )
41 | parser.add_argument(
42 | "-d",
43 | "--dev-requirements-file",
44 | type=pathlib.Path,
45 | metavar="FILE",
46 | default="requirements-dev.txt",
47 | help="Path to the dev requirements file to update or create.",
48 | )
49 | parser.add_argument(
50 | "-r",
51 | "--main-requirements-file",
52 | type=pathlib.Path,
53 | default="requirements.txt",
54 | metavar="FILE",
55 | help="Path to the main requirements file. Its requirements will be excluded "
56 | "from the generated dev requirements.",
57 | )
58 | args = parser.parse_args()
59 |
60 | utils_requirements.lock_dev_requirements(
61 | dev_requirements_file=args.dev_requirements_file,
62 | main_requirements_file=args.main_requirements_file,
63 | site_packages_dir=args.site_packages_dir,
64 | )
65 |
66 |
67 | if __name__ == "__main__":
68 | gen_dev_requirements()
69 |
--------------------------------------------------------------------------------
/etc/scripts/requirements.txt:
--------------------------------------------------------------------------------
1 | aboutcode_toolkit
2 | attrs
3 | commoncode
4 | click
5 | requests
6 | saneyaml
7 | pip
8 | setuptools
9 | twine
10 | wheel
11 | build
12 | packvers
13 |
--------------------------------------------------------------------------------
/etc/scripts/test_utils_pip_compatibility_tags.py:
--------------------------------------------------------------------------------
1 | """Generate and work with PEP 425 Compatibility Tags.
2 |
3 | copied from pip-20.3.1 pip/tests/unit/test_utils_compatibility_tags.py
4 | download_url: https://raw.githubusercontent.com/pypa/pip/20.3.1/tests/unit/test_utils_compatibility_tags.py
5 |
6 | Copyright (c) 2008-2020 The pip developers (see AUTHORS.txt file)
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining
9 | a copy of this software and associated documentation files (the
10 | "Software"), to deal in the Software without restriction, including
11 | without limitation the rights to use, copy, modify, merge, publish,
12 | distribute, sublicense, and/or sell copies of the Software, and to
13 | permit persons to whom the Software is furnished to do so, subject to
14 | the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be
17 | included in all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | """
27 |
28 | from unittest.mock import patch
29 | import sysconfig
30 |
31 | import pytest
32 |
33 | import utils_pip_compatibility_tags
34 |
35 |
36 | @pytest.mark.parametrize(
37 | "version_info, expected",
38 | [
39 | ((2,), "2"),
40 | ((2, 8), "28"),
41 | ((3,), "3"),
42 | ((3, 6), "36"),
43 | # Test a tuple of length 3.
44 | ((3, 6, 5), "36"),
45 | # Test a 2-digit minor version.
46 | ((3, 10), "310"),
47 | ],
48 | )
49 | def test_version_info_to_nodot(version_info, expected):
50 | actual = utils_pip_compatibility_tags.version_info_to_nodot(version_info)
51 | assert actual == expected
52 |
53 |
54 | class Testcompatibility_tags(object):
55 | def mock_get_config_var(self, **kwd):
56 | """
57 | Patch sysconfig.get_config_var for arbitrary keys.
58 | """
59 | get_config_var = sysconfig.get_config_var
60 |
61 | def _mock_get_config_var(var):
62 | if var in kwd:
63 | return kwd[var]
64 | return get_config_var(var)
65 |
66 | return _mock_get_config_var
67 |
68 | def test_no_hyphen_tag(self):
69 | """
70 | Test that no tag contains a hyphen.
71 | """
72 | import pip._internal.utils.compatibility_tags
73 |
74 | mock_gcf = self.mock_get_config_var(SOABI="cpython-35m-darwin")
75 |
76 | with patch("sysconfig.get_config_var", mock_gcf):
77 | supported = pip._internal.utils.compatibility_tags.get_supported()
78 |
79 | for tag in supported:
80 | assert "-" not in tag.interpreter
81 | assert "-" not in tag.abi
82 | assert "-" not in tag.platform
83 |
84 |
85 | class TestManylinux2010Tags(object):
86 | @pytest.mark.parametrize(
87 | "manylinux2010,manylinux1",
88 | [
89 | ("manylinux2010_x86_64", "manylinux1_x86_64"),
90 | ("manylinux2010_i686", "manylinux1_i686"),
91 | ],
92 | )
93 | def test_manylinux2010_implies_manylinux1(self, manylinux2010, manylinux1):
94 | """
95 | Specifying manylinux2010 implies manylinux1.
96 | """
97 | groups = {}
98 | supported = utils_pip_compatibility_tags.get_supported(platforms=[manylinux2010])
99 | for tag in supported:
100 | groups.setdefault((tag.interpreter, tag.abi), []).append(tag.platform)
101 |
102 | for arches in groups.values():
103 | if arches == ["any"]:
104 | continue
105 | assert arches[:2] == [manylinux2010, manylinux1]
106 |
107 |
108 | class TestManylinux2014Tags(object):
109 | @pytest.mark.parametrize(
110 | "manylinuxA,manylinuxB",
111 | [
112 | ("manylinux2014_x86_64", ["manylinux2010_x86_64", "manylinux1_x86_64"]),
113 | ("manylinux2014_i686", ["manylinux2010_i686", "manylinux1_i686"]),
114 | ],
115 | )
116 | def test_manylinuxA_implies_manylinuxB(self, manylinuxA, manylinuxB):
117 | """
118 | Specifying manylinux2014 implies manylinux2010/manylinux1.
119 | """
120 | groups = {}
121 | supported = utils_pip_compatibility_tags.get_supported(platforms=[manylinuxA])
122 | for tag in supported:
123 | groups.setdefault((tag.interpreter, tag.abi), []).append(tag.platform)
124 |
125 | expected_arches = [manylinuxA]
126 | expected_arches.extend(manylinuxB)
127 | for arches in groups.values():
128 | if arches == ["any"]:
129 | continue
130 | assert arches[:3] == expected_arches
131 |
--------------------------------------------------------------------------------
/etc/scripts/test_utils_pip_compatibility_tags.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_utils_pip_compatibility_tags.py
2 |
3 | type: github
4 | namespace: pypa
5 | name: pip
6 | version: 20.3.1
7 | subpath: tests/unit/test_utils_compatibility_tags.py
8 |
9 | package_url: pkg:github/pypa/pip@20.3.1#tests/unit/test_utils_compatibility_tags.py
10 |
11 | download_url: https://raw.githubusercontent.com/pypa/pip/20.3.1/tests/unit/test_utils_compatibility_tags.py
12 | copyright: Copyright (c) 2008-2020 The pip developers (see AUTHORS.txt file)
13 | license_expression: mit
14 | notes: subset copied from pip for tag handling
15 |
--------------------------------------------------------------------------------
/etc/scripts/test_utils_pypi_supported_tags.py:
--------------------------------------------------------------------------------
1 | # Licensed under the Apache License, Version 2.0 (the "License");
2 | # you may not use this file except in compliance with the License.
3 | # You may obtain a copy of the License at
4 | #
5 | # http://www.apache.org/licenses/LICENSE-2.0
6 | #
7 | # Unless required by applicable law or agreed to in writing, software
8 | # distributed under the License is distributed on an "AS IS" BASIS,
9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | # See the License for the specific language governing permissions and
11 | # limitations under the License.
12 |
13 | import pytest
14 |
15 | from utils_pypi_supported_tags import validate_platforms_for_pypi
16 |
17 | """
18 | Wheel platform checking tests
19 |
20 | Copied and modified on 2020-12-24 from
21 | https://github.com/pypa/warehouse/blob/37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d/tests/unit/forklift/test_legacy.py
22 | """
23 |
24 |
25 | def validate_wheel_filename_for_pypi(filename):
26 | """
27 | Validate if the filename is a PyPI/warehouse-uploadable wheel file name
28 | with supported platform tags. Return a list of unsupported platform tags or
29 | an empty list if all tags are supported.
30 | """
31 | from utils_thirdparty import Wheel
32 |
33 | wheel = Wheel.from_filename(filename)
34 | return validate_platforms_for_pypi(wheel.platforms)
35 |
36 |
37 | @pytest.mark.parametrize(
38 | "plat",
39 | [
40 | "any",
41 | "win32",
42 | "win_amd64",
43 | "win_ia64",
44 | "manylinux1_i686",
45 | "manylinux1_x86_64",
46 | "manylinux2010_i686",
47 | "manylinux2010_x86_64",
48 | "manylinux2014_i686",
49 | "manylinux2014_x86_64",
50 | "manylinux2014_aarch64",
51 | "manylinux2014_armv7l",
52 | "manylinux2014_ppc64",
53 | "manylinux2014_ppc64le",
54 | "manylinux2014_s390x",
55 | "manylinux_2_5_i686",
56 | "manylinux_2_12_x86_64",
57 | "manylinux_2_17_aarch64",
58 | "manylinux_2_17_armv7l",
59 | "manylinux_2_17_ppc64",
60 | "manylinux_2_17_ppc64le",
61 | "manylinux_3_0_s390x",
62 | "macosx_10_6_intel",
63 | "macosx_10_13_x86_64",
64 | "macosx_11_0_x86_64",
65 | "macosx_10_15_arm64",
66 | "macosx_11_10_universal2",
67 | # A real tag used by e.g. some numpy wheels
68 | (
69 | "macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64."
70 | "macosx_10_10_intel.macosx_10_10_x86_64"
71 | ),
72 | ],
73 | )
74 | def test_is_valid_pypi_wheel_return_true_for_supported_wheel(plat):
75 | filename = f"foo-1.2.3-cp34-none-{plat}.whl"
76 | assert not validate_wheel_filename_for_pypi(filename)
77 |
78 |
79 | @pytest.mark.parametrize(
80 | "plat",
81 | [
82 | "linux_x86_64",
83 | "linux_x86_64.win32",
84 | "macosx_9_2_x86_64",
85 | "macosx_12_2_arm64",
86 | "macosx_10_15_amd64",
87 | ],
88 | )
89 | def test_is_valid_pypi_wheel_raise_exception_for_aunsupported_wheel(plat):
90 | filename = f"foo-1.2.3-cp34-none-{plat}.whl"
91 | invalid = validate_wheel_filename_for_pypi(filename)
92 | assert invalid
93 |
--------------------------------------------------------------------------------
/etc/scripts/test_utils_pypi_supported_tags.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_utils_pypi_supported_tags.py
2 |
3 | type: github
4 | namespace: pypa
5 | name: warehouse
6 | version: 37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d
7 | subpath: tests/unit/forklift/test_legacy.py
8 |
9 | package_url: pkg:github/pypa/warehouse@37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d#tests/unit/forklift/test_legacy.py
10 |
11 | download_url: https://github.com/pypa/warehouse/blob/37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d/tests/unit/forklift/test_legacy.py
12 | copyright: Copyright (c) The warehouse developers
13 | homepage_url: https://warehouse.readthedocs.io
14 | license_expression: apache-2.0
15 | notes: Test for wheel platform checking copied and heavily modified on
16 | 2020-12-24 from warehouse. This contains the basic functions to check if a
17 | wheel file name is would be supported for uploading to PyPI.
18 |
--------------------------------------------------------------------------------
/etc/scripts/utils_pip_compatibility_tags.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: utils_pip_compatibility_tags.py
2 |
3 | type: github
4 | namespace: pypa
5 | name: pip
6 | version: 20.3.1
7 | subpath: src/pip/_internal/utils/compatibility_tags.py
8 |
9 | package_url: pkg:github/pypa/pip@20.3.1#src/pip/_internal/utils/compatibility_tags.py
10 |
11 | download_url: https://github.com/pypa/pip/blob/20.3.1/src/pip/_internal/utils/compatibility_tags.py
12 | copyright: Copyright (c) 2008-2020 The pip developers (see AUTHORS.txt file)
13 | license_expression: mit
14 | notes: subset copied from pip for tag handling
--------------------------------------------------------------------------------
/etc/scripts/utils_pypi_supported_tags.py:
--------------------------------------------------------------------------------
1 | # Licensed under the Apache License, Version 2.0 (the "License");
2 | # you may not use this file except in compliance with the License.
3 | # You may obtain a copy of the License at
4 | #
5 | # http://www.apache.org/licenses/LICENSE-2.0
6 | #
7 | # Unless required by applicable law or agreed to in writing, software
8 | # distributed under the License is distributed on an "AS IS" BASIS,
9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 | # See the License for the specific language governing permissions and
11 | # limitations under the License.
12 |
13 | import re
14 |
15 | """
16 | Wheel platform checking
17 |
18 | Copied and modified on 2020-12-24 from
19 | https://github.com/pypa/warehouse/blob/37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d/warehouse/forklift/legacy.py
20 |
21 | This contains the basic functions to check if a wheel file name is would be
22 | supported for uploading to PyPI.
23 | """
24 |
25 | # These platforms can be handled by a simple static list:
26 | _allowed_platforms = {
27 | "any",
28 | "win32",
29 | "win_amd64",
30 | "win_ia64",
31 | "manylinux1_x86_64",
32 | "manylinux1_i686",
33 | "manylinux2010_x86_64",
34 | "manylinux2010_i686",
35 | "manylinux2014_x86_64",
36 | "manylinux2014_i686",
37 | "manylinux2014_aarch64",
38 | "manylinux2014_armv7l",
39 | "manylinux2014_ppc64",
40 | "manylinux2014_ppc64le",
41 | "manylinux2014_s390x",
42 | "linux_armv6l",
43 | "linux_armv7l",
44 | }
45 | # macosx is a little more complicated:
46 | _macosx_platform_re = re.compile(r"macosx_(?P\d+)_(\d+)_(?P.*)")
47 | _macosx_arches = {
48 | "ppc",
49 | "ppc64",
50 | "i386",
51 | "x86_64",
52 | "arm64",
53 | "intel",
54 | "fat",
55 | "fat32",
56 | "fat64",
57 | "universal",
58 | "universal2",
59 | }
60 | _macosx_major_versions = {
61 | "10",
62 | "11",
63 | }
64 |
65 | # manylinux pep600 is a little more complicated:
66 | _manylinux_platform_re = re.compile(r"manylinux_(\d+)_(\d+)_(?P.*)")
67 | _manylinux_arches = {
68 | "x86_64",
69 | "i686",
70 | "aarch64",
71 | "armv7l",
72 | "ppc64",
73 | "ppc64le",
74 | "s390x",
75 | }
76 |
77 |
78 | def is_supported_platform_tag(platform_tag):
79 | """
80 | Return True if the ``platform_tag`` is supported on PyPI.
81 | """
82 | if platform_tag in _allowed_platforms:
83 | return True
84 | m = _macosx_platform_re.match(platform_tag)
85 | if m and m.group("major") in _macosx_major_versions and m.group("arch") in _macosx_arches:
86 | return True
87 | m = _manylinux_platform_re.match(platform_tag)
88 | if m and m.group("arch") in _manylinux_arches:
89 | return True
90 | return False
91 |
92 |
93 | def validate_platforms_for_pypi(platforms):
94 | """
95 | Validate if the wheel platforms are supported platform tags on Pypi. Return
96 | a list of unsupported platform tags or an empty list if all tags are
97 | supported.
98 | """
99 |
100 | # Check that if it's a binary wheel, it's on a supported platform
101 | invalid_tags = []
102 | for plat in platforms:
103 | if not is_supported_platform_tag(plat):
104 | invalid_tags.append(plat)
105 | return invalid_tags
106 |
--------------------------------------------------------------------------------
/etc/scripts/utils_pypi_supported_tags.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: utils_pypi_supported_tags.py
2 |
3 | type: github
4 | namespace: pypa
5 | name: warehouse
6 | version: 37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d
7 | subpath: warehouse/forklift/legacy.py
8 |
9 | package_url: pkg:github/pypa/warehouse@37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d#warehouse/forklift/legacy.py
10 |
11 | download_url: https://github.com/pypa/warehouse/blob/37a83dd342d9e3b3ab4f6bde47ca30e6883e2c4d/warehouse/forklift/legacy.py
12 | copyright: Copyright (c) The warehouse developers
13 | homepage_url: https://warehouse.readthedocs.io
14 | license_expression: apache-2.0
15 | notes: Wheel platform checking copied and heavily modified on 2020-12-24 from
16 | warehouse. This contains the basic functions to check if a wheel file name is
17 | would be supported for uploading to PyPI.
18 |
--------------------------------------------------------------------------------
/etc/scripts/utils_thirdparty.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: utils_thirdparty.py
2 | package_url: pkg:github.com/pypa/pip/@20.3.1#src/pip/_internal/models/wheel.py
3 | type: github
4 | namespace: pypa
5 | name: pip
6 | version: 20.3.1
7 | subpath: src/pip/_internal/models/wheel.py
8 |
9 | download_url: https://github.com/pypa/pip/blob/20.3.1/src/pip/_internal/models/wheel.py
10 | copyright: Copyright (c) 2008-2020 The pip developers (see AUTHORS.txt file)
11 | license_expression: mit
12 | notes: copied from pip-20.3.1 pip/_internal/models/wheel.py
13 | The models code has been heavily inspired from the ISC-licensed packaging-dists
14 | https://github.com/uranusjr/packaging-dists by Tzu-ping Chung
15 |
--------------------------------------------------------------------------------
/flake.lock:
--------------------------------------------------------------------------------
1 | {
2 | "nodes": {
3 | "nixpkgs": {
4 | "locked": {
5 | "lastModified": 1658380158,
6 | "narHash": "sha256-DBunkegKWlxPZiOcw3/SNIFg93amkdGIy2g0y/jDpHg=",
7 | "owner": "nixos",
8 | "repo": "nixpkgs",
9 | "rev": "a65b5b3f5504b8b89c196aba733bdf2b0bd13c16",
10 | "type": "github"
11 | },
12 | "original": {
13 | "owner": "nixos",
14 | "ref": "nixos-unstable",
15 | "repo": "nixpkgs",
16 | "type": "github"
17 | }
18 | },
19 | "root": {
20 | "inputs": {
21 | "nixpkgs": "nixpkgs"
22 | }
23 | }
24 | },
25 | "root": "root",
26 | "version": 7
27 | }
28 |
--------------------------------------------------------------------------------
/flake.nix:
--------------------------------------------------------------------------------
1 | {
2 | description = "Parse and compare all the package versions and all the ranges. From debian, npm, pypi, ruby and more. Process all the version range specs and expressions.";
3 |
4 | inputs = {
5 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
6 | };
7 |
8 | outputs = { self, nixpkgs }: ({
9 | overlays.default = import ./overlay.nix;
10 | }) // (
11 | let
12 | supportedSystems = [ "aarch64-darwin" "aarch64-linux" "x86_64-darwin" "x86_64-linux" ];
13 | forAllSystems = f: nixpkgs.lib.genAttrs supportedSystems (system: f system);
14 | nixpkgsFor = forAllSystems (system: self.overlays.default null nixpkgs.legacyPackages.${system});
15 | in
16 | {
17 | packages = forAllSystems (system: rec {
18 | python3Packages = {
19 | inherit (nixpkgsFor.${system}.python3Packages) univers;
20 | };
21 | default = python3Packages.univers;
22 | });
23 | }
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/mit.LICENSE:
--------------------------------------------------------------------------------
1 | Permission is hereby granted, free of charge, to any person obtaining
2 | a copy of this software and associated documentation files (the
3 | "Software"), to deal in the Software without restriction, including
4 | without limitation the rights to use, copy, modify, merge, publish,
5 | distribute, sublicense, and/or sell copies of the Software, and to
6 | permit persons to whom the Software is furnished to do so, subject to
7 | the following conditions:
8 |
9 | The above copyright notice and this permission notice shall be
10 | included in all copies or substantial portions of the Software.
11 |
12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
15 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
16 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
17 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/overlay.nix:
--------------------------------------------------------------------------------
1 | final: prev: rec {
2 | python3 = prev.python3.override {
3 | packageOverrides = final: prev:
4 | {
5 | univers = python3Packages.callPackage
6 | ({ lib
7 | , buildPythonPackage
8 | , git
9 | , setuptools-scm
10 | , attrs
11 | , packaging
12 | , pyparsing
13 | , semantic-version
14 | , semver
15 | , black
16 | , commoncode
17 | , pytestCheckHook
18 | , saneyaml
19 | }: buildPythonPackage rec {
20 | name = "univers";
21 |
22 | src = ./.;
23 |
24 | nativeBuildInputs = [ git setuptools-scm ];
25 | propagatedBuildInputs = [ attrs packaging pyparsing semantic-version semver ];
26 | checkInputs = [ black commoncode pytestCheckHook saneyaml ];
27 |
28 | dontConfigure = true; # ./configure tries to setup virtualenv and downloads dependencies
29 |
30 | pythonImportsCheck = [ "univers" ];
31 |
32 | meta = with lib; {
33 | description = "Library for parsing version ranges and expressions";
34 | homepage = "https://github.com/aboutcode-org/univers";
35 | license = with licenses; [ asl20 bsd3 mit ];
36 | };
37 | })
38 | { };
39 | };
40 | };
41 | python3Packages = prev.recurseIntoAttrs python3.pkgs;
42 | }
43 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["setuptools >= 50", "wheel", "setuptools_scm[toml] >= 6"]
3 | build-backend = "setuptools.build_meta"
4 |
5 | [tool.setuptools_scm]
6 | # this is used populated when creating a git archive
7 | # and when there is .git dir and/or there is no git installed
8 | fallback_version = "9999.50f83d1a-2025-06-11"
9 |
10 | [tool.pytest.ini_options]
11 | norecursedirs = [
12 | ".git",
13 | "bin",
14 | "dist",
15 | "build",
16 | "_build",
17 | "dist",
18 | "etc",
19 | "local",
20 | "ci",
21 | "docs",
22 | "man",
23 | "share",
24 | "samples",
25 | ".cache",
26 | ".settings",
27 | "Include",
28 | "include",
29 | "Lib",
30 | "lib",
31 | "lib64",
32 | "Lib64",
33 | "Scripts",
34 | "thirdparty",
35 | "tmp",
36 | "venv",
37 | "tests/data",
38 | ".eggs",
39 | "src/*/data",
40 | "tests/*/data"
41 | ]
42 |
43 | python_files = "*.py"
44 |
45 | python_classes = "Test"
46 | python_functions = "test"
47 |
48 | addopts = [
49 | "-rfExXw",
50 | "--strict-markers",
51 | "--doctest-modules"
52 | ]
53 |
54 | [tool.isort]
55 | profile = "black"
56 | line_length = 100
57 | force_single_line = true
58 | skip_gitignore = true
59 |
--------------------------------------------------------------------------------
/requirements-dev.txt:
--------------------------------------------------------------------------------
1 | execnet==1.9.0
2 | importlib-metadata==4.8.1
3 | iniconfig==1.1.1
4 | pluggy==1.0.0
5 | py==1.11.0
6 | pytest==7.2.0
7 | pytest-forked==1.4.0
8 | pytest-xdist==3.2.0
9 | toml==0.10.2
10 | typing-extensions==3.10.0.2
11 | zipp==3.6.0
12 | black==22.3.0
13 | typed-ast==1.4.3
14 | pathspec==0.9.0
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | attrs==21.2.0
2 | packaging==21.0
3 | pyparsing==2.4.7
4 | semantic-version==2.8.5
5 | semver==2.13.0
6 | isort==5.10.1
7 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [metadata]
2 | name = univers
3 | license = Apache-2.0 AND BSD-3-Clause AND MIT
4 |
5 | # description must be on ONE line https://github.com/pypa/setuptools/issues/1390
6 | description = A mostly universal library to parse and compare software package versions and version ranges. A companion to Package URLs.
7 | long_description = file:README.rst
8 | long_description_content_type = text/x-rst
9 | url = https://github.com/aboutcode-org/univers
10 |
11 | author = Shivam Sandbhor, nexB. Inc. and others
12 | author_email = info@aboutcode.org
13 |
14 | classifiers =
15 | Development Status :: 5 - Production/Stable
16 | Intended Audience :: Developers
17 | Programming Language :: Python :: 3
18 | Programming Language :: Python :: 3 :: Only
19 | Topic :: Software Development
20 | Topic :: Utilities
21 | keywords =
22 | semver
23 | utilities
24 | version
25 | release
26 | version range
27 | package URL
28 | purl
29 | arch
30 | pacman
31 | pypi
32 | rpm
33 | gentoo
34 | ebuild
35 | maven
36 | debian
37 | rubygems
38 |
39 | license_files =
40 | apache-2.0.LICENSE
41 | bsd-new.LICENSE
42 | mit.LICENSE
43 | NOTICE
44 | AUTHORS.rst
45 | CHANGELOG.rst
46 | README.rst
47 | CODE_OF_CONDUCT.rst
48 |
49 | [options]
50 | package_dir =
51 | =src
52 | packages = find:
53 | include_package_data = true
54 | zip_safe = false
55 |
56 | setup_requires = setuptools_scm[toml] >= 4
57 |
58 | python_requires = >=3.8
59 |
60 | install_requires =
61 | attrs
62 | packaging
63 | semantic-version
64 | semver
65 |
66 |
67 | [options.packages.find]
68 | where = src
69 |
70 |
71 | [options.extras_require]
72 | testing =
73 | pytest >= 6, != 7.0.0
74 | pytest-xdist >= 2
75 | aboutcode-toolkit >= 7.0.2
76 | pycodestyle >= 2.8.0
77 | twine
78 | black
79 | commoncode
80 | isort>=5.10.1
81 |
82 | docs =
83 | Sphinx>=5.0.2
84 | sphinx-rtd-theme>=1.0.0
85 | sphinx-reredirects >= 0.1.2
86 | doc8>=0.11.2
87 | sphinx-autobuild
88 | sphinx-rtd-dark-mode>=1.3.0
89 | sphinx-copybutton
90 |
91 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import setuptools
4 |
5 | if __name__ == "__main__":
6 | setuptools.setup()
7 |
--------------------------------------------------------------------------------
/shell.nix:
--------------------------------------------------------------------------------
1 | (import (fetchTarball https://github.com/edolstra/flake-compat/archive/b4a34015c698c7793d592d66adbab377907a2be8.tar.gz) {
2 | src = builtins.fetchGit ./.;
3 | }).shellNix
4 |
--------------------------------------------------------------------------------
/src/univers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aboutcode-org/univers/50f83d1a015153398315e46e55fa9e750c28a63f/src/univers/__init__.py
--------------------------------------------------------------------------------
/src/univers/arch.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) Christoph Reiter
3 | # SPDX-License-Identifier: MIT
4 | # Version utility extracted from msys2 https://github.com/msys2/msys2-web/
5 | # and further stripped down.
6 | #
7 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
8 |
9 | import re
10 | from itertools import zip_longest
11 | from typing import Dict
12 | from typing import List
13 | from typing import Optional
14 | from typing import Set
15 | from typing import Tuple
16 |
17 | from univers.utils import cmp
18 |
19 |
20 | def vercmp(v1: str, v2: str) -> int:
21 | def split(v: str) -> Tuple[str, str, Optional[str]]:
22 | if ":" in v:
23 | e, v = v.split(":", 1)
24 | else:
25 | e, v = ("0", v)
26 |
27 | r: Optional[str] = None
28 | if "-" in v:
29 | v, r = v.rsplit("-", 1)
30 | else:
31 | v, r = (v, None)
32 |
33 | return (e, v, r)
34 |
35 | digit, alpha, other = range(3)
36 |
37 | def get_type(c: str) -> int:
38 | assert c
39 | if c.isdigit():
40 | return digit
41 | elif c.isalpha():
42 | return alpha
43 | else:
44 | return other
45 |
46 | def parse(v: str) -> List[str]:
47 | parts: List[str] = []
48 | current = ""
49 | for c in v:
50 | if not current:
51 | current += c
52 | else:
53 | if get_type(c) == get_type(current):
54 | current += c
55 | else:
56 | parts.append(current)
57 | current = c
58 |
59 | if current:
60 | parts.append(current)
61 |
62 | return parts
63 |
64 | def rpmvercmp(v1: str, v2: str) -> int:
65 | for p1, p2 in zip_longest(parse(v1), parse(v2), fillvalue=None):
66 | if p1 is None:
67 | if get_type(p2) == alpha:
68 | return 1
69 | return -1
70 | elif p2 is None:
71 | if get_type(p1) == alpha:
72 | return -1
73 | return 1
74 |
75 | t1 = get_type(p1)
76 | t2 = get_type(p2)
77 | if t1 != t2:
78 | if t1 == digit:
79 | return 1
80 | elif t2 == digit:
81 | return -1
82 | elif t1 == other:
83 | return 1
84 | elif t2 == other:
85 | return -1
86 | elif t1 == other:
87 | ret = cmp(len(p1), len(p2))
88 | if ret != 0:
89 | return ret
90 | elif t1 == digit:
91 | ret = cmp(int(p1), int(p2))
92 | if ret != 0:
93 | return ret
94 | elif t1 == alpha:
95 | ret = cmp(p1, p2)
96 | if ret != 0:
97 | return ret
98 |
99 | return 0
100 |
101 | e1, v1, r1 = split(v1)
102 | e2, v2, r2 = split(v2)
103 |
104 | ret = rpmvercmp(e1, e2)
105 | if ret == 0:
106 | ret = rpmvercmp(v1, v2)
107 | if ret == 0 and r1 is not None and r2 is not None:
108 | ret = rpmvercmp(r1, r2)
109 |
110 | return ret
111 |
112 |
113 | def extract_upstream_version(version: str) -> str:
114 | return version.rsplit("-")[0].split("+", 1)[0].split("~", 1)[-1].split(":", 1)[-1]
115 |
116 |
117 | def strip_vcs(package_name: str) -> str:
118 | if package_name.endswith(("-cvs", "-svn", "-hg", "-darcs", "-bzr", "-git")):
119 | return package_name.rsplit("-", 1)[0]
120 | return package_name
121 |
122 |
123 | def arch_version_to_msys(v: str) -> str:
124 | return v.replace(":", "~")
125 |
126 |
127 | def version_is_newer_than(v1: str, v2: str) -> bool:
128 | return vercmp(v1, v2) == 1
129 |
130 |
131 | def split_depends(deps: List[str]) -> Dict[str, Set[str]]:
132 | r: Dict[str, Set[str]] = {}
133 | for d in deps:
134 | parts = re.split("([<>=]+)", d, 1)
135 | first = parts[0].strip()
136 | second = "".join(parts[1:]).strip()
137 | r.setdefault(first, set()).add(second)
138 | return r
139 |
140 |
141 | def split_optdepends(deps: List[str]) -> Dict[str, Set[str]]:
142 | r: Dict[str, Set[str]] = {}
143 | for d in deps:
144 | if ":" in d:
145 | a, b = d.split(":", 1)
146 | a, b = a.strip(), b.strip()
147 | else:
148 | a, b = d.strip(), ""
149 | e = r.setdefault(a, set())
150 | if b:
151 | e.add(b)
152 | return r
153 |
--------------------------------------------------------------------------------
/src/univers/arch.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: arch.py
2 | package_url: pkg:github/msys2/msys2-web@3ed2dde45a8761523b749e42c201a737c7613e6e
3 | copyright: |
4 | Copyright 2016-2020 Christoph Reiter
5 |
6 | license_expression: MIT
7 | homepage_url: https://github.com/msys2/msys2-web/
8 |
9 | notes: |
10 | The version comparison utility is extracted from msys2 and further stripped down.
11 |
12 | notice_file: arch.py.NOTICE
--------------------------------------------------------------------------------
/src/univers/arch.py.NOTICE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2017 Christoph Reiter
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
--------------------------------------------------------------------------------
/src/univers/bsd-new.LICENSE:
--------------------------------------------------------------------------------
1 | Redistribution and use in source and binary forms, with or without modification,
2 | are permitted provided that the following conditions are met:
3 |
4 | Redistributions of source code must retain the above copyright notice, this list
5 | of conditions and the following disclaimer.
6 |
7 | Redistributions in binary form must reproduce the above copyright notice, this
8 | list of conditions and the following disclaimer in the documentation and/or
9 | other materials provided with the distribution.
10 |
11 | Neither the name of the ORGANIZATION nor the names of its contributors may be
12 | used to endorse or promote products derived from this software without specific
13 | prior written permission.
14 |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
19 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
24 | THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/src/univers/conan/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aboutcode-org/univers/50f83d1a015153398315e46e55fa9e750c28a63f/src/univers/conan/__init__.py
--------------------------------------------------------------------------------
/src/univers/conan/errors.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: errors.py
2 | package_url: pkg:pypi/conan@2.0.0
3 | copyright: |
4 | Copyright (c) 2019 JFrog LTD
5 | download_url: https://github.com/conan-io/conan/blob/release/2.0/conans/errors.py
6 | license_expression: MIT
7 | homepage_url: https://github.com/conan-io/conan
8 | notice_file: errors.py.NOTICE
9 |
--------------------------------------------------------------------------------
/src/univers/conan/errors.py.NOTICE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 JFrog LTD
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/univers/conan/version.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: version.py
2 | package_url: pkg:pypi/conan@2.0.0
3 | copyright: |
4 | Copyright (c) 2019 JFrog LTD
5 | download_url: https://github.com/conan-io/conan/blob/release/2.0/conans/model/version.py
6 | license_expression: MIT
7 | homepage_url: https://github.com/conan-io/conan
8 | notice_file: version.py.NOTICE
9 |
--------------------------------------------------------------------------------
/src/univers/conan/version.py.NOTICE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 JFrog LTD
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/univers/conan/version_range.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2019 JFrog LTD
3 | # SPDX-License-Identifier: MIT
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 | from collections import namedtuple
8 |
9 | from univers.conan.errors import ConanException
10 | from univers.versions import ConanVersion
11 |
12 | _Condition = namedtuple("_Condition", ["operator", "version"])
13 |
14 |
15 | class _ConditionSet:
16 | def __init__(self, expression, prerelease):
17 | expressions = expression.split()
18 | self.prerelease = prerelease
19 | self.conditions = []
20 | for e in expressions:
21 | e = e.strip()
22 | if e[-1] == "-": # Include pre-releases
23 | e = e[:-1]
24 | self.prerelease = True
25 | self.conditions.extend(self._parse_expression(e))
26 |
27 | @staticmethod
28 | def _parse_expression(expression):
29 | if expression == "" or expression == "*":
30 | return [_Condition(">=", ConanVersion("0.0.0"))]
31 |
32 | operator = expression[0]
33 | if operator not in (">", "<", "^", "~", "="):
34 | operator = "="
35 | index = 0
36 | else:
37 | index = 1
38 | if operator in (">", "<"):
39 | if expression[1] == "=":
40 | operator += "="
41 | index = 2
42 | version = expression[index:]
43 | if version == "":
44 | raise ConanException(f"Error parsing version range {expression}")
45 | if operator == "~": # tilde minor
46 | v = ConanVersion(version)
47 | index = 1 if len(v.main) > 1 else 0
48 | return [_Condition(">=", v), _Condition("<", v.upper_bound(index))]
49 | elif operator == "^": # caret major
50 | v = ConanVersion(version)
51 |
52 | def first_non_zero(main):
53 | for i, m in enumerate(main):
54 | if m != 0:
55 | return i
56 | return len(main)
57 |
58 | initial_index = first_non_zero(v.main)
59 | return [_Condition(">=", v), _Condition("<", v.upper_bound(initial_index))]
60 | else:
61 | return [_Condition(operator, ConanVersion(version))]
62 |
63 | def valid(self, version):
64 | if version.pre:
65 | if not self.prerelease:
66 | return False
67 | for condition in self.conditions:
68 | if condition.operator == ">":
69 | if not version > condition.version:
70 | return False
71 | elif condition.operator == "<":
72 | if not version < condition.version:
73 | return False
74 | elif condition.operator == ">=":
75 | if not version >= condition.version:
76 | return False
77 | elif condition.operator == "<=":
78 | if not version <= condition.version:
79 | return False
80 | elif condition.operator == "=":
81 | if not version == condition.version:
82 | return False
83 | return True
84 |
85 |
86 | class VersionRange:
87 | def __init__(self, expression):
88 | self._expression = expression
89 | tokens = expression.split(",")
90 | prereleases = None
91 | for t in tokens[1:]:
92 | if "include_prerelease" in t:
93 | prereleases = True
94 | break
95 | version_expr = tokens[0]
96 | self.condition_sets = []
97 | for alternative in version_expr.split("||"):
98 | self.condition_sets.append(_ConditionSet(alternative, prereleases))
99 |
100 | def __str__(self):
101 | return self._expression
102 |
103 | def __contains__(self, version):
104 | assert isinstance(version, ConanVersion), type(version)
105 | for condition_set in self.condition_sets:
106 | if condition_set.valid(version):
107 | return True
108 | return False
109 |
--------------------------------------------------------------------------------
/src/univers/conan/version_range.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: version_range.py
2 | package_url: pkg:pypi/conan@2.0.0
3 | copyright: |
4 | Copyright (c) 2019 JFrog LTD
5 | download_url: https://github.com/conan-io/conan/blob/release/2.0/conans/model/version_range.py
6 | license_expression: MIT
7 | homepage_url: https://github.com/conan-io/conan
8 | notice_file: version_range.py.NOTICE
9 |
--------------------------------------------------------------------------------
/src/univers/conan/version_range.py.NOTICE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 JFrog LTD
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/univers/debian.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: debian.py
2 | package_url: pkg:pypi/deb-pkg-tools@8.4
3 | copyright: |
4 | Copyright (C) Peter Odding
5 |
6 | license_expression: mit
7 | homepage_url: https://github.com/xolox/python-deb-pkg-tools
8 |
9 | notes: |
10 | This has been substantially modified and enhanced from the original
11 | python-deb-pkg-tools code to extract the version comparison code.
12 | based on https://raw.githubusercontent.com/xolox/python-deb-pkg-tools/a3d6ef1d82c6342b6a57876fc2360875e033f8f0/deb_pkg_tools/version/native.py
13 | and on https://raw.githubusercontent.com/xolox/python-deb-pkg-tools/a3d6ef1d82c6342b6a57876fc2360875e033f8f0/deb_pkg_tools/version/__init__.py
14 | merged and simplified in a single module and further modified to work with
15 | our class structure.
16 |
17 | notice_file: debian.py.NOTICE
--------------------------------------------------------------------------------
/src/univers/debian.py.NOTICE:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Copyright (c) 2018 Peter Odding
4 | #
5 | # Permission is hereby granted, free of charge, to any person obtaining
6 | # a copy of this software and associated documentation files (the
7 | # "Software"), to deal in the Software without restriction, including
8 | # without limitation the rights to use, copy, modify, merge, publish,
9 | # distribute, sublicense, and/or sell copies of the Software, and to
10 | # permit persons to whom the Software is furnished to do so, subject to
11 | # the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be
14 | # included in all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
24 | # Debian packaging tools: Version comparison.
25 | # Original-Author: Peter Odding
26 | # Original-URL: https://github.com/xolox/python-deb-pkg-tools
27 |
--------------------------------------------------------------------------------
/src/univers/gem.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: gem.py
2 | license_expression: apache-2.0 AND mit
3 | download_url: https://raw.githubusercontent.com/coi-gov-pl/puppeter/04e2a2008bd89a0429b734fdde6da83813688865/puppeter/domain/model/gemrequirement.py
4 | copyright: |
5 | Copyright (c) nexB, Inc. and others.
6 | Copyright (c) Center for Information Technology, http://coi.gov.pl
7 | Copyright (c) Chad Fowler, Rich Kilmer, Jim Weirich and others.
8 | Copyright (c) Engine Yard and Andre Arko, Facebook, Inc. and its affiliates.
9 |
10 | package_url: pkg:pypi/puppeter@0.8.3#src/domain/model/gemrequirement.py
11 | homepage_url: https://github.com/coi-gov-pl/puppeter
12 | notice_file: gem.py.NOTICE
13 |
14 | notes: This file started as a subset of the coi.gov/pl code modified for
15 | use in univers. The original Apache-licensed puppeteer code was used as a base,
16 | extracting the Ruby version handling code. That coi code was in turn
17 | originally based on MIT-licensed Rubygems code ported to Python.
18 | This has been substantially modified and enhanced to pass correctly all the
19 | upstream Rubygems tests and work with univers. This mixed code has been further
20 | updated from the Rubygems ruby code from
21 | https://github.com/rubygems/rubygems specifically
22 | lib/rubygems/version.rb and lib/rubygems/requirement.rb
23 |
24 |
--------------------------------------------------------------------------------
/src/univers/gem.py.NOTICE:
--------------------------------------------------------------------------------
1 | # Copyright 2017 Center for Information Technology
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
--------------------------------------------------------------------------------
/src/univers/gentoo.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: gentoo.py
2 | package_url: pkg:pypi/pkgcore@0.11.8
3 | copyright: |
4 | Copyright (c) 2006-2019, pkgcore contributors
5 |
6 | license_expression: BSD-3-Clause
7 | homepage_url: https://github.com/pkgcore/pkgcore/blob/master/src/pkgcore/ebuild/cpv.py
8 |
9 | notes: The version comparison utility is extracted from pkgcore and further stripped down.
10 |
11 | notice_file: gentoo.py.NOTICE
--------------------------------------------------------------------------------
/src/univers/gentoo.py.NOTICE:
--------------------------------------------------------------------------------
1 | Redistribution and use in source and binary forms, with or without
2 | modification, are permitted provided that the following conditions are met:
3 |
4 | 1. Redistributions of source code must retain the above copyright notice,
5 | this list of conditions and the following disclaimer.
6 | 2. Redistributions in binary form must reproduce the above copyright
7 | notice, this list of conditions and the following disclaimer in the
8 | documentation and/or other materials provided with the distribution.
9 | 3. Neither the name of pkgcore nor the names of its
10 | contributors may be used to endorse or promote products derived from
11 | this software without specific prior written permission.
12 |
13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
17 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
23 | POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/src/univers/maven.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: maven.py
2 | package_url: pkg:pypi/pymaven-patch@0.2.9
3 | copyright: |
4 | Copyright (c) SAS Institute Inc.
5 |
6 | notes: This has been substantially modified and enhanced from the original
7 | pymaven code to extract the version comparison code.
8 |
9 | license_expression: apache-2.0
10 | homepage_url: https://github.com/nexB/pymaven
11 | notice_file: maven.py.NOTICE
--------------------------------------------------------------------------------
/src/univers/maven.py.NOTICE:
--------------------------------------------------------------------------------
1 | # Copyright (c) SAS Institute Inc.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
--------------------------------------------------------------------------------
/src/univers/nuget.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: nuget.py
2 | package_url: pkg:github/google/osv@0.0.14#lib/osv/nuget.py
3 | copyright: Copyright 2022 Google LLC and others
4 | download_url: https://raw.githubusercontent.com/google/osv/f5647ad2f746685b08debfba0293e442f2fb9945/lib/osv/nuget.py
5 | license_expression: apache-2.0
6 | homepage_url: https://github.com/google/osv/
7 | notice_file: nuget.py.NOTICE
--------------------------------------------------------------------------------
/src/univers/nuget.py.NOTICE:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
--------------------------------------------------------------------------------
/src/univers/rpm.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: rpm.py
2 | package_url: pkg:pypi/rpm_vercmp@0.1.2
3 | copyright: |
4 | Copyright (c) SAS Institute Inc.
5 |
6 | license_expression: apache-2.0
7 | homepage_url: https://github.com/nexB/python-rpm-vercmp
8 |
9 | notes: |
10 | This has been substantially modified and enhanced from the original code.
11 |
12 | notice_file: rpm.py.NOTICE
--------------------------------------------------------------------------------
/src/univers/rpm.py.README:
--------------------------------------------------------------------------------
1 | Pure Python implementation of rpmvercmp.
2 |
3 | The RPM Package Manager (http://rpm.org) has a version comparison algorithm,
4 | implemented in its C library, which performs the comparison in a certain way.
5 |
6 | In certain circumstances, where the C library is not installable (for example,
7 | on non-rpm based systems), or does not support the desired version of the
8 | python interpreter, the pure-python implementation may be useful.
9 |
10 | Source Code
11 | ===========
12 | https://github.com/sassoftware/python-rpm-vercmp
13 |
14 | Installation
15 | ============
16 | $ pip install rpm_vercmp
17 |
18 | Usage
19 | =====
20 |
21 | import rpm_vercmp
22 | assert rpm_vercmp.vercmp("1.0", "1.0") == 0
23 | assert rpm_vercmp.vercmp("1.0", "1.1") == -1
24 |
25 | Testing
26 | =======
27 | The testsuite uses rpm's test file in m4 format.
28 | The file cat be fetched from:
29 | https://raw.githubusercontent.com/rpm-software-management/rpm/master/tests/rpmvercmp.at
30 |
--------------------------------------------------------------------------------
/src/univers/rpm.py.antlir.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: rpm.py
2 | package_url: pkg:github/facebookincubator/antlir@120b20de91c55244ceacf61f82c5154a28446590#antlir/rpm/rpm_metadata.py
3 | copyright: |
4 | Copyright (c) Facebook, Inc. and its affiliates.
5 | Copyright (c) SAS Institute Inc.
6 |
7 | license_expression: mit AND Apache-2.0
8 | homepage_url: https://github.com/facebookincubator/antlir/
9 |
10 | notes: |
11 | This has been substantially modified and enhanced from the original code
12 | at https://github.com/facebookincubator/antlir/blob/120b20de91c55244ceacf61f82c5154a28446590/antlir/rpm/rpm_metadata.py
13 | itself taken from
14 | itself originally derived from the Apache-licensed
15 |
16 | notice_file: rpm.py.antlir.NOTICE
--------------------------------------------------------------------------------
/src/univers/rpm.py.antlir.NOTICE:
--------------------------------------------------------------------------------
1 |
2 | SPDX-License-Identifier: MIT AND Apache-2.0
3 |
4 | Copyright (c) Facebook, Inc. and its affiliates.
5 | Copyright (c) SAS Institute Inc.
6 |
7 | Licensed under the Apache License, Version 2.0 (the "License");
8 | you may not use this file except in compliance with the License.
9 | You may obtain a copy of the License at
10 |
11 | http://www.apache.org/licenses/LICENSE-2.0
12 |
13 | Unless required by applicable law or agreed to in writing, software
14 | distributed under the License is distributed on an "AS IS" BASIS,
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | See the License for the specific language governing permissions and
17 | limitations under the License.
18 |
--------------------------------------------------------------------------------
/src/univers/univers_semver.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) nexB Inc. and others.
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 | from univers.utils import remove_spaces
8 | from univers.version_constraint import VersionConstraint
9 | from univers.versions import SemverVersion
10 |
11 | """
12 | node-semver and Rubygems semver-like related utilities.
13 | """
14 |
15 |
16 | def get_caret_constraints(string):
17 | """
18 | Return a tuple of two VersionConstraint of ``SemverVersion`` representing
19 | the lower and upper bound of version constraint ``string`` that contains a
20 | caret node-semver- like range. Raise a ValueError if this is not a caret
21 | range.
22 |
23 | For example:
24 | >>> lower_bound, upper_bound = get_caret_constraints("^1.0.2")
25 | >>> vlow = SemverVersion("1.0.2")
26 | >>> vup = SemverVersion("2.0.0")
27 | >>> assert lower_bound == VersionConstraint(comparator=">=", version=vlow)
28 | >>> assert upper_bound == VersionConstraint(comparator="<", version=vup)
29 | """
30 | string = remove_spaces(string)
31 | if not string or not string.startswith("^"):
32 | raise ValueError(f"Invalid caret version range: {string!r}")
33 |
34 | version = string.lstrip("^")
35 | lower_bound = SemverVersion(version)
36 | upper_bound = SemverVersion(str(lower_bound.value.next_major()))
37 |
38 | return (
39 | VersionConstraint(comparator=">=", version=lower_bound),
40 | VersionConstraint(comparator="<", version=upper_bound),
41 | )
42 |
43 |
44 | def get_tilde_constraints(string, operator="~"):
45 | """
46 | Return a tuple of two VersionConstraint of ``SemverVersion`` representing
47 | the lower and upper bound of a version range ``string`` that contains a
48 | tilde node-semver-like range.
49 | Raise a ValueError if this is not a tilde range.
50 |
51 | For example:
52 | >>> lower_bound, upper_bound = get_tilde_constraints("~1.0.2")
53 | >>> vlow = SemverVersion("1.0.2")
54 | >>> vup = SemverVersion("1.1.0")
55 | >>> assert lower_bound == VersionConstraint(comparator=">=", version=vlow)
56 | >>> assert upper_bound == VersionConstraint(comparator="<", version=vup)
57 | """
58 | string = remove_spaces(string)
59 | if not string or not string.startswith(operator):
60 | raise ValueError(f"Invalid version range: {string!r} " f"does not start with {operator!r}")
61 |
62 | version = string.lstrip(operator)
63 | lower_bound = SemverVersion(version)
64 | upper_bound = SemverVersion(str(lower_bound.value.next_minor()))
65 |
66 | return (
67 | VersionConstraint(comparator=">=", version=lower_bound),
68 | VersionConstraint(comparator="<", version=upper_bound),
69 | )
70 |
71 |
72 | # FIXME: this is unlikely correct https://github.com/npm/node-semver/issues/112
73 | def get_pessimistic_constraints(string):
74 | """
75 | Return a tuple of two VersionConstraint of ``SemverVersion`` representing
76 | the lower and upper bound of version range ``string`` that contains a
77 | pessimistic Ruby range. Raise a ValueError if this is not a pessimistic
78 | Rubygems range.
79 |
80 | For example:
81 | >>> lower_bound, upper_bound = get_pessimistic_constraints("~>2.0.8")
82 | >>> vlow = SemverVersion("2.0.8")
83 | >>> vup = SemverVersion("2.1.0")
84 | >>> assert lower_bound == VersionConstraint(comparator=">=", version=vlow)
85 | >>> assert upper_bound == VersionConstraint(comparator="<", version=vup)
86 | """
87 | return get_tilde_constraints(string, operator="~>")
88 |
--------------------------------------------------------------------------------
/src/univers/utils.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) nexB Inc. and others.
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 |
8 | def remove_spaces(string):
9 | return "".join(string.split())
10 |
11 |
12 | def cmp(x, y):
13 | """
14 | Replacement for built-in Python 2 function cmp that was removed in Python 3
15 | From https://docs.python.org/2/library/functions.html?highlight=cmp#cmp :
16 |
17 | Compare the two objects x and y and return an integer according to the
18 | outcome. The return value is negative if x < y, zero if x == y and
19 | strictly positive if x > y.
20 | """
21 | if x == y:
22 | return 0
23 | elif x is None:
24 | return -1
25 | elif y is None:
26 | return 1
27 | else:
28 | # note that this is the minimal replacement function
29 | return (x > y) - (x < y)
30 |
--------------------------------------------------------------------------------
/tests/bsd-new.LICENSE:
--------------------------------------------------------------------------------
1 | Redistribution and use in source and binary forms, with or without modification,
2 | are permitted provided that the following conditions are met:
3 |
4 | Redistributions of source code must retain the above copyright notice, this list
5 | of conditions and the following disclaimer.
6 |
7 | Redistributions in binary form must reproduce the above copyright notice, this
8 | list of conditions and the following disclaimer in the documentation and/or
9 | other materials provided with the distribution.
10 |
11 | Neither the name of the ORGANIZATION nor the names of its contributors may be
12 | used to endorse or promote products derived from this software without specific
13 | prior written permission.
14 |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
19 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
24 | THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/tests/data/alpine_test.txt.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: alpine_test.txt
2 | description: alpine version comparison tests
3 | license_expression: gpl-2.0
4 | download_url: download_url: https://git.alpinelinux.org/apk-tools/plain/test/version.data?h=v2.12.9
5 | copyright: Copyright (c) Alpine Linux project and apk-tools contributors
6 | package_url: pkg:alpine/apk-tools@2.12.9#test/version.data
7 | notes: this test file does not have an explicit license but is assumed to be GPL-licensed like the rest of alpine
8 | homepage_url: https://git.alpinelinux.org/apk-tools/tree
9 | notice_file: alpine_test.txt.NOTICE
--------------------------------------------------------------------------------
/tests/data/alpine_test.txt.NOTICE:
--------------------------------------------------------------------------------
1 | # Alpine Package Keeper
2 | By Natanael Copa and Timo Teräs
3 | Alpine Package Keeper (apk) is a package manager developed for Alpine Linux.
--------------------------------------------------------------------------------
/tests/data/openssl/openssl_all_versions.txt:
--------------------------------------------------------------------------------
1 | 3.0.0
2 | 3.0.1
3 | 1.1.1
4 | 1.1.1a
5 | 1.1.1b
6 | 1.1.1c
7 | 1.1.1d
8 | 1.1.1e
9 | 1.1.1f
10 | 1.1.1g
11 | 1.1.1h
12 | 1.1.1i
13 | 1.1.1j
14 | 1.1.1k
15 | 1.1.1l
16 | 1.1.1m
17 | 1.0.2
18 | 1.0.2a
19 | 1.0.2b
20 | 1.0.2c
21 | 1.0.2d
22 | 1.0.2e
23 | 1.0.2f
24 | 1.0.2g
25 | 1.0.2h
26 | 1.0.2i
27 | 1.0.2j
28 | 1.0.2k
29 | 1.0.2l
30 | 1.0.2m
31 | 1.0.2n
32 | 1.0.2o
33 | 1.0.2p
34 | 1.0.2q
35 | 1.0.2r
36 | 1.0.2s
37 | 1.0.2t
38 | 1.0.2u
39 | 1.0.2v
40 | 1.0.2w
41 | 1.0.2x
42 | 1.0.2y
43 | 1.0.2za
44 | 1.0.2zb
45 | 1.0.2zc
46 | 3.0.2
47 | 1.1.1n
48 | 1.0.2zd
49 | 1.0.2zc-dev
50 | 1.1.0
51 | 1.1.0a
52 | 1.1.0b
53 | 1.1.0c
54 | 1.1.0d
55 | 1.1.0e
56 | 1.1.0f
57 | 1.1.0g
58 | 1.1.0h
59 | 1.1.0i
60 | 1.1.0j
61 | 1.1.0k
62 | 1.1.0l
63 | 1.0.1
64 | 1.0.1a
65 | 1.0.1b
66 | 1.0.1c
67 | 1.0.1d
68 | 1.0.1e
69 | 1.0.1f
70 | 1.0.1g
71 | 1.0.1h
72 | 1.0.1i
73 | 1.0.1j
74 | 1.0.1k
75 | 1.0.1l
76 | 1.0.1m
77 | 1.0.1n
78 | 1.0.1o
79 | 1.0.1p
80 | 1.0.1q
81 | 1.0.1r
82 | 1.0.1s
83 | 1.0.1t
84 | 1.0.1u
85 | 0.9.8
86 | 0.9.8a
87 | 0.9.8b
88 | 0.9.8c
89 | 0.9.8d
90 | 0.9.8e
91 | 0.9.8f
92 | 0.9.8g
93 | 0.9.8h
94 | 0.9.8i
95 | 0.9.8j
96 | 0.9.8k
97 | 0.9.8l
98 | 0.9.8m
99 | 0.9.8n
100 | 0.9.8o
101 | 0.9.8p
102 | 0.9.8q
103 | 0.9.8r
104 | 0.9.8s
105 | 0.9.8t
106 | 0.9.8u
107 | 0.9.8v
108 | 0.9.8w
109 | 0.9.8x
110 | 0.9.8y
111 | 0.9.8za
112 | 0.9.8zb
113 | 0.9.8zc
114 | 0.9.8zd
115 | 0.9.8ze
116 | 1.0.0
117 | 1.0.0a
118 | 1.0.0b
119 | 1.0.0c
120 | 1.0.0d
121 | 1.0.0e
122 | 1.0.0f
123 | 1.0.0g
124 | 1.0.0i
125 | 1.0.0j
126 | 1.0.0k
127 | 1.0.0l
128 | 1.0.0m
129 | 1.0.0n
130 | 1.0.0o
131 | 1.0.0p
132 | 1.0.0q
133 | 0.9.8zf
134 | 1.0.0r
135 | 0.9.8zg
136 | 1.0.0h
137 | 1.0.0s
138 | 1.0.0t
139 | 0.9.8zh
140 | 0.9.6
141 | 0.9.6a
142 | 0.9.6b
143 | 0.9.6c
144 | 0.9.6d
145 | 0.9.6e
146 | 0.9.7-beta3
147 | 0.9.7-beta5
148 | 0.9.7-beta1
149 | 0.9.7-alpha3
150 | 0.9.7-alpha2
151 | 0.9.7
152 | 0.9.6f
153 | 0.9.6g
154 | 0.9.6h
155 | 0.9.7a
156 | 0.9.6i
157 | 0.9.6j
158 | 0.9.7b
159 | 0.9.7c
160 | 0.9.6k
161 | 0.9.6l
162 | 0.9.7d
163 | 0.9.6m
164 | 0.9.7e
165 | 0.9.7f
166 | 0.9.6-cvs
167 | 0.9.7g
168 | 0.9.7h
169 | 0.9.7i
170 | 0.9.7j
171 | 0.9.7k
172 | 0.9.7l
--------------------------------------------------------------------------------
/tests/data/rpmvercmp.at:
--------------------------------------------------------------------------------
1 | # rpmvercmp.at: rpm version comparison tests
2 |
3 | m4_define([RPMVERCMP],[
4 | AT_SETUP([rpmvercmp($1, $2) = $3])
5 | AT_KEYWORDS([vercmp])
6 | AT_CHECK([
7 | runroot rpm --eval '%{lua: print(rpm.vercmp("$1", "$2"))}'], [0], [$3
8 | ], [])
9 | AT_CLEANUP
10 | ])
11 |
12 | AT_BANNER([RPM version comparison])
13 |
14 | RPMVERCMP(1.0, 1.0, 0)
15 | RPMVERCMP(1.0, 2.0, -1)
16 | RPMVERCMP(2.0, 1.0, 1)
17 |
18 | RPMVERCMP(2.0.1, 2.0.1, 0)
19 | RPMVERCMP(2.0, 2.0.1, -1)
20 | RPMVERCMP(2.0.1, 2.0, 1)
21 |
22 | RPMVERCMP(2.0.1a, 2.0.1a, 0)
23 | RPMVERCMP(2.0.1a, 2.0.1, 1)
24 | RPMVERCMP(2.0.1, 2.0.1a, -1)
25 |
26 | RPMVERCMP(5.5p1, 5.5p1, 0)
27 | RPMVERCMP(5.5p1, 5.5p2, -1)
28 | RPMVERCMP(5.5p2, 5.5p1, 1)
29 |
30 | RPMVERCMP(5.5p10, 5.5p10, 0)
31 | RPMVERCMP(5.5p1, 5.5p10, -1)
32 | RPMVERCMP(5.5p10, 5.5p1, 1)
33 |
34 | RPMVERCMP(10xyz, 10.1xyz, -1)
35 | RPMVERCMP(10.1xyz, 10xyz, 1)
36 |
37 | RPMVERCMP(xyz10, xyz10, 0)
38 | RPMVERCMP(xyz10, xyz10.1, -1)
39 | RPMVERCMP(xyz10.1, xyz10, 1)
40 |
41 | RPMVERCMP(xyz.4, xyz.4, 0)
42 | RPMVERCMP(xyz.4, 8, -1)
43 | RPMVERCMP(8, xyz.4, 1)
44 | RPMVERCMP(xyz.4, 2, -1)
45 | RPMVERCMP(2, xyz.4, 1)
46 |
47 | RPMVERCMP(5.5p2, 5.6p1, -1)
48 | RPMVERCMP(5.6p1, 5.5p2, 1)
49 |
50 | RPMVERCMP(5.6p1, 6.5p1, -1)
51 | RPMVERCMP(6.5p1, 5.6p1, 1)
52 |
53 | RPMVERCMP(6.0.rc1, 6.0, 1)
54 | RPMVERCMP(6.0, 6.0.rc1, -1)
55 |
56 | RPMVERCMP(10b2, 10a1, 1)
57 | RPMVERCMP(10a2, 10b2, -1)
58 |
59 | RPMVERCMP(1.0aa, 1.0aa, 0)
60 | RPMVERCMP(1.0a, 1.0aa, -1)
61 | RPMVERCMP(1.0aa, 1.0a, 1)
62 |
63 | RPMVERCMP(10.0001, 10.0001, 0)
64 | RPMVERCMP(10.0001, 10.1, 0)
65 | RPMVERCMP(10.1, 10.0001, 0)
66 | RPMVERCMP(10.0001, 10.0039, -1)
67 | RPMVERCMP(10.0039, 10.0001, 1)
68 |
69 | RPMVERCMP(4.999.9, 5.0, -1)
70 | RPMVERCMP(5.0, 4.999.9, 1)
71 |
72 | RPMVERCMP(20101121, 20101121, 0)
73 | RPMVERCMP(20101121, 20101122, -1)
74 | RPMVERCMP(20101122, 20101121, 1)
75 |
76 | RPMVERCMP(2_0, 2_0, 0)
77 | RPMVERCMP(2.0, 2_0, 0)
78 | RPMVERCMP(2_0, 2.0, 0)
79 |
80 | dnl RhBug:178798 case
81 | RPMVERCMP(a, a, 0)
82 | RPMVERCMP(a+, a+, 0)
83 | RPMVERCMP(a+, a_, 0)
84 | RPMVERCMP(a_, a+, 0)
85 | RPMVERCMP(+a, +a, 0)
86 | RPMVERCMP(+a, _a, 0)
87 | RPMVERCMP(_a, +a, 0)
88 | RPMVERCMP(+_, +_, 0)
89 | RPMVERCMP(_+, +_, 0)
90 | RPMVERCMP(_+, _+, 0)
91 | RPMVERCMP(+, _, 0)
92 | RPMVERCMP(_, +, 0)
93 |
94 | dnl Basic testcases for tilde sorting
95 | RPMVERCMP(1.0~rc1, 1.0~rc1, 0)
96 | RPMVERCMP(1.0~rc1, 1.0, -1)
97 | RPMVERCMP(1.0, 1.0~rc1, 1)
98 | RPMVERCMP(1.0~rc1, 1.0~rc2, -1)
99 | RPMVERCMP(1.0~rc2, 1.0~rc1, 1)
100 | RPMVERCMP(1.0~rc1~git123, 1.0~rc1~git123, 0)
101 | RPMVERCMP(1.0~rc1~git123, 1.0~rc1, -1)
102 | RPMVERCMP(1.0~rc1, 1.0~rc1~git123, 1)
103 |
104 | dnl Basic testcases for caret sorting
105 | RPMVERCMP(1.0^, 1.0^, 0)
106 | RPMVERCMP(1.0^, 1.0, 1)
107 | RPMVERCMP(1.0, 1.0^, -1)
108 | RPMVERCMP(1.0^git1, 1.0^git1, 0)
109 | RPMVERCMP(1.0^git1, 1.0, 1)
110 | RPMVERCMP(1.0, 1.0^git1, -1)
111 | RPMVERCMP(1.0^git1, 1.0^git2, -1)
112 | RPMVERCMP(1.0^git2, 1.0^git1, 1)
113 | RPMVERCMP(1.0^git1, 1.01, -1)
114 | RPMVERCMP(1.01, 1.0^git1, 1)
115 | RPMVERCMP(1.0^20160101, 1.0^20160101, 0)
116 | RPMVERCMP(1.0^20160101, 1.0.1, -1)
117 | RPMVERCMP(1.0.1, 1.0^20160101, 1)
118 | RPMVERCMP(1.0^20160101^git1, 1.0^20160101^git1, 0)
119 | RPMVERCMP(1.0^20160102, 1.0^20160101^git1, 1)
120 | RPMVERCMP(1.0^20160101^git1, 1.0^20160102, -1)
121 |
122 | dnl Basic testcases for tilde and caret sorting
123 | RPMVERCMP(1.0~rc1^git1, 1.0~rc1^git1, 0)
124 | RPMVERCMP(1.0~rc1^git1, 1.0~rc1, 1)
125 | RPMVERCMP(1.0~rc1, 1.0~rc1^git1, -1)
126 | RPMVERCMP(1.0^git1~pre, 1.0^git1~pre, 0)
127 | RPMVERCMP(1.0^git1, 1.0^git1~pre, 1)
128 | RPMVERCMP(1.0^git1~pre, 1.0^git1, -1)
129 |
130 | dnl These are included here to document current, arguably buggy behaviors
131 | dnl for reference purposes and for easy checking against unintended
132 | dnl behavior changes.
133 | dnl
134 | dnl AT_BANNER([RPM version comparison oddities])
135 | dnl RhBug:811992 case
136 | dnl RPMVERCMP(1b.fc17, 1b.fc17, 0)
137 | dnl RPMVERCMP(1b.fc17, 1.fc17, -1)
138 | dnl RPMVERCMP(1.fc17, 1b.fc17, 1)
139 | dnl RPMVERCMP(1g.fc17, 1g.fc17, 0)
140 | dnl RPMVERCMP(1g.fc17, 1.fc17, 1)
141 | dnl RPMVERCMP(1.fc17, 1g.fc17, -1)
142 |
143 | dnl Non-ascii characters are considered equal so these are all the same, eh...
144 | dnl RPMVERCMP(1.1.α, 1.1.α, 0)
145 | dnl RPMVERCMP(1.1.α, 1.1.β, 0)
146 | dnl RPMVERCMP(1.1.β, 1.1.α, 0)
147 | dnl RPMVERCMP(1.1.αα, 1.1.α, 0)
148 | dnl RPMVERCMP(1.1.α, 1.1.ββ, 0)
149 | dnl RPMVERCMP(1.1.ββ, 1.1.αα, 0)
150 |
--------------------------------------------------------------------------------
/tests/data/rpmvercmp.at.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: rpmvercmp.at
2 | description: rpm version comparison tests
3 | license_expression: gpl-2.0
4 | download_url: https://github.com/rpm-software-management/rpm/blob/04de5e6c854edf4ef4a79b44eac3b20451c88df5/tests/rpmvercmp.at
5 | copyright: Copyright (c) Red Hat Software, Inc.
6 | package_url: pkg:github/rpm-software-management/rpm@04de5e6c854edf4ef4a79b44eac3b20451c88df5#/tests/rpmvercmp.at
7 | notes: this test file does not have an explicit license but is assumed to be GPL-licensed like the rest of RPM
8 | homepage_url: https://github.com/rpm-software-management/rpm
9 | notice_file: rpmvercmp.at.NOTICE
--------------------------------------------------------------------------------
/tests/data/rpmvercmp.at.NOTICE:
--------------------------------------------------------------------------------
1 | Copyright (c) Red Hat Software, Inc.
2 |
3 | RPM was originally written by:
4 | Erik Troan
5 | Marc Ewing
6 |
7 | This test file has been maintained by:
8 | Panu Matilainen @pmatilai
9 |
10 | with contributions by:
11 | Pavlina Varekova @pavlinamv
12 | Igor Gnatenko
13 |
14 |
15 | This program is free software; you can redistribute it and/or modify
16 | it under the terms of the GNU General Public License as published by
17 | the Free Software Foundation; either version 2 of the License, or
18 | (at your option) any later version.
19 |
20 | This program is distributed in the hope that it will be useful,
21 | but WITHOUT ANY WARRANTY; without even the implied warranty of
22 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 | GNU General Public License for more details.
24 |
25 | You should have received a copy of the GNU General Public License
26 | along with this program; if not, write to the Free Software
27 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--------------------------------------------------------------------------------
/tests/data/test-suite-data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "description": "valid simple semver version",
4 | "vers": "vers:semver/=1.3.4",
5 | "canonical_vers": "vers:semver/1.3.4",
6 | "scheme": "semver",
7 | "constraints": [
8 | [{"comparator": "=", "version": "1.3.4"}]
9 | ],
10 | "is_invalid": false
11 | },
12 | {
13 | "description": "valid complex debian version",
14 | "vers": "vers:debian/ 5.0A , > = 2.6 & < 3, > = 3.4.4+reloaded2-13+deb9u1 ",
15 | "canonical_vers": "vers:debian/>=2.6&<3,>=3.4.4+reloaded2-13+deb9u1,5.0a",
16 | "scheme": "debian",
17 | "constraints": [
18 | [{"comparator": ">=", "version": "2.6"}, {"comparator": "<", "version": "3"}],
19 | [{"comparator": ">=", "version": "3.4.4+reloaded2-13+deb9u1"}],
20 | [{"comparator": "=", "version": "5.0a"}]
21 | ],
22 | "is_invalid": false
23 | }
24 | ]
25 |
--------------------------------------------------------------------------------
/tests/nuget/test_nuget_version_comparer.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) .NET Foundation. All rights reserved.
2 | # SPDX-License-Identifier: Apache-2.0
3 | # URL: https://github.com/NuGet/NuGet.Client
4 | # Ported to Python from the C# NuGet test suite and significantly modified
5 |
6 | import pytest
7 |
8 | from univers import nuget
9 |
10 |
11 | @pytest.mark.parametrize(
12 | "version1, version2",
13 | [
14 | ("1.0.0", "1.0.0"),
15 | ("1.0.0-BETA", "1.0.0-beta"),
16 | ("1.0.0-BETA+AA", "1.0.0-beta+aa"),
17 | ("1.0.0-BETA.X.y.5.77.0+AA", "1.0.0-beta.x.y.5.77.0+aa"),
18 | ("1.0.0", "1.0.0+beta"),
19 | ],
20 | )
21 | def test_VersionComparisonDefaultEqual(version1, version2):
22 | assert nuget.Version.from_string(version1) == nuget.Version.from_string(version2)
23 |
24 |
25 | @pytest.mark.parametrize(
26 | "version1, version2",
27 | [
28 | ("1.0", "1.0.0.0"),
29 | ("1.0+test", "1.0.0.0"),
30 | ("1.0.0.1-1.2.A", "1.0.0.1-1.2.a+A"),
31 | ("1.0.01", "1.0.1.0"),
32 | ],
33 | )
34 | def test_VersionComparisonDefaultEqualWithNuGetVersion(version1, version2):
35 | assert nuget.Version.from_string(version1) == nuget.Version.from_string(version2)
36 |
37 |
38 | @pytest.mark.parametrize(
39 | "version1, version2",
40 | [
41 | ("1.0", "1.0.0.1"),
42 | ("1.0+test", "1.0.0.1"),
43 | ("1.0.0.1-1.2.A", "1.0.0.1-1.2.a.A+A"),
44 | ("1.0.01", "1.0.1.2"),
45 | ],
46 | )
47 | def test_VersionComparisonDefaultNotEqualWithNuGetVersion(version1, version2):
48 | assert nuget.Version.from_string(version1) != nuget.Version.from_string(version2)
49 |
50 |
51 | @pytest.mark.parametrize(
52 | "version1, version2",
53 | [
54 | ("0.0.0", "1.0.0"),
55 | ("1.1.0", "1.0.0"),
56 | ("1.0.1", "1.0.0"),
57 | ("1.0.0-BETA", "1.0.0-beta2"),
58 | ("1.0.0+AA", "1.0.0-beta+aa"),
59 | ("1.0.0-BETA.X.y.5.77.0+AA", "1.0.0-beta.x.y.5.79.0+aa"),
60 | ],
61 | )
62 | def test_VersionComparisonDefaultNotEqual(version1, version2):
63 | assert nuget.Version.from_string(version1) != nuget.Version.from_string(version2)
64 |
65 |
66 | # FIXME: Semver considers these two the same, but this one NuGet test treated them as different
67 | @pytest.mark.parametrize(
68 | "version1, version2",
69 | [
70 | ("1.0.0-BETA+AA", "1.0.0-beta"),
71 | ],
72 | )
73 | def test_VersionComparisonDefaultNotEqual2(version1, version2):
74 | assert nuget.Version.from_string(version1) == nuget.Version.from_string(version2)
75 |
--------------------------------------------------------------------------------
/tests/nuget/test_nuget_version_parsing.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) .NET Foundation. All rights reserved.
2 | # SPDX-License-Identifier: Apache-2.0
3 | # URL: https://github.com/NuGet/NuGet.Client
4 | # Ported to Python from the C# NuGet test suite and significantly modified
5 |
6 | import pytest
7 |
8 | from univers import nuget
9 |
10 |
11 | @pytest.mark.parametrize(
12 | "version",
13 | [
14 | ("2"),
15 | ("2.0"),
16 | ("2.0.0"),
17 | ("2.0.0.0"),
18 | ],
19 | )
20 | def test_VersionLength(version):
21 | semVer = nuget.Version.from_string(version)
22 | assert semVer.to_string() == "2.0.0"
23 |
24 |
25 | @pytest.mark.parametrize(
26 | ("version", "expected"),
27 | [
28 | ("1.0.0-Beta", "1.0.0-beta"),
29 | ("1.0.0-Beta.2", "1.0.0-beta.2"),
30 | ("1.0.0+MetaOnly", "1.0.0+MetaOnly"),
31 | ("1.0.0", "1.0.0"),
32 | ("1.0.0-Beta+Meta", "1.0.0-beta+Meta"),
33 | ("1.0.0-RC.X+MetaAA", "1.0.0-rc.x+MetaAA"),
34 | ("1.0.0-RC.X.35.A.3455+Meta-A-B-C", "1.0.0-rc.x.35.a.3455+Meta-A-B-C"),
35 | ],
36 | )
37 | def test_FullVersionParsing(version, expected):
38 | version = nuget.Version.from_string(version)
39 | assert str(version) == expected
40 |
41 |
42 | @pytest.mark.parametrize(
43 | ["expected", "version"],
44 | [
45 | ("beta", "1.0.0-Beta"),
46 | ("beta", "1.0.0-Beta+Meta"),
47 | ("rc.x", "1.0.0-RC.X+Meta"),
48 | ("rc.x.35.a.3455", "1.0.0-RC.X.35.A.3455+Meta"),
49 | ],
50 | )
51 | def test_SpecialVersionParsing(expected, version):
52 | version = nuget.Version.from_string(version)
53 | assert version.prerelease == expected
54 |
55 |
56 | @pytest.mark.parametrize(
57 | "expected, version",
58 | [
59 | ("", "1.0.0-Beta"),
60 | ("Meta", "1.0.0-Beta+Meta"),
61 | ("MetaAA", "1.0.0-RC.X+MetaAA"),
62 | ("Meta-A-B-C", "1.0.0-RC.X.35.A.3455+Meta-A-B-C"),
63 | ],
64 | )
65 | def test_MetadataParsing(expected, version):
66 | version = nuget.Version.from_string(version)
67 | assert version.build == expected
68 |
69 |
70 | @pytest.mark.parametrize(
71 | "expected, version",
72 | [
73 | (False, "1.0.0-Beta"),
74 | (False, "1.0.0-Beta.2"),
75 | (True, "1.0.0+MetaOnly"),
76 | (False, "1.0.0"),
77 | (True, "1.0.0-Beta+Meta"),
78 | (True, "1.0.0-RC.X+MetaAA"),
79 | (True, "1.0.0-RC.X.35.A.3455+Meta-A-B-C"),
80 | ],
81 | )
82 | def test_HasMetadataParsing(expected, version):
83 | version = nuget.Version.from_string(version)
84 | assert bool(version.build) == expected
85 |
86 |
87 | @pytest.mark.parametrize(
88 | "major, minor, patch, version",
89 | [
90 | (0, 0, 0, "0.0.0"),
91 | (1, 0, 0, "1.0.0"),
92 | (3, 5, 1, "3.5.1"),
93 | (234, 234234, 1111, "234.234234.1111"),
94 | (3, 5, 1, "3.5.1+Meta"),
95 | (3, 5, 1, "3.5.1-x.y.z+AA"),
96 | ],
97 | )
98 | def test_VersionParsing(major, minor, patch, version):
99 | version = nuget.Version.from_string(version)
100 | assert version.major == major
101 | assert version.minor == minor
102 | assert version.patch == patch
103 |
--------------------------------------------------------------------------------
/tests/nuget_versioning_tests.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: nuget_versioning_tests
2 | package_url: pkg:github/NuGet/NuGet.Client@588d5d5fbf4e5d3fac29b655286a5f2f2a8a446f#test/NuGet.Core.Tests/NuGet.Versioning.Test
3 | copyright: Copyright (c) .NET Foundation and Contributors.
4 |
5 | license_expression: apache-2.0
6 | homepage_url: https://github.com/NuGet/NuGet.Client
7 |
8 | notes: |
9 | The C# version comparison test suite has been extracted from NugetClient
10 | and further stripped down. Then the interesting subsets have been converted
11 | to Python.
12 |
13 | notice_file: nuget_versioning_tests.NOTICE
14 |
--------------------------------------------------------------------------------
/tests/nuget_versioning_tests.NOTICE:
--------------------------------------------------------------------------------
1 | Copyright (c) .NET Foundation and Contributors.
2 |
3 | All rights reserved.
4 |
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
7 | these files except in compliance with the License. You may obtain a copy of the
8 | License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software distributed
13 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
14 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
15 | specific language governing permissions and limitations under the License.
16 |
--------------------------------------------------------------------------------
/tests/nuget_versioning_tests.README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | -----
4 |
5 | # NuGet Client Tools
6 |
7 | This repo contains the following clients:
8 |
9 | - [NuGet CLI](https://docs.microsoft.com/nuget/tools/nuget-exe-cli-reference)
10 | - [NuGet Package Manager for Visual Studio](https://docs.microsoft.com/nuget/tools/package-manager-ui)
11 | - [PowerShell CmdLets](https://docs.microsoft.com/nuget/tools/powershell-reference)
12 | - [NuGet functionality for dotnet.exe](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet)
13 |
14 | ## Open Source Code of Conduct
15 |
16 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
17 |
18 | ## Getting Started guide
19 |
20 | For how to contribute to this repo follow the [Contributing doc](CONTRIBUTING.md).
21 |
22 | ## NuGet/Home repo
23 |
24 | The [NuGet/Home](https://github.com/nuget/Home) repo is the starting point for all things NuGet. It has the [issue tracker](https://github.com/nuget/home/issues) and [basic information](https://github.com/nuget/home) about all things NuGet. Make sure to consult it before beginning your journey through NuGet code.
25 |
26 | ## Feedback
27 |
28 | File NuGet.Client bugs in the [NuGet/Home](https://github.com/nuget/home/issues).
29 |
30 | ## License
31 |
32 | Unless explicitly stated otherwise all files in this repository are licensed under the License in the root repository
33 |
--------------------------------------------------------------------------------
/tests/test_alpine.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) nexB Inc. and others.
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 | import operator
8 | from typing import NamedTuple
9 |
10 | import pytest
11 |
12 | from univers.versions import AlpineLinuxVersion
13 | from univers.versions import InvalidVersion
14 |
15 |
16 | class AlpineVersionComparison(NamedTuple):
17 | """
18 | We have this class to drive the tests, where we compare
19 | `version1` and `version2` on the basis of the `comparator`
20 | """
21 |
22 | version1: str
23 | comparator: str
24 | version2: str
25 |
26 | @classmethod
27 | def from_string(cls, s: str):
28 | segments = s.split()
29 |
30 | assert len(segments) == 3
31 | return cls(*segments)
32 |
33 | def compare(self):
34 | """
35 | Compare version1 and version2 with comparator
36 | and return True if comparison is valid, False otherwise
37 | """
38 | v1 = AlpineLinuxVersion(self.version1)
39 | v2 = AlpineLinuxVersion(self.version2)
40 | COMPARATORS = {
41 | "<": operator.lt,
42 | ">": operator.gt,
43 | "=": operator.eq,
44 | }
45 | comparator = COMPARATORS[self.comparator]
46 | return comparator(v1, v2)
47 |
48 |
49 | @pytest.mark.parametrize("test_case", open("./tests/data/alpine_test.txt").read().splitlines(False))
50 | def test_alpine_vers_cmp(test_case):
51 | avc = AlpineVersionComparison.from_string(test_case)
52 | assert avc.compare()
53 |
54 |
55 | @pytest.mark.parametrize(
56 | "test_case",
57 | [
58 | # these are the tests are not supported yet
59 | # when we start supporting these version,
60 | # they will be moved back to main test suite
61 | "2.10.1 > 02.08.01b",
62 | "02.08.01b < 4.77",
63 | "23_foo > 4_beta",
64 | "1.06-r6 < 006",
65 | "006 > 1.0.0",
66 | "2.10.1 > 02.08.01b",
67 | "02.08.01b < 4.77",
68 | "2.2.3-r2 < 013",
69 | "013 < 014-r1",
70 | "014-r1 > 1.3.1-r1",
71 | "3.0.0-r2 < 021109-r3",
72 | "021109-r3 < 20060512",
73 | "0.9.28.1 < 087-r1",
74 | "087-r1 < 103",
75 | # invalid. do string sort
76 | "1.0 < 1.0bc",
77 | ],
78 | )
79 | def test_invalid_alpine_vers_cmp(test_case):
80 | avc = AlpineVersionComparison.from_string(test_case)
81 | with pytest.raises(InvalidVersion):
82 | AlpineLinuxVersion(avc.version1)
83 | AlpineLinuxVersion(avc.version2)
84 |
--------------------------------------------------------------------------------
/tests/test_bundler_version_ranges_spec.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) Chad Fowler, Rich Kilmer, Jim Weirich and others.
3 | # Portions copyright (c) Engine Yard and Andre ArkoFacebook, Inc. and its affiliates.
4 | #
5 | # SPDX-License-Identifier: MIT
6 | #
7 | # Originally from https://github.com/rubygems/rubygems
8 |
9 | from univers.gem import GemRequirement
10 |
11 |
12 | def test_satisfied_by():
13 |
14 | assert not GemRequirement("!= 1").satisfied_by("1")
15 | assert GemRequirement("!= 1").satisfied_by("2")
16 |
17 | assert not GemRequirement("!= 1", "= 2").satisfied_by("1")
18 | assert GemRequirement("!= 1", "= 2").satisfied_by("2")
19 |
20 | assert not GemRequirement("!= 1", "> 1").satisfied_by("1")
21 | assert GemRequirement("!= 1", "> 1").satisfied_by("2")
22 |
23 | assert not GemRequirement("!= 1", ">= 1").satisfied_by("1")
24 | assert GemRequirement("!= 1", ">= 1").satisfied_by("2")
25 |
26 | assert not GemRequirement("= 1", ">= 0.1", "<= 1.1").satisfied_by("0.2")
27 | assert GemRequirement("= 1", ">= 0.1", "<= 1.1").satisfied_by("1")
28 | assert not GemRequirement("= 1", ">= 0.1", "<= 1.1").satisfied_by("3")
29 |
30 | assert GemRequirement("= 1", ">= 1", "<= 1").satisfied_by("1")
31 | assert not GemRequirement("= 1", ">= 1", "<= 1").satisfied_by("2")
32 | assert not GemRequirement("= 1", ">= 1", "<= 1").satisfied_by("0.1")
33 |
34 | assert GemRequirement("= 1", "~> 1").satisfied_by("1")
35 | assert not GemRequirement("= 1", "~> 1").satisfied_by("1.1")
36 |
37 | assert GemRequirement(">= 0.z", "= 0").satisfied_by("0")
38 | assert not GemRequirement(">= 0.z", "= 0").satisfied_by("1")
39 | assert not GemRequirement(">= 0.z", "= 0").satisfied_by("0.1")
40 | assert not GemRequirement(">= 0.z", "= 0").satisfied_by("0.z")
41 |
42 | assert GemRequirement(">= 0").satisfied_by("1")
43 | assert GemRequirement(">= 0").satisfied_by("2")
44 | assert GemRequirement(">= 0").satisfied_by("0")
45 |
46 | assert not GemRequirement(">= 1.0.0", "< 2.0.0").satisfied_by("3")
47 | assert GemRequirement(">= 1.0.0", "< 2.0.0").satisfied_by("1.5.1")
48 |
49 | assert GemRequirement("~> 1").satisfied_by("1")
50 | assert GemRequirement("~> 1").satisfied_by("1.1")
51 | assert not GemRequirement("~> 1").satisfied_by("2")
52 |
53 | assert not GemRequirement("~> 2.0", "~> 2.1").satisfied_by("1")
54 | assert GemRequirement("~> 2.0", "~> 2.1").satisfied_by("2.1.2")
55 |
56 | assert not GemRequirement(">= 4.1.0", "< 5.0", "= 5.2.1").satisfied_by("1")
57 | assert not GemRequirement(">= 4.1.0", "< 5.0", "= 5.2.1").satisfied_by("5.2.1")
58 | assert not GemRequirement(
59 | "< 5.0",
60 | "< 5.3",
61 | "< 6.0",
62 | "< 6",
63 | "= 5.2.0",
64 | "> 2",
65 | ">= 3.0",
66 | ">= 3.1",
67 | ">= 3.2",
68 | ">= 4.0.0",
69 | ">= 4.1.0",
70 | ">= 4.2.0",
71 | ">= 4.2",
72 | ">= 4",
73 | ).satisfied_by("5.2.0")
74 | assert not GemRequirement("!= 1", "< 2", "> 2").satisfied_by("1")
75 | assert not GemRequirement("!= 1", "<= 1", ">= 1").satisfied_by("1")
76 | assert not GemRequirement("< 2", "> 2").satisfied_by("1")
77 | assert not GemRequirement("< 2", "> 2", "= 2").satisfied_by("1")
78 | assert not GemRequirement("= 1", "!= 1").satisfied_by("1")
79 | assert not GemRequirement("= 1", "= 2").satisfied_by("1")
80 | assert not GemRequirement("= 1", "~> 2").satisfied_by("1")
81 | assert not GemRequirement(">= 0", "<= 0.a").satisfied_by("1")
82 | assert not GemRequirement("~> 2.0", "~> 3").satisfied_by("1")
83 |
--------------------------------------------------------------------------------
/tests/test_bundler_version_ranges_spec.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_bundler_version_ranges_spec.py
2 | package_url: pkg:github.com/rubygems/rubygems@5768c2bc5542ce05466d379981a433ba1ee1e10a
3 | copyright: |
4 | Portions copyright (c) André Arko
5 | Portions copyright (c) Engine Yard
6 |
7 | license_expression: mit
8 | homepage_url: https://github.com/rubygems/rubygems
9 |
10 | notes: This has been substantially modified and enhanced from the original code
11 | to port tests cases to Python
12 |
13 | notice_file: test_bundler_edgecases_spec.py.NOTICE
--------------------------------------------------------------------------------
/tests/test_bundler_version_ranges_spec.py.NOTICE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Portions copyright (c) 2010-2019 André Arko
4 | Portions copyright (c) 2009 Engine Yard
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/tests/test_codestyle.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) nexB Inc. and others.
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 | import subprocess
8 | import sys
9 | import unittest
10 |
11 | import pytest
12 |
13 |
14 | @pytest.mark.skipif(sys.platform == "darwin", reason="Test does not run on macOS13 and older.")
15 | class BaseTests(unittest.TestCase):
16 | def test_codestyle(self):
17 | args = "black --check -l 100 setup.py src tests"
18 | try:
19 | subprocess.check_output(args.split(), shell=False)
20 | except subprocess.CalledProcessError as e:
21 | print("===========================================================")
22 | print(e.output)
23 | print("===========================================================")
24 | raise Exception(
25 | "Black style check failed; please format the code using:\n"
26 | " python -m black -l 100 setup.py src tests",
27 | e.output,
28 | ) from e
29 |
30 | args = "isort --check-only src tests setup.py"
31 | try:
32 | subprocess.check_output(args.split(), shell=False)
33 | except Exception as e:
34 | print("===========================================================")
35 | print(e.output)
36 | print("===========================================================")
37 | raise Exception(
38 | "Unsorted imports, please sort your imports using isort. "
39 | "Alternatively, run ``isort src tests setup.py``",
40 | e.output,
41 | ) from e
42 |
--------------------------------------------------------------------------------
/tests/test_conan_version_bump.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2019 JFrog LTD
3 | # SPDX-License-Identifier: MIT
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 | import pytest
8 |
9 | from univers.versions import ConanVersion
10 |
11 | values = [
12 | ["1.0.0", 0, "2.0.0"],
13 | ["1.1.0", 0, "2.0.0"],
14 | ["1.1.1-pre", 0, "2.0.0"],
15 | ["1.1.1", 1, "1.2.0"],
16 | ["1.1.1", 2, "1.1.2"],
17 | ]
18 |
19 |
20 | @pytest.mark.parametrize("version, index, result", values)
21 | def test_version_bump(version, index, result):
22 | r = ConanVersion(version)
23 | bumped = r.bump(index)
24 | assert bumped == result
25 |
--------------------------------------------------------------------------------
/tests/test_conan_version_bump.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_conan_version_bump.py
2 | package_url: pkg:pypi/conan@2.0.0
3 | copyright: |
4 | Copyright (c) 2019 JFrog LTD
5 | download_url: https://github.com/conan-io/conan/tree/release/2.0/conans/test/unittests/model/version/test_conan_version_bump.py
6 | license_expression: MIT
7 | homepage_url: https://github.com/conan-io/conan
8 | notice_file: test_conan_version_bump.py.NOTICE
9 |
--------------------------------------------------------------------------------
/tests/test_conan_version_bump.py.NOTICE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 JFrog LTD
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/tests/test_conan_version_comparison.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2019 JFrog LTD
3 | # SPDX-License-Identifier: MIT
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 | import pytest
8 |
9 | from univers.versions import ConanVersion
10 |
11 | v = [
12 | ("1", "2"),
13 | ("1.0", "1.1"),
14 | ("1.0.2", "1.1.0"),
15 | ("1.3", "1.22"),
16 | ("1.1.3", "1.1.22"),
17 | ("1.1.1.3", "1.1.1.22"),
18 | ("1.1.1.1.3", "1.1.1.1.22"),
19 | # Different lengths
20 | ("1.0", "2"),
21 | ("1.2", "1.3.1"),
22 | ("1.0.2", "1.1"),
23 | # Now with letters
24 | ("1.1.a", "1.1.b"),
25 | ("1.1.1.abc", "1.1.1.abz"),
26 | ("a.b.c", "b.c"),
27 | ("1.1", "1.a"),
28 | ("1.1", "1.1a"),
29 | ("1.1", "1.1.a"),
30 | ("1.1.a", "1.2"),
31 | # Arterisk are before digits
32 | ("1.1*", "1.20"),
33 | ("1.1.*", "1.20"),
34 | ("1.2.2", "1.3.*"),
35 | ("1.2.2", "1.2.3*"),
36 | # build is easy
37 | ("1.1+b1", "1.1+b2"),
38 | ("1.1", "1.1+b2"),
39 | ("1.1+b1", "1.2"),
40 | ("1.1+b.3", "1.1+b.22"),
41 | # pre-release is challenging
42 | ("1.1-pre1", "1.1-pre2"),
43 | ("1.1-alpha.3", "1.1-alpha.22"),
44 | ("1.1-alpha.3+b1", "1.1-alpha.3+b2"),
45 | ("1.1-alpha.1", "1.1"),
46 | ("1.1", "1.2-alpha1"),
47 | ("1.1-alpha.1", "1.1.0"), # pre to the generic 1.1 is earlier than 1.1.0
48 | ("1.0.0-", "1.0.0-alpha1"),
49 | ]
50 |
51 |
52 | @pytest.mark.parametrize("v1, v2", v)
53 | def test_comparison(v1, v2):
54 | v1 = ConanVersion(v1)
55 | v2 = ConanVersion(v2)
56 | assert v1 < v2
57 | assert v2 > v1
58 | assert v1 != v2
59 | assert v1 <= v2
60 | assert v2 >= v1
61 |
62 |
63 | def test_comparison_with_integer():
64 | v1 = ConanVersion("13.0")
65 | # Issue: https://github.com/conan-io/conan/issues/12907
66 | assert v1 > ConanVersion("5")
67 | assert v1 >= ConanVersion("5")
68 | assert v1 < ConanVersion("20")
69 | assert v1 <= ConanVersion("20")
70 | assert v1 == ConanVersion("13")
71 | assert v1 != ConanVersion("14")
72 |
73 |
74 | e = [
75 | ("1", "1.0"),
76 | ("1", "1.0.0"),
77 | ("1.0", "1.0.0"),
78 | ("1.0", "1.0.0.0"),
79 | ("1-pre1", "1.0-pre1"),
80 | ("1-pre1", "1.0.0-pre1"),
81 | ("1.0-pre1", "1.0.0-pre1"),
82 | ("1.0-pre1.0", "1.0.0-pre1"),
83 | ("1-pre1+b1", "1.0-pre1+b1"),
84 | ("1-pre1+b1", "1.0.0-pre1+b1"),
85 | ("1.0-pre1+b1", "1.0.0-pre1+b1"),
86 | ("1+b1", "1.0+b1"),
87 | ("1+b1", "1.0+b1.0"),
88 | ("1+b1", "1.0.0+b1"),
89 | ("1.0+b1", "1.0.0+b1"),
90 | ]
91 |
92 |
93 | @pytest.mark.parametrize("v1, v2", e)
94 | def test_equality(v1, v2):
95 | v1 = ConanVersion(v1)
96 | v2 = ConanVersion(v2)
97 | assert v1 == v2
98 | assert not v1 != v2
99 |
100 |
101 | def test_elem_comparison():
102 | v1 = ConanVersion("1.2.3b.4-pre.1.2b+build.1.1b")
103 | major = v1.major
104 | assert major < 2
105 | assert major < "2"
106 | assert major == 1
107 | assert major != 3
108 | assert major > 0
109 | assert str(major) == "1"
110 | patch = v1.patch
111 | assert patch < 4
112 | assert patch > 2
113 | assert patch < "3c"
114 | assert patch > "3a"
115 | assert patch == "3b"
116 | micro = v1.micro
117 | assert micro > 3
118 | assert micro < 5
119 | assert micro == 4
120 |
--------------------------------------------------------------------------------
/tests/test_conan_version_comparison.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_conan_version_comparison.py
2 | package_url: pkg:pypi/conan@2.0.0
3 | copyright: |
4 | Copyright (c) 2019 JFrog LTD
5 | download_url: https://github.com/conan-io/conan/tree/release/2.0/conans/test/unittests/model/version/test_conan_version_comparison.py
6 | license_expression: MIT
7 | homepage_url: https://github.com/conan-io/conan
8 | notice_file: test_conan_version_comparison.py.NOTICE
9 |
--------------------------------------------------------------------------------
/tests/test_conan_version_comparison.py.NOTICE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 JFrog LTD
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/tests/test_conan_version_range.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2019 JFrog LTD
3 | # SPDX-License-Identifier: MIT
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 | import pytest
8 |
9 | from univers.conan.errors import ConanException
10 | from univers.conan.version_range import VersionRange
11 | from univers.versions import ConanVersion
12 |
13 | values = [
14 | [">1.0.0", [[[">", "1.0.0"]]], ["1.0.1"], ["0.1"]],
15 | ["<2.0", [[["<", "2.0"]]], ["1.0.1"], ["2.1"]],
16 | [">1 <2.0", [[[">", "1"], ["<", "2.0"]]], ["1.5.1"], ["0.1", "2.1"]],
17 | # tilde
18 | ["~2.5", [[[">=", "2.5"], ["<", "2.6-"]]], ["2.5.0", "2.5.3"], ["2.7", "2.6.1"]],
19 | ["~2.5.1", [[[">=", "2.5.1"], ["<", "2.6.0-"]]], ["2.5.1", "2.5.3"], ["2.5", "2.6.1"]],
20 | ["~1", [[[">=", "1"], ["<", "2-"]]], ["1.3", "1.8.1"], ["0.8", "2.2"]],
21 | # caret
22 | ["^1.2", [[[">=", "1.2"], ["<", "2.0-"]]], ["1.2.1", "1.51"], ["1", "2", "2.0.1"]],
23 | ["^1.2.3", [[[">=", "1.2.3"], ["<", "2.0.0-"]]], ["1.2.3", "1.2.4"], ["2", "2.1", "2.0.1"]],
24 | ["^0.1.2", [[[">=", "0.1.2"], ["<", "0.2.0-"]]], ["0.1.3", "0.1.44"], ["1", "0.3", "0.2.1"]],
25 | # Identity
26 | ["1.0.0", [[["=", "1.0.0"]]], ["1.0.0"], ["2", "1.0.1"]],
27 | ["=1.0.0", [[["=", "1.0.0"]]], ["1.0.0"], ["2", "1.0.1"]],
28 | # Any
29 | ["*", [[[">=", "0.0.0"]]], ["1.0", "a.b"], []],
30 | ["", [[[">=", "0.0.0"]]], ["1.0", "a.b"], []],
31 | # Unions
32 | ["1.0.0 || 2.1.3", [[["=", "1.0.0"]], [["=", "2.1.3"]]], ["1.0.0", "2.1.3"], ["2", "1.0.1"]],
33 | [
34 | ">1 <2.0 || ^3.2 ",
35 | [[[">", "1"], ["<", "2.0"]], [[">=", "3.2"], ["<", "4.0-"]]],
36 | ["1.5", "3.3"],
37 | ["2.1", "0.1", "5"],
38 | ],
39 | # pre-releases
40 | ["", [[[">=", "0.0.0"]]], ["1.0"], ["1.0-pre.1"]],
41 | ["*, include_prerelease=True", [[[">=", "0.0.0"]]], ["1.0", "1.0-pre.1"], []],
42 | ["*-", [[[">=", "0.0.0"]]], ["1.0", "1.0-pre.1"], []],
43 | [">1- <2.0", [[[">", "1"], ["<", "2.0"]]], ["1.5.1-pre1"], ["2.1-pre1"]],
44 | [
45 | ">1- <2.0 || ^3.2 ",
46 | [[[">", "1"], ["<", "2.0"]], [[">=", "3.2"], ["<", "4.0-"]]],
47 | ["1.5-a1", "3.3"],
48 | ["3.3-a1"],
49 | ],
50 | ["^1.1.2-", [[[">=", "1.1.2"], ["<", "2.0.0-"]]], ["1.2.3", "1.2.0-alpha1"], ["2.0.0-alpha1"]],
51 | ["~1.1.2-", [[[">=", "1.1.2"], ["<", "1.2.0-"]]], ["1.1.3", "1.1.3-alpha1"], ["1.2.0-alpha1"]],
52 | ]
53 |
54 |
55 | @pytest.mark.parametrize("version_range, conditions, versions_in, versions_out", values)
56 | def test_range(version_range, conditions, versions_in, versions_out):
57 | r = VersionRange(version_range)
58 | for condition_set, expected_condition_set in zip(r.condition_sets, conditions):
59 | for condition, expected_condition in zip(condition_set.conditions, expected_condition_set):
60 | assert condition.operator == expected_condition[0]
61 | assert condition.version == ConanVersion(expected_condition[1])
62 |
63 | for v in versions_in:
64 | assert ConanVersion(v) in r
65 |
66 | for v in versions_out:
67 | assert ConanVersion(v) not in r
68 |
69 |
70 | def test_wrong_range_syntax():
71 | # https://github.com/conan-io/conan/issues/12692
72 | with pytest.raises(ConanException):
73 | VersionRange(">= 1.0")
74 |
--------------------------------------------------------------------------------
/tests/test_conan_version_range.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_conan_version_range.py
2 | package_url: pkg:pypi/conan@2.0.0
3 | copyright: |
4 | Copyright (c) 2019 JFrog LTD
5 | download_url: https://github.com/conan-io/conan/tree/release/2.0/conans/test/unittests/model/version/test_conan_version_range.py
6 | license_expression: MIT
7 | homepage_url: https://github.com/conan-io/conan
8 | notice_file: test_conan_version_range.py.NOTICE
9 |
--------------------------------------------------------------------------------
/tests/test_conan_version_range.py.NOTICE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 JFrog LTD
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/tests/test_debian_version.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_debian_version.py
2 | license_expression: apache-2.0
3 | download_url: https://raw.githubusercontent.com/nexB/debian-inspector/b8f413de99c3f21bca759aba94cc815791b06619/tests/test_version.py
4 | copyright: Copyright (c) nexB Inc. and others.
5 | package_url: pkg:pypi/debian-inspector@0.9.10#tests/test_version.py
6 | notes: this subset of tests has been modified to tests version comparison and parsing
7 | homepage_url: https://github.com/aboutcode-org/debian-inspector
8 | notice_file: test_debian_version.py.NOTICE
9 |
--------------------------------------------------------------------------------
/tests/test_debian_version.py.NOTICE:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Copyright (c) 2018 Peter Odding
4 | #
5 | # Permission is hereby granted, free of charge, to any person obtaining
6 | # a copy of this software and associated documentation files (the
7 | # "Software"), to deal in the Software without restriction, including
8 | # without limitation the rights to use, copy, modify, merge, publish,
9 | # distribute, sublicense, and/or sell copies of the Software, and to
10 | # permit persons to whom the Software is furnished to do so, subject to
11 | # the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be
14 | # included in all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
24 | # Debian packaging tools: Version comparison.
25 | # Original-Author: Peter Odding
26 | # Original-URL: https://github.com/xolox/python-deb-pkg-tools
27 |
--------------------------------------------------------------------------------
/tests/test_debian_version_python_deb_pkg_tools.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) Peter Odding
3 | # URL: https://github.com/xolox/python-deb-pkg-tools
4 | # SPDX-License-Identifier: MIT
5 | #
6 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
7 |
8 |
9 | from unittest import TestCase
10 |
11 | from univers.debian import Version
12 |
13 |
14 | class DebPkgToolsTestCase(TestCase):
15 | def test_version_sorting(self):
16 | # Check version sorting implemented on top of `=' and `<<' comparisons.
17 | expected_order = ["0.1", "0.5", "1.0", "2.0", "3.0", "1:0.4", "2:0.3"]
18 | assert list(sorted(expected_order)) != expected_order
19 | result = [str(v) for v in sorted(map(Version.from_string, expected_order))]
20 | assert result == expected_order
21 |
22 | def test_version_comparison(self):
23 | assert Version.from_string("1.0") > Version.from_string("0.5")
24 | assert Version.from_string("1:0.5") > Version.from_string("2.0")
25 | assert not Version.from_string("0.5") > Version.from_string("2.0")
26 |
27 | assert Version.from_string("0.75") >= Version.from_string("0.5")
28 | assert Version.from_string("0.50") >= Version.from_string("0.5")
29 | assert Version.from_string("1:0.5") >= Version.from_string("5.0")
30 | assert not Version.from_string("0.2") >= Version.from_string("0.5")
31 |
32 | assert Version.from_string("0.5") < Version.from_string("1.0")
33 | assert Version.from_string("2.0") < Version.from_string("1:0.5")
34 | assert not Version.from_string("2.0") < Version.from_string("0.5")
35 |
36 | assert Version.from_string("0.5") <= Version.from_string("0.75")
37 | assert Version.from_string("0.5") <= Version.from_string("0.50")
38 | assert Version.from_string("5.0") <= Version.from_string("1:0.5")
39 | assert not Version.from_string("0.5") <= Version.from_string("0.2")
40 |
41 | assert Version.from_string("42") == Version.from_string("42")
42 | assert Version.from_string("0.5") == Version.from_string("0:0.5")
43 | assert not Version.from_string("0.5") == Version.from_string("1.0")
44 |
45 | assert Version.from_string("1") != Version.from_string("0")
46 | assert not Version.from_string("0.5") != Version.from_string("0:0.5")
47 |
48 | assert Version.from_string("1.3~rc2") < Version.from_string("1.3")
49 |
--------------------------------------------------------------------------------
/tests/test_debian_version_python_deb_pkg_tools.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_version_python_deb_pkg_tools.py
2 | name: python-debian
3 | license_expression: mit
4 | download_url: https://raw.githubusercontent.com/xolox/python-deb-pkg-tools/a3d6ef1d82c6342b6a57876fc2360875e033f8f0/deb_pkg_tools/tests.py
5 | copyright: Copyright (c) Peter Odding
6 | package_url: pkg:pypi/deb-pkg-tools@8.4#deb_pkg_tools/tests.py
7 | notes: this subset of tests has been modified to tests version comparison and parsing
8 | homepage_url: https://github.com/xolox/python-deb-pkg-tools
--------------------------------------------------------------------------------
/tests/test_gem.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) Center for Information Technology, http://coi.gov.pl
2 | # SPDX-License-Identifier: Apache-2.0
3 | # this has been significantly modified from the original
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 | # notes: This has been substantially modified and enhanced from the original
8 | # puppeteer code to extract the Ruby version handling code.
9 |
10 | from univers.gem import GemRequirement
11 | from univers.gem import GemVersion
12 |
13 |
14 | def test_gem_version_release():
15 | assert GemVersion("1.2.4.beta").release() == GemVersion("1.2.4")
16 |
17 |
18 | def test_gem_version_bump():
19 | assert GemVersion("1.2.4").bump() == GemVersion("1.3.0")
20 |
21 |
22 | def test_gem_version_compare():
23 | assert GemVersion("1.3.0") == GemVersion("1.3")
24 | assert GemVersion("1.3.0") <= GemVersion("1.3")
25 | assert GemVersion("1.1.3") <= GemVersion("1.3")
26 | assert GemVersion("1.4.pre") >= GemVersion("1.3")
27 | assert GemVersion("1.4.pre") != GemVersion("1.4")
28 |
29 |
30 | def test_gem_requirement():
31 | assert GemRequirement("3.4").satisfied_by("3.4.0")
32 | assert GemRequirement("~> 3.4").satisfied_by("3.4.8")
33 | assert GemRequirement(">= 3.4").satisfied_by("4.4.8")
34 | assert GemRequirement(">= 3.4", "<4").satisfied_by("3.45.8")
35 |
36 |
37 | def test_gem_requirement_fails1():
38 | assert GemRequirement(">= 3.4", "<4").satisfied_by("4.1") is False
39 |
40 |
41 | def test_gem_requirement_fails2():
42 | assert GemRequirement("~> 3").satisfied_by("4.1.0.pre") is False
43 |
--------------------------------------------------------------------------------
/tests/test_gem.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_gem.py
2 | license_expression: apache-2.0
3 | download_url: https://raw.githubusercontent.com/coi-gov-pl/puppeter/develop/tests/domain/model/test_gemrequirement.py
4 | copyright: Copyright (c) Center for Information Technology http://coi.gov.pl
5 | package_url: pkg:pypi/puppeter@0.8.3#tests/domain/model/test_gemrequirement.py
6 | notes: this subset of tests has been modified to tests version comparison and parsing
7 | homepage_url: https://github.com/coi-gov-pl/puppeter
8 | notice_file: test_gem.py.NOTICE
9 |
--------------------------------------------------------------------------------
/tests/test_gem.py.NOTICE:
--------------------------------------------------------------------------------
1 | # Copyright 2017 Center for Information Technology
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
--------------------------------------------------------------------------------
/tests/test_gentoo.py:
--------------------------------------------------------------------------------
1 | # test_vercmp.py -- Portage Unit Testing Functionality
2 | # Copyright 2006 Gentoo Foundation
3 | # SPDX-License-Identifier: GPL-2.0-only
4 | # this has been significantly modified from the original
5 | #
6 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
7 |
8 |
9 | from unittest import TestCase
10 |
11 | from univers.gentoo import vercmp
12 |
13 |
14 | class VerCmpTestCase(TestCase):
15 | """A simple testCase for univers.gentoo.vercmp()"""
16 |
17 | def testVerCmpGreater(self):
18 |
19 | tests = [
20 | ("6.0", "5.0"),
21 | ("5.0", "5"),
22 | ("1.0-r1", "1.0-r0"),
23 | ("1.0-r1", "1.0"),
24 | ("999999999999999999999999999999", "999999999999999999999999999998"),
25 | ("1.0.0", "1.0"),
26 | ("1.0.0", "1.0b"),
27 | ("1b", "1"),
28 | ("1b_p1", "1_p1"),
29 | ("1.1b", "1.1"),
30 | ("12.2.5", "12.2b"),
31 | ]
32 | for test in tests:
33 | self.assertFalse(
34 | vercmp(test[0], test[1]) <= 0, msg="%s < %s? Wrong!" % (test[0], test[1])
35 | )
36 |
37 | def testVerCmpLess(self):
38 | """
39 | pre < alpha < beta < rc < p -> test each of these, they are inductive (or should be..)
40 | """
41 | tests = [
42 | ("4.0", "5.0"),
43 | ("5", "5.0"),
44 | ("1.0_pre2", "1.0_p2"),
45 | ("1.0_alpha2", "1.0_p2"),
46 | ("1.0_alpha1", "1.0_beta1"),
47 | ("1.0_beta3", "1.0_rc3"),
48 | ("1.001000000000000000001", "1.001000000000000000002"),
49 | ("1.00100000000", "1.0010000000000000001"),
50 | ("999999999999999999999999999998", "999999999999999999999999999999"),
51 | ("1.01", "1.1"),
52 | ("1.0-r0", "1.0-r1"),
53 | ("1.0", "1.0-r1"),
54 | ("1.0", "1.0.0"),
55 | ("1.0b", "1.0.0"),
56 | ("1_p1", "1b_p1"),
57 | ("1", "1b"),
58 | ("1.1", "1.1b"),
59 | ("12.2b", "12.2.5"),
60 | ]
61 | for test in tests:
62 | self.assertFalse(
63 | vercmp(test[0], test[1]) >= 0, msg="%s > %s? Wrong!" % (test[0], test[1])
64 | )
65 |
66 | def testVerCmpEqual(self):
67 |
68 | tests = [
69 | ("4.0", "4.0"),
70 | ("1.0", "1.0"),
71 | ("1.0-r0", "1.0"),
72 | ("1.0", "1.0-r0"),
73 | ("1.0-r0", "1.0-r0"),
74 | ("1.0-r1", "1.0-r1"),
75 | ]
76 | for test in tests:
77 | self.assertFalse(
78 | vercmp(test[0], test[1]) != 0, msg="%s != %s? Wrong!" % (test[0], test[1])
79 | )
80 |
81 | def testVerNotEqual(self):
82 |
83 | tests = [
84 | ("1", "2"),
85 | ("1.0_alpha", "1.0_pre"),
86 | ("1.0_beta", "1.0_alpha"),
87 | ("0", "0.0"),
88 | ("1.0-r0", "1.0-r1"),
89 | ("1.0-r1", "1.0-r0"),
90 | ("1.0", "1.0-r1"),
91 | ("1.0-r1", "1.0"),
92 | ("1.0", "1.0.0"),
93 | ("1_p1", "1b_p1"),
94 | ("1b", "1"),
95 | ("1.1b", "1.1"),
96 | ("12.2b", "12.2"),
97 | ]
98 | for test in tests:
99 | self.assertFalse(
100 | vercmp(test[0], test[1]) == 0, msg="%s == %s? Wrong!" % (test[0], test[1])
101 | )
102 |
--------------------------------------------------------------------------------
/tests/test_gentoo.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_gentoo.py
2 | package_url: pkg:ebuild/sys-apps/portage@3.0.13#tests/versions/test_vercmp.py
3 | copyright: Copyright 1998-2016 Gentoo Foundation
4 |
5 | license_expression: GPL-2.0-only
6 | homepage_url: https://gitweb.gentoo.org/proj/portage.git/
7 |
8 | notes: version comparison tests extracted from portage and further stripped down.
9 |
10 | notice_file: gentoo.py.NOTICE
--------------------------------------------------------------------------------
/tests/test_gentoo.py.NOTICE:
--------------------------------------------------------------------------------
1 | +about_resource: test_gentoo.py
2 | +package_url: pkg:ebuild/sys-apps/portage@3.0.13#tests/versions/test_vercmp.py
3 | +copyright: |
4 | + Copyright 1998-2016 Gentoo Foundation
5 | +
6 | +license_expression: GPL-2.0-only
7 | +homepage_url: https://gitweb.gentoo.org/proj/portage.git/
8 | +
9 | +notes: |
10 | + The version comparison utility is extracted from portage and further stripped down.
11 | +
12 | +notice_file: gentoo.py.NOTICE
--------------------------------------------------------------------------------
/tests/test_gentoo_pkgcore.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_gentoo_pkgcore.py
2 | package_url: pkg:pypi/pkgcore@0.11.8#tests/ebuild/test_cpv.py
3 | copyright: Copyright (c) 2006-2019, pkgcore contributors
4 | license_expression: BSD-3-Clause
5 | homepage_url: https://github.com/pkgcore/pkgcore/blob/master/tests/ebuild/test_cpv.py
6 | notes: The version comparison utility code is extracted from pkgcore and further stripped down.
7 | notice_file: gentoo.py.NOTICE
--------------------------------------------------------------------------------
/tests/test_gentoo_pkgcore.py.NOTICE:
--------------------------------------------------------------------------------
1 | Redistribution and use in source and binary forms, with or without
2 | modification, are permitted provided that the following conditions are met:
3 |
4 | 1. Redistributions of source code must retain the above copyright notice,
5 | this list of conditions and the following disclaimer.
6 | 2. Redistributions in binary form must reproduce the above copyright
7 | notice, this list of conditions and the following disclaimer in the
8 | documentation and/or other materials provided with the distribution.
9 | 3. Neither the name of pkgcore nor the names of its
10 | contributors may be used to endorse or promote products derived from
11 | this software without specific prior written permission.
12 |
13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
17 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
23 | POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/tests/test_maven_version.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_maven_version.py
2 | license_expression: apache-2.0
3 | download_url: https://raw.githubusercontent.com/nexB/pymaven/f0fe2c908283916daf2573c484433ed55dc4b907/tests/test_versioning.py
4 | copyright: Copyright (c) SAS Institute Inc.
5 | package_url: pkg:pypi/pymaven-patch@0.2.9#tests/test_versioning.py
6 | notes: this subset of tests has been modified to tests version comparison and parsing
7 | homepage_url: https://github.com/nexB/pymaven
8 | notice_file: test_maven_version.py.NOTICE
--------------------------------------------------------------------------------
/tests/test_maven_version.py.NOTICE:
--------------------------------------------------------------------------------
1 | # Copyright (c) SAS Institute Inc.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
--------------------------------------------------------------------------------
/tests/test_maven_version_range.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) nexB Inc. and others.
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 | from univers.version_constraint import VersionConstraint
8 | from univers.version_range import MavenVersionRange
9 | from univers.versions import MavenVersion
10 |
11 |
12 | def test_maven_version_range_from_native_with_lower_inclusive():
13 | version_range = MavenVersionRange.from_native("[1.0.0,2.0.0)")
14 | assert version_range == MavenVersionRange(
15 | constraints=(
16 | VersionConstraint(comparator=">=", version=MavenVersion(string="1.0.0")),
17 | VersionConstraint(comparator="<", version=MavenVersion(string="2.0.0")),
18 | )
19 | )
20 |
21 |
22 | def test_maven_version_range_from_native_with_nothing_inclusive():
23 | version_range = MavenVersionRange.from_native(" ( 1.0.0 , 2.1.4 ) ")
24 | assert version_range == MavenVersionRange(
25 | constraints=(
26 | VersionConstraint(comparator=">", version=MavenVersion(string="1.0.0")),
27 | VersionConstraint(comparator="<", version=MavenVersion(string="2.1.4")),
28 | )
29 | )
30 |
31 |
32 | def test_maven_version_range_from_native_for_pinned_version():
33 | version_range = MavenVersionRange.from_native("[1.0.0]")
34 | assert version_range == MavenVersionRange(
35 | constraints=(VersionConstraint(comparator="=", version=MavenVersion(string="1.0.0")),)
36 | )
37 |
38 |
39 | def test_maven_version_range_from_native_for_illformed_version():
40 | try:
41 | MavenVersionRange.from_native("(1.0.0]")
42 | assert False, "should have raised an exception"
43 | except ValueError:
44 | assert True
45 |
46 |
47 | def test_maven_version_range_from_native_str_representation():
48 | version_range = MavenVersionRange.from_native("[1.0.0,5.1)")
49 | assert str(version_range) == "vers:maven/>=1.0.0|<5.1"
50 |
51 |
52 | def test_maven_version_range_from_native_for_multiple_version_ranges():
53 | version_range = MavenVersionRange.from_native("[2.0,2.3.1] , [2.4.0,2.12.2) , [2.13.0,2.15.0)")
54 | assert version_range == MavenVersionRange(
55 | constraints=(
56 | VersionConstraint(comparator=">=", version=MavenVersion(string="2.0")),
57 | VersionConstraint(comparator="<=", version=MavenVersion(string="2.3.1")),
58 | VersionConstraint(comparator=">=", version=MavenVersion(string="2.4.0")),
59 | VersionConstraint(comparator="<", version=MavenVersion(string="2.12.2")),
60 | VersionConstraint(comparator=">=", version=MavenVersion(string="2.13.0")),
61 | VersionConstraint(comparator="<", version=MavenVersion(string="2.15.0")),
62 | )
63 | )
64 |
65 |
66 | def test_maven_version_range_from_native_for_multiple_pinned_versions_and_a_range():
67 | version_range = MavenVersionRange.from_native("[2.0] , [2.4.0] , [2.13.0,2.15.0)")
68 | assert version_range == MavenVersionRange(
69 | constraints=(
70 | VersionConstraint(comparator="=", version=MavenVersion(string="2.0")),
71 | VersionConstraint(comparator="=", version=MavenVersion(string="2.4.0")),
72 | VersionConstraint(comparator=">=", version=MavenVersion(string="2.13.0")),
73 | VersionConstraint(comparator="<", version=MavenVersion(string="2.15.0")),
74 | )
75 | )
76 |
--------------------------------------------------------------------------------
/tests/test_nuget.py:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google LLC
2 | # Copyright (c) .NET Foundation. All rights reserved.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 | # pylint: disable=line-too-long
17 | # Many tests are ported from
18 | # https://github.com/NuGet/NuGet.Client/blob/dev/test/NuGet.Core.Tests/NuGet.Versioning.Test/VersionComparerTests.cs
19 |
20 | import unittest
21 |
22 | from univers.nuget import Version
23 | from univers.versions import NugetVersion
24 |
25 |
26 | class NuGetTest(unittest.TestCase):
27 | """NuGet version tests."""
28 |
29 | def setUp(self):
30 | self.maxDiff = None # pylint: disable=invalid-name
31 |
32 | def check_order(self, comparison, first, second):
33 | """Check order."""
34 | comparison(NugetVersion.build_value(first), NugetVersion.build_value(second))
35 |
36 | def test_equals(self):
37 | """Test version equals."""
38 | self.check_order(self.assertEqual, "1.0.0", "1.0.0")
39 | self.check_order(self.assertEqual, "1.0.0-BETA", "1.0.0-beta")
40 | self.check_order(self.assertEqual, "1.0.0-BETA+AA", "1.0.0-beta+aa")
41 | self.check_order(self.assertEqual, "1.0.0-BETA.X.y.5.77.0+AA", "1.0.0-beta.x.y.5.77.0+aa")
42 | self.check_order(self.assertEqual, "1.0.0", "1.0.0+beta")
43 |
44 | self.check_order(self.assertEqual, "1.0", "1.0.0.0")
45 | self.check_order(self.assertEqual, "1.0+test", "1.0.0.0")
46 | self.check_order(self.assertEqual, "1.0.0.1-1.2.A", "1.0.0.1-1.2.A")
47 | self.check_order(self.assertEqual, "1.0.01", "1.0.1.0")
48 |
49 | def test_not_equals(self):
50 | """Test version not equals."""
51 | self.check_order(self.assertNotEqual, "1.0", "1.0.0.1")
52 | self.check_order(self.assertNotEqual, "1.0+test", "1.0.0.1")
53 | self.check_order(self.assertNotEqual, "1.0.0.1-1.2.A", "1.0.0.1-1.2.a.A+A")
54 | self.check_order(self.assertNotEqual, "1.0.01", "1.0.1.2")
55 | self.check_order(self.assertNotEqual, "0.0.0", "1.0.0")
56 | self.check_order(self.assertNotEqual, "1.1.0", "1.0.0")
57 | self.check_order(self.assertNotEqual, "1.0.1", "1.0.0")
58 | self.check_order(self.assertNotEqual, "1.0.0-BETA", "1.0.0-beta2")
59 | self.check_order(self.assertNotEqual, "1.0.0+AA", "1.0.0-beta+aa")
60 | self.check_order(
61 | self.assertNotEqual, "1.0.0-BETA.X.y.5.77.0+AA", "1.0.0-beta.x.y.5.79.0+aa"
62 | )
63 |
64 | def test_less(self):
65 | """Test version less."""
66 | self.check_order(self.assertLess, "0.0.0", "1.0.0")
67 | self.check_order(self.assertLess, "1.0.0", "1.1.0")
68 | self.check_order(self.assertLess, "1.0.0", "1.0.1")
69 | self.check_order(self.assertLess, "1.999.9999", "2.1.1")
70 | self.check_order(self.assertLess, "1.0.0-BETA", "1.0.0-beta2")
71 | self.check_order(self.assertLess, "1.0.0-beta+AA", "1.0.0+aa")
72 | self.check_order(self.assertLess, "1.0.0-BETA", "1.0.0-beta.1+AA")
73 | self.check_order(self.assertLess, "1.0.0-BETA.X.y.5.77.0+AA", "1.0.0-beta.x.y.5.79.0+aa")
74 | self.check_order(self.assertLess, "1.0.0-BETA.X.y.5.79.0+AA", "1.0.0-beta.x.y.5.790.0+abc")
75 |
76 | self.check_order(self.assertLess, "1.0.0", "1.0.0.1")
77 | self.check_order(self.assertLess, "1.0.0.1-alpha", "1.0.0.1-pre")
78 | self.check_order(self.assertLess, "1.0.0-pre", "1.0.0.1-alpha")
79 | self.check_order(self.assertLess, "1.0.0", "1.0.0.1-alpha")
80 | self.check_order(self.assertLess, "0.9.9.1", "1.0.0")
81 |
82 | def test_NugetVersion_hash(self):
83 | vers1 = NugetVersion("1.0.1+23")
84 | vers2 = NugetVersion("1.0.1+23")
85 | assert hash(vers1) == hash(vers2)
86 |
87 | def test_nuget_semver_hash(self):
88 | vers1 = Version.from_string("51.0.0+2")
89 | vers2 = Version.from_string("51.0.0+2")
90 | assert hash(vers1) == hash(vers2)
91 |
--------------------------------------------------------------------------------
/tests/test_nuget.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_nuget.py
2 | package_url: pkg:github/google/osv@0.0.14#lib/osv/nuget_test.py
3 | download_url: https://raw.githubusercontent.com/google/osv/f5647ad2f746685b08debfba0293e442f2fb9945/lib/osv/nuget_test.py
4 | copyright: Copyright 2022 Google LLC
5 |
6 | license_expression: apache-2.0
7 | homepage_url: https://github.com/google/osv/
8 | notice_file: test_nuget.py.NOTICE
--------------------------------------------------------------------------------
/tests/test_nuget.py.NOTICE:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
--------------------------------------------------------------------------------
/tests/test_openssl_versort.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) nexB Inc. and others.
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 | from pathlib import Path
8 |
9 | from commoncode import testcase
10 |
11 | from tests import util_tests
12 | from univers.versions import OpensslVersion
13 |
14 |
15 | class TestOpenssl(testcase.FileBasedTesting):
16 | test_data_dir = str(Path(__file__).resolve().parent / "data" / "openssl")
17 |
18 | def test_openssl_version_sort(self):
19 | versions_file = self.get_test_loc("openssl_all_versions.txt")
20 | with open(versions_file) as f:
21 | all_openssl_versions = f.readlines()
22 | results = [OpensslVersion(x.strip()) for x in all_openssl_versions]
23 | results.sort()
24 | results = [version_to_dict(x) for x in results]
25 | expected_file = self.get_test_loc("openssl_versort_expected.json", must_exist=False)
26 | util_tests.check_results_against_json(results, expected_file)
27 |
28 |
29 | def version_to_dict(version):
30 | return {
31 | "string": version.string,
32 | "normalized_string": version.normalized_string,
33 | "value": str(version.value),
34 | }
35 |
--------------------------------------------------------------------------------
/tests/test_pacman_vercmp.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2009-2020 by Pacman Development Team
2 | # Copyright (c) 2008 by Dan McGee
3 | # SPDX-License-Identifier: Apache-2.0
4 | # this has been significantly modified from the original
5 | #
6 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
7 |
8 | from univers.versions import ArchLinuxVersion
9 |
10 |
11 | def test_same_length():
12 | assert ArchLinuxVersion("1.5.0") == ArchLinuxVersion("1.5.0")
13 | assert ArchLinuxVersion("1.5.1") > ArchLinuxVersion("1.5.0")
14 |
15 |
16 | def test_mixed_length():
17 | assert ArchLinuxVersion("1.5.1") > ArchLinuxVersion("1.5")
18 |
19 |
20 | def test_with_pkgrel_same_length():
21 | assert ArchLinuxVersion("1.5.0-1") == ArchLinuxVersion("1.5.0-1")
22 | assert ArchLinuxVersion("1.5.0-1") < ArchLinuxVersion("1.5.0-2")
23 | assert ArchLinuxVersion("1.5.0-1") < ArchLinuxVersion("1.5.1-1")
24 | assert ArchLinuxVersion("1.5.0-2") < ArchLinuxVersion("1.5.1-1")
25 |
26 |
27 | def test_alpha_dotted_versions():
28 | assert ArchLinuxVersion("1.5.a") > ArchLinuxVersion("1.5")
29 | assert ArchLinuxVersion("1.5.b") > ArchLinuxVersion("1.5.a")
30 | assert ArchLinuxVersion("1.5.1") > ArchLinuxVersion("1.5.b")
31 |
32 |
33 | def test_with_epoch():
34 | assert ArchLinuxVersion("0:1.0") == ArchLinuxVersion("0:1.0")
35 | assert ArchLinuxVersion("0:1.0") < ArchLinuxVersion("0:1.1")
36 | assert ArchLinuxVersion("1:1.0") > ArchLinuxVersion("0:1.0")
37 | assert ArchLinuxVersion("1:1.0") > ArchLinuxVersion("0:1.1")
38 | assert ArchLinuxVersion("1:1.0") < ArchLinuxVersion("2:1.1")
39 |
40 |
41 | def test_with_epoch_mixed_pkgrel():
42 | assert ArchLinuxVersion("1:1.0") > ArchLinuxVersion("0:1.0-1")
43 | assert ArchLinuxVersion("1:1.0-1") > ArchLinuxVersion("0:1.1-1")
44 |
45 |
46 | def test_with_only_one_version_with_epoch():
47 | assert ArchLinuxVersion("0:1.0") == ArchLinuxVersion("1.0")
48 | assert ArchLinuxVersion("0:1.0") < ArchLinuxVersion("1.1")
49 | assert ArchLinuxVersion("0:1.1") > ArchLinuxVersion("1.0")
50 | assert ArchLinuxVersion("1:1.0") > ArchLinuxVersion("1.0")
51 | assert ArchLinuxVersion("1:1.0") > ArchLinuxVersion("1.1")
52 | assert ArchLinuxVersion("1:1.1") > ArchLinuxVersion("1.1")
53 |
54 |
55 | def test_alpha_dot_and_dashes():
56 | assert ArchLinuxVersion("1.5.b-1") == ArchLinuxVersion("1.5.b")
57 | assert ArchLinuxVersion("1.5-1") < ArchLinuxVersion("1.5.b")
58 |
59 |
60 | # def test_same_content_different_separators():
61 | # assert ArchLinuxVersion("2.0") == ArchLinuxVersion("2_0")
62 | # assert ArchLinuxVersion("2.0_a") == ArchLinuxVersion("2_0.a")
63 | # assert ArchLinuxVersion("2.0a ") < ArchLinuxVersion("2.0.a")
64 | # assert ArchLinuxVersion("2___a") == ArchLinuxVersion("2_a")
65 |
66 |
67 | def test_with_pkgrel_mixed_length():
68 | assert ArchLinuxVersion("1.5-1") < ArchLinuxVersion("1.5.1-1")
69 | assert ArchLinuxVersion("1.5-2") < ArchLinuxVersion("1.5.1-1")
70 | assert ArchLinuxVersion("1.5-2") < ArchLinuxVersion("1.5.1-2")
71 |
72 |
73 | def test_with_mixed_pkgrel_inclusion():
74 | assert ArchLinuxVersion("1.5") == ArchLinuxVersion("1.5-1")
75 | assert ArchLinuxVersion("1.5-1") == ArchLinuxVersion("1.5")
76 | assert ArchLinuxVersion("1.1-1") == ArchLinuxVersion("1.1")
77 | assert ArchLinuxVersion("1.0-1") < ArchLinuxVersion("1.1")
78 | assert ArchLinuxVersion("1.1-1") > ArchLinuxVersion("1.0")
79 |
80 |
81 | def test_alphanumeric_versions():
82 | assert ArchLinuxVersion("1.5b-1") < ArchLinuxVersion("1.5-1")
83 | assert ArchLinuxVersion("1.5b ") < ArchLinuxVersion("1.5 ")
84 | assert ArchLinuxVersion("1.5b-1") < ArchLinuxVersion("1.5 ")
85 | assert ArchLinuxVersion("1.5b ") < ArchLinuxVersion("1.5.1")
86 |
87 |
88 | def test_manpage_cases():
89 | assert ArchLinuxVersion("1.0a") < ArchLinuxVersion("1.0alpha")
90 | assert ArchLinuxVersion("1.0alpha") < ArchLinuxVersion("1.0b")
91 | assert ArchLinuxVersion("1.0b") < ArchLinuxVersion("1.0beta")
92 | assert ArchLinuxVersion("1.0beta") < ArchLinuxVersion("1.0rc")
93 | assert ArchLinuxVersion("1.0rc") < ArchLinuxVersion("1.0")
94 |
--------------------------------------------------------------------------------
/tests/test_pacman_vercmp.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_pacman_vercmp.py
2 | license_expression: apache-2.0
3 | download_url: https://git.archlinux.org/pacman.git/plain/test/util/vercmptest.sh
4 | copyright: |
5 | Copyright (c) 2009-2020 by Pacman Development Team
6 | Copyright (c) 2008 by Dan McGee
7 |
8 | package_url: pkg:pypi/pymaven-patch@0.2.9#tests/test_versioning.py
9 | notes: this subset of tests has been modified to tests version comparison and parsing
10 | homepage_url: https://git.archlinux.org/pacman.git
11 | notice_file: test_pacman_vercmp.py.NOTICE
--------------------------------------------------------------------------------
/tests/test_pacman_vercmp.py.NOTICE:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2009-2020 by Pacman Development Team
2 | # Copyright (c) 2008 by Dan McGee
3 | #
4 | # This program is free software; you can redistribute it and/or modify
5 | # it under the terms of the GNU General Public License as published by
6 | # the Free Software Foundation; either version 2 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # This program is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | # GNU General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU General Public License
15 | # along with this program. If not, see .
--------------------------------------------------------------------------------
/tests/test_pypi_version.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) nexB Inc. and others.
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 | from unittest import TestCase
8 |
9 | from packaging import version as packaging_version
10 |
11 | from univers.versions import InvalidVersion
12 | from univers.versions import PypiVersion
13 |
14 | # version comparison is already tested at:
15 | # https://github.com/pypa/packaging/blob/main/tests/test_version.py
16 |
17 |
18 | class TestPYPIVersion(TestCase):
19 | def test_constructor(self):
20 | pypi_version = PypiVersion("2.4.5")
21 | assert pypi_version.value == packaging_version.Version("2.4.5")
22 | self.assertRaises(InvalidVersion, PypiVersion, "2.//////")
23 |
24 | def test_compare(self):
25 | pypi_version = PypiVersion("2.4.5")
26 | assert pypi_version == PypiVersion("2.4.5")
27 | assert pypi_version != PypiVersion("2.4.6")
28 | assert pypi_version > PypiVersion("2.4.4")
29 | assert pypi_version >= PypiVersion("2.4.4")
30 | assert pypi_version < PypiVersion("2.4.6")
31 | assert pypi_version <= PypiVersion("2.4.6")
32 | assert PypiVersion("2.4") == PypiVersion("2.4.0")
33 |
--------------------------------------------------------------------------------
/tests/test_python_semver.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) nexB Inc. and others.
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 | from unittest import TestCase
8 |
9 | import semver
10 |
11 |
12 | class TestPythonSemver(TestCase):
13 | def test_semver_hash(self):
14 | # python-semver doesn't consider build while hashing
15 | vers1 = semver.VersionInfo.parse("1.2.3")
16 | vers2 = semver.VersionInfo.parse("1.2.3+1")
17 | assert hash(vers1) == hash(vers2)
18 |
--------------------------------------------------------------------------------
/tests/test_rpm.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) Facebook, Inc. and its affiliates.
2 | # SPDX-License-Identifier: MIT
3 |
4 | import unittest
5 |
6 | from univers.rpm import RpmVersion
7 | from univers.rpm import compare_rpm_versions
8 |
9 |
10 | class RpmMetadataTestCase(unittest.TestCase):
11 | def test_rpm_compare_versions(self):
12 | # Taste data was generated with:
13 | # rpmdev-vercmp
14 | # which also uses the same Python rpm lib.
15 | #
16 | # This number of test cases is excessive but does show how interesting
17 | # RPM version comparisons can be.
18 | test_evr_data = [
19 | # Non-alphanumeric (except ~) are ignored for equality
20 | ((1, "2", "3"), (1, "2", "3"), 0), # 1:2-3 == 1:2-3
21 | ((1, ":2>", "3"), (1, "-2-", "3"), 0), # 1::2>-3 == 1:-2--3
22 | ((1, "2", "3?"), (1, "2", "?3"), 0), # 1:2-?3 == 1:2-3?
23 | # epoch takes precedence no matter what
24 | ((0, "2", "3"), (1, "2", "3"), -1), # 0:2-3 < 1:2-3
25 | ((1, "1", "3"), (0, "2", "3"), 1), # 1:1-3 > 0:2-3
26 | # version and release trigger the real comparison rules
27 | ((0, "1", "3"), (0, "2", "3"), -1), # 0:1-3 < 0:2-3
28 | ((0, "~2", "3"), (0, "1", "3"), -1), # 0:~2-3 < 0:1-3
29 | ((0, "~", "3"), (0, "1", "3"), -1), # 0:~-3 < 0:1-3
30 | ((0, "1", "3"), (0, "~", "3"), 1), # 0:1-3 > 0:~-3
31 | ((0, "^1", "3"), (0, "^", "3"), 1), # 0:^1-3 > 0:^-3
32 | ((0, "^", "3"), (0, "^1", "3"), -1), # 0:^-3 < 0:^1-3
33 | ((0, "0333", "b"), (0, "0033", "b"), 1), # 0:0333-b > 0:0033-b
34 | ((0, "0033", "b"), (0, "0333", "b"), -1), # 0:0033-b < 0:0333-b
35 | ((0, "3", "~~"), (0, "3", "~~~"), 1), # 0:3-~~ > 0:3-~~~
36 | ((0, "3", "~~~"), (0, "3", "~~"), -1), # 0:3-~~~ < 0:3-~~
37 | ((0, "3", "~~~"), (0, "3", "~~~"), 0), # 0:3-~~~ == 0:3-~~~
38 | ((0, "a2aa", "b"), (0, "a2a", "b"), 1), # 0:a2aa-b > 0:a2a-b
39 | ((0, "33", "b"), (0, "aaa", "b"), 1), # 0:33-b > 0:aaa-b
40 | ]
41 |
42 | for evr1, evr2, expected in test_evr_data:
43 | a = RpmVersion(*evr1)
44 | b = RpmVersion(*evr2)
45 | self.assertEqual(
46 | compare_rpm_versions(a, b),
47 | expected,
48 | f"failed: {evr1}, {evr2}, {expected}",
49 | )
50 |
--------------------------------------------------------------------------------
/tests/test_rpm.py.antlir.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_rpm.py
2 | package_url: pkg:github/facebookincubator/antlir@120b20de91c55244ceacf61f82c5154a28446590#antlir/rpm/tests/test_rpm_metadata.py
3 | copyright: |
4 | Copyright (c) Facebook, Inc. and its affiliates.
5 |
6 | license_expression: mit
7 | homepage_url: https://github.com/facebookincubator/antlir/
8 |
9 | notes: |
10 | This has been substantially modified and enhanced from the original code
11 |
12 | notice_file: test_rpm.py.antlir.NOTICE
--------------------------------------------------------------------------------
/tests/test_rpm.py.mit.NOTICE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Facebook, Inc. and its affiliates.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/tests/test_rpm_vercmp.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) nexB Inc. and others
3 | # Copyright (c) SAS Institute Inc.
4 | # SPDX-License-Identifier: Apache-2.0
5 | # this has been significantly modified from the original
6 | #
7 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
8 |
9 | import io
10 | import os
11 | import re
12 | import unittest
13 |
14 | from univers import rpm as vercmp
15 |
16 | get_vercmp_test = re.compile(
17 | r"(.*)" r"RPMVERCMP\(" r"([^, ]*) *, *" r"([^, ]*) *, *" r"([^\)]*)" r"\).*"
18 | ).match
19 |
20 |
21 | def parse_rpmvercmp_tests(fobj, with_buggy_comparisons=True):
22 | """
23 | Yield triples (version1, version2, comparison result) describing the RPM
24 | version comparison tests found in the rpmvercmp.at test file-like object at
25 | ``fobj`` Optionally include "buggy" upstream tests.
26 | """
27 | for line in fobj:
28 | line = line.strip()
29 | if not line:
30 | continue
31 | if not with_buggy_comparisons and line.startswith("dnl"):
32 | continue
33 | match = get_vercmp_test(line)
34 | if not match:
35 | continue
36 | yield match.group(2), match.group(3), int(match.group(4))
37 |
38 |
39 | class ParserTest(unittest.TestCase):
40 | def test_parse_without_buggy(self):
41 | fobj = io.StringIO(
42 | """
43 | bla
44 | bla
45 | RPMVERCMP(1, 2, -1)
46 | dnl RPMVERCMP(1a, 1b, -1)
47 | """
48 | )
49 | parser = parse_rpmvercmp_tests(fobj, with_buggy_comparisons=False)
50 | expected = [("1", "2", -1)]
51 | assert list(parser) == expected
52 |
53 | def test_parse_with_buggy(self):
54 | fobj = io.StringIO(
55 | """
56 | bla
57 | bla
58 | RPMVERCMP(1, 2, -1)
59 | dnl RPMVERCMP(1a, 1b, -1)
60 | """
61 | )
62 | parser = parse_rpmvercmp_tests(fobj, with_buggy_comparisons=True)
63 | expected = [("1", "2", -1), ("1a", "1b", -1)]
64 | assert list(parser) == expected
65 |
66 |
67 | class VersionCompareTest(unittest.TestCase):
68 | pass
69 |
70 |
71 | def create_test_function(ver1, ver2, expected, name):
72 | """
73 | Return a test function closed on test arguments.
74 | """
75 |
76 | def test_rpm_version(self):
77 | ver1_str = str(ver1).encode("utf-8")
78 | ver2_str = str(ver2).encode("utf-8")
79 | print(f"testing (ver1={ver1_str}, ver2={ver2_str}, expected=expected{expected}")
80 | result = vercmp.vercmp(ver1, ver2)
81 | if result != expected:
82 | assert result == (expected, ver1, ver2)
83 |
84 | test_rpm_version.__name__ = name
85 | return test_rpm_version
86 |
87 |
88 | def get_tests():
89 | """
90 | Yield test function from rpmvercmp.at data.
91 | """
92 | test_file = os.path.join(os.path.dirname(__file__), "data", "rpmvercmp.at")
93 |
94 | with io.open(test_file, encoding="utf-8") as rpmtests:
95 | tests = list(parse_rpmvercmp_tests(rpmtests, with_buggy_comparisons=True))
96 | for test_count, (ver1, ver2, expected) in enumerate(tests, 1):
97 | name = f"test_rpm_version_{test_count}"
98 | yield create_test_function(ver1, ver2, expected, name)
99 |
100 | # Make sure we still test something, in case the m4 file drops
101 | # content this will fail the test
102 | assert test_count > 20
103 |
104 |
105 | def build_tests():
106 | """
107 | Create tests from rpmvercmp.at data and attach them to a test class.
108 | """
109 | for i, test_func in enumerate(get_tests()):
110 | name = f"test_rpm_version_{i}"
111 | setattr(VersionCompareTest, name, test_func)
112 |
113 |
114 | build_tests()
115 |
--------------------------------------------------------------------------------
/tests/test_rpm_vercmp.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_rpm_vercmp.py
2 | license_expression: apache-2.0
3 | download_url: https://raw.githubusercontent.com/nexB/python-rpm-vercmp/15c5c29727c61d5d01e6a7d1a9b956f0d7af41bd/rpm_vercmp/tests/vercmp_test.py
4 | copyright: Copyright (c) SAS Institute Inc.
5 | package_url: pkg:pypi/rpm_vercmp@0.1.2#/rpm_vercmp/tests/vercmp_test.py
6 | notes: this subset of tests has been modified to tests version comparison and parsing
7 | homepage_url: https://github.com/nexB/python-rpm-vercmp
8 | notice_file: test_rpm_vercmp.py.NOTICE
--------------------------------------------------------------------------------
/tests/test_rubygems_gem_requirement.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_rubygems_gem_requirement.py
2 | package_url: pkg:github.com/rubygems/rubygems@5768c2bc5542ce05466d379981a433ba1ee1e10a
3 | copyright: |
4 | Copyright (c) Chad Fowler, Rich Kilmer, Jim Weirich and others.
5 | Portions copyright (c) Engine Yard and Andre Arko
6 |
7 | license_expression: mit
8 | homepage_url: https://github.com/rubygems/rubygems
9 |
10 | notes: This has been substantially modified and enhanced from the original code
11 | to port tests cases to Python. The original license is a choice of MIT or Ruby
12 | license. We selected to use the MIT license here.
13 |
14 | notice_file: test_rubygems_gem_requirement.py.NOTICE
--------------------------------------------------------------------------------
/tests/test_rubygems_gem_requirement.py.NOTICE:
--------------------------------------------------------------------------------
1 | Copyright (c) Chad Fowler, Rich Kilmer, Jim Weirich and others.
2 | Portions copyright (c) Engine Yard and Andre Arko
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | 'Software'), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/tests/test_rubygems_gem_version.py.ABOUT:
--------------------------------------------------------------------------------
1 | about_resource: test_rubygems_gem_version.py
2 | package_url: pkg:github.com/rubygems/rubygems@5768c2bc5542ce05466d379981a433ba1ee1e10a
3 | copyright: |
4 | Copyright (c) Chad Fowler, Rich Kilmer, Jim Weirich and others.
5 | Portions copyright (c) Engine Yard and Andre Arko
6 |
7 | license_expression: mit
8 | homepage_url: https://github.com/rubygems/rubygems
9 |
10 | notes: This has been substantially modified and enhanced from the original code
11 | to port tests cases to Python. The original license is a choice of MIT or Ruby
12 | license. We selected to use the MIT license here.
13 |
14 | notice_file: test_rubygems_gem_version.py.NOTICE
--------------------------------------------------------------------------------
/tests/test_rubygems_gem_version.py.NOTICE:
--------------------------------------------------------------------------------
1 | Copyright (c) Chad Fowler, Rich Kilmer, Jim Weirich and others.
2 | Portions copyright (c) Engine Yard and Andre Arko
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | 'Software'), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/tests/test_skeleton_codestyle.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) nexB Inc. and others. All rights reserved.
3 | # ScanCode is a trademark of nexB Inc.
4 | # SPDX-License-Identifier: Apache-2.0
5 | # See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
6 | # See https://github.com/aboutcode-org/skeleton for support or download.
7 | # See https://aboutcode.org for more information about nexB OSS projects.
8 | #
9 |
10 | import configparser
11 | import subprocess
12 | import unittest
13 |
14 |
15 | class BaseTests(unittest.TestCase):
16 | def test_skeleton_codestyle(self):
17 | """
18 | This test shouldn't run in proliferated repositories.
19 | """
20 | setup_cfg = configparser.ConfigParser()
21 | setup_cfg.read("setup.cfg")
22 | if setup_cfg["metadata"]["name"] != "skeleton":
23 | return
24 |
25 | args = "black --check -l 100 setup.py etc tests"
26 | try:
27 | subprocess.check_output(args.split())
28 | except subprocess.CalledProcessError as e:
29 | print("===========================================================")
30 | print(e.output)
31 | print("===========================================================")
32 | raise Exception(
33 | "Black style check failed; please format the code using:\n"
34 | " python -m black -l 100 setup.py etc tests",
35 | e.output,
36 | ) from e
37 |
--------------------------------------------------------------------------------
/tests/test_vers.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # Copyright (c) nexB Inc. and others.
4 | # SPDX-License-Identifier: Apache-2.0
5 | #
6 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
7 |
8 | import json
9 | import os
10 | import re
11 | import unittest
12 | from unittest.case import expectedFailure
13 |
14 | from univers.version_range import VersionRange
15 |
16 |
17 | def create_test_function(
18 | description,
19 | vers,
20 | canonical_vers,
21 | is_invalid,
22 | scheme,
23 | constraints,
24 | test_func_prefix="test_vers_",
25 | **kwargs
26 | ):
27 | """
28 | Return a new (test function, test_name) where the test_function closed on
29 | test arguments. If is_error is True the tests are expected to raise an
30 | Exception.
31 | """
32 | if is_invalid:
33 |
34 | def test_vers(self):
35 | try:
36 | VersionRange.from_string(vers)
37 | self.fail("Should raise a ValueError")
38 | except ValueError:
39 | pass
40 |
41 | try:
42 | VersionRange.from_string(canonical_vers)
43 | self.fail("Should raise a ValueError")
44 | except ValueError:
45 | pass
46 |
47 | else:
48 |
49 | def test_vers(self):
50 | # parsing the test canonical `vers` then re-building a `vers` from these
51 | # parsed components should return the test canonical `vers`
52 | cano = VersionRange.from_string(vers)
53 | assert canonical_vers == cano.to_string()
54 |
55 | # parsing the test `vers` should return the components parsed from the
56 | # test canonical `vers`
57 | parsed = VersionRange.from_string(canonical_vers)
58 | assert str(cano) == str(parsed)
59 |
60 | # parsing the test `vers` then re-building a `vers` from these parsed
61 | # components should return the test canonical `vers`
62 | assert canonical_vers == parsed.to_string()
63 |
64 | # building a `vers` from the test ranges should return the test
65 | # canonical `vers`
66 | built = VersionRange(scheme, constraints)
67 | assert canonical_vers == built.to_string()
68 |
69 | # create a good function name for use in test discovery
70 | if not description:
71 | description = vers
72 | if is_invalid:
73 | test_func_prefix += "is_invalid_"
74 | test_name = python_safe_name(test_func_prefix + description)
75 | test_vers.__name__ = test_name
76 | test_vers.funcname = test_name
77 | return test_vers, test_name
78 |
79 |
80 | def python_safe_name(s):
81 | """
82 | Return a name derived from string `s` safe to use as a Python function name.
83 |
84 | For example:
85 | >>> s = "not `\\a /`good` -safe name ??"
86 | >>> assert python_safe_name(s) == 'not_good_safe_name'
87 | """
88 | no_punctuation = re.compile(r"[\W_]", re.MULTILINE).sub
89 | s = s.lower()
90 | s = no_punctuation(" ", s)
91 | s = "_".join(s.split())
92 | return s
93 |
94 |
95 | class VersTest(unittest.TestCase):
96 | pass
97 |
98 |
99 | def build_tests(clazz=VersTest, test_file="test-suite-data.json"):
100 | """
101 | Dynamically build test methods for each vers test found in the `test_file`
102 | JSON file and attach a test method to the `clazz` class.
103 | """
104 | test_data_dir = os.path.join(os.path.dirname(__file__), "data")
105 | test_file = os.path.join(test_data_dir, test_file)
106 |
107 | with open(test_file) as tf:
108 | tests_data = json.load(tf)
109 | for items in tests_data:
110 | test_func, test_name = create_test_function(**items)
111 | # TODO: remove once implemented
112 | test_func = expectedFailure(test_func)
113 | # attach that method to the class
114 | setattr(clazz, test_name, test_func)
115 |
116 |
117 | # build_tests()
118 |
--------------------------------------------------------------------------------
/tests/test_version_comparison.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) nexB Inc. and others.
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 | import pytest
8 |
9 | from univers import versions
10 |
11 |
12 | @pytest.mark.parametrize(
13 | "version_class",
14 | [
15 | versions.SemverVersion,
16 | versions.GolangVersion,
17 | versions.PypiVersion,
18 | versions.GenericVersion,
19 | versions.ComposerVersion,
20 | versions.NginxVersion,
21 | versions.ArchLinuxVersion,
22 | versions.DebianVersion,
23 | versions.RpmVersion,
24 | versions.MavenVersion,
25 | versions.NugetVersion,
26 | versions.GentooVersion,
27 | versions.OpensslVersion,
28 | versions.LegacyOpensslVersion,
29 | versions.AlpineLinuxVersion,
30 | ],
31 | )
32 | def test_version_comparators_are_working(version_class):
33 | assert version_class("1.0.0") == version_class("1.0.0")
34 | assert version_class("1.0.0") != version_class("1.0.1")
35 | assert version_class("1.0.0") < version_class("1.0.1")
36 | assert version_class("1.0.1") > version_class("1.0.0")
37 | assert version_class("1.0.0") <= version_class("1.0.1")
38 | assert version_class("1.0.1") >= version_class("1.0.0")
39 | assert version_class("1.0.0") <= version_class("1.0.0")
40 | assert version_class("1.0.0") >= version_class("1.0.0")
41 |
--------------------------------------------------------------------------------
/tests/test_version_constraint.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) nexB Inc. and others.
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 | import pytest
8 |
9 | from univers import versions
10 | from univers.version_constraint import VersionConstraint
11 |
12 |
13 | @pytest.mark.parametrize(
14 | "version, spec, expected",
15 | [
16 | ("2.7", "<=3.4", True),
17 | ("2.7.1", "<=3.4", True),
18 | ("2.7.1rc1", "<=3.4", True),
19 | ("2.7.15", "<=3.4", True),
20 | ("2.7.15rc1", "<=3.4", True),
21 | ("2.7", ">=3.4", False),
22 | ("2.7.1", ">=3.4", False),
23 | ("2.7.1rc1", ">=3.4", False),
24 | ("2.7.15", ">=3.4", False),
25 | ("2.7.15rc1", ">=3.4", False),
26 | ("0.0.0", ">=1.0.0", False),
27 | ("1.2.3", ">=1.0.0", True),
28 | ("1.2.3b1", ">=1.0.0", True),
29 | ("1.0.1b1", ">=1.0.0", True),
30 | ("1.0.0b1", ">=1.0.0", False),
31 | ("1.0.0b1", ">=1.0.0b1", True),
32 | ],
33 | )
34 | def test_pypi_comparison(version, spec, expected):
35 | version = versions.PypiVersion(version)
36 | constraint = VersionConstraint.from_string(
37 | string=spec,
38 | version_class=versions.PypiVersion,
39 | )
40 | assert (version in constraint) is expected
41 |
42 |
43 | @pytest.mark.parametrize(
44 | "version, spec, expected",
45 | [
46 | ("2.7.1", "<=3.4.3", True),
47 | ("1.1.0", ">1.0.0", True),
48 | ("2.0.0", "<=2.0.0", True),
49 | ("1.9999.9999", "<=2.0.0", True),
50 | ("0.2.9", "<=2.0.0", True),
51 | ("1.9999.9999", "<2.0.0", True),
52 | ("0.1.1-alpha", ">=0.1.1-beta", False),
53 | ("1.0.0+20130313144700", "=1.0.0+9999999999", False),
54 | ],
55 | )
56 | def test_semver_comparison(version, spec, expected):
57 | version = versions.SemverVersion(version)
58 | constraint = VersionConstraint.from_string(
59 | string=spec,
60 | version_class=versions.SemverVersion,
61 | )
62 | assert (version in constraint) is expected
63 |
64 |
65 | @pytest.mark.parametrize(
66 | "original, inverted",
67 | [
68 | (">2.7.1", "<=2.7.1"),
69 | ("!=1.1.0", "=1.1.0"),
70 | ("=2.0.0", "!=2.0.0"),
71 | ("<=0.9999.9999", ">0.9999.9999"),
72 | (">=0.2.9", "<0.2.9"),
73 | ("<1.9999.9999", ">=1.9999.9999"),
74 | ("*", None),
75 | ],
76 | )
77 | def test_invert_opertaion(original, inverted):
78 | constraint = VersionConstraint.from_string(
79 | string=original,
80 | version_class=versions.SemverVersion,
81 | )
82 | if inverted:
83 | inverted_constraint = VersionConstraint.from_string(
84 | string=inverted,
85 | version_class=versions.SemverVersion,
86 | )
87 | assert constraint.invert() == inverted_constraint
88 | else:
89 | assert constraint.invert() is None
90 |
--------------------------------------------------------------------------------
/tests/util_tests.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) nexB Inc. and others.
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 | # Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
6 |
7 | import json
8 | import os
9 |
10 | import saneyaml
11 |
12 | """
13 | Shared testing utilities
14 | """
15 |
16 | # Used for tests to regenerate fixtures with regen=True: run a test with this
17 | # env. var set to any value to regenarte expected result files. For example with:
18 | # "UNIVERS_REGEN_TEST_FIXTURES=yes pytest -vvs tests"
19 | UNIVERS_REGEN_TEST_FIXTURES = os.getenv("UNIVERS_REGEN_TEST_FIXTURES", False)
20 |
21 |
22 | def check_results_against_json(
23 | results,
24 | expected_file,
25 | regen=UNIVERS_REGEN_TEST_FIXTURES,
26 | ):
27 | """
28 | Check the JSON-serializable mapping or sequence ``results`` against the
29 | expected data in the JSON ``expected_file``
30 |
31 | If ``regen`` is True, the ``expected_file`` is overwritten with the
32 | ``results`` data. This is convenient for updating tests expectations.
33 | """
34 | if regen:
35 | with open(expected_file, "w") as reg:
36 | json.dump(results, reg, indent=2, separators=(",", ": "))
37 | expected = results
38 | else:
39 | with open(expected_file) as exp:
40 | expected = json.load(exp)
41 |
42 | # NOTE we redump the JSON as a YAML string for easier display of
43 | # the failures comparison/diff
44 | if results != expected:
45 | assert saneyaml.dump(results) == saneyaml.dump(expected)
46 |
--------------------------------------------------------------------------------