Example #1
0
def _create_git_remote_repo(
    remote_repos_path: pathlib.Path,
    remote_repo_name: str,
    remote_repo_post_init: Optional[CreateProjectCallbackProtocol] = None,
) -> pathlib.Path:
    remote_repo_path = remote_repos_path / remote_repo_name
    run(["git", "init", remote_repo_name], cwd=remote_repos_path)

    if remote_repo_post_init is not None and callable(remote_repo_post_init):
        remote_repo_post_init(remote_repo_path=remote_repo_path)

    return remote_repo_path
Example #2
0
def _create_hg_remote_repo(
    remote_repos_path: pathlib.Path,
    remote_repo_name: str,
    remote_repo_post_init: Optional[CreateProjectCallbackProtocol] = None,
) -> pathlib.Path:
    """Create a test hg repo to for checkout / commit purposes"""
    remote_repo_path = remote_repos_path / remote_repo_name
    run(["hg", "init", remote_repo_name], cwd=remote_repos_path)

    if remote_repo_post_init is not None and callable(remote_repo_post_init):
        remote_repo_post_init(remote_repo_path=remote_repo_path)

    return remote_repo_path
Example #3
0
def _create_svn_remote_repo(
    remote_repos_path: pathlib.Path,
    remote_repo_name: str,
    remote_repo_post_init: Optional[CreateProjectCallbackProtocol] = None,
) -> pathlib.Path:
    """Create a test SVN repo to for checkout / commit purposes"""

    remote_repo_path = remote_repos_path / remote_repo_name
    run(["svnadmin", "create", remote_repo_path])

    if remote_repo_post_init is not None and callable(remote_repo_post_init):
        remote_repo_post_init(remote_repo_path=remote_repo_path)

    return remote_repo_path
Example #4
0
def test_repo_git_obtain_initial_commit_repo(
    tmp_path: pathlib.Path,
    constructor: ProjectTestFactory,
    lazy_constructor_options: ProjectTestFactoryLazyKwargs,
) -> None:
    """initial commit repos return 'initial'.

    note: this behaviors differently from git(1)'s use of the word "bare".
    running `git rev-parse --is-bare-repository` would return false.
    """
    repo_name = "my_git_project"

    run(["git", "init", repo_name], cwd=tmp_path)

    bare_dir = tmp_path / repo_name
    git_repo: GitProject = constructor(**lazy_constructor_options(**locals()))

    git_repo.obtain()
    assert git_repo.get_revision() == "initial"
Example #5
0
def git_remote_repo_single_commit_post_init(
        remote_repo_path: pathlib.Path) -> None:
    testfile_filename = "testfile.test"
    run(["touch", testfile_filename], cwd=remote_repo_path)
    run(["git", "add", testfile_filename], cwd=remote_repo_path)
    run(["git", "commit", "-m", "test file for dummyrepo"],
        cwd=remote_repo_path)
Example #6
0
def test_repo_git_obtain_full(
    tmp_path: pathlib.Path,
    git_remote_repo: pathlib.Path,
    constructor: ProjectTestFactory,
    lazy_constructor_options: ProjectTestFactoryLazyKwargs,
) -> None:
    git_repo: GitProject = constructor(**lazy_constructor_options(**locals()))
    git_repo.obtain()

    test_repo_revision = run(["git", "rev-parse", "HEAD"], cwd=git_remote_repo)

    assert git_repo.get_revision() == test_repo_revision
    assert os.path.exists(tmp_path / "myrepo")
Example #7
0
def test_progress_callback(
    tmp_path: pathlib.Path,
    git_remote_repo: pathlib.Path,
    mocker: MockerFixture,
    constructor: ProjectTestFactory,
    lazy_constructor_options: ProjectTestFactoryLazyKwargs,
) -> None:
    def progress_callback_spy(output: str,
                              timestamp: datetime.datetime) -> None:
        assert isinstance(output, str)
        assert isinstance(timestamp, datetime.datetime)

    progress_callback = mocker.Mock(name="progress_callback_stub",
                                    side_effect=progress_callback_spy)

    run(["git", "rev-parse", "HEAD"], cwd=git_remote_repo)

    # create a new repo with the repo as a remote
    git_repo: GitProject = constructor(**lazy_constructor_options(**locals()))
    git_repo.obtain()

    assert progress_callback.called
Example #8
0
def test_repo_mercurial(
    tmp_path: pathlib.Path,
    projects_path: pathlib.Path,
    hg_remote_repo: pathlib.Path,
) -> None:
    repo_name = "my_mercurial_project"

    mercurial_repo = create_project(
        url=f"file://{hg_remote_repo}",
        dir=projects_path / repo_name,
        vcs="hg",
    )

    run(["hg", "init", mercurial_repo.repo_name], cwd=tmp_path)

    mercurial_repo.update_repo()

    test_repo_revision = run(
        ["hg", "parents", "--template={rev}"], cwd=projects_path / repo_name
    )

    assert mercurial_repo.get_revision() == test_repo_revision
