예제 #1
0
def _delete_ref(repo, ref_name, force, dry_run):
    ref = repo.ref(ref_name)
    if not ref and not force:
        raise ValueError("Reference not found: %s" % ref_name)
    if not dry_run:
        ref.delete()
    return lib.status("Deleted %s" % ref_name, dry_run=dry_run)
예제 #2
0
def _delete_ref(repo, ref_name, force, dry_run):
  ref = repo.ref(ref_name)
  if not ref and not force:
    raise ValueError("Reference not found: %s" % ref_name)
  if not dry_run:
    ref.delete()
  return lib.status("Deleted %s" % ref_name, dry_run=dry_run)
예제 #3
0
def assemble_authors(config, args):
  """
  Assemble a list of authors as an AUTHORS.md file based on GitHub repo history and a
  authors-info.{yml,json} file.
  """
  github = config.github
  repo = config.repo
  roles_filename = None
  for filename in _ROLES_FILES:
    if os.path.isfile(filename):
      roles_filename = filename

  header = None
  footer = None
  roles = {}
  if roles_filename:
    yield lib.status("Info from: %s" % roles_filename)
    with codecs.open(roles_filename, "r", "utf-8") as f:
      info = yaml.safe_load(f)
      header = info.get("header")
      footer = info.get("footer")
      roles = info.get("roles")
      exclude = info.get("exclude")
  else:
    yield lib.status("No roles file")

  author_list = []
  for contributor in repo.contributors():
    user = github.user(contributor.login)
    author_list.append((user.login, user.name, roles.get(user.login)))

  yield lib.status("Read %s authors" % len(author_list))

  # Sort alphabetically by login.
  author_list.sort(key=lambda (login, name, role): login.lower())

  def format_user(login, name):
    if login and name:
      return u"%s (%s)" % (name, login)
    elif login:
      return login
    else:
      raise ValueError("Missing login name")

  commit_tallies = {}
  for stat in repo.contributor_statistics():
    commit_tallies[stat.author.login] = stat.total

  yield lib.status("Read %s contributor stats" % len(commit_tallies))

  issue_tallies = defaultdict(int)
  for issue in repo.issues(state="all"):
    issue_tallies[issue.user.login] += 1

  yield lib.status("Read %s issues/PRs" % len(issue_tallies))

  with codecs.open("AUTHORS.md", "w", "utf-8") as f:
    f.write(u"# Authors\n\n")
    if header:
      f.write(u"%s\n\n" % header)
    for (login, name, role) in author_list:
      if login in exclude:
        continue

      user_url = "https://github.com/%s" % login
      # Link to commits by that author
      commits_count = commit_tallies.get(login, 0)
      commits_url = "%s/commits?author=%s" % (repo.html_url, urllib.quote_plus(login))
      # Link to issues and PRs by that author.
      issues_count = issue_tallies.get(login, 0)
      issues_url = "%s/issues?q=%s" % (repo.html_url, urllib.quote_plus("author:%s" % login))

      role_str = u" \u2014 _%s_" % role if role else ""
      f.write(u"* [%s](%s) \u2014 [%s+](%s)/[%s+](%s)%s\n" % \
        (format_user(login, name), user_url, commits_count, commits_url, issues_count, issues_url, role_str))
    if footer:
      f.write(u"\n%s\n\n" % footer)

    f.write(u"\n(This file was auto-generated by [ghizmo assemble-authors](https://github.com/jlevy/ghizmo).)")
