Ejemplo n.º 1
0
 def update(self, dest, url, rev_options):
     # type: (str, HiddenText, RevOptions) -> None
     cmd_args = make_command(
         'update',
         self.get_remote_call_options(),
         rev_options.to_args(),
         dest,
     )
     self.run_command(cmd_args)
Ejemplo n.º 2
0
    def fetch_new(self, dest, url, rev_options):

        # type: (str, HiddenText, 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,
        )
Ejemplo n.º 3
0
 def switch(self, dest: str, url: HiddenText,
            rev_options: RevOptions) -> None:
     cmd_args = make_command(
         "switch",
         self.get_remote_call_options(),
         rev_options.to_args(),
         url,
         dest,
     )
     self.run_command(cmd_args)
 def switch(self, dest, url, rev_options):
     # type: (str, HiddenText, RevOptions) -> None
     cmd_args = make_command(
         "switch",
         self.get_remote_call_options(),
         rev_options.to_args(),
         url,
         dest,
     )
     self.run_command(cmd_args)
Ejemplo n.º 5
0
 def fetch_new(self, dest, url, rev_options):
     # type: (str, HiddenText, 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)
Ejemplo n.º 6
0
    def export(self, location, url):
        # type: (str, HiddenText) -> None
        """
        Export the Bazaar repository at the url to the destination location
        """
        # Remove the location to make sure Bazaar can export it correctly
        if os.path.exists(location):
            rmtree(location)

        url, rev_options = self.get_url_rev_options(url)
        self.run_command(
            make_command("export", location, url, rev_options.to_args()))
Ejemplo n.º 7
0
 def run_command(
     cls,
     cmd,  # type: Union[List[str], CommandArgs]
     show_stdout=True,  # type: bool
     cwd=None,  # type: Optional[str]
     on_returncode="raise",  # type: Literal["raise", "warn", "ignore"]
     extra_ok_returncodes=None,  # type: Optional[Iterable[int]]
     command_desc=None,  # type: Optional[str]
     extra_environ=None,  # type: Optional[Mapping[str, Any]]
     spinner=None,  # type: Optional[SpinnerInterface]
     log_failed_cmd=True,  # type: bool
     stdout_only=False,  # type: bool
 ):
     # type: (...) -> str
     """
     Run a VCS subcommand
     This is simply a wrapper around call_subprocess that adds the VCS
     command name, and checks that the VCS is available
     """
     cmd = make_command(cls.name, *cmd)
     try:
         return call_subprocess(
             cmd,
             show_stdout,
             cwd,
             on_returncode=on_returncode,
             extra_ok_returncodes=extra_ok_returncodes,
             command_desc=command_desc,
             extra_environ=extra_environ,
             unset_environ=cls.unset_environ,
             spinner=spinner,
             log_failed_cmd=log_failed_cmd,
             stdout_only=stdout_only,
         )
     except FileNotFoundError:
         # errno.ENOENT = no such file or directory
         # In other words, the VCS executable isn't available
         raise BadCommand(
             f"Cannot find command {cls.name!r} - do you have "
             f"{cls.name!r} installed and in your PATH?"
         )
     except PermissionError:
         # errno.EACCES = Permission denied
         # This error occurs, for instance, when the command is installed
         # only for another user. So, the current user don't have
         # permission to call the other user command.
         raise BadCommand(
             f"No permission to execute {cls.name!r} - install it "
             f"locally, globally (ask admin), or check your PATH. "
             f"See possible solutions at "
             f"https://pip.pypa.io/en/latest/reference/pip_freeze/"
             f"#fixing-permission-denied."
         )
Ejemplo n.º 8
0
    def fetch_new(self, dest, url, rev_options):
        # type: (str, HiddenText, RevOptions) -> None
        rev_display = rev_options.to_display()
        logger.info("Cloning %s%s to %s", url, rev_display, display_path(dest))
        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)
            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)
Ejemplo n.º 9
0
 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)
Ejemplo n.º 10
0
 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)
Ejemplo n.º 11
0
 def fetch_new(self, dest, url, rev_options):
     # type: (str, HiddenText, 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)
     )
     run_command(cmd_args)
Ejemplo n.º 12
0
 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,
     )
Ejemplo n.º 13
0
 def update(self, dest, url, rev_options):
     # type: (str, HiddenText, RevOptions) -> None
     # First fetch changes from the default remote
     if self.get_git_version() >= parse_version('1.9.0'):
         # 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)
Ejemplo n.º 14
0
 def fetch_new(self, dest, url, rev_options):
     # type: (str, HiddenText, 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(
         'checkout', '-q', self.get_remote_call_options(),
         rev_options.to_args(), url, dest,
     )
     self.run_command(cmd_args)
