<commit_before>#!/usr/bin/env python
"""
Script to edit downstream PRs with CHANGELOG release note and label metadata.

Usage:
  ./downstream_changelog_info.py path/to/.git/.id
  python /downstream_changelog_info.py

Note that release_note/labels are authoritative - if empty or not set in the MM
upstream PR, release notes will be removed from downstreams and labels
unset.
"""
from pyutils import strutils, downstreams
from github import Github
import os
import sys
import argparse

CHANGELOG_LABEL_PREFIX = "changelog: "

def downstream_changelog_info(gh, upstream_pr_num, changelog_repos):
  """Edit downstream PRs with CHANGELOG info.

  Args:
    gh: github.Github client
    upstream_pr_num: Upstream PR number
    changelog_repos: List of repo names to downstream changelog metadata for
  """
  # Parse CHANGELOG info from upstream
  print "Fetching upstream PR '%s'..." % upstream_pr_num
  upstream_pr = gh.get_repo(downstreams.UPSTREAM_REPO)\
                  .get_pull(upstream_pr_num)
  release_note = strutils.get_release_note(upstream_pr.body)
  labels_to_add = strutils.find_prefixed_labels(
    [l.name for l in upstream_pr.labels],
    CHANGELOG_LABEL_PREFIX)

  if not labels_to_add and not release_note:
    print "No release note or labels found, skipping PR %d" % (
      upstream_pr_num)
    return

  print "Found changelog info on upstream PR %d:" % (
    upstream_pr.number)
  print "Release Note: \"%s\"" % release_note
  print "Labels: %s" % labels_to_add

  parsed_urls = downstreams.get_parsed_downstream_urls(gh, upstream_pr.number)
  if not parsed_urls:
    print "No downstreams found for upstream PR %d, returning!" % (
      upstream_pr.number)
    return

  for repo_name, pulls in parsed_urls:
    print "Found downstream PR for repo %s" % repo_name
    
    if repo_name not in changelog_repos:
      print "[DEBUG] skipping repo %s with no CHANGELOG" % repo_name
      continue

    print "Generating changelog for pull requests in %s" % repo_name
    
    print "Fetching repo %s" % repo_name
    ghrepo = gh.get_repo(repo_name)

    for _r, prnum in pulls:
      print "Fetching %s PR %d" % repo_name, prnum
      pr = ghrepo.get_pull(int(prnum))
      set_changelog_info(pr, release_note, labels_to_add)

def set_changelog_info(gh_pull, release_note, labels_to_add):
  """Set release note and labels on a downstream PR in Github.

  Args:
    gh_pull: A github.PullRequest.PullRequest handle
    release_note: String of release note text to set
    labels_to_add: List of strings. Changelog-related labels to add/replace.
  """
  print "Setting changelog info for downstream PR %d" % prnum
  edited_body = strutils.set_release_note(release_note, gh_pull.body)
  gh_pull.edit(body=edited_body)<commit_msg>parens around format string (#2196)<commit_after>#!/usr/bin/env python
"""
Script to edit downstream PRs with CHANGELOG release note and label metadata.

Usage:
  ./downstream_changelog_info.py path/to/.git/.id
  python /downstream_changelog_info.py

Note that release_note/labels are authoritative - if empty or not set in the MM
upstream PR, release notes will be removed from downstreams and labels
unset.
"""
from pyutils import strutils, downstreams
from github import Github
import os
import sys
import argparse

CHANGELOG_LABEL_PREFIX = "changelog: "

def downstream_changelog_info(gh, upstream_pr_num, changelog_repos):
  """Edit downstream PRs with CHANGELOG info.

  Args:
    gh: github.Github client
    upstream_pr_num: Upstream PR number
    changelog_repos: List of repo names to downstream changelog metadata for
  """
  # Parse CHANGELOG info from upstream
  print "Fetching upstream PR '%s'..." % upstream_pr_num
  upstream_pr = gh.get_repo(downstreams.UPSTREAM_REPO)\
                  .get_pull(upstream_pr_num)
  release_note = strutils.get_release_note(upstream_pr.body)
  labels_to_add = strutils.find_prefixed_labels(
    [l.name for l in upstream_pr.labels],
    CHANGELOG_LABEL_PREFIX)

  if not labels_to_add and not release_note:
    print "No release note or labels found, skipping PR %d" % (
      upstream_pr_num)
    return

  print "Found changelog info on upstream PR %d:" % (
    upstream_pr.number)
  print "Release Note: \"%s\"" % release_note
  print "Labels: %s" % labels_to_add

  parsed_urls = downstreams.get_parsed_downstream_urls(gh, upstream_pr.number)
  if not parsed_urls:
    print "No downstreams found for upstream PR %d, returning!" % (
      upstream_pr.number)
    return

  for repo_name, pulls in parsed_urls:
    print "Found downstream PR for repo %s" % repo_name
    
    if repo_name not in changelog_repos:
      print "[DEBUG] skipping repo %s with no CHANGELOG" % repo_name
      continue

    print "Generating changelog for pull requests in %s" % repo_name
    
    print "Fetching repo %s" % repo_name
    ghrepo = gh.get_repo(repo_name)

    for _r, prnum in pulls:
      print "Fetching %s PR %d" % (repo_name, prnum)
      pr = ghrepo.get_pull(int(prnum))
      set_changelog_info(pr, release_note, labels_to_add)

def set_changelog_info(gh_pull, release_note, labels_to_add):
  """Set release note and labels on a downstream PR in Github.

  Args:
    gh_pull: A github.PullRequest.PullRequest handle
    release_note: String of release note text to set
    labels_to_add: List of strings. Changelog-related labels to add/replace.
  """
  print "Setting changelog info for downstream PR %d" % prnum
  edited_body = strutils.set_release_note(release_note, gh_pull.body)
  gh_pull.edit(body=edited_body)
{'fraction_non_alphanumeric': 0.07704858593183467, 'fraction_numerical': 0.0007251631617113851, 'mean_word_length': 3.91273374888691, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6607622', 'n_tokens_mistral': 1884, 'n_tokens_neox': 1812, 'n_words': 555}