예제 #4
0
def assemble_authors(config, args):
    """
  Assemble a list of authors as an AUTHORS.md file based on GitHub repo history and a
  authors-info.{yml,json} file.
  """
    github = config.github
    repo = config.repo
    roles_filename = None
    for filename in _ROLES_FILES:
        if os.path.isfile(filename):
            roles_filename = filename

    header = None
    footer = None
    # Assemble roles, keyed by login.
    roles = {}
    if roles_filename:
        yield lib.status("Info from: %s" % roles_filename)
        with codecs.open(roles_filename, "r", "utf-8") as f:
            info = yaml.safe_load(f)
            header = info.get("header")
            footer = info.get("footer")
            roles = info.get("roles")
            exclude = info.get("exclude")
    else:
        yield lib.status("No roles file")

    author_list = []
    for contributor in repo.contributors():
        user = github.user(contributor.login)
        author_list.append((user.login, user, roles.get(user.login)))

    # If any roles are listed but were somehow missing from the contributors return by the API
    # (for example the commits weren't linked up to the account properly), include them too.
    contributors_found = {
        contributor.login
        for contributor in repo.contributors()
    }
    for login in roles:
        if login not in contributors_found:
            user = github.user(login)
            yield lib.status(
                "Author has a role but is not returned by GitHub as a contributor: %s (%s)"
                % (login, user))
            author_list.append((login, user, roles.get(login)))

    yield lib.status("Read %s authors" % len(author_list))

    # Sort alphabetically by login.
    author_list.sort(key=lambda (login, user, role): login.lower())

    def format_user(login, name):
        if login and name:
            return u"%s (%s)" % (name, login)
        elif login:
            return login
        else:
            raise ValueError("Missing login name")

    commit_tallies = {}
    for stat in repo.contributor_statistics():
        yield lib.status("contrib stat: login '%s' total '%s'" %
                         (stat.author.login, stat.total))
        commit_tallies[stat.author.login] = stat.total

    yield lib.status("Read %s contributor stats" % len(commit_tallies))

    issue_tallies = defaultdict(int)
    for issue in repo.issues(state="all"):
        issue_tallies[issue.user.login] += 1

    yield lib.status("Read %s issues/PRs" % len(issue_tallies))

    yield {"commit_tallies": commit_tallies, "issue_tallies": issue_tallies}

    with codecs.open("AUTHORS.md", "w", "utf-8") as f:
        f.write(u"# Authors\n\n")
        if header:
            f.write(u"%s\n\n" % header)
        for (login, user, role) in author_list:
            name = user.name if user else None
            if login in exclude:
                continue

            user_url = "https://github.com/%s" % login if user else None
            # Link to commits by that author
            commits_count = commit_tallies.get(login, 0)
            commits_url = "%s/commits?author=%s" % (repo.html_url,
                                                    urllib.quote_plus(login))
            # Link to issues and PRs by that author.
            issues_count = issue_tallies.get(login, 0)
            issues_url = "%s/issues?q=%s" % (
                repo.html_url, urllib.quote_plus("author:%s" % login))

            yield lib.status("login '%s' commits %s issues %s" %
                             (login, commits_count, issues_count))

            user_link = format_user(login, name)
            if user_url:
                user_link = "[%s](%s)" % (user_link, user_url)
            f.write(u"* %s" % user_link)
            if commits_count or issues_count:
                f.write(u" \u2014 [%s+](%s)/[%s+](%s)" %
                        (commits_count, commits_url, issues_count, issues_url))
            if role:
                f.write(u" \u2014 _%s_" % role)
            f.write("\n")
        if footer:
            f.write(u"\n%s\n\n" % footer)

        f.write(
            u"\n(This file was auto-generated by [ghizmo assemble-authors](https://github.com/jlevy/ghizmo).)"
        )
