Example #1
0
def lister(op, sess, stem: str = None, put_team: str = None):
    """
    list matching repos
    optionally, add to specified EXISTING team
    """

    if put_team and not gb.team_exists(op, put_team):
        raise ValueError(f"Team {put_team} does not exist in {op.login}")

    # %% get user / organization handle
    userorg = gb.user_or_org(sess, op.login)
    # %% prepare to loop over repos
    repos = gb.get_repos(userorg)

    to_act: T.Iterable[github.Repository.Repository]
    if stem:
        to_act = (repo for repo in repos if repo.name.startswith(stem))
    else:
        to_act = repos

    for repo in to_act:
        teams = repo.get_teams()
        if teams.totalCount == 0:
            if put_team:
                print(repo.name, "=>", put_team)
                team = op.get_team_by_slug(put_team)
                team.add_to_repos(repo)
            else:
                print(repo.name)
Example #2
0
def main(oauth: Path, orgname: str, stem: str):
    # %% authentication
    user, sess = gb.connect(oauth)
    assert isinstance(user, github.AuthenticatedUser.AuthenticatedUser
                      ), "unwatch is for users only, not orgs"
    gb.check_api_limit(sess)
    # %% get organization handle
    org = gb.user_or_org(sess, orgname)
    # %% prepare to loop over repos
    repos = gb.get_repos(org)

    to_act = [
        repo for repo in repos
        if user.has_in_watched(repo) and repo.name.startswith(stem)
    ]
    if not to_act:
        raise SystemExit(
            f"There were no repos left to unwatch with {stem} in {orgname}")

    print("\ntype affirmative to UNWATCH",
          "\n".join([repo.full_name for repo in to_act]))
    if input() != "affirmative":
        raise SystemExit("Aborted")

    for repo in to_act:
        user.remove_from_watched(repo)
        print("UnWatched:", repo.full_name)
Example #3
0
def main():
    p = ArgumentParser(
        description="Set Private GitHub repos for a user/organization with repo names matching pattern"
    )
    p.add_argument("userorgname", help="GitHub username / organizations")
    p.add_argument("oauth", help="Oauth filename")
    p.add_argument("pattern", help="make private repos with name starting with this string")
    P = p.parse_args()

    # %% authentication
    sess = gb.session(P.oauth)
    gb.check_api_limit(sess)
    # %% get user / organization handle
    userorg = gb.user_or_org(sess, P.userorgname)
    # %% prepare to loop over repos
    repos = gb.get_repos(userorg)

    to_act = [repo for repo in repos if repo.name.startswith(P.pattern) and not repo.private]
    if not to_act:
        raise SystemExit(
            f"There were no repos left to make private with {P.pattern} in {P.userorgname}"
        )

    print("\ntype affirmative to make PRIVATE", "\n".join([repo.full_name for repo in to_act]))
    if input() != "affirmative":
        raise SystemExit("Aborted")

    for repo in to_act:
        repo.edit(private=True)
        print("private:", repo.full_name)
Example #4
0
def main():
    p = ArgumentParser(description="List user/organization repos")
    p.add_argument("user", help="Git remote username / organization name")
    p.add_argument("oauth", help="Oauth filename", nargs="?")
    p.add_argument("-p",
                   "--pattern",
                   help="only repos with name starting with this string")
    p.add_argument("-settings",
                   help="open settings page for each repo",
                   action="store_true")
    p.add_argument("-alerts",
                   help="open alerts page for each repo",
                   action="store_true")
    P = p.parse_args()

    # %% authentication
    sess = gb.session(P.oauth)
    gb.check_api_limit(sess)
    # %% get user / organization handle
    userorg = gb.user_or_org(sess, P.user)
    # %% prepare to loop over repos
    repos = gb.get_repos(userorg)

    if P.pattern:
        repos = (repo for repo in repos if repo.name.startswith(P.pattern))

    for repo in repos:
        print(repo.full_name)
        if P.settings:
            webbrowser.open_new_tab("https://github.com/" + repo.full_name +
                                    "/settings")
        if P.alerts:
            webbrowser.open_new_tab("https://github.com/" + repo.full_name +
                                    "/network/alerts")
Example #5
0
def test_get_repos():
    try:
        userorg = pgu.user_or_org(pgu.session(), OK_username)
        repos = pgu.get_repos(userorg)
    except (ConnectionRefusedError, gexc.RateLimitExceededException):
        pytest.skip("GitHub API limit exceeded")

    assert len(list(repos)) > 0
Example #6
0
def main(username: str, oauth: str, stem: str):
    # %% authentication
    sess = gb.session(P.oauth)
    gb.check_api_limit(sess)
    # %% get user / organization handle
    userorg = gb.user_or_org(sess, P.user)
    # %% prepare to loop over repos
    repos = gb.get_repos(userorg)

    to_act = (repo for repo in repos if repo.name.startswith(stem) and not repo.archived)

    for repo in to_act:
        print(repo.full_name)
