Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(469)

Side by Side Diff: trychange_git.py

Issue 23205010: Create trychange_git.py, for starting tryjobs in a pure-git world. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Better build properties. Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """Client-side script to send local git changes to a tryserver.
7
8 It pushes the local feature branch to a private ref on googlesource
9 and posts a description of the job to an appengine instance, where it will get
10 picked up by the buildbot tryserver itself.
11 """
12
13 from __future__ import print_function
14
15 import json
16 import os
17 import subprocess
18 import sys
19 import urllib
20
21
22 def DieWithError(msg):
23 """Prints the message to stderr and exits."""
24 print(msg, file=sys.stderr)
25 sys.exit(1)
26
27
28 def RunGit(*args, **kwargs):
29 """Runs the given git command with arguments, or dies.
30
31 Passes the given kwargs (e.g. cwd or env) through to subprocess."""
32 cmd = ('git',) + args
33 try:
34 return subprocess.check_output(cmd, **kwargs).strip()
35 except subprocess.CalledProcessError as e:
36 DieWithError('Command "%s" failed.\n%s' % (' '.join(cmd), e))
37
38
39 def EnsureInGitRepo():
40 """Quick sanity check to make sure we're in a git repo."""
41 if not RunGit('rev-parse', '--is-inside-work-tree') == 'true':
42 DieWithError('You don\'t appear to be inside a git repository.')
43
44
45 def GetCodeReviewSettings():
46 """Reads codereview.settings and returns a dict of settings."""
47 top_dir = RunGit('rev-parse', '--show-toplevel')
48 this_dir = os.getcwd()
49 assert this_dir.startswith(top_dir), (top_dir, this_dir)
50
51 settings_file = os.path.join(this_dir, 'codereview.settings')
52 while not os.path.isfile(settings_file):
53 this_dir = os.path.split(this_dir)[0]
54 if not this_dir.startswith(top_dir):
55 DieWithError('Unable to find codereview.settings in this repo.')
56 settings_file = os.path.join(this_dir, 'codereview.settings')
57
58 settings = {}
59 with open(settings_file, 'r') as f:
60 for line in f.readlines():
61 if line.startswith('#'):
62 continue
63 k, v = line.split(':', 1)
64 settings[k.strip()] = v.strip()
65 return settings
66
67
68 def PushBranch():
69 """Pushes the current local branch to a ref in the try repo.
70
71 The try repo is either the remote called 'try', or 'origin' otherwise.
72 The ref is '/refs/try/<username>/<local branch>-<short hash>.
73
74 Returns the ref to which the local branch was pushed."""
75 username = RunGit('config', '--get', 'user.email').split('@', 1)[0]
76 branch = RunGit('symbolic-ref', '--short', '-q', 'HEAD')
77 commit = RunGit('rev-parse', branch)[:8]
78 remotes = RunGit('remote').splitlines()
79 if not all((username, branch, commit, remotes)):
80 DieWithError('Unable to get necessary git configuration.')
81
82 remote = 'try' if 'try' in remotes else 'origin'
83 ref = 'refs/try/%s/%s-%s' % (username, branch, commit)
84
85 RunGit('push', remote, '%s:%s' % (branch, ref))
86 return ref
87
88
89 def MakeJob(project, jobname, ref):
90 """Creates a job description blob."""
91 email = RunGit('config', '--get', 'user.email')
92 repository = RunGit('config', '--get', 'remote.origin.url')
93 job = {
94 # Fields for buildbot sourcestamp.
95 'project': project,
96 'repository': repository,
97 'branch': ref,
98 'revision': 'HEAD',
99 # Fields for buildbot builder factory.
100 'buildername': jobname,
101 'recipe': project,
102 # Other useful fields.
103 'blamelist': [email],
104 }
105 return json.dumps(job)
106
107
108 def PostJob(server, project, job):
109 """POSTs the job description blob to the tryserver instance."""
110 url = '%s/%s/push' % (server, project)
111 data = urllib.urlencode({'job': job})
112 try:
113 conn = urllib.urlopen(url, data)
114 except IOError as e:
115 DieWithError(e)
116 response = conn.getcode()
117 if response != 200:
118 DieWithError('Failed to POST. Got: %d' % response)
119
120
121 def Main(argv):
122 """Main entry point."""
123 EnsureInGitRepo()
124
125 settings = GetCodeReviewSettings()
126 server = settings.get('TRYSERVER_HTTP_HOST')
cmp 2013/08/20 05:52:29 It would be for the best to enforce that TRYSERVER
agable 2013/08/20 07:48:08 Done.
127 project = settings.get('TRYSERVER_PROJECT')
128 jobnames = settings.get('TRYSERVER_JOB_NAME')
129 if not all((server, project, jobnames)):
130 DieWithError('Missing configuration in codereview.settings.')
131
132 ref = PushBranch()
133 for jobname in jobnames.split(','):
134 job = MakeJob(project, jobname, ref)
135 PostJob(server, project, job)
136
137
138 if __name__ == "__main__":
cmp 2013/08/20 05:52:29 single quotes here instead of double quotes
agable 2013/08/20 07:48:08 Done.
139 sys.exit(Main(sys.argv))
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698