Ejemplo n.º 15
0
    def run_command(
            cls,
            cmd,  # type: Union[List[str], CommandArgs]
            show_stdout=True,  # type: bool
            cwd=None,  # type: Optional[str]
            on_returncode='raise',  # type: str
            extra_ok_returncodes=None,  # type: Optional[Iterable[int]]
            command_desc=None,  # type: Optional[str]
            extra_environ=None,  # type: Optional[Mapping[str, Any]]
            spinner=None,  # type: Optional[SpinnerInterface]
            log_failed_cmd=True,  # type: bool
            stdout_only=False,  # type: bool
    ):

        # type: (...) -> str
        """

        Run a VCS subcommand

        This is simply a wrapper around call_subprocess that adds the VCS

        command name, and checks that the VCS is available

        """

        cmd = make_command(cls.name, *cmd)

        try:

            return call_subprocess(cmd,
                                   show_stdout,
                                   cwd,
                                   on_returncode=on_returncode,
                                   extra_ok_returncodes=extra_ok_returncodes,
                                   command_desc=command_desc,
                                   extra_environ=extra_environ,
                                   unset_environ=cls.unset_environ,
                                   spinner=spinner,
                                   log_failed_cmd=log_failed_cmd,
                                   stdout_only=stdout_only)

        except FileNotFoundError:

            # errno.ENOENT = no such file or directory

            # In other words, the VCS executable isn't available

            raise BadCommand('Cannot find command {cls.name!r} - do you have '
                             '{cls.name!r} installed and in your '
                             'PATH?'.format(**locals()))
Ejemplo n.º 16
0
    def export(self, location, url):
        # type: (str, HiddenText) -> None
        """Export the svn repository at the url to the destination location"""
        url, rev_options = self.get_url_rev_options(url)

        logger.info('Exporting svn repository %s to %s', url, location)
        with indent_log():
            if os.path.exists(location):
                # Subversion doesn't like to check out over an existing
                # directory --force fixes this, but was only added in svn 1.5
                rmtree(location)
            cmd_args = make_command(
                'export', self.get_remote_call_options(),
                rev_options.to_args(), url, location,
            )
Ejemplo n.º 17
0
 def switch(self, dest, url, rev_options):
     # type: (str, HiddenText, 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)
Ejemplo n.º 18
0
 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(
         "checkout",
         "-q",
         self.get_remote_call_options(),
         rev_options.to_args(),
         url,
         dest,
     )
     self.run_command(cmd_args)
Ejemplo n.º 19
0
 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)
Ejemplo n.º 20
0
    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
Ejemplo n.º 21
0
    def resolve_revision(cls, dest, url, rev_options):
        # type: (str, HiddenText, 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 rev.startswith('refs/'):
            return rev_options

        # If it looks like a ref, we have to fetch it explicitly.
        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
Ejemplo n.º 22
0
 def run_command(
     cls,
     cmd,  # type: Union[List[str], CommandArgs]
     show_stdout=True,  # type: bool
     cwd=None,  # type: Optional[str]
     on_returncode="raise",  # type: str
     extra_ok_returncodes=None,  # type: Optional[Iterable[int]]
     command_desc=None,  # type: Optional[str]
     extra_environ=None,  # type: Optional[Mapping[str, Any]]
     spinner=None,  # type: Optional[SpinnerInterface]
     log_failed_cmd=True,  # type: bool
 ):
     # type: (...) -> Text
     """
     Run a VCS subcommand
     This is simply a wrapper around call_subprocess that adds the VCS
     command name, and checks that the VCS is available
     """
     cmd = make_command(cls.name, *cmd)
     try:
         return call_subprocess(
             cmd,
             show_stdout,
             cwd,
             on_returncode=on_returncode,
             extra_ok_returncodes=extra_ok_returncodes,
             command_desc=command_desc,
             extra_environ=extra_environ,
             unset_environ=cls.unset_environ,
             spinner=spinner,
             log_failed_cmd=log_failed_cmd,
         )
     except OSError as e:
         # errno.ENOENT = no such file or directory
         # In other words, the VCS executable isn't available
         if e.errno == errno.ENOENT:
             raise BadCommand(
                 "Cannot find command %r - do you have "
                 "%r installed and in your "
                 "PATH?" % (cls.name, cls.name)
             )
         else:
             raise  # re-raise exception if a different error occurred
Ejemplo n.º 23
0
 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)