Example #9
0
    def _get_svn_url_rev(cls, location: str) -> Tuple[Optional[str], int]:
        _svn_xml_url_re = re.compile('url="([^"]+)"')
        _svn_rev_re = re.compile(r'committed-rev="(\d+)"')
        _svn_info_xml_rev_re = re.compile(r'\s*revision="(\d+)"')
        _svn_info_xml_url_re = re.compile(r"<url>(.*)</url>")

        entries_path = os.path.join(location, ".svn", "entries")
        if os.path.exists(entries_path):
            with open(entries_path) as f:
                data = f.read()
        else:  # subversion >= 1.7 does not have the 'entries' file
            data = ""

        url = None
        if data.startswith("8") or data.startswith("9") or data.startswith("10"):
            entries = list(map(str.splitlines, data.split("\n\x0c\n")))
            del entries[0][0]  # get rid of the '8'
            url = entries[0][3]
            revs = [int(d[9]) for d in entries if len(d) > 9 and d[9]] + [0]
        elif data.startswith("<?xml"):
            match = _svn_xml_url_re.search(data)
            if not match:
                raise ValueError(f"Badly formatted data: {data!r}")
            url = match.group(1)  # get repository URL
            revs = [int(m.group(1)) for m in _svn_rev_re.finditer(data)] + [0]
        else:
            try:
                # subversion >= 1.7
                # Note that using get_remote_call_options is not necessary here
                # because `svn info` is being run against a local directory.
                # We don't need to worry about making sure interactive mode
                # is being used to prompt for passwords, because passwords
                # are only potentially needed for remote server requests.
                xml = run(
                    ["svn", "info", "--xml", location],
                )
                match = _svn_info_xml_url_re.search(xml)
                assert match is not None
                url = match.group(1)
                revs = [int(m.group(1)) for m in _svn_info_xml_rev_re.finditer(xml)]
            except Exception:
                url, revs = None, []

        if revs:
            rev = max(revs)
        else:
            rev = 0

        return url, rev
Example #10
0
    def run(
        self,
        cmd: _CMD,
        cwd: None = None,
        check_returncode: bool = True,
        log_in_real_time: Optional[bool] = None,
        *args: Any,
        **kwargs: Any,
    ) -> str:
        """Return combined stderr/stdout from a command.

        This method will also prefix the VCS command bin_name. By default runs
        using the cwd `libvcs.projects.base.BaseProject.dir` of the repo.

        Parameters
        ----------
        cwd : str
            dir command is run from, defaults to `libvcs.projects.base.BaseProject.dir`.

        check_returncode : bool
            Indicate whether a :exc:`~exc.CommandError` should be raised if return code
            is different from 0.

        Returns
        -------
        str
            combined stdout/stderr in a big string, newlines retained
        """

        if cwd is None:
            cwd = getattr(self, "dir", None)

        if isinstance(cmd, Sequence):
            cmd = [self.bin_name, *cmd]
        else:
            cmd = [self.bin_name, cmd]

        return run(
            cmd,
            callback=(self.progress_callback
                      if callable(self.progress_callback) else None),
            check_returncode=check_returncode,
            log_in_real_time=log_in_real_time or self.log_in_real_time
            or False,
            cwd=cwd,
        )
Example #11
0
def gitconfig(user_path: pathlib.Path) -> pathlib.Path:
    gitconfig = user_path / ".gitconfig"
    user_email = "*****@*****.**"
    gitconfig.write_text(
        textwrap.dedent(f"""
  [user]
    email = {user_email}
    name = {getpass.getuser()}
  [color]
    diff = auto
    """),
        encoding="utf-8",
    )

    output = run(["git", "config", "--get", "user.email"])
    assert user_email in output, "Should use our fixture config and home directory"

    return gitconfig