예제 #5
0
def assemble_authors(config, args):
  """
  Assemble a list of authors as an AUTHORS.md file based on GitHub repo history and a
  authors-info.{yml,json} file. Supports roles (for each person) and groups of people
  (leads, contributors, etc.).
  """
  github = config.github
  repo = config.repo
  authors_info_filename = None
  for filename in _AUTHORS_INFO_FILES:
    if os.path.isfile(filename):
      authors_info_filename = filename

  header = None
  footer = None
  groups = []
  exclude = []
  # Assemble roles, keyed by login.
  roles = {}
  if authors_info_filename:
    yield lib.status("Info from: %s" % authors_info_filename)
    with open(authors_info_filename, "r", encoding="utf-8") as f:
      info = yaml.safe_load(f)
      header = info.get("header")
      footer = info.get("footer")
      roles = info.get("roles")
      groups = info.get("groups")
      exclude = info.get("exclude")
    yield {"roles": roles, "groups": groups}
  else:
    yield lib.status("No roles file")

  login_to_user = {}
  for contributor in repo.contributors():
    user = github.user(contributor.login)
    login_to_user[user.login] = user

  # If any roles are listed but were somehow missing from the contributors return by the API
  # (for example the commits weren't linked up to the account properly), include them too.
  contributors_found = {contributor.login for contributor in repo.contributors()}
  unknown_contributors = []
  for login in roles:
    if login not in contributors_found:
      user = github.user(login)
      if user:
        yield lib.status("Author has a role but is not returned by GitHub as a contributor: %s (%s)" % (login, user))
      else:
        yield lib.status("Author has a role but is not a contributor or a known user: %s [%s]" % (user, type(user)))
        unknown_contributors.append(login)

      login_to_user[login] = user

  yield lib.status("Found %s authors" % len(login_to_user))
  yield lib.status("Found without GitHub user info: %s" % unknown_contributors)

  # Get a list of each group of logins.
  grouped_authors = [[] for g in groups]
  default_group = None
  assigned_logins = set()
  for count, group in enumerate(groups):
    yield lib.status("Group %s: %s" % (count, group))
    group["number"] = count
    if "members" in group:
      members = group["members"]
      assert isinstance(members, list)
      lib.status("members %s" % members)
      for login in members:
        grouped_authors[count].append(login)
        assigned_logins.add(login)
    else:
      yield lib.status("group has no members: %s %s %s" % (count, group, grouped_authors[count]))
      default_group = grouped_authors[count]

  yield {"all_logins": list(login_to_user.keys()), "assigned_logins": list(assigned_logins)}

  # Put all unassigned logins into last group.
  assert default_group is not None, "must have a group with no explicit members for unassigned contributors"
  default_group.extend(set(login_to_user.keys()).difference(assigned_logins))

  # Sort each group alphabetically by login.
  for logins in grouped_authors:
    logins.sort(key=lambda login: login.lower())

  def format_user(login, name):
    if login and name:
      return "%s (%s)" % (name, login)
    elif login:
      return login
    else:
      raise ValueError("Missing login name")

  commit_tallies = {}
  for stat in repo.contributor_statistics():
    yield lib.status("contrib stat: login '%s' total '%s'" % (stat.author.login, stat.total))
    commit_tallies[stat.author.login] = stat.total

  yield lib.status("Read %s contributor stats" % len(commit_tallies))

  issue_tallies = defaultdict(int)
  for issue in repo.issues(state="all"):
    issue_tallies[issue.user.login] += 1

  yield lib.status("Read %s issues/PRs" % len(issue_tallies))

  yield {"commit_tallies": commit_tallies, "issue_tallies": issue_tallies}

  with open("AUTHORS.md", "w", encoding="utf-8") as f:
    f.write("# Authors\n\n")
    if header:
      f.write("%s\n\n" % header)
    for group_number, logins in enumerate(grouped_authors):

      f.write("\n*%s*\n\n" % groups[group_number]["name"])

      for login in logins:
        user = login_to_user.get(login)
        role = roles.get(login)

        name = user.name if user else None
        if login in exclude:
          continue

        user_url = "https://github.com/%s" % login if user else None
        # Link to commits by that author
        commits_count = commit_tallies.get(login, 0)
        commits_url = "%s/commits?author=%s" % (repo.html_url, urllib.parse.quote_plus(login))
        # Link to issues and PRs by that author.
        issues_count = issue_tallies.get(login, 0)
        issues_url = "%s/issues?q=%s" % (repo.html_url, urllib.parse.quote_plus("author:%s" % login))

        yield lib.status("login '%s' commits %s issues %s" % (login, commits_count, issues_count))

        user_link = format_user(login, name)
        if user_url:
          user_link = "[%s](%s)" % (user_link, user_url)
        f.write("* %s" % user_link)
        if commits_count or issues_count:
          f.write(" — [%s+](%s)/[%s+](%s)" % (commits_count, commits_url, issues_count, issues_url))
        if role:
          f.write(" — _%s_" % role)
        f.write("\n")

    if footer:
      f.write("\n%s\n\n" % footer)

    f.write("\n(This file was auto-generated by [ghizmo assemble-authors](https://github.com/jlevy/ghizmo).)")