Ejemplo n.º 24
0
 def run_command(
     cls,
     cmd,  # type: Union[List[str], CommandArgs]
     cwd=None,  # type: Optional[str]
     extra_environ=None,  # type: Optional[Mapping[str, Any]]
     extra_ok_returncodes=None,  # type: Optional[Iterable[int]]
     log_failed_cmd=True  # type: bool
 ):
   
     cmd = make_command(cls.name, *cmd)
     try:
         return call_subprocess(cmd, cwd,
                                extra_environ=extra_environ,
                                extra_ok_returncodes=extra_ok_returncodes,
                                log_failed_cmd=log_failed_cmd)
     except OSError as e:
        
         if e.errno == errno.ENOENT:
             raise BadCommand(
                 'Cannot find command {cls.name!r} - do you have '
                 '{cls.name!r} installed and in your '
                 'PATH?'.format(**locals()))
         else:
             raise  # re-raise exception if a different error occurred
Ejemplo n.º 25
0
 def update(self, dest, url, rev_options):
     # type: (str, HiddenText, RevOptions) -> None
     cmd_args = make_command("pull", "-q", rev_options.to_args())
     self.run_command(cmd_args, cwd=dest)
Ejemplo n.º 26
0

@pytest.mark.parametrize(
    "args, expected",
    [
        (["pip", "list"], "pip list"),
        (
            [
                "foo", "space space", "new\nline", 'double"quote',
                "single'quote"
            ],
            """foo 'space space' 'new\nline' 'double"quote' 'single'"'"'quote'""",
        ),
        # Test HiddenText arguments.
        (
            make_command(hide_value("secret1"), "foo", hide_value("secret2")),
            "'****' foo '****'",
        ),
    ],
)
def test_format_command_args(args: CommandArgs, expected: str) -> None:
    actual = format_command_args(args)
    assert actual == expected


def test_make_subprocess_output_error() -> None:
    cmd_args = ["test", "has space"]
    cwd = "/path/to/cwd"
    lines = ["line1\n", "line2\n", "line3\n"]
    actual = make_subprocess_output_error(
        cmd_args=cmd_args,
Ejemplo n.º 27
0
 @classmethod
 def run_command(
     cls,
     cmd,  # type: Union[List[str], CommandArgs]
     cwd=None,  # type: Optional[str]
     extra_environ=None,  # type: Optional[Mapping[str, Any]]
     extra_ok_returncodes=None,  # type: Optional[Iterable[int]]
     log_failed_cmd=True  # type: bool
 ):
     # type: (...) -> Text
     """
     Run a VCS subcommand
     This is simply a wrapper around call_subprocess that adds the VCS
     command name, and checks that the VCS is available
     """
     cmd = make_command(cls.name, *cmd)
     try:
         return call_subprocess(cmd, cwd,
                                extra_environ=extra_environ,
                                extra_ok_returncodes=extra_ok_returncodes,
                                log_failed_cmd=log_failed_cmd)
     except OSError as e:
         # errno.ENOENT = no such file or directory
         # In other words, the VCS executable isn't available
         if e.errno == errno.ENOENT:
             raise BadCommand(
                 'Cannot find command {cls.name!r} - do you have '
                 '{cls.name!r} installed and in your '
                 'PATH?'.format(**locals()))
         else:
             raise  # re-raise exception if a different error occurred
Ejemplo n.º 28
0
    format_command_args,
    make_command,
    make_subprocess_output_error,
    subprocess_logger,
)


@pytest.mark.parametrize(
    'args, expected',
    [
        (['pip', 'list'], 'pip list'),
        (['foo', 'space space', 'new\nline', 'double"quote', "single'quote"],
         """foo 'space space' 'new\nline' 'double"quote' 'single'"'"'quote'"""
         ),
        # Test HiddenText arguments.
        (make_command(hide_value('secret1'), 'foo',
                      hide_value('secret2')), "'****' foo '****'"),
    ])
def test_format_command_args(args, expected):
    actual = format_command_args(args)
    assert actual == expected


def test_make_subprocess_output_error():
    cmd_args = ['test', 'has space']
    cwd = '/path/to/cwd'
    lines = ['line1\n', 'line2\n', 'line3\n']
    actual = make_subprocess_output_error(
        cmd_args=cmd_args,
        cwd=cwd,
        lines=lines,
        exit_status=3,
Ejemplo n.º 29
0
 def update(self, dest, url, rev_options):
     # type: (str, HiddenText, RevOptions) -> None
     self.run_command(['pull', '-q'], cwd=dest)
     cmd_args = make_command('update', '-q', rev_options.to_args())
     self.run_command(cmd_args, cwd=dest)
Ejemplo n.º 30
0
 def switch(self, dest, url, rev_options):
     # type: (str, HiddenText, RevOptions) -> None
     self.run_command(make_command('switch', url), cwd=dest)