8000 Fix broken tag prefix on Windows and add CI by mathijsvdv · Pull Request #283 · python-versioneer/python-versioneer · GitHub
[go: up one dir, main page]

Skip to content

Fix broken tag prefix on Windows and add CI #283

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Feb 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
e20a08f
CI: Run tests on Windows
effigies Aug 25, 2021
662a2c7
TEST: Handle Windows and POSIX paths
effigies Aug 25, 2021
243f304
TEST: Add an rm -rf implementation to deal with Windows
effigies Aug 25, 2021
40a07c7
Merge branch 'ci/windows' of https://github.com/effigies/python-versi…
mathijsvdv Feb 9, 2022
7b2acf3
Empty commit for testing github action
mathijsvdv Feb 9, 2022
0169966
Disable the '--match' argument when `tag_prefix` is absent
mathijsvdv Feb 10, 2022
570fcc8
Use os.path.join for `venv_dir`
mathijsvdv Feb 12, 2022
b43e416
Add `test_no_tag_prefix` by adding `tag_prefix` as a parameter to `ru…
mathijsvdv Feb 13, 2022
1fef909
Run pip using `python -m pip` and `rundemo` optionally using python.
mathijsvdv Feb 13, 2022
4875183
Remove `test_sdist` and `test_sdist_subproject` from the `DistutilsRe…
mathijsvdv Feb 13, 2022
961efb3
Remove whitespace in blank line
mathijsvdv Feb 13, 2022
90f15bb
Add ls {envdir} for debugging purposes
mathijsvdv Feb 13, 2022
b366d27
Use virtualenv>=20 for the tests
mathijsvdv Feb 13, 2022
00da1de
Put `use_python=True` for the remaining tests that use `rundemo` as a…
mathijsvdv Feb 13, 2022
edb2962
Remove `ls` line again as it's no longer needed for debugging
mathijsvdv Feb 13, 2022
59dcff7
Remove virtualenv import
mathijsvdv Feb 13, 2022
b1fa00e
Add Test Git (cmd) and Test Git (Powershell)
mathijsvdv Feb 13, 2022
4d121bf
Merge remote-tracking branch 'upstream/master' into maint/windows
effigies Feb 19, 2022
5249630
CI: Run Windows tests on all shells, Py310 only
effigies Feb 19, 2022
60e8b51
STY: Minor adjustments
effigies Feb 19, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions .github/workflows/tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,28 @@ on:
schedule:
- cron: '0 0 * * MON'

defaults:
run:
shell: bash

jobs:
stable:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: ['ubuntu-latest']
python-version: [3.6, 3.7, 3.8, 3.9, '3.10', 'pypy-3.7']
shell: ['bash']
include:
- os: 'windows-2019'
python-version: '3.10'
shell: 'bash'
- os: 'windows-2019'
python-version: '3.10'
shell: 'pwsh'
- os: 'windows-2019'
python-version: '3.10'
shell: 'cmd'