Example #12
0
    def run(
        self,
        args: _CMD,
        *,
        quiet: Optional[bool] = None,
        username: Optional[str] = None,
        password: Optional[str] = None,
        no_auth_cache: Optional[bool] = None,
        non_interactive: Optional[bool] = True,
        trust_server_cert: Optional[bool] = None,
        config_dir: Optional[pathlib.Path] = None,
        config_option: Optional[pathlib.Path] = None,
        **kwargs: Any,
    ) -> str:
        """
        Passing None to a subcommand option, the flag won't be passed unless otherwise
        stated.

        `svn help` and `svn help [cmd]`

        Wraps svn's `Options
        <https://svnbook.red-bean.com/en/1.7/svn.ref.svn.html#svn.ref.svn.sw>`_.

        Parameters
        ----------
        quiet :
            -q / --quiet
        username :
            --username
        password :
            --password
        no_auth_cache :
            --no-auth-cache
        non_interactive :
            --non-interactive, defaults to True
        trust_server_cert :
            --trust-server-cert
        config_dir :
            --config-dir
        config_option :
            --config-option, ``FILE:SECTION:OPTION=[VALUE]``
        cwd : :attr:`libvcs._internal.types.StrOrBytesPath`, optional
            Defaults to :attr:`~.cwd`

        Examples
        --------
        >>> svn = Svn(dir=tmp_path)
        >>> svn.run(['help'])
        "usage: svn <subcommand> [options] [args]..."
        """

        if isinstance(args, Sequence):
            cli_args = ["svn", *args]
        else:
            cli_args = ["svn", args]

        if "cwd" not in kwargs:
            kwargs["cwd"] = self.dir

        if no_auth_cache is True:
            cli_args.append("--no-auth-cache")
        if non_interactive is True:
            cli_args.append("--non-interactive")
        if username is not None:
            cli_args.extend(["--username", username])
        if password is not None:
            cli_args.extend(["--password", password])
        if trust_server_cert is True:
            cli_args.append("--trust-server_cert")
        if config_dir is not None:
            cli_args.extend(["--config-dir", str(config_dir)])
        if config_option is not None:
            cli_args.extend(["--config-option", str(config_option)])

        return run(args=cli_args, **kwargs)
Example #13
0
    def run(
        self,
        args: _CMD,
        *,
        config: Optional[str] = None,
        repository: Optional[str] = None,
        quiet: Optional[bool] = None,
        help: Optional[bool] = None,
        encoding: Optional[str] = None,
        encoding_mode: Optional[str] = None,
        verbose: Optional[bool] = None,
        traceback: Optional[bool] = None,
        debug: Optional[bool] = None,
        debugger: Optional[bool] = None,
        profile: Optional[bool] = None,
        version: Optional[bool] = None,
        hidden: Optional[bool] = None,
        time: Optional[bool] = None,
        pager: Optional[HgPagerType] = None,
        color: Optional[HgColorType] = None,
        **kwargs: Any,
    ) -> str:
        """
        Passing None to a subcommand option, the flag won't be passed unless otherwise
        stated.

        `hg help` and `hg help [cmd]`

        Wraps hg's `Options <https://www.mercurial-scm.org/doc/hg.1.html>`_.

        Parameters
        ----------
        quiet : bool
            -q / --quiet
        repository : str
            ``--repository REPO``
        cwd : :attr:`libvcs._internal.types.StrOrBytesPath`, optional
            ``--cwd DIR``, Defaults to :attr:`~.cwd`
        verbose : bool
            ``-v / --verbose``
        non_interactive : bool
            ``-y / --noninteractive``, defaults to True
        color : HgColorTypeLiteral
            ``--color``
        debug : bool
            ``--debug``
        debugger : bool
            ``--debugger``
        encoding : str
            ``--encoding ENCODE``
        encoding_mode : str
            ``--encodingmode MODE``
        traceback : bool
            ``--traceback``
        time : bool
            ``--time``
        profile : bool
            ``--profile``
        version : bool
            ``--version``
        help : bool
            ``-h / --help``
        hidden : bool
            ``--hidden``
        pager : HgPagerType
            ``--pager TYPE``
        config :
            ``--config CONFIG [+]``, ``section.name=value``

        Examples
        --------
        >>> hg = Hg(dir=tmp_path)
        >>> hg.run(['help'])
        "Mercurial Distributed SCM..."
        """

        if isinstance(args, Sequence):
            cli_args = ["hg", *args]
        else:
            cli_args = ["hg", args]

        if "cwd" not in kwargs:
            kwargs["cwd"] = self.dir

        if repository is not None:
            cli_args.extend(["--repository", repository])
        if config is not None:
            cli_args.extend(["--config", config])
        if pager is not None:
            cli_args.append(["--pager", pager])
        if color is not None:
            cli_args.append(["--color", color])
        if verbose is True:
            cli_args.append("verbose")
        if quiet is True:
            cli_args.append("--quiet")
        if debug is True:
            cli_args.append("--debug")
        if debugger is True:
            cli_args.append("--debugger")
        if traceback is True:
            cli_args.append("--traceback")
        if time is True:
            cli_args.append("--time")
        if profile is True:
            cli_args.append("--profile")
        if version is True:
            cli_args.append("--version")
        if help is True:
            cli_args.append("--help")

        return run(args=cli_args, **kwargs)