def fetch_new(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: rev_display = rev_options.to_display() logger.info("Cloning %s%s to %s", url, rev_display, display_path(dest)) if self.get_git_version() >= (2, 17): # Git added support for partial clone in 2.17 # https://git-scm.com/docs/partial-clone # Speeds up cloning by functioning without a complete copy of repository self.run_command( make_command( "clone", "--filter=blob:none", "-q", url, dest, ) ) else: self.run_command(make_command("clone", "-q", url, dest)) if rev_options.rev: # Then a specific revision was requested. rev_options = self.resolve_revision(dest, url, rev_options) branch_name = getattr(rev_options, "branch_name", None) logger.debug("Rev options %s, branch_name %s", rev_options, branch_name) if branch_name is None: # Only do a checkout if the current commit id doesn't match # the requested revision. if not self.is_commit_id_equal(dest, rev_options.rev): cmd_args = make_command( "checkout", "-q", rev_options.to_args(), ) self.run_command(cmd_args, cwd=dest) elif self.get_current_branch(dest) != branch_name: # Then a specific branch was requested, and that branch # is not yet checked out. track_branch = f"origin/{branch_name}" cmd_args = [ "checkout", "-b", branch_name, "--track", track_branch, ] self.run_command(cmd_args, cwd=dest) else: sha = self.get_revision(dest) rev_options = rev_options.make_new(sha) logger.info("Resolved %s to commit %s", url, rev_options.rev) #: repo may contain submodules self.update_submodules(dest)
def test_rev_options_to_args( vc_class: Type[VersionControl], expected1: List[str], expected2: List[str], kwargs: Dict[str, Any], ) -> None: """ Test RevOptions.to_args(). """ assert RevOptions(vc_class, **kwargs).to_args() == expected1 assert RevOptions(vc_class, "123", **kwargs).to_args() == expected2
def fetch_new(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: rev_display = rev_options.to_display() logger.info( "Checking out %s%s to %s", url, rev_display, display_path(dest), ) cmd_args = make_command("branch", "-q", rev_options.to_args(), url, dest) self.run_command(cmd_args)
def test_rev_options_make_new(): """ Test RevOptions.make_new(). """ # The choice of VersionControl class doesn't matter here since # the implementation is the same for all of them. rev_options = RevOptions(Git, 'master', extra_args=['foo', 'bar']) new_options = rev_options.make_new('develop') assert new_options is not rev_options assert new_options.extra_args == ['foo', 'bar'] assert new_options.rev == 'develop' assert new_options.vc_class is Git
def test_rev_options_make_new() -> None: """ Test RevOptions.make_new(). """ # The choice of VersionControl class doesn't matter here since # the implementation is the same for all of them. rev_options = RevOptions(Git, "master", extra_args=["foo", "bar"]) new_options = rev_options.make_new("develop") assert new_options is not rev_options assert new_options.extra_args == ["foo", "bar"] assert new_options.rev == "develop" assert new_options.vc_class is Git
def fetch_new(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: rev_display = rev_options.to_display() logger.info( "Cloning hg %s%s to %s", url, rev_display, display_path(dest), ) self.run_command(make_command("clone", "--noupdate", "-q", url, dest)) self.run_command( make_command("update", "-q", rev_options.to_args()), cwd=dest, )
def test_fetch_new_revision(self): rev_options = RevOptions(Subversion, '123') self.svn.fetch_new(self.dest, self.url, rev_options) self.assert_call_args([ 'svn', 'checkout', '-q', '--non-interactive', '-r', '123', 'svn+http://username:[email protected]/', '/tmp/test' ])
def update(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: cmd_args = make_command( "update", self.get_remote_call_options(), rev_options.to_args(), dest, ) self.run_command(cmd_args)
def fetch_new(self, dest: str, url: HiddenText, rev_options: RevOptions, verbosity: int) -> None: rev_display = rev_options.to_display() logger.info( "Checking out %s%s to %s", url, rev_display, display_path(dest), ) if verbosity <= 0: flag = "--quiet" elif verbosity == 1: flag = "" else: flag = f"-{'v'*verbosity}" cmd_args = make_command("branch", flag, rev_options.to_args(), url, dest) self.run_command(cmd_args)
def switch(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: self.run_command( make_command("config", "remote.origin.url", url), cwd=dest, ) cmd_args = make_command("checkout", "-q", rev_options.to_args()) self.run_command(cmd_args, cwd=dest) self.update_submodules(dest)
def _install_gist(self, fullname, gist_hash): repo_path = os.path.join(self.clone_path, gist_hash) #if not self._is_installed(fullname): url = "https://gist.github.com/%s.git" % (gist_hash, ) self._ensure_clone_path_present() repo_path = os.path.join(self.clone_path, gist_hash) git = vcs.get_backend_for_scheme("git+https") if not os.path.exists(repo_path): logger.debug("Cloning %s to %s", url, repo_path) git.fetch_new(repo_path, url, RevOptions(git, "master")) else: logger.debug("Updating %s from %s", repo_path, url) git.update(repo_path, url, RevOptions(git, "master")) return repo_path
def resolve_revision( cls, dest: str, url: HiddenText, rev_options: RevOptions ) -> RevOptions: """ Resolve a revision to a new RevOptions object with the SHA1 of the branch, tag, or ref if found. Args: rev_options: a RevOptions object. """ rev = rev_options.arg_rev # The arg_rev property's implementation for Git ensures that the # rev return value is always non-None. assert rev is not None sha, is_branch = cls.get_revision_sha(dest, rev) if sha is not None: rev_options = rev_options.make_new(sha) rev_options.branch_name = rev if is_branch else None return rev_options # Do not show a warning for the common case of something that has # the form of a Git commit hash. if not looks_like_hash(rev): logger.warning( "Did not find branch or tag '%s', assuming revision or ref.", rev, ) if not cls._should_fetch(dest, rev): return rev_options # fetch the requested revision cls.run_command( make_command("fetch", "-q", url, rev_options.to_args()), cwd=dest, ) # Change the revision to the SHA of the ref we fetched sha = cls.get_revision(dest, rev="FETCH_HEAD") rev_options = rev_options.make_new(sha) return rev_options
def setUp(self): patcher = patch('pip._internal.vcs.versioncontrol.call_subprocess') self.addCleanup(patcher.stop) self.call_subprocess_mock = patcher.start() # Test Data. self.url = 'svn+http://username:[email protected]/' # use_interactive is set to False to test that remote call options are # properly added. self.svn = Subversion(use_interactive=False) self.rev_options = RevOptions(Subversion) self.dest = '/tmp/test'
def switch(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: repo_config = os.path.join(dest, self.dirname, "hgrc") config = configparser.RawConfigParser() try: config.read(repo_config) config.set("paths", "default", url.secret) with open(repo_config, "w") as config_file: config.write(config_file) except (OSError, configparser.NoSectionError) as exc: logger.warning("Could not switch Mercurial repository to %s: %s", url, exc) else: cmd_args = make_command("update", "-q", rev_options.to_args()) self.run_command(cmd_args, cwd=dest)
def _install_module(self, modulename): self._ensure_clone_path_present() modulename = modulename.replace("_minus_", "-") module_path = modulename.replace(".", "/") # TODO: might use hash of url instead of ns, because ns could be registered dynamically repo_path = os.path.join(self.clone_path, self.ns, module_path) Path(repo_path).mkdir(parents=True, exist_ok=True) url = self.url % (modulename, ) git = vcs.get_backend_for_scheme("git+https") if not os.path.exists(os.path.join(repo_path, ".git")): logger.debug("Cloning %s to %s", url, repo_path) git.fetch_new(repo_path, url, RevOptions(git, "master")) else: # TODO: should throttle here logger.debug("Updating %s from %s", repo_path, url) git.update(repo_path, url, RevOptions(git, "master")) return repo_path
def update(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: # First fetch changes from the default remote if self.get_git_version() >= (1, 9): # fetch tags in addition to everything else self.run_command(["fetch", "-q", "--tags"], cwd=dest) else: self.run_command(["fetch", "-q"], cwd=dest) # Then reset to wanted revision (maybe even origin/master) rev_options = self.resolve_revision(dest, url, rev_options) cmd_args = make_command("reset", "--hard", "-q", rev_options.to_args()) self.run_command(cmd_args, cwd=dest) #: update submodules self.update_submodules(dest)
def fetch_new(self, dest: str, url: HiddenText, rev_options: RevOptions, verbosity: int) -> None: rev_display = rev_options.to_display() logger.info( "Checking out %s%s to %s", url, rev_display, display_path(dest), ) if verbosity <= 0: flag = "--quiet" else: flag = "" cmd_args = make_command( "checkout", flag, self.get_remote_call_options(), rev_options.to_args(), url, dest, ) self.run_command(cmd_args)
def fetch_new( self, dest: str, url: HiddenText, rev_options: RevOptions, verbosity: int ) -> None: rev_display = rev_options.to_display() logger.info( "Cloning hg %s%s to %s", url, rev_display, display_path(dest), ) if verbosity <= 0: flags: Tuple[str, ...] = ("--quiet",) elif verbosity == 1: flags = () elif verbosity == 2: flags = ("--verbose",) else: flags = ("--verbose", "--debug") self.run_command(make_command("clone", "--noupdate", *flags, url, dest)) self.run_command( make_command("update", *flags, rev_options.to_args()), cwd=dest, )
def test_fetch_new_revision(self) -> None: rev_options = RevOptions(Subversion, "123") self.svn.fetch_new(self.dest, hide_url(self.url), rev_options) self.assert_call_args( [ "svn", "checkout", "-q", "--non-interactive", "-r", "123", hide_url("svn+http://username:[email protected]/"), "/tmp/test", ] )
def test_rev_options_to_display() -> None: """ Test RevOptions.to_display(). """ # The choice of VersionControl class doesn't matter here since # the implementation is the same for all of them. rev_options = RevOptions(Git) assert rev_options.to_display() == "" rev_options = RevOptions(Git, "master") assert rev_options.to_display() == " (to revision master)"
def test_rev_options_repr() -> None: rev_options = RevOptions(Git, "develop") assert repr(rev_options) == "<RevOptions git: rev='develop'>"
def update(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None: cmd_args = make_command("pull", "-q", rev_options.to_args()) self.run_command(cmd_args, cwd=dest)
def test_rev_options_to_args(vc_class, expected1, expected2, kwargs): """ Test RevOptions.to_args(). """ assert RevOptions(vc_class, **kwargs).to_args() == expected1 assert RevOptions(vc_class, '123', **kwargs).to_args() == expected2
def test_rev_options_repr(): rev_options = RevOptions(Git, 'develop') assert repr(rev_options) == "<RevOptions git: rev='develop'>"