defaults:
run:
shell: ${{ matrix.shell }}
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
Expand Down
8 changes: 3 additions & 5 deletions src/git/from_vcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command):
version string, meaning we're inside a checked out source tree.
"""
GITS = ["git"]
TAG_PREFIX_REGEX = "*"
if sys.platform == "win32":
GITS = ["git.cmd", "git.exe"]
TAG_PREFIX_REGEX = r"\*"

_, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root,
hide_stderr=True)
Expand All @@ -34,12 +32,12 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command):
print("Directory %s not under git control" % root)
raise NotThisMethod("'git rev-parse --git-dir' returned error")

MATCH_ARGS = ["--match", "%s*" % tag_prefix] if tag_prefix else []

# if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
# if there isn't one, this yields HEX[-dirty] (no NUM)
describe_out, rc = runner(GITS, ["describe", "--tags", "--dirty",
"--always", "--long",
"--match",
"%s%s" % (tag_prefix, TAG_PREFIX_REGEX)],
"--always", "--long", *MATCH_ARGS],
cwd=root)
# --long was added in git-1.5.5
if describe_out is None:
Expand Down
10 changes: 10 additions & 0 deletions test/git/common.py
8000
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import os, sys
import stat
import shutil
from subprocess_helper import run_command

GITS = ["git"]
Expand Down Expand Up @@ -41,3 +43,11 @@ def project_file(self, *path):

def subpath(self, *path):
return os.path.join(self.testdir, *path)

def rmtree(self, path):
# rm -rf <path>
# Found on https://stackoverflow.com/a/1889686
def remove_readonly(func, path, excinfo):
os.chmod(path, stat.S_IWRITE)
func(path)
shutil.rmtree(path, onerror=remove_readonly)
39 changes: 26 additions & 13 deletions test/git/test_git.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#! /usr/bin/python

import os, sys
import posixpath
import shutil
import tarfile
import unittest
import tempfile
import re


from pkg_resources import parse_version
Expand Down Expand Up @@ -402,7 +404,10 @@ def test_project_in_subdir(self):
# i.e. setup.py -- is not located in the root directory
self.run_test("test/demoapp", False, "project")

def run_test(self, demoapp_dir, script_only, project_sub_dir):
def test_no_tag_prefix(self):
self.run_test("test/demoapp", False, ".", tag_prefix="")

def run_test(self, demoapp_dir, script_only, project_sub_dir, tag_prefix=None):
# The test dir should live under /tmp/ or /var/ or somewhere that
# isn't the child of the versioneer repo's .git directory, since that
# will confuse the tests that check what happens when there is no
Expand All @@ -411,7 +416,7 @@ def run_test(self, demoapp_dir, script_only, project_sub_dir):
self.testdir = tempfile.mkdtemp()
if VERBOSE: print("testdir: %s" % (self.testdir,))
if os.path.exists(self.testdir):
shutil.rmtree(self.testdir)
self.rmtree(self.testdir)

# Our tests run from a git repo that lives here. All self.git()
# operations run from this directory unless overridden.
Expand All @@ -431,6 +436,13 @@ def run_test(self, demoapp_dir, script_only, project_sub_dir):
with open(setup_cfg_fn, "r") as f:
setup_cfg = f.read()
setup_cfg = setup_cfg.replace("@VCS@", "git")

tag_prefix_regex = "tag_prefix = (.*)"
if tag_prefix is None:
tag_prefix = re.search(tag_prefix_regex, setup_cfg).group(1)
else:
setup_cfg = re.sub(tag_prefix_regex, f"tag_prefix = {tag_prefix}", setup_cfg)

with open(setup_cfg_fn, "w") as f:
f.write(setup_cfg)
shutil.copyfile("versioneer.py", self.project_file("versioneer.py"))
Expand All @@ -447,10 +459,11 @@ def run_test(self, demoapp_dir, script_only, project_sub_dir):

out = self.python("versioneer.py", "setup").splitlines()
self.assertEqual(out[0], "creating src/demo/_version.py")
init = os.path.join("src/demo", "__init__.py")
if script_only:
self.assertEqual(out[1], " src/demo/__init__.py doesn't exist, ok")
self.assertEqual(out[1], f" {init} doesn't exist, ok")
else:
self.assertEqual(out[1], " appending to src/demo/__init__.py")
self.assertEqual(out[1], f" appending to {init}")
self.assertEqual(out[2], " appending 'versioneer.py' to MANIFEST.in")
self.assertEqual(out[3], " appending versionfile_source ('src/demo/_version.py') to MANIFEST.in")

Expand All @@ -464,7 +477,7 @@ def remove_pyc(s):
]
out = set(remove_pyc(self.git("status", "--porcelain").splitlines()))
def pf(fn):
return os.path.normpath(os.path.join(self.project_sub_dir, fn))
return posixpath.normpath(posixpath.join(self.project_sub_dir, fn))
expected = {"A %s" % pf(".gitattributes"),
"M %s" % pf("MANIFEST.in"),
"A %s" % pf("src/demo/_version.py"),
Expand All @@ -483,9 +496,9 @@ def pf(fn):
out = self.python("versioneer.py", "setup").splitlines()
self.assertEqual(out[0], "creating src/demo/_version.py")
if script_only:
self.assertEqual(out[1], " src/demo/__init__.py doesn't exist, ok")
self.assertEqual(out[1], f" {init} doesn't exist, ok")
else:
self.assertEqual(out[1], " src/demo/__init__.py unmodified")
self.assertEqual(out[1], f" {init} unmodified")
self.assertEqual(out[2], " 'versioneer.py' already in MANIFEST.in")
self.assertEqual(out[3], " versionfile_source already in MANIFEST.in")
out = set(remove_pyc(self.git("status", "--porcelain").splitlines()))
Expand Down Expand Up @@ -525,7 +538,7 @@ def pf(fn):
# S3: we commit that change, then make the first tag (1.0)
self.git("add", self.project_file("setup.py"))
self.git("commit", "-m", "dirty")
self.git("tag", "demo-1.0")
self.git("tag", f"{tag_prefix}1.0")
# also add an unrelated tag, to test exclusion. git-describe appears
# to return the highest lexicographically-sorted tag, so make sure
# the unrelated one sorts earlier
Expand Down Expand Up @@ -580,22 +593,22 @@ def pf(fn):

def do_checks(self, state, exps):
if os.path.exists(self.subpath("out")):
shutil.rmtree(self.subpath("out"))
self.rmtree(self.subpath("out"))
# TA: project tree
self.check_version(self.projdir, state, "TA", exps["TA"])

# TB: .git-less copy of project tree
target = self.subpath("out/demoapp-TB")
shutil.copytree(self.projdir, target)
if os.path.exists(os.path.join(target, ".git")):
shutil.rmtree(os.path.join(target, ".git"))
self.rmtree(os.path.join(target, ".git"))
self.check_version(target, state, "TB", exps["TB"])

# TC: project tree in versionprefix-named parentdir
target = self.subpath("out/demo-1.1")
shutil.copytree(self.projdir, target)
if os.path.exists(os.path.join(target, ".git")):
shutil.rmtree(os.path.join(target, ".git"))
self.rmtree(os.path.join(target, ".git"))
self.check_version(target, state, "TC", ["1.1", None, False, None]) # XXX

# TD: project subdir of an unpacked git-archive tarball
Expand All @@ -611,7 +624,7 @@ def do_checks(self, state, exps):
# TE: unpacked setup.py sdist tarball
dist_path = os.path.join(self.projdir, "dist")
if os.path.exists(dist_path):
shutil.rmtree(dist_path)
self.rmtree(dist_path)
self.python("setup.py", "sdist", "--formats=tar")
files = os.listdir(dist_path)
self.assertTrue(len(files)==1, files)
Expand Down Expand Up @@ -646,7 +659,7 @@ def check_version(self, workdir, state, tree, exps):

# RB: setup.py build; rundemo --version
if os.path.exists(os.path.join(workdir, "build")):
shutil.rmtree(os.path.join(workdir, "build"))
self.rmtree(os.path.join(workdir, "build"))
self.python("setup.py", "build", "--build-lib=build/lib",
"--build-scripts=build/lib", workdir=workdir)
build_lib = os.path.join(workdir, "build", "lib")
Expand Down
62 changes: 35 additions & 27 deletions test/git/test_invocations.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import os, sys, shutil, unittest, tempfile, tarfile, virtualenv, warnings
import os, sys, shutil, unittest, tempfile, tarfile, warnings
from wheel.bdist_wheel import get_abi_tag, get_platform
from packaging.tags import interpreter_name, interpreter_version

Expand Down Expand Up @@ -39,7 +39,7 @@ def setUp(self):
def make_venv(self, mode):
if not os.path.exists(self.subpath("venvs")):
os.mkdir(self.subpath("venvs"))
venv_dir = self.subpath("venvs/%s" % mode)
venv_dir = self.subpath(os.path.join("venvs", mode))
# python3 on OS-X uses a funky two-part executable and an environment
# variable to communicate between them. If this variable is still set
# by the time a virtualenv's 'pip' or 'python' is run, and if that
Expand All @@ -53,27 +53,35 @@ def make_venv(self, mode):
# switching to 'venv' on py3, but only py3.4 includes pip, and even
# then it's an ancient version.
os.environ.pop("__PYVENV_LAUNCHER__", None)
virtualenv.logger = virtualenv.Logger([]) # hush
# virtualenv causes DeprecationWarning/ResourceWarning on py3
with warnings.catch_warnings():
warnings.simplefilter("ignore")
virtualenv.create_environment(venv_dir)
self.python('-m', 'virtualenv', venv_dir, workdir=self.testdir)
self.run_in_venv(venv_dir, venv_dir,
'pip', 'install', '-U',
'pip', 'wheel', 'packaging')
return venv_dir

def run_in_venv(self, venv, workdir, command, *args):
bins = {"python": os.path.join(venv, "bin", "python"),
"pip": os.path.join(venv, "bin", "pip"),
"rundemo": os.path.join(venv, "bin", "rundemo"),
}
def get_venv_bin(self, venv, command):
if sys.platform == "win32":
return os.path.join(venv, "Scripts", command)

return os.path.join(venv, "bin", command)

def run_in_venv(self, venv, workdir, command, *args, use_python=False):
bin_args = [self.get_venv_bin(venv, command)]
pybin = self.get_venv_bin(venv, "python")

if command == "pip":
bin_args = [pybin, "-m", "pip"]
args = ["--isolated", "--no-cache-dir"] + list(args)
return self.command(bins[command], *args, workdir=workdir)
elif command == "rundemo" and use_python:
bin_args = [pybin] + bin_args

return self.command(*bin_args, *args, workdir=workdir)

def check_in_venv(self, venv):
out = self.run_in_venv(venv, venv, "rundemo")
def check_in_venv(self, venv, use_python=False):
out = self.run_in_venv(venv, venv, "rundemo", use_python=use_python)
v = dict(line.split(":", 1) for line in out.splitlines())
self.assertEqual(v["version"], "2.0")
return v
Expand Down Expand Up @@ -417,13 +425,13 @@ def test_install(self):
repodir = self.make_distutils_repo()
venv = self.make_venv("distutils-repo-install")
self.run_in_venv(venv, repodir, "python", "setup.py", "install")
self.check_in_venv(venv)
self.check_in_venv(venv, use_python=True)

def test_install_subproject(self):
projectdir = self.make_distutils_repo_subproject()
venv = self.make_venv("distutils-repo-install-subproject")
self.run_in_venv(venv, projectdir, "python", "setup.py", "install")
self.check_in_venv(venv)
self.check_in_venv(venv, use_python=True)

def test_pip_wheel(self):
self.make_distutils_wheel_with_pip()
Expand All @@ -433,37 +441,37 @@ def test_pip_install(self):
repodir = self.make_distutils_repo()
venv = self.make_venv("distutils-repo-pip-install")
self.run_in_venv(venv, repodir, "pip", "install", ".")
self.check_in_venv(venv)
self.check_in_venv(venv, use_python=True)

def test_pip_install_subproject(self):
projectdir = self.make_distutils_repo_subproject()
venv = self.make_venv("distutils-repo-pip-install-subproject")
self.run_in_venv(venv, projectdir, "pip", "install", ".")
self.check_in_venv(venv)
self.check_in_venv(venv, use_python=True)

def test_pip_install_from_afar(self):
repodir = self.make_distutils_repo()
venv = self.make_venv("distutils-repo-pip-install-from-afar")
self.run_in_venv(venv, venv, "pip", "install", repodir)
self.check_in_venv(venv)
self.check_in_venv(venv, use_python=True)

def test_pip_install_from_afar_subproject(self):
projectdir = self.make_distutils_repo_subproject()
venv = self.make_venv("distutils-repo-pip-install-from-afar-subproject")
self.run_in_venv(venv, venv, "pip", "install", projectdir)
self.check_in_venv(venv)
self.check_in_venv(venv, use_python=True)

def test_pip_install_editable(self):
repodir = self.make_distutils_repo()
venv = self.make_venv("distutils-repo-pip-install-editable")
self.run_in_venv(venv, repodir, "pip", "install", "--editable", ".")
self.check_in_venv(venv)
self.check_in_venv(venv, use_python=True)

def test_pip_install_editable_subproject(self):
projectdir = self.make_distutils_repo_subproject()
venv = self.make_venv("distutils-repo-pip-install-editable-subproject")
self.run_in_venv(venv, projectdir, "pip", "install", "--editable", ".")
self.check_in_venv(venv)
self.check_in_venv(venv, use_python=True)

class SetuptoolsRepo(_Invocations, unittest.TestCase):
def test_install(self):
Expand Down Expand Up @@ -589,14 +597,14 @@ def test_pip_install(self):
venv = self.make_venv("distutils-sdist-pip-install")
self.run_in_venv(venv, venv,
"pip", "install", sdist)
self.check_in_venv(venv)
self.check_in_venv(venv, use_python=True)

def test_pip_install_subproject(self):
sdist = self.make_distutils_sdist_subproject()
venv = self.make_venv("distutils-sdist-pip-install-subproject")
self.run_in_venv(venv, venv,
"pip", "install", sdist)
self.check_in_venv(venv)
self.check_in_venv(venv, use_python=True)

class SetuptoolsSdist(_Invocations, unittest.TestCase):
def test_pip_install(self):
Expand Down Expand Up @@ -645,13 +653,13 @@ def test_install(self):
unpacked = self.make_distutils_unpacked()
venv = self.make_venv("distutils-unpacked-install")
self.run_in_venv(venv, unpacked, "python", "setup.py", "install")
self.check_in_venv(venv)
self.check_in_venv(venv, use_python=True)

def test_install_subproject(self):
unpacked = self.make_distutils_subproject_unpacked()
venv = self.make_venv("distutils-subproject-unpacked-install")
self.run_in_venv(venv, unpacked, "python", "setup.py", "install")
self.check_in_venv(venv)
self.check_in_venv(venv, use_python=True)

def test_pip_wheel(self):
unpacked = self.make_distutils_unpacked()
Expand All @@ -668,19 +676,19 @@ def test_pip_install(self):
repodir = self.make_distutils_unpacked()
venv = self.make_venv("distutils-unpacked-pip-install")
self.run_in_venv(venv, repodir, "pip", "install", ".")
self.check_in_venv(venv)
self.check_in_venv(venv, use_python=True)

def test_pip_install_subproject(self):
unpacked = self.make_distutils_subproject_unpacked()
venv = self.make_venv("distutils-subproject-unpacked-pip-install")
self.run_in_venv(venv, unpacked, "pip", "install", ".")
self.check_in_venv(venv)
self.check_in_venv(venv, use_python=True)

def test_pip_install_from_afar(self):
repodir = self.make_distutils_unpacked()
venv = self.make_venv("distutils-unpacked-pip-install-from-afar")
self.run_in_venv(venv, venv, "pip", "install", repodir)
self.check_in_venv(venv)
self.check_in_venv(venv, use_python=True)

class SetuptoolsUnpacked(_Invocations, unittest.TestCase):
def test_install(self):
Expand Down
Loading
0