diff -Nru setuptools-scm-3.4.3+really3.3.3/appveyor.yml setuptools-scm-4.1.2/appveyor.yml --- setuptools-scm-3.4.3+really3.3.3/appveyor.yml 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/appveyor.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -environment: - matrix: - - PYTHON: "C:\\Python27" - TOXENV: "py-test" - - - PYTHON: "C:\\Python27-x64" - TOXENV: "py-test" - - - PYTHON: "C:\\Python34" - TOXENV: "py-test" - - - PYTHON: "C:\\Python34-x64" - TOXENV: "py-test" - -init: - - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" - - - ECHO "Updating Environment" - - python -m pip install -U setuptools - - python -m pip install -U pip - - python -m pip install -U wheel - - python -m pip install -U tox - - -install: - # Check that we have the expected version and architecture for Python - - python -c "import sys, os;sys.stdout.write(str(sys.version) + os.linesep)" - - "python -c \"import struct; print(struct.calcsize('P') * 8)\"" - - python -m pip list - -build: false # Not a C# project, build stuff at the test step instead. - -test_script: - # Build the compiled extension and run the project tests - - python -m tox - -after_test: - # If tests are successful, create a whl package for the project. - - "%CMD_IN_ENV% python setup.py bdist_wheel" - - ps: "ls dist" - -artifacts: - # Archive the generated wheel package in the ci.appveyor.com build report. - - path: dist\* - diff -Nru setuptools-scm-3.4.3+really3.3.3/CHANGELOG.rst setuptools-scm-4.1.2/CHANGELOG.rst --- setuptools-scm-3.4.3+really3.3.3/CHANGELOG.rst 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/CHANGELOG.rst 2020-05-31 12:31:56.000000000 +0000 @@ -1,3 +1,85 @@ +v4.1.2 +======= + +* disallow git tags without dots by default again - #449 + +v4.1.1 +======= + +* drop jaraco.windows from pyproject.toml, allows for wheel builds on python2 + + +v4.1.0 +======= + +* include python 3.9 via the deadsnakes action +* return release_branch_semver scheme (it got dropped in a bad rebase) +* undo the devendoring of the samefile backport for python2.7 on windows +* re-enable the building of universal wheels +* fix handling of missing git/hg on python2.7 (python 3 exceptions where used) +* correct the tox flake8 invocation +* trigger builds on tags again + +v4.0.0 +====== + +* Add ``parentdir_project_version`` to support installs from GitHub release + tarballs. +* use Coordinated Universal Time (UTC) +* switch to github actions for ci +* fix documentation for ``tag_regex`` and add support for single digit versions +* document handling of enterprise distros with unsupported setuptools versions #312 +* switch to declarative metadata +* drop the internal copy of samefile and use a dependency on jaraco.windows on legacy systems +* select git tags based on the presence of numbers instead of dots +* enable getting a version form a parent folder prefix +* add release-branch-semver version scheme +* make global configuration available to version metadata +* drop official support for python 3.4 + +v3.5.0 +====== + +* add ``no-local-version`` local scheme and improve documentation for schemes + +v3.4.4 +====== + +* fix #403: also sort out resource warnings when dealing with git file finding + +v3.4.3 +====== + +* fix #399: ensure the git file finder terminates subprocess after reading archive + +v3.4.2 +====== + +* fix #395: correctly transfer tag regex in the Configuration constructor +* rollback --first-parent for git describe as it turns out to be a regression for some users + +v3.4.1 +====== + +* pull in #377 to fix #374: correctly set up the default version scheme for pyproject usage. + this bugfix got missed when ruushing the release. + +v3.4.0 +====== + +* fix #181 - add support for projects built under setuptools declarative config + by way of the setuptools.finalize_distribution_options hook in Setuptools 42. + +* fix #305 - ensure the git file finder closes filedescriptors even when errors happen + +* fix #381 - clean out env vars from the git hook system to ensure correct function from within + +* modernize docs wrt importlib.metadata + +*edited* + +* use --first-parent for git describe + v3.3.3 ====== diff -Nru setuptools-scm-3.4.3+really3.3.3/debian/changelog setuptools-scm-4.1.2/debian/changelog --- setuptools-scm-3.4.3+really3.3.3/debian/changelog 2020-06-20 19:52:14.000000000 +0000 +++ setuptools-scm-4.1.2/debian/changelog 2020-07-17 10:28:26.000000000 +0000 @@ -1,3 +1,33 @@ +setuptools-scm (4.1.2-3ubuntu1) groovy; urgency=medium + + * Merge from Debian unstable, remaining changes: + - Build-depend on python-all, not python. + - Invoke python2, not python. + + -- Dmitry Shachnev Fri, 17 Jul 2020 13:28:26 +0300 + +setuptools-scm (4.1.2-3) unstable; urgency=medium + + * Improve the patch to accept debian version tags. + + -- Julien Puydt Sat, 11 Jul 2020 15:59:12 +0200 + +setuptools-scm (4.1.2-2) unstable; urgency=medium + + * Add a patch to fix a typo. + * Add a patch to accept debian version tags. (Closes: #933739) + + -- Julien Puydt Sat, 11 Jul 2020 15:09:40 +0200 + +setuptools-scm (4.1.2-1) unstable; urgency=medium + + * Update team mailing list address. + * New upstream release (Closes: #964800). + * Drop the only patch (upstreamed). + * Make upstream testsuite run. + + -- Julien Puydt Sat, 11 Jul 2020 00:09:09 +0200 + setuptools-scm (3.4.3+really3.3.3-5ubuntu2) groovy; urgency=medium * Invoke python2, not python. diff -Nru setuptools-scm-3.4.3+really3.3.3/debian/control setuptools-scm-4.1.2/debian/control --- setuptools-scm-3.4.3+really3.3.3/debian/control 2020-06-20 19:37:00.000000000 +0000 +++ setuptools-scm-4.1.2/debian/control 2020-07-17 10:28:26.000000000 +0000 @@ -1,6 +1,6 @@ Source: setuptools-scm Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: Debian Python Modules Team +XSBC-Original-Maintainer: Debian Python Modules Team Uploaders: Julien Puydt Section: python Priority: optional diff -Nru setuptools-scm-3.4.3+really3.3.3/debian/patches/accept_debian_tags.patch setuptools-scm-4.1.2/debian/patches/accept_debian_tags.patch --- setuptools-scm-3.4.3+really3.3.3/debian/patches/accept_debian_tags.patch 1970-01-01 00:00:00.000000000 +0000 +++ setuptools-scm-4.1.2/debian/patches/accept_debian_tags.patch 2020-07-17 10:28:26.000000000 +0000 @@ -0,0 +1,16 @@ +Description: accept debian version tags +Author: Julien Puydt +Forwarded: Debian-specific + +--- setuptools-scm.orig/src/setuptools_scm/git.py ++++ setuptools-scm/src/setuptools_scm/git.py +@@ -149,5 +149,9 @@ + dirty = False + + tag, number, node = describe_output.rsplit("-", 2) ++ if tag.startswith('debian/'): ++ tag = tag[7:] ++ if tag.startswith('upstream/'): ++ tag = tag[9:] + number = int(number) + return tag, number, node, dirty diff -Nru setuptools-scm-3.4.3+really3.3.3/debian/patches/clean_file_close.patch setuptools-scm-4.1.2/debian/patches/clean_file_close.patch --- setuptools-scm-3.4.3+really3.3.3/debian/patches/clean_file_close.patch 2020-06-05 15:17:09.000000000 +0000 +++ setuptools-scm-4.1.2/debian/patches/clean_file_close.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -Description: cleanly close a file so tests don't break -Author: Julien Puydt -Forwarded: https://github.com/pypa/setuptools_scm/issues/403 - ---- setuptools-scm.orig/src/setuptools_scm/file_finder_git.py -+++ setuptools-scm/src/setuptools_scm/file_finder_git.py -@@ -4,6 +4,7 @@ - import logging - from .file_finder import scm_find_files - from .utils import trace -+from contextlib import closing - - log = logging.getLogger(__name__) - -@@ -28,16 +29,16 @@ - - - def _git_interpret_archive(fd, toplevel): -- tf = tarfile.open(fileobj=fd, mode="r|*") -- git_files = set() -- git_dirs = {toplevel} -- for member in tf.getmembers(): -- name = os.path.normcase(member.name).replace("/", os.path.sep) -- if member.type == tarfile.DIRTYPE: -- git_dirs.add(name) -- else: -- git_files.add(name) -- return git_files, git_dirs -+ with tarfile.open(fileobj=fd, mode="r|*") as tf: -+ git_files = set() -+ git_dirs = {toplevel} -+ for member in tf.getmembers(): -+ name = os.path.normcase(member.name).replace("/", os.path.sep) -+ if member.type == tarfile.DIRTYPE: -+ git_dirs.add(name) -+ else: -+ git_files.add(name) -+ return git_files, git_dirs - - - def _git_ls_files_and_dirs(toplevel): -@@ -46,7 +47,8 @@ - cmd = ["git", "archive", "--prefix", toplevel + os.path.sep, "HEAD"] - proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, cwd=toplevel) - try: -- return _git_interpret_archive(proc.stdout, toplevel) -+ with closing(proc.stdout): -+ return _git_interpret_archive(proc.stdout, toplevel) - except Exception: - if proc.wait() != 0: - log.exception("listing git files failed - pretending there aren't any") diff -Nru setuptools-scm-3.4.3+really3.3.3/debian/patches/fix_typo.patch setuptools-scm-4.1.2/debian/patches/fix_typo.patch --- setuptools-scm-3.4.3+really3.3.3/debian/patches/fix_typo.patch 1970-01-01 00:00:00.000000000 +0000 +++ setuptools-scm-4.1.2/debian/patches/fix_typo.patch 2020-07-17 10:28:26.000000000 +0000 @@ -0,0 +1,15 @@ +Description: fix typo +Author: Julien Puydt +Forwarded: https://github.com/pypa/setuptools_scm/issues/463 + +--- setuptools-scm.orig/src/setuptools_scm/version.py ++++ setuptools-scm/src/setuptools_scm/version.py +@@ -207,7 +207,7 @@ + ) + parsed_version = _parse_tag(tag, preformatted, config) + trace("version", tag, "->", parsed_version) +- assert parsed_version is not None, "cant parse version %s" % tag ++ assert parsed_version is not None, "can't parse version %s" % tag + return ScmVersion( + parsed_version, distance, node, dirty, preformatted, branch, config, **kw + ) diff -Nru setuptools-scm-3.4.3+really3.3.3/debian/patches/series setuptools-scm-4.1.2/debian/patches/series --- setuptools-scm-3.4.3+really3.3.3/debian/patches/series 2020-06-05 15:17:09.000000000 +0000 +++ setuptools-scm-4.1.2/debian/patches/series 2020-07-17 10:28:26.000000000 +0000 @@ -1 +1,2 @@ -clean_file_close.patch +accept_debian_tags.patch +fix_typo.patch diff -Nru setuptools-scm-3.4.3+really3.3.3/debian/tests/control setuptools-scm-4.1.2/debian/tests/control --- setuptools-scm-3.4.3+really3.3.3/debian/tests/control 2020-06-05 15:17:09.000000000 +0000 +++ setuptools-scm-4.1.2/debian/tests/control 2020-07-17 10:28:26.000000000 +0000 @@ -1,2 +1,2 @@ Tests: testsuite -Depends: git, mercurial, python3-pytest, python3-setuptools, python3-setuptools-scm +Depends: git, mercurial, python3-pytest, python3-setuptools, python3-setuptools-scm, python3-toml diff -Nru setuptools-scm-3.4.3+really3.3.3/default.nix setuptools-scm-4.1.2/default.nix --- setuptools-scm-3.4.3+really3.3.3/default.nix 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/default.nix 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -{pkgs ? import {}}: -with pkgs.pythonPackages; -buildPythonPackage { - name = "setuptools_scm"; - src = ./.; - version = "git"; - buildInputs = [ - setuptools - pip - pytest - pkgs.git - pkgs.mercurial - ]; -} diff -Nru setuptools-scm-3.4.3+really3.3.3/.github/FUNDING.yml setuptools-scm-4.1.2/.github/FUNDING.yml --- setuptools-scm-3.4.3+really3.3.3/.github/FUNDING.yml 1970-01-01 00:00:00.000000000 +0000 +++ setuptools-scm-4.1.2/.github/FUNDING.yml 2020-05-31 12:31:56.000000000 +0000 @@ -0,0 +1 @@ +tidelift: pypi/setuptools-scm diff -Nru setuptools-scm-3.4.3+really3.3.3/.github/workflows/pre-commit.yml setuptools-scm-4.1.2/.github/workflows/pre-commit.yml --- setuptools-scm-3.4.3+really3.3.3/.github/workflows/pre-commit.yml 1970-01-01 00:00:00.000000000 +0000 +++ setuptools-scm-4.1.2/.github/workflows/pre-commit.yml 2020-05-31 12:31:56.000000000 +0000 @@ -0,0 +1,20 @@ +name: pre-commit + +on: + pull_request: + push: + branches: [master] + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-python@v1 + - name: set PY + run: echo "::set-env name=PY::$(python --version --version | sha256sum | cut -d' ' -f1)" + - uses: actions/cache@v1 + with: + path: ~/.cache/pre-commit + key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }} + - uses: pre-commit/action@v1.0.0 diff -Nru setuptools-scm-3.4.3+really3.3.3/.github/workflows/python-tests.yml setuptools-scm-4.1.2/.github/workflows/python-tests.yml --- setuptools-scm-3.4.3+really3.3.3/.github/workflows/python-tests.yml 1970-01-01 00:00:00.000000000 +0000 +++ setuptools-scm-4.1.2/.github/workflows/python-tests.yml 2020-05-31 12:31:56.000000000 +0000 @@ -0,0 +1,155 @@ +name: python tests+artifacts+release + +on: + pull_request: + push: + branches: + - master + tags: + - "v*" + release: + +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + python_version: [ '2.7', '3.5', '3.6', '3.7', '3.8', 'pypy2', 'pypy3' ] + os: [windows-latest, ubuntu-latest] #, macos-latest] + exclude: + - os: windows-latest + python_version: "pypy2" + include: + - os: ubuntu-latest + python_version: '3.9-dev' + + name: ${{ matrix.os }} - Python ${{ matrix.python_version }} + steps: + - uses: actions/checkout@v1 + - name: Setup python + uses: actions/setup-python@v2 + if: matrix.python_version != '3.9-dev' + with: + python-version: ${{ matrix.python_version }} + architecture: x64 + - name: Set up Python ${{ matrix.python_version }} (deadsnakes) + uses: deadsnakes/action@v1.0.0 + if: matrix.python_version == '3.9-dev' + with: + python-version: ${{ matrix.python_version }} + architecture: x64 + - run: pip install -U setuptools + - run: pip install -e .[toml] pytest + - run: pytest + + check_selfinstall: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python_version: [ '2.7', '3.5', '3.6', '3.7', '3.8', 'pypy2', 'pypy3' ] + name: check self install - Python ${{ matrix.python_version }} + steps: + - uses: actions/checkout@v1 + - name: Setup python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python_version }} + architecture: x64 + # self install testing needs some clarity + # so its being executed without any other tools running + - run: pip install -U setuptools + - run: python setup.py egg_info + - run: python setup.py sdist + - run: easy_install dist/* + - run: python testing/check_self_install.py + + + eggs: + runs-on: ubuntu-latest + + needs: [test] + name: Python ${{ matrix.python_version }} eggs + strategy: + matrix: + python_version: ['2.7', '3.5', '3.6', '3.7', '3.8', '3.9-dev'] + steps: + - uses: actions/checkout@v1 + - name: Setup python + uses: actions/setup-python@v2 + if: matrix.python_version != '3.9-dev' + with: + python-version: ${{ matrix.python_version }} + architecture: x64 + - name: Set up Python ${{ matrix.python_version }} (deadsnakes) + uses: deadsnakes/action@v1.0.0 + if: matrix.python_version == '3.9-dev' + with: + python-version: ${{ matrix.python_version }} + architecture: x64 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install --upgrade wheel setuptools + - run: python setup.py egg_info + - name: Build package + run: python setup.py bdist_egg + - uses: actions/upload-artifact@v2 + with: + name: dist + path: dist + + dist: + runs-on: ubuntu-latest + + needs: [test] + name: Python bdist/wheel + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-python@v1 + with: + python-version: "3.8" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install --upgrade wheel setuptools + - run: python setup.py egg_info + - name: Build package + run: python setup.py bdist_wheel sdist + - uses: actions/upload-artifact@v2 + with: + name: dist + path: dist + + + dist_check: + runs-on: ubuntu-latest + needs: [eggs, dist] + steps: + - uses: actions/setup-python@v2 + with: + python-version: "3.8" + - name: Install dependencies + run: pip install twine + - uses: actions/download-artifact@v2 + with: + name: dist + path: dist + - run: twine check dist/* + + dist_upload: + + runs-on: ubuntu-latest + if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') + needs: [dist_check] + steps: + - uses: actions/download-artifact@v2 + with: + name: dist + path: dist + - name: Publish package to PyPI + uses: pypa/gh-action-pypi-publish@master + with: + user: __token__ + password: ${{ secrets.pypi_token }} diff -Nru setuptools-scm-3.4.3+really3.3.3/.gitignore setuptools-scm-4.1.2/.gitignore --- setuptools-scm-3.4.3+really3.3.3/.gitignore 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/.gitignore 2020-05-31 12:31:56.000000000 +0000 @@ -20,6 +20,8 @@ # Distribution / packaging .env/ env/ +.venv/ +venv/ build/ dist/ .eggs/ diff -Nru setuptools-scm-3.4.3+really3.3.3/MANIFEST.in setuptools-scm-4.1.2/MANIFEST.in --- setuptools-scm-3.4.3+really3.3.3/MANIFEST.in 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/MANIFEST.in 2020-05-31 12:31:56.000000000 +0000 @@ -1,5 +1,4 @@ exclude *.nix -exclude appveyor.yml exclude .travis.yaml exclude .pre-commit-config.yaml include *.py @@ -7,3 +6,5 @@ include tox.ini include *.rst include LICENSE +include *.toml +recursive-include testing *.bash diff -Nru setuptools-scm-3.4.3+really3.3.3/.pre-commit-config.yaml setuptools-scm-4.1.2/.pre-commit-config.yaml --- setuptools-scm-3.4.3+really3.3.3/.pre-commit-config.yaml 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/.pre-commit-config.yaml 2020-05-31 12:31:56.000000000 +0000 @@ -1,13 +1,12 @@ exclude: setuptools_scm/win_py31_compat.py repos: - repo: https://github.com/ambv/black - rev: 18.4a4 + rev: 19.10b0 hooks: - id: black args: [--safe, --quiet] - python_version: python3.6 - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v1.2.3 + rev: v2.5.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -15,6 +14,6 @@ - id: debug-statements - id: flake8 - repo: https://github.com/asottile/pyupgrade - rev: v1.2.0 + rev: v2.3.0 hooks: - id: pyupgrade diff -Nru setuptools-scm-3.4.3+really3.3.3/pyproject.toml setuptools-scm-4.1.2/pyproject.toml --- setuptools-scm-3.4.3+really3.3.3/pyproject.toml 1970-01-01 00:00:00.000000000 +0000 +++ setuptools-scm-4.1.2/pyproject.toml 2020-05-31 12:31:56.000000000 +0000 @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools>=34.4", "wheel"] +build-backend = "setuptools.build_meta" diff -Nru setuptools-scm-3.4.3+really3.3.3/README.rst setuptools-scm-4.1.2/README.rst --- setuptools-scm-3.4.3+really3.3.3/README.rst 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/README.rst 2020-05-31 12:31:56.000000000 +0000 @@ -5,14 +5,75 @@ in SCM metadata instead of declaring them as the version argument or in a SCM managed file. -It also handles file finders for the supported SCMs. +Additionally ``setuptools_scm`` provides setuptools with a list of files that are managed by the SCM +(i.e. it automatically adds all of the SCM-managed files to the sdist). +Unwanted files must be excluded by discarding them via ``MANIFEST.in``. .. image:: https://travis-ci.org/pypa/setuptools_scm.svg?branch=master :target: https://travis-ci.org/pypa/setuptools_scm +.. image:: https://tidelift.com/badges/package/pypi/setuptools-scm + :target: https://tidelift.com/subscription/pkg/pypi-setuptools-scm?utm_source=pypi-setuptools-scm&utm_medium=readme + + +``pyproject.toml`` usage +------------------------ + +The preferred way to configure ``setuptools_scm`` is to author +settings in a ``tool.setuptools_scm`` section of ``pyproject.toml``. + +This feature requires Setuptools 42 or later, released in Nov, 2019. +If your project needs to support build from sdist on older versions +of Setuptools, you will need to also implement the ``setup.py usage`` +for those legacy environments. + +First, ensure that ``setuptools_scm`` is present during the project's +built step by specifying it as one of the build requirements. + +.. code:: toml + + # pyproject.toml + [build-system] + requires = ["setuptools>=42", "wheel", "setuptools_scm[toml]>=3.4"] + +Note that the ``toml`` extra must be supplied. + +That will be sufficient to require ``setuptools_scm`` for projects +that support PEP 518 (`pip `_ and +`pep517 `_). Many tools, +especially those that invoke ``setup.py`` for any reason, may +continue to rely on ``setup_requires``. For maximum compatibility +with those uses, consider also including a ``setup_requires`` directive +(described below in ``setup.py usage`` and ``setup.cfg``). + +To enable version inference, add this section to your pyproject.toml: + +.. code:: toml + + # pyproject.toml + [tool.setuptools_scm] + +Including this section is comparable to supplying +``use_scm_version=True`` in ``setup.py``. Additionally, +include arbitrary keyword arguments in that section +to be supplied to ``get_version()``. For example: + +.. code:: toml + + # pyproject.toml + + [tool.setuptools_scm] + write_to = "pkg/version.py" + + ``setup.py`` usage ------------------ +The following settings are considered legacy behavior and +superseded by the ``pyproject.toml`` usage, but for maximal +compatibility, projects may also supply the configuration in +this older form. + To use ``setuptools_scm`` just modify your project's ``setup.py`` file like this: @@ -39,25 +100,16 @@ from setuptools import setup setup( ..., - use_scm_version = {"root": "..", "relative_to": __file__}, + use_scm_version = { + "root": "..", + "relative_to": __file__, + "local_scheme": "node-and-timestamp" + }, setup_requires=['setuptools_scm'], ..., ) -Once configured, you can access the version number in your package via -``pkg_resources`` (`PEP-0396 `_). For -example: - -.. code:: python - - from pkg_resources import get_distribution, DistributionNotFound - try: - __version__ = get_distribution(__name__).version - except DistributionNotFound: - # package is not installed - pass - -You can also confirm the version number locally via ``setup.py``: +You can confirm the version number locally via ``setup.py``: .. code-block:: shell @@ -70,8 +122,8 @@ not defined in ``setup.cfg``. -``setup.cfg`` -------------- +``setup.cfg`` usage +------------------- If using `setuptools 30.3.0 `_ @@ -130,6 +182,43 @@ See `setup.py Usage`_ above for how to use this within ``setup.py``. +Retrieving package version at runtime +------------------------------------- + +If you have opted not to hardcode the version number inside the package, +you can retrieve it at runtime from PEP-0566_ metadata using +``importlib.metadata`` from the standard library +or the `importlib_metadata`_ backport: + +.. code:: python + + from importlib.metadata import version, PackageNotFoundError + + try: + __version__ = version(__name__) + except PackageNotFoundError: + # package is not installed + pass + +Alternatively, you can use ``pkg_resources`` which is included in +``setuptools``: + +.. code:: python + + from pkg_resources import get_distribution, DistributionNotFound + + try: + __version__ = get_distribution(__name__).version + except DistributionNotFound: + # package is not installed + pass + +This does place a runtime dependency on ``setuptools``. + +.. _PEP-0566: https://www.python.org/dev/peps/pep-0566/ +.. _importlib_metadata: https://pypi.org/project/importlib-metadata/ + + Usage from Sphinx ----------------- @@ -174,9 +263,9 @@ distance and clean: ``{next_version}.dev{distance}+{scm letter}{revision hash}`` no distance and not clean: - ``{tag}+dYYYMMMDD`` + ``{tag}+dYYYYMMDD`` distance and not clean: - ``{next_version}.dev{distance}+{scm letter}{revision hash}.dYYYMMMDD`` + ``{next_version}.dev{distance}+{scm letter}{revision hash}.dYYYYMMDD`` The next version is calculated by adding ``1`` to the last numeric component of the tag. @@ -212,6 +301,26 @@ Git archives are not supported due to Git shortcomings +File finders hook makes most of MANIFEST.in unnecessary +------------------------------------------------------- + +``setuptools_scm`` implements a `file_finders +`_ +entry point which returns all files tracked by your SCM. This eliminates +the need for a manually constructed ``MANIFEST.in`` in most cases where this +would be required when not using ``setuptools_scm``, namely: + +* To ensure all relevant files are packaged when running the ``sdist`` command. + +* When using `include_package_data `_ + to include package data as part of the ``build`` or ``bdist_wheel``. + +``MANIFEST.in`` may still be used: anything defined there overrides the hook. +This is mostly useful to exclude files tracked in your SCM from packages, +although in principle it can be used to explicitly include non-tracked files +too. + + Configuration parameters ------------------------ @@ -254,16 +363,28 @@ supplying ``__file__``. :tag_regex: - A Python regex string to extract the version part from any SCM tag. - The regex needs to contain three named groups prefix, version and suffix, - where ``version`` captures the actual version information. + A Python regex string to extract the version part from any SCM tag. + The regex needs to contain either a single match group, or a group + named ``version``, that captures the actual version information. Defaults to the value of ``setuptools_scm.config.DEFAULT_TAG_REGEX`` (see `config.py `_). +:parentdir_prefix_version: + If the normal methods for detecting the version (SCM version, + sdist metadata) fail, and the parent directory name starts with + ``parentdir_prefix_version``, then this prefix is stripped and the rest of + the parent directory name is matched with ``tag_regex`` to get a version + string. If this parameter is unset (the default), then this fallback is + not used. + + This is intended to cover GitHub's "release tarballs", which extract into + directories named ``projectname-tag/`` (in which case + ``parentdir_prefix_version`` can be set e.g. to ``projectname-``). + :fallback_version: A version string that will be used if no other method for detecting the - version worked (e.g., when using a tarball with no metadata). If this is + version worked (e.g., when using a tarball with no metadata). If this is unset (the default), setuptools_scm will error if it fails to detect the version. @@ -300,7 +421,8 @@ setup( use_scm_version={ - 'write_to': 'version.txt', + 'write_to': 'version.py', + 'write_to_template': '__version__ = "{version}"', 'tag_regex': r'^(?Pv)?(?P[^\+]+)(?P.*)?$', } ) @@ -335,7 +457,7 @@ entrypoint's name. E.g. for the built-in entrypoint for git the entrypoint is named ``.git`` and references ``setuptools_scm.git:parse`` - The return value MUST be a ``setuptools.version.ScmVersion`` instance + The return value MUST be a ``setuptools_scm.version.ScmVersion`` instance created by the function ``setuptools_scm.version:meta``. ``setuptools_scm.files_command`` @@ -350,18 +472,32 @@ ``setuptools_scm.version_scheme`` Configures how the version number is constructed given a - ``setuptools.version.ScmVersion`` instance and should return a string + ``setuptools_scm.version.ScmVersion`` instance and should return a string representing the version. Available implementations: - :guess-next-dev: automatically guesses the next development version (default) - :post-release: generates post release versions (adds :code:`postN`) + :guess-next-dev: Automatically guesses the next development version (default). + Guesses the upcoming release by incrementing the pre-release segment if present, + otherwise by incrementing the micro segment. Then appends :code:`.devN`. + :post-release: generates post release versions (adds :code:`.postN`) + :python-simplified-semver: Basic semantic versioning. Guesses the upcoming release + by incrementing the minor segment and setting the micro segment to zero if the + current branch contains the string ``'feature'``, otherwise by incrementing the + micro version. Then appends :code:`.devN`. Not compatible with pre-releases. + :release-branch-semver: Semantic versioning for projects with release branches. The + same as ``guess-next-dev`` (incrementing the pre-release or micro segment) if on + a release branch: a branch whose name (ignoring namespace) parses as a version + that matches the most recent tag up to the minor segment. Otherwise if on a + non-release branch, increments the minor segment and sets the micro segment to + zero, then appends :code:`.devN`. ``setuptools_scm.local_scheme`` Configures how the local part of a version is rendered given a - ``setuptools.version.ScmVersion`` instance and should return a string + ``setuptools_scm.version.ScmVersion`` instance and should return a string representing the local version. + Dates and times are in Coordinated Universal Time (UTC), because as part + of the version, they should be location independent. Available implementations: @@ -370,6 +506,8 @@ :node-and-timestamp: like ``node-and-date`` but with a timestamp of the form ``{:%Y%m%d%H%M%S}`` instead :dirty-tag: adds ``+dirty`` if the current workdir has changes + :no-local-version: omits local version, useful e.g. because pypi does + not support it Importing in ``setup.py`` @@ -413,6 +551,26 @@ $ PYTHONPATH=$PWD:$PWD/src pytest +Interaction with Enterprise Distributions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some enterprise distributions like RHEL7 and others +ship rather old setuptools versions due to various release management details. + +On such distributions one might observe errors like: + +:code:``setuptools_scm.version.SetuptoolsOutdatedWarning: your setuptools is too old (<12)`` + +In those case its typically possible to build by using a sdist against ``setuptools_scm<2.0``. +As those old setuptools versions lack sensible types for versions, +modern setuptools_scm is unable to support them sensibly. + +In case the project you need to build can not be patched to either use old setuptools_scm, +its still possible to install a more recent version of setuptools in order to handle the build +and/or install the package by using wheels or eggs. + + + Code of Conduct --------------- @@ -422,3 +580,10 @@ `PyPA Code of Conduct`_. .. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ + +Security Contact +================ + +To report a security vulnerability, please use the +`Tidelift security contact `_. +Tidelift will coordinate the fix and disclosure. diff -Nru setuptools-scm-3.4.3+really3.3.3/setup.cfg setuptools-scm-4.1.2/setup.cfg --- setuptools-scm-3.4.3+really3.3.3/setup.cfg 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/setup.cfg 2020-05-31 12:31:56.000000000 +0000 @@ -1,9 +1,85 @@ -[bdist_wheel] -universal=1 - [metadata] # ensure that the LICENSE file is included in the built wheels license_file = LICENSE +license = MIT +name = setuptools_scm +url = https://github.com/pypa/setuptools_scm/ +author = Ronny Pfannschmidt +author_email = opensource@ronnypfannschmidt.de +description = the blessed package to manage your versions by scm tags +long_description= file:README.rst + + +classifiers= + Development Status :: 5 - Production/Stable + Intended Audience :: Developers + License :: OSI Approved :: MIT License + Programming Language :: Python + Programming Language :: Python :: 2.7 + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.5 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + Topic :: Software Development :: Libraries + Topic :: Software Development :: Version Control + Topic :: System :: Software Distribution + Topic :: Utilities + + +[options] +zip_safe = true +python_requires= >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* +install_requires= + setuptools +packages=find: +package_dir= + =src + +[options.packages.find] +where=src + +[options.extras_require] +toml = toml + + +[options.entry_points] -[devpi:upload] -formats=sdist,bdist_wheel +distutils.setup_keywords = + use_scm_version = setuptools_scm.integration:version_keyword + +setuptools.file_finders = + setuptools_scm = setuptools_scm.integration:find_files + +setuptools.finalize_distribution_options= + setuptools_scm = setuptools_scm.integration:infer_version + +setuptools_scm.parse_scm = + .hg = setuptools_scm.hg:parse + .git = setuptools_scm.git:parse + +setuptools_scm.parse_scm_fallback = + .hg_archival.txt = setuptools_scm.hg:parse_archival + PKG-INFO = setuptools_scm.hacks:parse_pkginfo + pip-egg-info = setuptools_scm.hacks:parse_pip_egg_info + setup.py = setuptools_scm.hacks:fallback_version + +setuptools_scm.files_command = + .hg = setuptools_scm.file_finder_hg:hg_find_files + .git = setuptools_scm.file_finder_git:git_find_files + +setuptools_scm.version_scheme = + guess-next-dev = setuptools_scm.version:guess_next_dev_version + post-release = setuptools_scm.version:postrelease_version + python-simplified-semver = setuptools_scm.version:simplified_semver_version + release-branch-semver = setuptools_scm.version:release_branch_semver_version + +setuptools_scm.local_scheme = + node-and-date = setuptools_scm.version:get_local_node_and_date + node-and-timestamp = setuptools_scm.version:get_local_node_and_timestamp + dirty-tag = setuptools_scm.version:get_local_dirty_tag + no-local-version = setuptools_scm.version:get_no_local_node + + +[bdist_wheel] +universal = 1 diff -Nru setuptools-scm-3.4.3+really3.3.3/setup.py setuptools-scm-4.1.2/setup.py --- setuptools-scm-3.4.3+really3.3.3/setup.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/setup.py 2020-05-31 12:31:56.000000000 +0000 @@ -24,6 +24,9 @@ sys.path.insert(0, src) pkg_resources.working_set.add_entry(src) + # FIXME: remove debug + print(src) + print(pkg_resources.working_set) from setuptools_scm.hacks import parse_pkginfo from setuptools_scm.git import parse as parse_git from setuptools_scm.version import guess_next_dev_version, get_local_node_and_date @@ -46,73 +49,5 @@ return dict(version=get_version(root=here, parse=parse, **config)) -with open("README.rst") as fp: - long_description = fp.read() - - -arguments = dict( - name="setuptools_scm", - url="https://github.com/pypa/setuptools_scm/", - zip_safe=True, - author="Ronny Pfannschmidt", - author_email="opensource@ronnypfannschmidt.de", - description=("the blessed package to manage your versions by scm tags"), - long_description=long_description, - license="MIT", - packages=["setuptools_scm"], - package_dir={"": "src"}, - entry_points=""" - [distutils.setup_keywords] - use_scm_version = setuptools_scm.integration:version_keyword - - [setuptools.file_finders] - setuptools_scm = setuptools_scm.integration:find_files - - [setuptools_scm.parse_scm] - .hg = setuptools_scm.hg:parse - .git = setuptools_scm.git:parse - - [setuptools_scm.parse_scm_fallback] - .hg_archival.txt = setuptools_scm.hg:parse_archival - PKG-INFO = setuptools_scm.hacks:parse_pkginfo - pip-egg-info = setuptools_scm.hacks:parse_pip_egg_info - setup.py = setuptools_scm.hacks:fallback_version - - [setuptools_scm.files_command] - .hg = setuptools_scm.file_finder_hg:hg_find_files - .git = setuptools_scm.file_finder_git:git_find_files - - [setuptools_scm.version_scheme] - guess-next-dev = setuptools_scm.version:guess_next_dev_version - post-release = setuptools_scm.version:postrelease_version - python-simplified-semver = setuptools_scm.version:simplified_semver_version - - [setuptools_scm.local_scheme] - node-and-date = setuptools_scm.version:get_local_node_and_date - node-and-timestamp = \ - setuptools_scm.version:get_local_node_and_timestamp - dirty-tag = setuptools_scm.version:get_local_dirty_tag - """, - classifiers=[ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", - "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Topic :: Software Development :: Libraries", - "Topic :: Software Development :: Version Control", - "Topic :: System :: Software Distribution", - "Topic :: Utilities", - ], - python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", -) - if __name__ == "__main__": - arguments.update(scm_config()) - setuptools.setup(**arguments) + setuptools.setup(**scm_config()) diff -Nru setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/config.py setuptools-scm-4.1.2/src/setuptools_scm/config.py --- setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/config.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/src/setuptools_scm/config.py 2020-05-31 12:31:56.000000000 +0000 @@ -6,8 +6,9 @@ from .utils import trace -DEFAULT_TAG_REGEX = r"^(?:[\w-]+-)?(?P[vV]?\d+(?:\.\d+){0,2}[^\+]+)(?:\+.*)?$" -DEFAULT_VERSION_SCHEME = "version_scheme" +DEFAULT_TAG_REGEX = r"^(?:[\w-]+-)?(?P[vV]?\d+(?:\.\d+){0,2}[^\+]*)(?:\+.*)?$" +DEFAULT_VERSION_SCHEME = "guess-next-dev" +DEFAULT_LOCAL_SCHEME = "node-and-date" def _check_tag_regex(value): @@ -39,32 +40,36 @@ class Configuration(object): """ Global configuration model """ - _root = None - version_scheme = None - local_scheme = None - write_to = None - write_to_template = None - fallback_version = None - _relative_to = None - parse = None - _tag_regex = None - _absolute_root = None - - def __init__(self, relative_to=None, root="."): + def __init__( + self, + relative_to=None, + root=".", + version_scheme=DEFAULT_VERSION_SCHEME, + local_scheme=DEFAULT_LOCAL_SCHEME, + write_to=None, + write_to_template=None, + tag_regex=DEFAULT_TAG_REGEX, + parentdir_prefix_version=None, + fallback_version=None, + fallback_root=".", + parse=None, + git_describe_command=None, + ): # TODO: self._relative_to = relative_to self._root = "." self.root = root - self.version_scheme = DEFAULT_VERSION_SCHEME - self.local_scheme = "node-and-date" - self.write_to = "" - self.write_to_template = None - self.fallback_version = None - self.fallback_root = "." - self.parse = None - self.tag_regex = DEFAULT_TAG_REGEX - self.git_describe_command = None + self.version_scheme = version_scheme + self.local_scheme = local_scheme + self.write_to = write_to + self.write_to_template = write_to_template + self.parentdir_prefix_version = parentdir_prefix_version + self.fallback_version = fallback_version + self.fallback_root = fallback_root + self.parse = parse + self.tag_regex = tag_regex + self.git_describe_command = git_describe_command @property def fallback_root(self): @@ -105,3 +110,16 @@ @tag_regex.setter def tag_regex(self, value): self._tag_regex = _check_tag_regex(value) + + @classmethod + def from_file(cls, name="pyproject.toml"): + """ + Read Configuration from pyproject.toml (or similar). + Raises exceptions when file is not found or toml is + not installed or the file has invalid format or does + not contain the [tool.setuptools_scm] section. + """ + with open(name) as strm: + defn = __import__("toml").load(strm) + section = defn.get("tool", {})["setuptools_scm"] + return cls(**section) diff -Nru setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/file_finder_git.py setuptools-scm-4.1.2/src/setuptools_scm/file_finder_git.py --- setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/file_finder_git.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/src/setuptools_scm/file_finder_git.py 2020-05-31 12:31:56.000000000 +0000 @@ -28,16 +28,16 @@ def _git_interpret_archive(fd, toplevel): - tf = tarfile.open(fileobj=fd, mode="r|*") - git_files = set() - git_dirs = {toplevel} - for member in tf.getmembers(): - name = os.path.normcase(member.name).replace("/", os.path.sep) - if member.type == tarfile.DIRTYPE: - git_dirs.add(name) - else: - git_files.add(name) - return git_files, git_dirs + with tarfile.open(fileobj=fd, mode="r|*") as tf: + git_files = set() + git_dirs = {toplevel} + for member in tf.getmembers(): + name = os.path.normcase(member.name).replace("/", os.path.sep) + if member.type == tarfile.DIRTYPE: + git_dirs.add(name) + else: + git_files.add(name) + return git_files, git_dirs def _git_ls_files_and_dirs(toplevel): @@ -46,7 +46,12 @@ cmd = ["git", "archive", "--prefix", toplevel + os.path.sep, "HEAD"] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, cwd=toplevel) try: - return _git_interpret_archive(proc.stdout, toplevel) + try: + return _git_interpret_archive(proc.stdout, toplevel) + finally: + # ensure we avoid resource warnings by cleaning up the process + proc.stdout.close() + proc.terminate() except Exception: if proc.wait() != 0: log.exception("listing git files failed - pretending there aren't any") @@ -57,5 +62,8 @@ toplevel = _git_toplevel(path) if not toplevel: return [] + fullpath = os.path.abspath(os.path.normpath(path)) + if not fullpath.startswith(toplevel): + trace("toplevel mismatch", toplevel, fullpath) git_files, git_dirs = _git_ls_files_and_dirs(toplevel) return scm_find_files(path, git_files, git_dirs) diff -Nru setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/file_finder.py setuptools-scm-4.1.2/src/setuptools_scm/file_finder.py --- setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/file_finder.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/src/setuptools_scm/file_finder.py 2020-05-31 12:31:56.000000000 +0000 @@ -31,10 +31,9 @@ # directory not in scm, don't walk it's content dirnames[:] = [] continue - if ( - os.path.islink(dirpath) - and not os.path.relpath(realdirpath, realpath).startswith(os.pardir) - ): + if os.path.islink(dirpath) and not os.path.relpath( + realdirpath, realpath + ).startswith(os.pardir): # a symlink to a directory not outside path: # we keep it in the result and don't walk its content res.append(os.path.join(path, os.path.relpath(dirpath, path))) @@ -51,6 +50,6 @@ # dirpath + filename with symlinks preserved fullfilename = os.path.join(dirpath, filename) if os.path.normcase(os.path.realpath(fullfilename)) in scm_files: - res.append(os.path.join(path, os.path.relpath(fullfilename, path))) + res.append(os.path.join(path, os.path.relpath(fullfilename, realpath))) seen.add(realdirpath) return res diff -Nru setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/git.py setuptools-scm-4.1.2/src/setuptools_scm/git.py --- setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/git.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/src/setuptools_scm/git.py 2020-05-31 12:31:56.000000000 +0000 @@ -65,7 +65,7 @@ def warn_on_shallow(wd): """experimental, may change at any time""" if wd.is_shallow(): - warnings.warn('"%s" is shallow and may cause errors' % (wd.path,)) + warnings.warn('"{}" is shallow and may cause errors'.format(wd.path)) def fetch_on_shallow(wd): diff -Nru setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/hacks.py setuptools-scm-4.1.2/src/setuptools_scm/hacks.py --- setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/hacks.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/src/setuptools_scm/hacks.py 2020-05-31 12:31:56.000000000 +0000 @@ -1,6 +1,6 @@ import os from .utils import data_from_mime, trace -from .version import meta +from .version import tag_to_version, meta def parse_pkginfo(root, config=None): @@ -25,5 +25,13 @@ def fallback_version(root, config=None): + if config.parentdir_prefix_version is not None: + _, parent_name = os.path.split(os.path.abspath(root)) + if parent_name.startswith(config.parentdir_prefix_version): + version = tag_to_version( + parent_name[len(config.parentdir_prefix_version) :], config + ) + if version is not None: + return meta(str(version), preformatted=True, config=config) if config.fallback_version is not None: return meta(config.fallback_version, preformatted=True, config=config) diff -Nru setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/hg.py setuptools-scm-4.1.2/src/setuptools_scm/hg.py --- setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/hg.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/src/setuptools_scm/hg.py 2020-05-31 12:31:56.000000000 +0000 @@ -15,9 +15,7 @@ # ignore commits that only modify .hgtags and nothing else: " and (merge() or file('re:^(?!\\.hgtags).*$'))" " and not tag({tag!r}))" # ignore the tagged commit itself - ).format( - tag=tag - ) + ).format(tag=tag) if tag != "0.0": commits = do( ["hg", "log", "-r", revset, "--template", "{node|short}"], @@ -71,7 +69,12 @@ def get_latest_normalizable_tag(root): # Gets all tags containing a '.' (see #229) from oldest to newest cmd = [ - "hg", "log", "-r", "ancestors(.) and tag('re:\\.')", "--template", "{tags}\n" + "hg", + "log", + "-r", + "ancestors(.) and tag('re:\\.')", + "--template", + "{tags}\n", ] outlines = do(cmd, root).split() if not outlines: @@ -81,7 +84,7 @@ def get_graph_distance(root, rev1, rev2="."): - cmd = ["hg", "log", "-q", "-r", "%s::%s" % (rev1, rev2)] + cmd = ["hg", "log", "-q", "-r", "{}::{}".format(rev1, rev2)] out = do(cmd, root) return len(out.strip().splitlines()) - 1 diff -Nru setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/__init__.py setuptools-scm-4.1.2/src/setuptools_scm/__init__.py --- setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/__init__.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/src/setuptools_scm/__init__.py 2020-05-31 12:31:56.000000000 +0000 @@ -5,7 +5,12 @@ import os import warnings -from .config import Configuration +from .config import ( + Configuration, + DEFAULT_VERSION_SCHEME, + DEFAULT_LOCAL_SCHEME, + DEFAULT_TAG_REGEX, +) from .utils import function_has_arg, string_types from .version import format_version, meta from .discover import iter_matching_entrypoints @@ -116,12 +121,13 @@ def get_version( root=".", - version_scheme="guess-next-dev", - local_scheme="node-and-date", + version_scheme=DEFAULT_VERSION_SCHEME, + local_scheme=DEFAULT_LOCAL_SCHEME, write_to=None, write_to_template=None, relative_to=None, - tag_regex=None, + tag_regex=DEFAULT_TAG_REGEX, + parentdir_prefix_version=None, fallback_version=None, fallback_root=".", parse=None, @@ -134,30 +140,24 @@ root of the repository by supplying ``__file__``. """ - config = Configuration() - config.root = root - config.fallback_root = fallback_root - config.version_scheme = version_scheme - config.local_scheme = local_scheme - config.write_to = write_to - config.write_to_template = write_to_template - config.relative_to = relative_to - config.tag_regex = tag_regex - config.fallback_version = fallback_version - config.parse = parse - config.git_describe_command = git_describe_command + config = Configuration(**locals()) + return _get_version(config) + +def _get_version(config): parsed_version = _do_parse(config) if parsed_version: version_string = format_version( - parsed_version, version_scheme=version_scheme, local_scheme=local_scheme + parsed_version, + version_scheme=config.version_scheme, + local_scheme=config.local_scheme, ) dump_version( - root=root, + root=config.root, version=version_string, - write_to=write_to, - template=write_to_template, + write_to=config.write_to, + template=config.write_to_template, ) return version_string diff -Nru setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/integration.py setuptools-scm-4.1.2/src/setuptools_scm/integration.py --- setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/integration.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/src/setuptools_scm/integration.py 2020-05-31 12:31:56.000000000 +0000 @@ -1,8 +1,8 @@ from pkg_resources import iter_entry_points from .version import _warn_if_setuptools_outdated -from .utils import do -from . import get_version +from .utils import do, trace_exception +from . import _get_version, Configuration def version_keyword(dist, keyword, value): @@ -13,8 +13,8 @@ value = {} if getattr(value, "__call__", None): value = value() - - dist.metadata.version = get_version(**value) + config = Configuration(**value) + dist.metadata.version = _get_version(config) def find_files(path=""): @@ -28,3 +28,21 @@ if res: return res return [] + + +def _args_from_toml(name="pyproject.toml"): + # todo: more sensible config initialization + # move this elper back to config and unify it with the code from get_config + + with open(name) as strm: + defn = __import__("toml").load(strm) + return defn.get("tool", {})["setuptools_scm"] + + +def infer_version(dist): + + try: + config = Configuration.from_file() + except Exception: + return trace_exception() + dist.metadata.version = _get_version(config) diff -Nru setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/utils.py setuptools-scm-4.1.2/src/setuptools_scm/utils.py --- setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/utils.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/src/setuptools_scm/utils.py 2020-05-31 12:31:56.000000000 +0000 @@ -10,6 +10,8 @@ import os import io import platform +import traceback +import datetime DEBUG = bool(os.environ.get("SETUPTOOLS_SCM_DEBUG")) @@ -19,12 +21,37 @@ string_types = (str,) if PY3 else (str, unicode) # noqa +def no_git_env(env): + # adapted from pre-commit + # Too many bugs dealing with environment variables and GIT: + # https://github.com/pre-commit/pre-commit/issues/300 + # In git 2.6.3 (maybe others), git exports GIT_WORK_TREE while running + # pre-commit hooks + # In git 1.9.1 (maybe others), git exports GIT_DIR and GIT_INDEX_FILE + # while running pre-commit hooks in submodules. + # GIT_DIR: Causes git clone to clone wrong thing + # GIT_INDEX_FILE: Causes 'error invalid object ...' during commit + for k, v in env.items(): + if k.startswith("GIT_"): + trace(k, v) + return { + k: v + for k, v in env.items() + if not k.startswith("GIT_") + or k in ("GIT_EXEC_PATH", "GIT_SSH", "GIT_SSH_COMMAND") + } + + def trace(*k): if DEBUG: print(*k) sys.stdout.flush() +def trace_exception(): + DEBUG and traceback.print_exc() + + def ensure_stripped_str(str_or_bytes): if isinstance(str_or_bytes, str): return str_or_bytes.strip() @@ -43,7 +70,6 @@ def _popen_pipes(cmd, cwd): - return subprocess.Popen( cmd, stdout=subprocess.PIPE, @@ -51,7 +77,8 @@ cwd=str(cwd), env=_always_strings( dict( - os.environ, + no_git_env(os.environ), + # os.environ, # try to disable i18n LC_ALL="C", LANGUAGE="", @@ -94,6 +121,22 @@ return data +class UTC(datetime.tzinfo): + _ZERO = datetime.timedelta(0) + + def utcoffset(self, dt): + return self._ZERO + + def tzname(self, dt): + return "UTC" + + def dst(self, dt): + return self._ZERO + + +utc = UTC() + + def function_has_arg(fn, argname): assert inspect.isfunction(fn) diff -Nru setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/version.py setuptools-scm-4.1.2/src/setuptools_scm/version.py --- setuptools-scm-3.4.3+really3.3.3/src/setuptools_scm/version.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/src/setuptools_scm/version.py 2020-05-31 12:31:56.000000000 +0000 @@ -2,10 +2,9 @@ import datetime import warnings import re -from itertools import chain, repeat, islice from .config import Configuration -from .utils import trace, string_types +from .utils import trace, string_types, utc from pkg_resources import iter_entry_points @@ -16,11 +15,6 @@ SEMVER_LEN = 3 -def _pad(iterable, size, padding=None): - padded = chain(iterable, repeat(padding)) - return list(islice(padded, size)) - - def _parse_version_tag(tag, config): tagstring = tag if not isinstance(tag, string_types) else str(tag) match = config.tag_regex.match(tagstring) @@ -34,11 +28,11 @@ result = { "version": match.group(key), - "prefix": match.group(0)[:match.start(key)], - "suffix": match.group(0)[match.end(key):], + "prefix": match.group(0)[: match.start(key)], + "suffix": match.group(0)[match.end(key) :], } - trace("tag '%s' parsed to %s" % (tag, result)) + trace("tag '{}' parsed to {}".format(tag, result)) return result @@ -89,7 +83,7 @@ tagdict = _parse_version_tag(tag, config) if not isinstance(tagdict, dict) or not tagdict.get("version", None): - warnings.warn("tag %r no version found" % (tag,)) + warnings.warn("tag {!r} no version found".format(tag)) return None version = tagdict["version"] @@ -97,7 +91,9 @@ if tagdict.get("suffix", ""): warnings.warn( - "tag %r will be stripped of its suffix '%s'" % (tag, tagdict["suffix"]) + "tag {!r} will be stripped of its suffix '{}'".format( + tag, tagdict["suffix"] + ) ) if VERSION_CLASS is not None: @@ -122,7 +118,6 @@ class ScmVersion(object): - def __init__( self, tag_version, @@ -131,6 +126,7 @@ dirty=False, preformatted=False, branch=None, + config=None, **kw ): if kw: @@ -140,11 +136,12 @@ distance = 0 self.distance = distance self.node = node - self.time = datetime.datetime.now() + self.time = datetime.datetime.now(utc) self._extra = kw self.dirty = dirty self.preformatted = preformatted self.branch = branch + self.config = config @property def extra(self): @@ -192,7 +189,14 @@ def meta( - tag, distance=None, dirty=False, node=None, preformatted=False, config=None, **kw + tag, + distance=None, + dirty=False, + node=None, + preformatted=False, + branch=None, + config=None, + **kw ): if not config: warnings.warn( @@ -202,7 +206,9 @@ parsed_version = _parse_tag(tag, preformatted, config) trace("version", tag, "->", parsed_version) assert parsed_version is not None, "cant parse version %s" % tag - return ScmVersion(parsed_version, distance, node, dirty, preformatted, **kw) + return ScmVersion( + parsed_version, distance, node, dirty, preformatted, branch, config, **kw + ) def guess_next_version(tag_version): @@ -237,12 +243,14 @@ def guess_next_simple_semver(version, retain, increment=True): - parts = map(int, str(version).split(".")) - parts = _pad(parts, retain, 0) + parts = [int(i) for i in str(version).split(".")[:retain]] + while len(parts) < retain: + parts.append(0) if increment: parts[-1] += 1 - parts = _pad(parts, SEMVER_LEN, 0) - return ".".join(map(str, parts)) + while len(parts) < SEMVER_LEN: + parts.append(0) + return ".".join(str(i) for i in parts) def simplified_semver_version(version): @@ -259,6 +267,35 @@ ) +def release_branch_semver_version(version): + if version.exact: + return version.format_with("{tag}") + if version.branch is not None: + # Does the branch name (stripped of namespace) parse as a version? + branch_ver = _parse_version_tag(version.branch.split("/")[-1], version.config) + if branch_ver is not None: + # Does the branch version up to the minor part match the tag? If not it + # might be like, an issue number or something and not a version number, so + # we only want to use it if it matches. + tag_ver_up_to_minor = str(version.tag).split(".")[:SEMVER_MINOR] + branch_ver_up_to_minor = branch_ver["version"].split(".")[:SEMVER_MINOR] + if branch_ver_up_to_minor == tag_ver_up_to_minor: + # We're in a release/maintenance branch, next is a patch/rc/beta bump: + return version.format_next_version(guess_next_version) + # We're in a development branch, next is a minor bump: + return version.format_next_version(guess_next_simple_semver, retain=SEMVER_MINOR) + + +def release_branch_semver(version): + warnings.warn( + "release_branch_semver is deprecated and will be removed in future. " + + "Use release_branch_semver_version instead", + category=DeprecationWarning, + stacklevel=2, + ) + return release_branch_semver_version(version) + + def _format_local_with_time(version, time_format): if version.exact or version.node is None: @@ -283,6 +320,10 @@ return version.format_choice("", "+dirty") +def get_no_local_node(_): + return "" + + def postrelease_version(version): if version.exact: return version.format_with("{tag}") diff -Nru setuptools-scm-3.4.3+really3.3.3/testing/check_self_install.py setuptools-scm-4.1.2/testing/check_self_install.py --- setuptools-scm-3.4.3+really3.3.3/testing/check_self_install.py 1970-01-01 00:00:00.000000000 +0000 +++ setuptools-scm-4.1.2/testing/check_self_install.py 2020-05-31 12:31:56.000000000 +0000 @@ -0,0 +1,5 @@ +import pkg_resources +import setuptools_scm + +dist = pkg_resources.get_distribution("setuptools_scm") +assert dist.version == setuptools_scm.get_version(), dist.version diff -Nru setuptools-scm-3.4.3+really3.3.3/testing/conftest.py setuptools-scm-4.1.2/testing/conftest.py --- setuptools-scm-3.4.3+really3.3.3/testing/conftest.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/testing/conftest.py 2020-05-31 12:31:56.000000000 +0000 @@ -1,6 +1,7 @@ import os import itertools import pytest +import six os.environ["SETUPTOOLS_SCM_DEBUG"] = "1" VERSION_PKGS = ["setuptools", "setuptools_scm"] @@ -21,6 +22,9 @@ commit_command = None add_command = None + def __repr__(self): + return "".format(cwd=self.cwd) + def __init__(self, cwd): self.cwd = cwd self.__counter = itertools.count() @@ -33,10 +37,13 @@ return do(cmd, self.cwd) def write(self, name, value, **kw): - filename = self.cwd.join(name) + filename = self.cwd / name if kw: value = value.format(**kw) - filename.write(value) + if isinstance(value, six.text_type): + filename.write_text(value) + else: + filename.write_bytes(value) return filename def _reason(self, given_reason): @@ -83,5 +90,7 @@ @pytest.fixture -def wd(tmpdir): - return Wd(tmpdir.ensure("wd", dir=True)) +def wd(tmp_path): + target_wd = tmp_path.resolve() / "wd" + target_wd.mkdir() + return Wd(target_wd) diff -Nru setuptools-scm-3.4.3+really3.3.3/testing/play_out_381.bash setuptools-scm-4.1.2/testing/play_out_381.bash --- setuptools-scm-3.4.3+really3.3.3/testing/play_out_381.bash 1970-01-01 00:00:00.000000000 +0000 +++ setuptools-scm-4.1.2/testing/play_out_381.bash 2020-05-31 12:31:56.000000000 +0000 @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +set -euxo pipefail + +rm -rf y z home venv tmp + +[ ! -d black ] && git clone https://github.com/psf/black +export SETUPTOOLS_SCM_DEBUG=1 +export PRE_COMMIT_HOME="$PWD/home" +export TMPDIR="$PWD/tmp" + +git init y +git init z +git -C z commit --allow-empty -m 'commit!' +git -C y submodule add "$PWD/z" +cat > "$PWD/y/.git/modules/z/hooks/pre-commit" < ../file1 - ) + assert set(find_files("adir")) == _sep( + {"adir/filea", "adir/file1link"} + ) # -> ../file1 @pytest.mark.skipif( sys.platform == "win32", reason="symlinks to files not supported on windows" ) def test_symlink_file_source_not_in_scm(inwd): - (inwd.cwd / "adir" / "file1link").mksymlinkto("../file1") + (inwd.cwd / "adir" / "file1link").symlink_to("../file1") assert set(find_files("adir")) == _sep({"adir/filea"}) @pytest.mark.skipif(sys.platform == "win32", reason="symlinks to dir not supported") def test_symlink_loop(inwd): - (inwd.cwd / "adir" / "loop").mksymlinkto("../adir") + (inwd.cwd / "adir" / "loop").symlink_to("../adir") inwd.add_and_commit() assert set(find_files("adir")) == _sep({"adir/filea", "adir/loop"}) # -> ../adir @pytest.mark.skipif(sys.platform == "win32", reason="symlinks to dir not supported") def test_symlink_loop_outside_path(inwd): - (inwd.cwd / "bdir" / "loop").mksymlinkto("../bdir") - (inwd.cwd / "adir" / "bdirlink").mksymlinkto("../bdir") + (inwd.cwd / "bdir" / "loop").symlink_to("../bdir") + (inwd.cwd / "adir" / "bdirlink").symlink_to("../bdir") inwd.add_and_commit() assert set(find_files("adir")) == _sep({"adir/filea", "adir/bdirlink/fileb"}) @pytest.mark.skipif(sys.platform == "win32", reason="symlinks to dir not supported") def test_symlink_dir_out_of_git(inwd): - (inwd.cwd / "adir" / "outsidedirlink").mksymlinkto(os.path.join(__file__, "..")) + (inwd.cwd / "adir" / "outsidedirlink").symlink_to(os.path.join(__file__, "..")) inwd.add_and_commit() assert set(find_files("adir")) == _sep({"adir/filea"}) @@ -112,68 +121,62 @@ sys.platform == "win32", reason="symlinks to files not supported on windows" ) def test_symlink_file_out_of_git(inwd): - (inwd.cwd / "adir" / "outsidefilelink").mksymlinkto(__file__) + (inwd.cwd / "adir" / "outsidefilelink").symlink_to(__file__) inwd.add_and_commit() assert set(find_files("adir")) == _sep({"adir/filea"}) def test_empty_root(inwd): subdir = inwd.cwd / "cdir" / "subdir" - subdir.ensure(dir=True) - (subdir / "filec").ensure(file=True) + subdir.mkdir(parents=True) + (subdir / "filec").touch() inwd.add_and_commit() assert set(find_files("cdir")) == _sep({"cdir/subdir/filec"}) def test_empty_subdir(inwd): subdir = inwd.cwd / "adir" / "emptysubdir" / "subdir" - subdir.ensure(dir=True) - (subdir / "xfile").ensure(file=True) + subdir.mkdir(parents=True) + (subdir / "xfile").touch() inwd.add_and_commit() - assert ( - set(find_files("adir")) == _sep({"adir/filea", "adir/emptysubdir/subdir/xfile"}) + assert set(find_files("adir")) == _sep( + {"adir/filea", "adir/emptysubdir/subdir/xfile"} ) @pytest.mark.skipif(sys.platform == "win32", reason="symlinks not supported on windows") def test_double_include_through_symlink(inwd): - (inwd.cwd / "data").ensure(dir=True) - (inwd.cwd / "data" / "datafile").ensure(file=True) - (inwd.cwd / "adir" / "datalink").mksymlinkto("../data") - (inwd.cwd / "adir" / "filealink").mksymlinkto("filea") - inwd.add_and_commit() - assert ( - set(find_files()) - == _sep( - { - "file1", - "adir/datalink", # -> ../data - "adir/filealink", # -> filea - "adir/filea", - "bdir/fileb", - "data/datafile", - } - ) + (inwd.cwd / "data").mkdir() + (inwd.cwd / "data" / "datafile").touch() + (inwd.cwd / "adir" / "datalink").symlink_to("../data") + (inwd.cwd / "adir" / "filealink").symlink_to("filea") + inwd.add_and_commit() + assert set(find_files()) == _sep( + { + "file1", + "adir/datalink", # -> ../data + "adir/filealink", # -> filea + "adir/filea", + "bdir/fileb", + "data/datafile", + } ) @pytest.mark.skipif(sys.platform == "win32", reason="symlinks not supported on windows") def test_symlink_not_in_scm_while_target_is(inwd): - (inwd.cwd / "data").ensure(dir=True) - (inwd.cwd / "data" / "datafile").ensure(file=True) + (inwd.cwd / "data").mkdir() + (inwd.cwd / "data" / "datafile").touch() inwd.add_and_commit() - (inwd.cwd / "adir" / "datalink").mksymlinkto("../data") - (inwd.cwd / "adir" / "filealink").mksymlinkto("filea") - assert ( - set(find_files()) - == _sep( - { - "file1", - "adir/filea", - # adir/datalink and adir/afilelink not included - # because the symlink themselves are not in scm - "bdir/fileb", - "data/datafile", - } - ) + (inwd.cwd / "adir" / "datalink").symlink_to("../data") + (inwd.cwd / "adir" / "filealink").symlink_to("filea") + assert set(find_files()) == _sep( + { + "file1", + "adir/filea", + # adir/datalink and adir/afilelink not included + # because the symlink_to themselves are not in scm + "bdir/fileb", + "data/datafile", + } ) diff -Nru setuptools-scm-3.4.3+really3.3.3/testing/test_functions.py setuptools-scm-4.1.2/testing/test_functions.py --- setuptools-scm-3.4.3+really3.3.3/testing/test_functions.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/testing/test_functions.py 2020-05-31 12:31:56.000000000 +0000 @@ -16,7 +16,6 @@ class MockTime(object): - def __format__(self, *k): return "time" @@ -51,9 +50,12 @@ [ ("exact", "guess-next-dev node-and-date", "1.1"), ("zerodistance", "guess-next-dev node-and-date", "1.2.dev0"), + ("zerodistance", "guess-next-dev no-local-version", "1.2.dev0"), ("dirty", "guess-next-dev node-and-date", "1.2.dev0+dtime"), + ("dirty", "guess-next-dev no-local-version", "1.2.dev0"), ("distance", "guess-next-dev node-and-date", "1.2.dev3"), ("distancedirty", "guess-next-dev node-and-date", "1.2.dev3+dtime"), + ("distancedirty", "guess-next-dev no-local-version", "1.2.dev3"), ("exact", "post-release node-and-date", "1.1"), ("zerodistance", "post-release node-and-date", "1.1.post0"), ("dirty", "post-release node-and-date", "1.1.post0+dtime"), diff -Nru setuptools-scm-3.4.3+really3.3.3/testing/test_git.py setuptools-scm-4.1.2/testing/test_git.py --- setuptools-scm-3.4.3+really3.3.3/testing/test_git.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/testing/test_git.py 2020-05-31 12:31:56.000000000 +0000 @@ -1,16 +1,30 @@ import sys from setuptools_scm import integration -from setuptools_scm.utils import do +from setuptools_scm.utils import do, has_command from setuptools_scm import git import pytest -from datetime import date +from datetime import datetime from os.path import join as opj from setuptools_scm.file_finder_git import git_find_files +import warnings + + +skip_if_win_27 = pytest.mark.skipif( + sys.platform == "win32" and sys.version_info[0] < 3, + reason="Not supported on Windows + Python 2.7", +) + + +with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + if not has_command("git"): + pytestmark = pytest.mark.skip(reason="git executable not found") @pytest.fixture -def wd(wd): +def wd(wd, monkeypatch): + monkeypatch.delenv("HOME", raising=False) wd("git init") wd("git config user.email test@example.com") wd('git config user.name "a test"') @@ -33,9 +47,10 @@ def test_root_relative_to(tmpdir, wd, monkeypatch): monkeypatch.delenv("SETUPTOOLS_SCM_DEBUG") - p = wd.cwd.ensure("sub/package", dir=1) - p.join("setup.py").write( - """from setuptools import setup + p = wd.cwd.joinpath("sub/package") + p.mkdir(parents=True) + p.joinpath("setup.py").write_text( + u"""from setuptools import setup setup(use_scm_version={"root": "../..", "relative_to": __file__}) """ @@ -45,6 +60,7 @@ @pytest.mark.issue("https://github.com/pypa/setuptools_scm/issues/298") +@pytest.mark.issue(403) def test_file_finder_no_history(wd, caplog): file_list = git_find_files(str(wd.cwd)) assert file_list == [] @@ -110,11 +126,22 @@ wd.write("test.txt", "test2") wd("git add test.txt") assert wd.version.startswith("0.1.dev1") - today = date.today() + # the date on the tag is in UTC + today = datetime.utcnow().date() # we are dirty, check for the tag assert today.strftime(".d%Y%m%d") in wd.version +@pytest.mark.issue(193) +def test_git_worktree_support(wd, tmpdir): + wd.commit_testfile() + worktree = tmpdir.join("work_tree") + wd("git worktree add -b work-tree %s" % worktree) + + res = do([sys.executable, "-m", "setuptools_scm", "ls"], cwd=worktree) + assert str(worktree) in res + + @pytest.fixture def shallow_wd(wd, tmpdir): wd.commit_testfile() @@ -147,8 +174,10 @@ def test_find_files_stop_at_root_git(wd): wd.commit_testfile() - wd.cwd.ensure("project/setup.cfg") - assert integration.find_files(str(wd.cwd / "project")) == [] + project = wd.cwd / "project" + project.mkdir() + project.joinpath("setup.cfg").touch() + assert integration.find_files(str(project)) == [] @pytest.mark.issue(128) @@ -163,7 +192,8 @@ assert wd.version.startswith("0.1.dev1+g") -def test_git_archive_export_ignore(wd): +@skip_if_win_27 +def test_git_archive_export_ignore(wd, monkeypatch): wd.write("test1.txt", "test") wd.write("test2.txt", "test") wd.write( @@ -174,28 +204,30 @@ ) wd("git add test1.txt test2.txt") wd.commit() - with wd.cwd.as_cwd(): - assert integration.find_files(".") == [opj(".", "test1.txt")] + monkeypatch.chdir(wd.cwd) + assert integration.find_files(".") == [opj(".", "test1.txt")] +@skip_if_win_27 @pytest.mark.issue(228) -def test_git_archive_subdirectory(wd): +def test_git_archive_subdirectory(wd, monkeypatch): wd("mkdir foobar") wd.write("foobar/test1.txt", "test") wd("git add foobar") wd.commit() - with wd.cwd.as_cwd(): - assert integration.find_files(".") == [opj(".", "foobar", "test1.txt")] + monkeypatch.chdir(wd.cwd) + assert integration.find_files(".") == [opj(".", "foobar", "test1.txt")] +@skip_if_win_27 @pytest.mark.issue(251) -def test_git_archive_run_from_subdirectory(wd): +def test_git_archive_run_from_subdirectory(wd, monkeypatch): wd("mkdir foobar") wd.write("foobar/test1.txt", "test") wd("git add foobar") wd.commit() - with (wd.cwd / "foobar").as_cwd(): - assert integration.find_files(".") == [opj(".", "test1.txt")] + monkeypatch.chdir(wd.cwd / "foobar") + assert integration.find_files(".") == [opj(".", "test1.txt")] def test_git_feature_branch_increments_major(wd): @@ -218,6 +250,24 @@ assert wd.get_version( tag_regex=r"^apache-arrow-([\.0-9]+)$", git_describe_command="git describe --dirty --tags --long --exclude *js* ", - ).startswith( - "0.11.2" - ) + ).startswith("0.11.2") + + +@pytest.mark.issue("https://github.com/pypa/setuptools_scm/issues/411") +@pytest.mark.xfail(reason="https://github.com/pypa/setuptools_scm/issues/449") +def test_non_dotted_version(wd): + wd.commit_testfile() + wd("git tag apache-arrow-1") + wd.commit_testfile() + assert wd.get_version().startswith("2") + + +@pytest.mark.issue("https://github.com/pypa/setuptools_scm/issues/381") +def test_gitdir(monkeypatch, wd): + """ + """ + wd.commit_testfile() + normal = wd.version + # git hooks set this and break subsequent setuptools_scm unless we clean + monkeypatch.setenv("GIT_DIR", __file__) + assert wd.version == normal diff -Nru setuptools-scm-3.4.3+really3.3.3/testing/test_integration.py setuptools-scm-4.1.2/testing/test_integration.py --- setuptools-scm-3.4.3+really3.3.3/testing/test_integration.py 1970-01-01 00:00:00.000000000 +0000 +++ setuptools-scm-4.1.2/testing/test_integration.py 2020-05-31 12:31:56.000000000 +0000 @@ -0,0 +1,42 @@ +import sys + +import pytest + +from setuptools_scm.utils import do + + +@pytest.fixture +def wd(wd): + try: + wd("git init") + except OSError: + pytest.skip("git executable not found") + + wd("git config user.email test@example.com") + wd('git config user.name "a test"') + wd.add_command = "git add ." + wd.commit_command = "git commit -m test-{reason}" + return wd + + +def test_pyproject_support(tmpdir, monkeypatch): + pytest.importorskip("toml") + monkeypatch.delenv("SETUPTOOLS_SCM_DEBUG") + pkg = tmpdir.ensure("package", dir=42) + pkg.join("pyproject.toml").write( + """[tool.setuptools_scm] +fallback_version = "12.34" +""" + ) + pkg.join("setup.py").write("__import__('setuptools').setup()") + res = do((sys.executable, "setup.py", "--version"), pkg) + assert res == "12.34" + + +def test_pyproject_support_with_git(tmpdir, monkeypatch, wd): + monkeypatch.delenv("SETUPTOOLS_SCM_DEBUG") + pkg = tmpdir.join("wd") + pkg.join("pyproject.toml").write("""[tool.setuptools_scm]""") + pkg.join("setup.py").write("__import__('setuptools').setup()") + res = do((sys.executable, "setup.py", "--version"), pkg) + assert res == "0.1.dev0" diff -Nru setuptools-scm-3.4.3+really3.3.3/testing/test_mercurial.py setuptools-scm-4.1.2/testing/test_mercurial.py --- setuptools-scm-3.4.3+really3.3.3/testing/test_mercurial.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/testing/test_mercurial.py 2020-05-31 12:31:56.000000000 +0000 @@ -2,7 +2,15 @@ from setuptools_scm.hg import archival_to_version, parse from setuptools_scm import integration from setuptools_scm.config import Configuration +from setuptools_scm.utils import has_command import pytest +import warnings + + +with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + if not has_command("hg"): + pytestmark = pytest.mark.skip(reason="hg executable not found") @pytest.fixture @@ -16,7 +24,9 @@ archival_mapping = { "1.0": {"tag": "1.0"}, "1.1.dev3+h000000000000": { - "latesttag": "1.0", "latesttagdistance": "3", "node": "0" * 20 + "latesttag": "1.0", + "latesttagdistance": "3", + "node": "0" * 20, }, "0.0": {"node": "0" * 20}, "1.2.2": {"tag": "release-1.2.2"}, @@ -36,15 +46,17 @@ ) -def test_find_files_stop_at_root_hg(wd): +def test_find_files_stop_at_root_hg(wd, monkeypatch): wd.commit_testfile() - wd.cwd.ensure("project/setup.cfg") + project = wd.cwd / "project" + project.mkdir() + project.joinpath("setup.cfg").touch() # setup.cfg has not been committed - assert integration.find_files(str(wd.cwd / "project")) == [] + assert integration.find_files(str(project)) == [] # issue 251 wd.add_and_commit() - with (wd.cwd / "project").as_cwd(): - assert integration.find_files() == ["setup.cfg"] + monkeypatch.chdir(project) + assert integration.find_files() == ["setup.cfg"] # XXX: better tests for tag prefixes @@ -79,7 +91,7 @@ def test_version_from_archival(wd): # entrypoints are unordered, # cleaning the wd ensure this test wont break randomly - wd.cwd.join(".hg").remove() + wd.cwd.joinpath(".hg").rename(wd.cwd / ".nothg") wd.write(".hg_archival.txt", "node: 000000000000\n" "tag: 0.1\n") assert wd.version == "0.1" @@ -142,8 +154,8 @@ def test_version_bump_from_commit_including_hgtag_mods(wd): """ Test the case where a commit includes changes to .hgtags and other files """ - with wd.cwd.join(".hgtags").open("a") as tagfile: - tagfile.write("0 0\n") + with wd.cwd.joinpath(".hgtags").open("ab") as tagfile: + tagfile.write(b"0 0\n") wd.write("branchfile", "branchtext") wd(wd.add_command) assert wd.version.startswith("1.0.1.dev1+") # bump from dirty version diff -Nru setuptools-scm-3.4.3+really3.3.3/testing/test_regressions.py setuptools-scm-4.1.2/testing/test_regressions.py --- setuptools-scm-3.4.3+really3.3.3/testing/test_regressions.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/testing/test_regressions.py 2020-05-31 12:31:56.000000000 +0000 @@ -27,9 +27,13 @@ res = do((sys.executable, "setup.py", "--version"), p) assert res == "1.0" - do("git init", p.dirpath()) - res = do((sys.executable, "setup.py", "--version"), p) - assert res == "0.1.dev0" + try: + do("git init", p.dirpath()) + except OSError: + pass + else: + res = do((sys.executable, "setup.py", "--version"), p) + assert res == "0.1.dev0" def test_pip_egg_info(tmpdir, monkeypatch): diff -Nru setuptools-scm-3.4.3+really3.3.3/testing/test_version.py setuptools-scm-4.1.2/testing/test_version.py --- setuptools-scm-3.4.3+really3.3.3/testing/test_version.py 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/testing/test_version.py 2020-05-31 12:31:56.000000000 +0000 @@ -1,6 +1,11 @@ import pytest from setuptools_scm.config import Configuration -from setuptools_scm.version import meta, simplified_semver_version, tags_to_versions +from setuptools_scm.version import ( + meta, + simplified_semver_version, + release_branch_semver_version, + tags_to_versions, +) c = Configuration() @@ -44,6 +49,42 @@ @pytest.mark.parametrize( + "version, expected_next", + [ + pytest.param(meta("1.0.0", config=c), "1.0.0", id="exact"), + pytest.param( + meta("1.0.0", distance=2, branch="master", config=c), + "1.1.0.dev2", + id="development_branch", + ), + pytest.param( + meta("1.0.0rc1", distance=2, branch="master", config=c), + "1.1.0.dev2", + id="development_branch_release_candidate", + ), + pytest.param( + meta("1.0.0", distance=2, branch="maintenance/1.0.x", config=c), + "1.0.1.dev2", + id="release_branch_legacy_version", + ), + pytest.param( + meta("1.0.0", distance=2, branch="release-1.0", config=c), + "1.0.1.dev2", + id="release_branch_with_prefix", + ), + pytest.param( + meta("1.0.0", distance=2, branch="bugfix/3434", config=c), + "1.1.0.dev2", + id="false_positive_release_branch", + ), + ], +) +def test_next_release_branch_semver(version, expected_next): + computed = release_branch_semver_version(version) + assert computed == expected_next + + +@pytest.mark.parametrize( "tag, expected", [ pytest.param("v1.0.0", "1.0.0"), @@ -53,7 +94,6 @@ ) def test_tag_regex1(tag, expected): config = Configuration() - config.tag_regex = r"^(?Pv)?(?P[^\+]+)(?P.*)?$" if "+" in tag: # pytest bug wrt cardinality with pytest.warns(UserWarning): diff -Nru setuptools-scm-3.4.3+really3.3.3/tox.ini setuptools-scm-4.1.2/tox.ini --- setuptools-scm-3.4.3+really3.3.3/tox.ini 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/tox.ini 2020-05-31 12:31:56.000000000 +0000 @@ -2,6 +2,7 @@ envlist=py{27,34,35,36,37,38}-test,flake8,check_readme,py{27,37}-selfcheck [pytest] +testpaths=testing filterwarnings=error markers= issue(id): reference to github issue @@ -9,6 +10,7 @@ [flake8] max-complexity = 10 max-line-length = 88 +ignore=E203,W503 exclude= .git, .tox, @@ -25,9 +27,12 @@ test: False deps= pytest + setuptools >= 42 commands= - test: py.test [] + test: pytest [] selfcheck: python setup.py --version +extras = + toml [testenv:flake8] skip_install=True @@ -35,7 +40,7 @@ flake8 mccabe commands = - flake8 setuptools_scm/ testing/ setup.py --exclude=setuptools_scm/win_py31_compat.py + flake8 src/setuptools_scm/ testing/ setup.py --exclude=setuptools_scm/win_py31_compat.py [testenv:check_readme] skip_install=True diff -Nru setuptools-scm-3.4.3+really3.3.3/.travis.yml setuptools-scm-4.1.2/.travis.yml --- setuptools-scm-3.4.3+really3.3.3/.travis.yml 2019-05-12 09:27:00.000000000 +0000 +++ setuptools-scm-4.1.2/.travis.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,98 +0,0 @@ -language: python -sudo: false - -stages: -- linting -- test -- deploy - - -credentials: - - &pypi - provider: pypi - user: ronny - # use when testing, may require recreation of the user and its credentials - # server: https://test.pypi.org/legacy/ # Remove for deployment to official PyPi repo - password: - secure: QGJhDXmfFDKysMJJV/ONGaHHzG/aImhU3DdhEP63d657iQSn/Cb4EG/l9YmVnRzpJ94nSDXZB8YwptR7rid0bOtidb32lxN8n6UiWILCXWeAN2FE+tT9/0xIct4HUJZ8OttD1gft/Di722Gy+s9PzFwjwrV4efkxCzgjfYOjkMeq3aO6NoG3ur0iZXJh7ODwLp4sRFep2NpIEaXm2qMdnnXpck6bJ1q/NtvPx9CAZivd9HYa0evg5j1ENTz1mXXafhgF+0vRCBXA33xJuysO6CKtk+2mizL1QHfosOERiKl9+zPyZw+VvSchbCVwgxrMSiRcpGag+4SegyHrj1M/2YqfFzMF/yuFGcqXl2VkEqlnBQOVMNW3Kdcmnm+caNbddnv+M384WFz4nV8nWjcsD5l27+XlMWfuvskDIvZKtVCXmmbtqgwM4tqoYd6uxbnooRfwINTGx8sNzKP10xkaesB3ZBCEpecOKA1AXUAZ74RfYWWExv6eIuVGwyIJmOcD8M/17N8g58GxxO+88gx50EuhyNiRjYZDUipfVydfJwBwpD+p695NixUMITuksucQftjHsQp+laGWJlDIPvFwI85wDJUYAyrzn6L1W+smkm1bGomuliW2MJfxeSZAmSk4CE5VOpIWQTBmDLR3pxBhcaqzwdd4mAWvMi/fpM4yJJI= - on: - tags: yes -python: -- '2.7' -- '3.4' -- '3.5' -- '3.6' -- '3.7' -- '3.8-dev' -dist: xenial # needed for 3.7+ -env: -- TOXENV=py-test - -jobs: - include: - - stage: linting - name: check readme - python: '3.6' - env: TOXENV=check_readme - # - stage: test - # python: '3.7' - # dist: xenial - - stage: test - python: '2.7' - env: SELFINSTALL=1 - - stage: test - python: '3.6' - env: SELFINSTALL=1 - - - stage: linting - python: '3.6' - name: validate pre-commit - env: - install: - - pip install pre-commit - - pre-commit install-hooks - script: - - pre-commit run --all-files - - - &deploy - stage: deploy - name: "modern distributions" - python: '3.6' - install: - - pip install -U pip setuptools wheel - script: skip - deploy: - <<: *pypi - distributions: "sdist bdist_wheel" - - - &bdist_egg - <<: *deploy - name: "python eggs 2.7" - python: '2.7' - deploy: - <<: *pypi - distributions: "bdist_egg" - - <<: *bdist_egg - name: "python eggs 3.4" - python: '3.4' - - <<: *bdist_egg - name: "python eggs 3.5" - python: '3.5' - - <<: *bdist_egg - name: "python eggs 3.6" - python: '3.6' - - <<: *bdist_egg - name: "python eggs 3.7" - python: '3.7' - - <<: *bdist_egg - name: "python eggs 3.8" - python: '3.8-dev' - -cache: - directories: - - $HOME/.cache/pip - - $HOME/.cache/pre-commit - -install: pip install tox -script: -- python testing/runtests_travis.py