1#!/usr/bin/env python 2# 3# Copyright 2019 Google Inc. 4# 5# Use of this source code is governed by a BSD-style license that can be 6# found in the LICENSE file. 7 8 9import os 10import re 11import subprocess 12import sys 13 14from infra import git 15from infra import go 16 17_TOOLS_DIR = os.path.dirname(os.path.abspath(__file__)) 18_REPO_ROOT = os.path.realpath(os.path.join(_TOOLS_DIR, os.pardir)) 19_INFRA_BOTS = os.path.join(_REPO_ROOT, 'infra', 'bots') 20sys.path.insert(0, _INFRA_BOTS) 21import git_utils 22 23 24REFS_HEADS_PREFIX = 'refs/heads/' 25CHROME_REF_PREFIX = REFS_HEADS_PREFIX + 'chrome/m' 26SK_MILESTONE_H = os.path.join('include', 'core', 'SkMilestone.h') 27SK_MILESTONE_TMPL = r'#define SK_MILESTONE %s' 28SK_MILESTONE_RE = SK_MILESTONE_TMPL % r'(\d+)' 29SKIA_REPO = 'https://skia.googlesource.com/skia.git' 30SUPPORTED_CHROME_BRANCHES = 2 # Per infra policy; see skbug.com/8940 31UPDATE_MILESTONE_COMMIT_MSG = '''Update Skia milestone to %d''' 32 33 34def get_current_milestone(): 35 '''Read SkMilestone.h and parse out the current milestone.''' 36 sk_milestone = os.path.join(_REPO_ROOT, SK_MILESTONE_H) 37 with open(sk_milestone, 'r') as f: 38 contents = f.read() 39 for line in contents.splitlines(): 40 m = re.match(SK_MILESTONE_RE, line) 41 if m: 42 return int(m.groups()[0]) 43 print >> sys.stderr, ( 44 'Failed to parse %s; has the format changed?' % SK_MILESTONE_H) 45 sys.exit(1) 46 47 48def create_new_branch(new_branch, branch_at): 49 '''Create a temporary checkout of the repo, create the new branch and push.''' 50 b = new_branch[len(REFS_HEADS_PREFIX):] 51 with git_utils.NewGitCheckout(SKIA_REPO, local=_REPO_ROOT): 52 git.git('checkout', '-b', b) 53 git.git('reset', '--hard', branch_at) 54 git.git('push', '--set-upstream', 'origin', b) 55 56 57def update_milestone(m): 58 '''Update SkMilestone.h to match the given milestone number.''' 59 with git_utils.NewGitCheckout(SKIA_REPO, local=_REPO_ROOT): 60 with git_utils.GitBranch( 61 'update_milestone', UPDATE_MILESTONE_COMMIT_MSG % m): 62 with open(SK_MILESTONE_H, 'r+') as f: 63 contents = re.sub( 64 SK_MILESTONE_RE, SK_MILESTONE_TMPL % str(m), f.read(), flags=re.M) 65 f.seek(0) 66 f.write(contents) 67 f.truncate() 68 git.git('diff') 69 70 71def update_infra_config(old_branch, new_branch): 72 '''Create a CL to add infra support for the new branch and remove the old.''' 73 owner = git.git('config', 'user.email').rstrip() 74 if not owner: 75 print >> sys.stderr, ('No configured git user; please run ' 76 '"git config user.email <your email>".') 77 sys.exit(1) 78 go.get(go.INFRA_GO+'/go/supported_branches/cmd/new-branch') 79 subprocess.check_call(['new-branch', 80 '--branch', new_branch[len(REFS_HEADS_PREFIX):], 81 '--delete', old_branch[len(REFS_HEADS_PREFIX):], 82 '--owner', owner, 83 '--exclude-trybots=chromium.*', 84 '--exclude-trybots=.*Android_Framework.*']) 85 86 87def main(): 88 if len(sys.argv) != 2 or '--help' in sys.argv or '-h' in sys.argv: 89 print >> sys.stderr, 'Usage: %s <commit hash for branch>' % sys.argv[0] 90 sys.exit(1) 91 go.check() 92 branch_at = sys.argv[1] 93 m = get_current_milestone() 94 new_branch = '%s%d' % (CHROME_REF_PREFIX, m) 95 old_branch = '%s%d' % (CHROME_REF_PREFIX, m-SUPPORTED_CHROME_BRANCHES) 96 print 'Creating branch %s and removing support (eg. CQ) for %s' % ( 97 new_branch, old_branch) 98 create_new_branch(new_branch, branch_at) 99 update_milestone(m+1) 100 update_infra_config(old_branch, new_branch) 101 102 103if __name__ == '__main__': 104 main() 105