def prepare(self): if self.target: os.environ[setupmeta.SCM_DESCRIBE] = "v2.3.0-3-g1234abc" return # Create a temp origin and clone folder self.temp = tempfile.mkdtemp() self.origin = os.path.join(self.temp, "origin.git") self.target = os.path.join(self.temp, "work") os.makedirs(self.origin) self.run_git("init", "--bare", self.origin, cwd=self.temp) self.run_git("clone", self.origin, self.target, cwd=self.temp) copytree(self.folder, self.target) for command in self.preparation: if command.startswith("mv"): # Unfortunately there is no 'mv' on Windows _, source, dest = command.split() source = os.path.join(self.target, source) dest = os.path.join(self.target, dest) shutil.copytree(source, dest) shutil.rmtree(source) else: setupmeta.run_program(*command.split(), cwd=self.target) self.run_git("add", ".") self.run_git("commit", "-m", "Initial commit") self.run_git("push", "origin", "master") self.run_git("tag", "-a", "v1.2.3", "-m", "Initial tag at v1.2.3") self.run_git("push", "--tags", "origin", "master")
def test_wheel(sample_project): # Fake existence of a build folder, that should be in .gitignore (but isn't) # Presence of a new file there should not mark version as dirty build_folder = os.path.join(sample_project, "build") os.mkdir(build_folder) with open(os.path.join(build_folder, "report.txt"), "w") as fh: fh.write("This is some build report\n") dist_folder = os.path.join(sample_project, "dist") assert setupmeta.run_program("pip", "wheel", "--only-binary", ":all:", "-w", "dist", ".") == 0 files = os.listdir(dist_folder) assert len(files) == 2 assert "sample-0.1.0-py2.py3-none-any.whl" in files # Now let's modify one of the files with open(os.path.join(sample_project, "sample.py"), "w") as fh: fh.write("print('hello')\n") assert setupmeta.run_program("pip", "wheel", "--only-binary", ":all:", "-w", "dist", ".") == 0 files = os.listdir(dist_folder) assert len(files) == 3 assert "sample-0.1.0-py2.py3-none-any.whl" in files assert "sample-0.1.0.dirty-py2.py3-none-any.whl" in files
def test_run_program(): setupmeta.DEBUG = True with conftest.capture_output() as out: assert setupmeta.run_program('ls', capture=True, dryrun=True) is None assert setupmeta.run_program('ls', capture=False, dryrun=True) == 0 assert setupmeta.run_program('ls', 'foo/does/not/exist', capture=None) != 0 assert setupmeta.run_program('ls', 'foo/does/not/exist', capture=True) == '' assert "No such file or directory" in setupmeta.run_program( 'ls', 'foo/does/not/exist', capture='all') assert setupmeta.run_program( '/foo/does/not/exist', capture=True, dryrun=True) is None assert setupmeta.run_program('/foo/does/not/exist', capture=False) != 0 with pytest.raises(SystemExit): setupmeta.run_program('/foo/does/not/exist', fatal=True) with pytest.raises(SystemExit): assert setupmeta.run_program('ls', 'foo/does/not/exist', fatal=True) assert 'exitcode' in out setupmeta.DEBUG = False
def bump(self, what, commit=False, simulate_branch=None): if self.problem: setupmeta.abort(self.problem) branch = simulate_branch or self.scm.get_branch() if branch not in self.strategy.branches: setupmeta.abort("Can't bump branch '%s', need one of %s" % (branch, self.strategy.branches)) gv = self.scm.get_version() if gv and gv.dirty: if commit: setupmeta.abort("You have pending changes, can't bump") print("Note: you have pending changes, commit (or stash) them before using --commit") next_version = self.strategy.bumped(what, gv) if not commit: print("Not committing bump, use --commit to commit") vdefs = self.meta.definitions.get("version") if vdefs: self.update_sources(next_version, commit, vdefs) self.scm.apply_tag(commit, next_version) if not self.strategy.hook: return hook = setupmeta.project_path(self.strategy.hook) if setupmeta.is_executable(hook): setupmeta.run_program(hook, self.meta.name, branch, next_version, fatal=True, dryrun=not commit, cwd=setupmeta.project_path())
def run_command(self, message, *args): if not self.commit: print("Would %s: %s" % (message, setupmeta.represented_args(args))) return first, _, rest = message.partition(" ") first = "%s%s" % (first[0].upper(), first[1:]) message = "%sing %s..." % (first, rest) print(message) setupmeta.run_program(*args, fatal=True)
def test_git_versioning(sample_project): output = setupmeta.run_program(sys.executable, "setup.py", "--version", capture=True) assert output == "0.1.0" output = setupmeta.run_program(sys.executable, "setup.py", "explain", capture="all") assert "0.1.0" in output assert "UserWarning" not in output # New file does not change dirtiness write_to_file("foo", "print('hello')") output = setupmeta.run_program(sys.executable, "setup.py", "--version", capture=True) assert output == "0.1.0" # Modify existing file makes checkout dirty write_to_file("sample.py", "print('hello')") output = setupmeta.run_program(sys.executable, "setup.py", "--version", capture=True) assert output == "0.1.0.dirty" # git add -> version should still be dirty, as we didn't commit yet conftest.run_git("add", "sample.py") output = setupmeta.run_program(sys.executable, "setup.py", "--version", capture=True) assert output == "0.1.0.dirty" # git commit -> version reflects new distance conftest.run_git("commit", "-m", "Testing") output = setupmeta.run_program(sys.executable, "setup.py", "--version", capture=True) assert output == "0.1.1" # Bump minor, we should get 0.2.0 output = setupmeta.run_program(sys.executable, "setup.py", "version", "--bump", "minor", "--commit", capture=True) assert "Not pushing bump, use --push to push" in output assert "Running: git tag -a v0.2.0" in output output = setupmeta.run_program(sys.executable, "setup.py", "--version", capture=True) assert output == "0.2.0"
def check_version_output(expected): output = setupmeta.run_program(sys.executable, "setup.py", "--version", capture="all") output = conftest.cleaned_output(output) assert output == expected
def run_git(*args, **kwargs): # git requires a user.email configured, which is usually done in ~/.gitconfig, however under tox, we don't have $HOME defined kwargs.setdefault("capture", True) kwargs.setdefault("fatal", True) output = setupmeta.run_program("git", "-c", "user.name=Tester", "-c", "[email protected]", *args, **kwargs) return output
def test_wheel(sample_project): # Fake existence of a build folder, that should be in .gitignore (but isn't) # Presence of a new file should not mark version as dirty build_folder = os.path.join(sample_project, "build") os.mkdir(build_folder) with open(os.path.join(build_folder, "report.txt"), "w") as fh: fh.write("This is some build report\n") output = setupmeta.run_program("pip", "-vvv", "wheel", "--only-binary", ":all:", "-w", "dist", ".", capture=True) meta = get_metadata_line(output) assert meta == "sample-0.1.0.dist-info/METADATA" # Now let's modify one of the files with open(os.path.join(sample_project, "sample.py"), "w") as fh: fh.write("print('hello')\n") output = setupmeta.run_program("pip", "-vvv", "wheel", "--only-binary", ":all:", "-w", "dist", ".", capture=True) meta = get_metadata_line(output) assert meta == "sample-0.1.0.dirty.dist-info/METADATA"
def run_setup_py(folder, *args): if folder == setupmeta.project_path() or not os.path.isabs(folder): return cleaned_output( setupmeta.run_program(sys.executable, os.path.join(folder, "setup.py"), *args, capture="all", fatal=True)) return run_internal_setup_py(folder, *args)
def test_brand_new_project(): with setupmeta.temp_resource(): conftest.run_git("init") with open("setup.py", "w") as fh: fh.write(SAMPLE_EMPTY_PROJECT) # Test that we avoid warning about no tags etc on brand new empty git repos output = setupmeta.run_program(sys.executable, "setup.py", "--version", capture="all") output = conftest.cleaned_output(output) assert output == "0.0.0"
def run_git(self, *args, **kwargs): cwd = kwargs.pop("cwd", self.target) # git requires a user.email configured, which is usually done in ~/.gitconfig, however under tox, we don't have $HOME defined output = setupmeta.run_program( "git", "-c", "[email protected]", *args, cwd=cwd, capture=kwargs.pop("capture", True), fatal=kwargs.pop("fatal", True), **kwargs ) return output
def run_git(self, *args, **kwargs): cwd = kwargs.pop('cwd', self.target) # git requires a user.email configured, which is usually done in ~/.gitconfig, however under tox, we don't have $HOME defined output = setupmeta.run_program('git', '-c', '[email protected]', *args, cwd=cwd, capture=kwargs.pop('capture', True), fatal=kwargs.pop('fatal', True), **kwargs) return output
def get_output(self, *args, **kwargs): """ Run SCM's CLI program with 'args' and optional additional 'kwargs' (passed through to subprocess.Popen) Command is ran with cwd being 'self.root' :param args: CLI arguments (example: describe --tags) :param kwargs: Additional named arguments :return str|int: Output if kwargs['capture'] is True, exit code otherwise """ capture = kwargs.pop("capture", True) cwd = kwargs.pop("cwd", self.root) return setupmeta.run_program(self.program, *args, capture=capture, cwd=cwd, **kwargs)
def prepare(self): if self.target: os.environ[setupmeta.SCM_DESCRIBE] = "v2.3.0-3-g1234abc" return # Create a temp origin and clone folder self.temp = tempfile.mkdtemp() self.origin = os.path.join(self.temp, "origin.git") self.target = os.path.join(self.temp, "work") os.makedirs(self.origin) self.run_git("init", "--bare", self.origin, cwd=self.temp) self.run_git("clone", self.origin, self.target, cwd=self.temp) copytree(self.folder, self.target) for command in self.preparation: setupmeta.run_program(*command.split(), cwd=self.target) self.run_git("add", ".") self.run_git("commit", "-m", "Initial commit") self.run_git("push", "origin", "master") self.run_git("tag", "-a", "v1.2.3", "-m", "Initial tag at v1.2.3") self.run_git("push", "--tags", "origin", "master")
def sample_project(): """Yield a sample git project, seeded with files from tests/sample""" old_cd = os.getcwd() try: with setupmeta.temp_resource() as temp: source = resouce("sample") dest = os.path.join(temp, "sample") shutil.copytree(source, dest) files = os.listdir(dest) setupmeta.run_program("git", "init", cwd=dest) setupmeta.run_program("git", "add", *files, cwd=dest) setupmeta.run_program("git", "commit", "-m", "Initial commit", cwd=dest) setupmeta.run_program("git", "tag", "-a", "v0.1.0", "-m", "Version 2.4.2", cwd=dest) os.chdir(dest) yield dest finally: os.chdir(old_cd)
def run_program(program, *args, **kwargs): capture = kwargs.pop("capture", True) fatal = kwargs.pop("fatal", True) represented = "%s %s" % (program, setupmeta.represented_args(args)) print("Running: %s" % represented) if not setupmeta.WINDOWS and "PYCHARM_HOSTED" in os.environ and "python" in program and args and args[ 0].startswith("-m"): # Temporary workaround for https://youtrack.jetbrains.com/issue/PY-40692 wrapper = os.path.join(os.path.dirname(__file__), "pydev-wrapper.sh") args = [wrapper, program] + list(args) program = "/bin/sh" output = setupmeta.run_program(program, *args, capture=capture, fatal=fatal, **kwargs) if output and capture: print("output:") print(output) return output
def test_run_program(): setupmeta.DEBUG = True with conftest.capture_output() as out: assert setupmeta.run_program("ls", capture=True, dryrun=True) is None assert setupmeta.run_program("ls", capture=False, dryrun=True) == 0 assert setupmeta.run_program("ls", "foo/does/not/exist", capture=None) != 0 assert setupmeta.run_program("pip", "--version", capture=True) assert setupmeta.run_program("pip", "foo bar", capture=True) == "" assert "unknown command" in setupmeta.run_program("pip", "foo bar", capture="all") assert setupmeta.run_program( "/foo/does/not/exist", capture=True, dryrun=True) is None assert setupmeta.run_program("/foo/does/not/exist", capture=False) != 0 with pytest.raises(SystemExit): setupmeta.run_program("/foo/does/not/exist", fatal=True) with pytest.raises(SystemExit): assert setupmeta.run_program("ls", "foo/does/not/exist", fatal=True) assert "exitcode" in out setupmeta.DEBUG = False