def repo_path_to_local_path(repo_path):
    """
    Convert a repository path into a local file system path.

    This repository path is extended (compared to the repository path
    used by RepoInfo) by adding support for existing local directories.

    The process typically includes checking for a local directory or
    parsing a full or short repository URL and then cloning the repository.

    Arguments:
        repo_path {string} -- Path of a remote repository or a local directory.

    Returns:
        string -- Path of a local directory equivalent to the one
                  specified by the repository path.
                  In case of local directories, the paths are equal.

    """
    if repo_path is None:
        return None

    if isdir(repo_path):
        return repo_path

    info = RepoInfo.parse_repo_info(repo_path)

    if info and info.clone_or_pull():
        return info.dir
    else:
        return None
示例#2
0
def get_repo_analysis(repo_path):
    """
    Get analysis of a repository given its path.

    Only one of the possible return values will be returned.
    Use `isinstance` to determine the type of the returned value.

    Returns:
        string -- Message describing the state of the repo's analysis.
        DetectionResult -- Detection result retrieved from the database.
        list[dict] -- List of repositories matching the repository path.

    """
    # Strip leading and trailing whitespace from the repo path.
    repo_path = repo_path.strip()
    repo_id = None

    try:
        repo_info = RepoInfo.parse_repo_info(repo_path)

        conn = pg_conn(db_url)

        if not repo_info:
            if re.fullmatch(r"^[\w\.\-]+$", repo_path):
                repos = _find_repos_by_metadata(conn, repo_path)

                # No repository matches the given repository path.
                if not repos:
                    raise UserInputError(
                        "No matching repository found in the database")

                # Exact one matching repository.
                if len(repos) == 1:
                    return _get_repo_summary(conn, repos[0])

                # Multiple repositories match the repository path.
                else:
                    return repos

            else:
                raise UserInputError("Invalid Git repository path format")

        repo_id = _try_insert_repo(conn, repo_info)

        if repo_id is not None:
            Thread(target=analyze_repo, args=(repo_info, repo_id)).start()
            return "The repository has been added to the queue"

        repo_dict = _get_repo_dict_from_repoinfo(conn, repo_info)

        return _get_repo_summary(conn, repo_dict)

    except PG_Error as ex:
        handle_pg_error(ex, conn, repo_id)
        return "Database error"

    finally:
        conn.close()
    def test_repoinfo_clone(self):
        """Test the RepoInfo's ability to clone a repository."""
        info = RepoInfo.parse_repo_info(
            "https://github.com/calebdehaan/codeDuplicationParser")

        assert info is not None
        assert info.clone_or_pull()

        self._check_repo_info(info)
    def test_repoinfo_pull_no_change(self):
        """Test the RepoInfo's ability to pull a repo without any change."""
        info = RepoInfo.parse_repo_info(
            "https://github.com/calebdehaan/codeDuplicationParser")

        assert info is not None

        # Clone the repository for the first time.
        assert info.clone_or_pull()
        self._check_repo_info(info)

        # Pull the repository because it already exists.
        assert info.clone_or_pull()
        self._check_repo_info(info)
def test_repoinfo_parse_attrib():
    """Test RepoInfo's attributes after parsing a repository path."""
    info = RepoInfo.parse_repo_info("hTTpS://GiTHuB.CoM/username/repository")

    assert info is not None

    assert info.url == "https://:@github.com/username/repository"

    assert info.server == "github.com"
    assert info.user == "username"
    assert info.name == "repository"

    expected_dir = path_join("github.com", "username", "repository")
    assert relpath(info.dir, clone_root_dir) == expected_dir

    assert info.hash is None
def test_repoinfo_parse_valid():
    """Test RepoInfo parser's ability to parse valid repository paths."""
    VALID_PATHS = [
        "https://github.com/user/repo", "HTTPS://GITHUB.COM/user/repo",
        "https://www.github.com/user/repo", "https://gitlab.com/user/repo",
        "HTTPS://GITLAB.COM/user/repo", "https://www.gitlab.com/user/repo",
        "http://github.com/user/repo",
        "https://github.com/user_user-user.user/repo.repo-repo_repo",
        "github.com/user/repo", "user/repo", "user//repo", "/user/repo",
        "user/repo/", "/user/repo/", "////user/repo////",
        "////user////repo////", "user_user-user.user/repo.repo-repo_repo",
        "///user_user-user.user///repo.repo-repo_repo///"
    ]

    for p in VALID_PATHS:
        assert RepoInfo.parse_repo_info(p) is not None, \
            f"\"{p}\" is a valid repository path"
def test_repoinfo_parse_invalid():
    """Test RepoInfo parser's ability to detect invalid repository paths."""
    INVALID_PATHS = [
        "",
        "https://",
        "https//github.com/user/repo",
        "https/github.com/user/repo",
        "://github.com/user/repo",
        "//github.com/user/repo"
        "/github.com/user/repo"
        "https://github,com/user/repo",
        "https://github;com/user/repo",
        "https;//github.com/user/repo",
        "https:\\\\github.com\\user\\repo",
    ]

    for p in INVALID_PATHS:
        assert RepoInfo.parse_repo_info(p) is None, \
            f"\"{p}\" is not a valid repository path"