예제 #6
0
파일: authors.py 프로젝트: jlevy/ghizmo
def assemble_authors(config, args):
  """
  Assemble a list of authors as an AUTHORS.md file based on GitHub repo history and a
  authors-info.{yml,json} file.
  """
  github = config.github
  repo = config.repo
  roles_filename = None
  for filename in _ROLES_FILES:
    if os.path.isfile(filename):
      roles_filename = filename

  header = None
  footer = None
  # Assemble roles, keyed by login.
  roles = {}
  if roles_filename:
    yield lib.status("Info from: %s" % roles_filename)
    with codecs.open(roles_filename, "r", "utf-8") as f:
      info = yaml.safe_load(f)
      header = info.get("header")
      footer = info.get("footer")
      roles = info.get("roles")
      exclude = info.get("exclude")
  else:
    yield lib.status("No roles file")

  author_list = []
  for contributor in repo.contributors():
    user = github.user(contributor.login)
    author_list.append((user.login, user, roles.get(user.login)))

  # If any roles are listed but were somehow missing from the contributors return by the API
  # (for example the commits weren't linked up to the account properly), include them too.
  contributors_found = { contributor.login for contributor in repo.contributors() }
  for login in roles:
    if login not in contributors_found:
      user = github.user(login)
      yield lib.status("Author has a role but is not returned by GitHub as a contributor: %s (%s)" % (login, user))
      author_list.append((login, user, roles.get(login)))

  yield lib.status("Read %s authors" % len(author_list))

  # Sort alphabetically by login, with assigned roles grouped first.
  author_list.sort(key=lambda (login, user, role): ((0 if role else 1), login.lower()))

  def format_user(login, name):
    if login and name:
      return u"%s (%s)" % (name, login)
    elif login:
      return login
    else:
      raise ValueError("Missing login name")

  commit_tallies = {}
  for stat in repo.contributor_statistics():
    yield lib.status("contrib stat: login '%s' total '%s'" % (stat.author.login, stat.total))
    commit_tallies[stat.author.login] = stat.total

  yield lib.status("Read %s contributor stats" % len(commit_tallies))

  issue_tallies = defaultdict(int)
  for issue in repo.issues(state="all"):
    issue_tallies[issue.user.login] += 1

  yield lib.status("Read %s issues/PRs" % len(issue_tallies))

  yield { "commit_tallies": commit_tallies, "issue_tallies": issue_tallies }

  with codecs.open("AUTHORS.md", "w", "utf-8") as f:
    f.write(u"# Authors\n\n")
    if header:
      f.write(u"%s\n\n" % header)
    for (login, user, role) in author_list:
      name = user.name if user else None
      if login in exclude:
        continue

      user_url = "https://github.com/%s" % login if user else None
      # Link to commits by that author
      commits_count = commit_tallies.get(login, 0)
      commits_url = "%s/commits?author=%s" % (repo.html_url, urllib.quote_plus(login))
      # Link to issues and PRs by that author.
      issues_count = issue_tallies.get(login, 0)
      issues_url = "%s/issues?q=%s" % (repo.html_url, urllib.quote_plus("author:%s" % login))

      yield lib.status("login '%s' commits %s issues %s" % (login, commits_count, issues_count))

      user_link = format_user(login, name)
      if user_url:
        user_link = "[%s](%s)" % (user_link, user_url)
      f.write(u"* %s" % user_link)
      if commits_count or issues_count:
        f.write(u" \u2014 [%s+](%s)/[%s+](%s)" % (commits_count, commits_url, issues_count, issues_url))
      if role:
        f.write(u" \u2014 _%s_" % role)
      f.write("\n")
    if footer:
      f.write(u"\n%s\n\n" % footer)

    f.write(u"\n(This file was auto-generated by [ghizmo assemble-authors](https://github.com/jlevy/ghizmo).)")