def test_git_install_checkout(traced_repo_copy, tmpdir): git_dist = traced_repo_copy["git_dist"] git_pkg = git_dist.packages[0] tmpdir = str(tmpdir) branch = current_branch(GitRunner(traced_repo_copy["repo_local"])) other_branch = "other_" + branch install_dir = op.join(tmpdir, "installed") runner = GitRunner(cwd=install_dir) run = partial(runner.run, expect_stderr=True) # Installing to a non-existing location will be more aggressive, creating a # new branch at the recorded hexsha rather than just detaching there. git_pkg.path = install_dir git_pkg.branch = other_branch install(git_dist, install_dir, check=True) assert current_branch(runner) == other_branch # If the recorded branch is in the existing installation repo and has the # same hexsha, we check it out. run(["git", "checkout", branch]) run(["git", "branch", "--force", other_branch, git_pkg.hexsha]) install(git_dist, install_dir) assert current_hexsha(runner) == git_pkg.hexsha assert current_branch(runner) == other_branch # Otherwise, we detach. run(["git", "checkout", branch]) run(["git", "branch", "--force", other_branch, git_pkg.hexsha + "^"]) install(git_dist, install_dir) assert current_hexsha(runner) == git_pkg.hexsha assert not current_branch(runner)
def test_git_install(traced_repo_copy, tmpdir): git_dist = traced_repo_copy["git_dist"] git_pkg = git_dist.packages[0] tmpdir = str(tmpdir) # Install package to a new location. install_dir = op.join(tmpdir, "installed") git_pkg.path = install_dir install(git_dist, install_dir, check=True) # Installing a second time works if the root hexsha's match. install(git_dist, install_dir, check=True) runner = GitRunner(cwd=install_dir) # We don't try to change the state of the repository if it's dirty. runner(["git", "reset", "--hard", "HEAD^"]) hexsha_existing = current_hexsha(runner) create_tree(install_dir, {"dirt": "dirt"}) with swallow_logs(new_level=logging.WARNING) as log: install(git_dist, install_dir) assert "repository is dirty" in log.out assert current_hexsha(runner) == hexsha_existing # We end up on the intended commit (detached) if the existing installation # repo is clean. os.remove(op.join(install_dir, "dirt")) install(git_dist, install_dir) assert current_hexsha(runner) == git_pkg.hexsha assert not current_branch(runner)
def test_git_repo(git_repo): paths = [ # Both full ... os.path.join(git_repo, "foo"), # ... and relative paths work. "bar", # So do paths in subdirectories. os.path.join(git_repo, "subdir/baz") ] runner = GitRunner(git_repo) branch = current_branch(runner) tracer = VCSTracer() with chpwd(git_repo): dists = list( tracer.identify_distributions(paths + [COMMON_SYSTEM_PATH])) assert_distributions(dists, expected_length=1, expected_unknown={COMMON_SYSTEM_PATH}, expected_subset={ "name": "git", "packages": [{ "files": [op.relpath(p) for p in paths], "path": git_repo, "branch": branch }] }) assert dists[0][0].packages[0].hexsha assert dists[0][0].packages[0].root_hexsha hexshas, _ = runner(["git", "rev-list", branch]) root_hexsha = hexshas.strip('\n').split('\n')[-1] repo = dists[0][0].packages[0] assert repo.root_hexsha == root_hexsha assert repo._diff_cmp_id == (repo.root_hexsha, ) assert repo.commit == repo.hexsha # Above we identify a subdirectory file, but we should not # identify the subdirectory itself because in principle Git is # not tracking directories. subdir = os.path.join(git_repo, "subdir") assert not list(tracer.identify_distributions([subdir]))
def test_git_install_detached(traced_repo_copy, tmpdir): git_dist = traced_repo_copy["git_dist"] git_pkg = git_dist.packages[0] tmpdir = str(tmpdir) # Install package to a new location. install_dir = op.join(tmpdir, "installed") git_pkg.path = install_dir runner = GitRunner(cwd=install_dir) install(git_dist, install_dir) # We detach if there is no recorded branch. git_pkg.branch = None runner(["git", "checkout", "master"], expect_stderr=True) install(git_dist, install_dir) assert current_hexsha(runner) == git_pkg.hexsha assert not current_branch(runner)
def traced_repo(git_repo_pair_module): """Return a Git repo pair and the traced GitDistribution for the local repo. """ repo_local, repo_remote = git_repo_pair_module runner = GitRunner(cwd=repo_local) runner(["git", "remote", "add", "dummy-remote", "nowhere"]) tracer = VCSTracer() dists = list(tracer.identify_distributions([op.join(repo_local, "foo")])) git_dist = dists[0][0] assert len(git_dist.packages) == 1 return { "repo_local": repo_local, "repo_remote": repo_remote, "git_dist": git_dist }
def test_git_repo_empty(git_repo_empty): branch = current_branch(GitRunner(git_repo_empty)) tracer = VCSTracer() # Should not crash when given path to empty repo. assert_distributions( tracer.identify_distributions([git_repo_empty]), expected_length=1, expected_unknown=set(), expected_subset={ "name": "git", "packages": [{ "path": git_repo_empty, "branch": branch, # We do not include repo path itself. "files": [] }] })
def test_git_repo_detached(git_repo): runner = GitRunner(git_repo) branch = current_branch(runner) # If we are in a detached state, we still don't identify the # repository itself. runner(["git", "checkout", branch + "^{}", "--"], expect_stderr=True) hexsha_branch, _ = runner(["git", "rev-parse", branch]) hexsha_branch = hexsha_branch.strip() tracer = VCSTracer() dists = list(tracer.identify_distributions([git_repo])) pkg = dists[0][0].packages[0] # We do not include repository path itself. assert pkg.files == [] assert pkg.hexsha == hexsha_branch assert not pkg.branch assert not pkg.remotes
def test_git_install_add_remotes(traced_repo_copy, tmpdir): git_dist = traced_repo_copy["git_dist"] git_pkg = git_dist.packages[0] tmpdir = str(tmpdir) install_dir = op.join(tmpdir, "installed") runner = GitRunner(cwd=install_dir) git_pkg.path = install_dir git_pkg.tracked_remote = "foo" url = git_pkg.remotes["origin"]["url"] git_pkg.remotes = { "foo": { "url": url }, "bar": { "contains": True, "url": url } } install(git_dist, install_dir) installed_remotes = runner(["git", "remote"])[0].splitlines() assert set(installed_remotes) == {"foo", "bar"}
def test_git_repo_remotes(git_repo_pair): repo_local, repo_remote = git_repo_pair runner = GitRunner() tracer = VCSTracer() # Set remote.pushdefault to a value we know doesn't exist. # Otherwise, the test machine may have remote.pushdefault globally # configured to point to "origin". runner(["git", "config", "remote.pushdefault", "notexisting"], cwd=repo_local) # Add another remote that doesn't contain the current commit (in # fact doesn't actually exist), so that we test the "listed as # remote but doesn't contain" case. runner(["git", "remote", "add", "fakeremote", "fakepath"], cwd=repo_local) paths = [os.path.join(repo_local, "foo")] dists_nopush = list(tracer.identify_distributions(paths)) assert_distributions(dists_nopush, expected_length=1, expected_subset={ "name": "git", "packages": [{ "files": [op.relpath(p, repo_local) for p in paths], "path": repo_local, "branch": "master", "tracked_remote": "origin", "remotes": { "origin": { "url": repo_remote, "contains": True }, "fakeremote": { "url": "fakepath" } } }] }) pkg_nopush = dists_nopush[0][0].packages[0] assert set(pkg_nopush.remotes.keys()) == {"origin", "fakeremote"} # fakeremote, which doesn't contain the current commit, doesn't # have contains=True. assert "contains" in pkg_nopush.remotes["origin"] assert "contains" not in pkg_nopush.remotes["fakeremote"] # pushurl is not included in the output above because it is not # set. assert "pushurl" not in list(pkg_nopush.remotes.values()) # If we set the pushurl and retrace, it is included. runner(["git", "config", "remote.origin.pushurl", repo_remote], cwd=repo_local) dists_push = list(tracer.identify_distributions(paths)) pkg_push = dists_push[0][0].packages[0] assert pkg_push.remotes["origin"]["pushurl"] == repo_remote # If we are at a commit that none of the remotes are known to # contain, there are no listed remotes. with chpwd(repo_local): runner(["git", "commit", "--allow-empty", "-m", "empty commit"]) dists_nocontain = list(tracer.identify_distributions(paths)) assert not dists_nocontain[0][0].packages[0].remotes.values() # The remote repository, however, doesn't have a remote, so there # are not listed remotes. paths = [os.path.join(repo_remote, "foo")] dists_remote = list(tracer.identify_distributions(paths)) assert not dists_remote[0][0].packages[0].remotes.values()