def main():
    p = ArgumentParser(description='Set all collaborator permission to "read"')
    p.add_argument("user", help="GitHub username / organizations")
    p.add_argument("oauth", help="Oauth filename")
    p.add_argument("pattern",
                   help="modify repos with name starting with this string")
    p.add_argument("--omit", help="dont consider these admins", nargs="+")
    P = p.parse_args()

    # %% authentication
    sess = gb.session(P.oauth)
    gb.check_api_limit(sess)
    # %% get user / organization handle
    userorg = gb.user_or_org(sess, P.user)
    # %% prepare to loop over repos
    repos = gb.get_repos(userorg)

    to_modify = [repo for repo in repos if repo.name.startswith(P.pattern)]

    print(
        "\ntype affirmative to remove all collaborators from\n",
        "\n".join([repo.full_name for repo in to_modify]),
    )
    modify = input() == "affirmative"

    for repo in to_modify:
        gb.check_api_limit(sess)

        collabs = repo.get_collaborators()

        admins = [c.login for c in collabs if c.login not in P.omit]
        if not admins:
            continue

        print("admins", repo.full_name, " ".join(admins))
        if modify:
            if repo.archived:
                logging.error(
                    f"could not remove collabs from archived {repo.full_name}")
                webbrowser.open_new_tab("https://github.com/" +
                                        repo.full_name + "/settings")
                continue

            for admin in admins:
                repo.remove_from_collaborators(admin)
Example #8
0
def main(username: str, oauth: str, stem: str):
    # %% authentication
    sess = gb.session(P.oauth)
    gb.check_api_limit(sess)
    # %% get user / organization handle
    userorg = gb.user_or_org(sess, P.user)
    # %% prepare to loop over repos
    repos = gb.get_repos(userorg)

    # filter repos
    to_act = (repo for repo in repos if repo.name.startswith(stem)
              and repo.name != ".github" and not repo.fork
              and not repo.archived and repo.owner.login == userorg.login)

    for repo in to_act:
        try:
            repo.get_license()
        except github.GithubException:
            print(repo.full_name)
Example #9
0
def main(user: str, oauth: Path, pattern: str, only_empty: bool) -> typing.List[str]:
    # %% authentication
    sess = gb.session(oauth)
    gb.check_api_limit(sess)
    # %% get user / organization handle
    userorg = gb.user_or_org(sess, user)
    # %% prepare to loop over repos
    repos = gb.get_repos(userorg)

    to_act = (repo for repo in repos if repo.name.startswith(pattern))

    empty: typing.List[str] = []
    for repo in to_act:
        print(f"examining {repo.name}", end="\r")
        authors: typing.Dict[str, int] = {}
        try:
            for commit in repo.get_commits():
                if only_empty:
                    break
                if not commit.stats:  # GitHub API bug?
                    continue
                if commit.stats.total == 0:
                    continue
                if not commit.author:  # GitHub API bug?
                    continue
                if commit.author.login in authors:
                    authors[commit.author.login] += commit.stats.total
                else:
                    authors[commit.author.login] = commit.stats.total
            if not only_empty:
                ax = figure().gca()
                ax.scatter(authors.keys(), authors.values())
                ax.get_yaxis().get_major_formatter().set_useOffset(False)
                ax.set_ylabel("total LoC changed")
                ax.set_yscale("log")
                ax.set_title(repo.name)
        except github.GithubException as exc:
            if "empty" in exc.data["message"]:
                empty.append(repo.name)
    print()  # flush stdout \r

    return sorted(empty)
def main():
    p = ArgumentParser(description="mass copy files by language")
    p.add_argument("copyfn", help="file to copy into repos")
    p.add_argument("targetfn", help="path to copy file into in repos")
    p.add_argument("language", help="coding language to consider (case-sensitive)")
    p.add_argument("oauth", help="Oauth file")
    p.add_argument("userorg", help="Github Username or Organization")
    p.add_argument("-stem", help="beginning of repo names", default="")
    P = p.parse_args()

    language = P.language
    copyfn = Path(P.copyfn).expanduser().resolve(True)
    copy_text = copyfn.read_text()
    target = P.targetfn
    sess = gb.session(P.oauth)
    gb.check_api_limit(sess)
    # %% get user / organization handle
    userorg = gb.user_or_org(sess, P.userorg)
    # %% prepare to loop over repos
    repos = gb.get_repos(userorg)

    to_act = (repo for repo in repos if repo.name.startswith(P.stem))
    for repo in to_act:
        # sometimes a large amount of HTML, CSS, or docs show up as first language.
        langs = repo.get_languages()
        if not langs.get(language):
            continue
        try:
            existing = repo.get_contents(target)
            existing_code = base64.b64decode(existing.content).decode("utf8")
            if existing_code.strip() != copy_text.strip():
                print(repo.full_name, "different from", copyfn)
                repo.update_file(target, "update CI", copy_text, existing.sha)
        except github.GithubException:  # file not exist on remote
            print("copying", copyfn, "to", target, "in", repo.full_name)
            repo.create_file(target, "init CI", copy_text)
Example #11
0
def test_bad_username():
    with pytest.raises(ValueError):
        pgu.user_or_org(pgu.session(), random_username)