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

Side by Side Diff: tools/llvm/diff-diff.py

Issue 8391032: Part 2 of 3: Moving tools/llvm to pnacl/ (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client/
Patch Set: '' Created 9 years, 1 month 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 | « tools/llvm/common-tools.sh ('k') | tools/llvm/gutman.sh » ('j') | 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/python
2 # Copyright 2011 The Native Client Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can
4 # be found in the LICENSE file.
5
6 import sys
7 import subprocess
8 import os
9 import tempfile
10
11 def main():
12 if len(sys.argv) not in (2,3):
13 print "Syntax: %s <repo_dir> [merge_rev]" % (sys.argv[0])
14 print "If merge_rev is omitted, this script produces a"
15 print "diff-diff of the merge in the working directory."
16 sys.exit(0)
17
18 repo_dir = sys.argv[1]
19 merge_rev = None
20 if len(sys.argv) == 3:
21 merge_rev = sys.argv[2]
22
23 diffdiff(repo_dir, merge_rev)
24 return 0
25
26 def diffdiff(repo_dir, merge_rev = None):
27 """ Print the 'diff diff' of a merge.
28
29 This is roughly equivalent to doing:
30 hg diff vendor:pnacl-sfi > tmp1 (before the merge)
31 hg diff vendor:pnacl-sfi > tmp2 (after the merge)
32 diff tmp1 tmp2 (this is the diff-diff)
33
34 If merge_rev is None, prints the diff-diff of the
35 current merge in progress (in the working directory).
36 If merge_rev is specified, the diff-diff of an previous
37 (already committed) merge is generated."""
38
39 entries = GetMercurialLog(repo_dir)
40
41 if merge_rev:
42 if merge_rev not in entries:
43 Fatal("Can't find revision '%s'" % merge_rev)
44 cur = entries[merge_rev]
45 if len(cur['parent']) != 2:
46 Fatal("Specified revision is not a merge!")
47 p1,p2 = cur['parent']
48 else:
49 cur = None
50 p1,p2 = GetWorkingDirParents(entries, repo_dir)
51
52 # Make p1 the "vendor" branch parent
53 if p2['branch'] == 'vendor':
54 p1,p2 = p2,p1
55
56 # Identify and verify the situation
57 if cur:
58 assert(cur['branch'] == 'pnacl-sfi')
59 assert(p1['branch'] == 'vendor')
60 assert(p2['branch'] == 'pnacl-sfi')
61 assert(len(p1['parent']) == 1)
62 prev_vendor = p1['parent'][0]
63 prev_merge = FindPreviousMerge(p2)
64 assert(prev_vendor['branch'] == 'vendor')
65 assert(prev_merge['branch'] == 'pnacl-sfi')
66 assert(prev_vendor in prev_merge['parent'])
67
68 diff1 = MakeTemp(hg_diff(repo_dir, prev_vendor, p2))
69 diff2 = MakeTemp(hg_diff(repo_dir, p1, cur))
70
71 out,err,ret = Run(None, ['diff',diff1,diff2], errexit=False)
72 if ret == 2:
73 Fatal("diff failed (%d): %s" % (ret, err))
74 if ret == 0:
75 Fatal("diff output empty")
76 if ret != 1:
77 Fatal("Unexpected return value from diff (%d)" % ret)
78 sys.stdout.write(out)
79
80 DeleteTemp(diff1)
81 DeleteTemp(diff2)
82 return 0
83
84 def hg_diff(dir, r1, r2):
85 assert(r1 is not None)
86 if r2 is None:
87 return Run(dir, "hg diff -r %s" % r1['changeset'])
88 else:
89 return Run(dir, "hg diff -r %s:%s" % (r1['changeset'], r2['changeset']))
90
91 def MakeTemp(contents):
92 """ Create a temporary file with specific contents,
93 and return the filename """
94
95 f,tempname = tempfile.mkstemp(prefix='diff-diff-tmp')
96 f = open(tempname, 'w')
97 f.write(contents)
98 f.close()
99 return tempname
100
101 def DeleteTemp(tempname):
102 os.remove(tempname)
103
104 def Fatal(msg):
105 print msg
106 sys.exit(1)
107
108 def Run(dir, args, errexit=True):
109 if isinstance(args, str):
110 args = args.split(' ')
111 p = subprocess.Popen(args, cwd=dir,
112 stdout=subprocess.PIPE,
113 stderr=subprocess.PIPE)
114 out, err = p.communicate()
115 if not errexit:
116 return out, err, p.returncode
117 if p.returncode:
118 Fatal("%s (%d): (STDERR): %s" % (' '.join(args), p.returncode, err))
119 if len(err) > 0:
120 Fatal("%s (STDERR): %s" % (' '.join(args), err))
121 return out
122
123
124 def GetWorkingDirParents(entries, dir):
125 out = Run(dir, 'hg identify -i')
126 revs = out.split('+')
127
128 # If this is a merge, hg identify -i returns:
129 # changeset1+changeset2+
130 if len(revs) != 3:
131 Fatal("Working directory is not a merge. Please specify a revision!")
132 return entries[revs[0]], entries[revs[1]]
133
134 def GetMercurialLog(dir):
135 """ Read the Mercurial log into a dictionary of log entries """
136 entries = []
137 out = Run(dir, 'hg log')
138 blocks = out.strip().split('\n\n')
139 for b in blocks:
140 entry = dict()
141 entry['parent'] = []
142 for line in b.split('\n'):
143 sep = line.find(':')
144 tag = line[0:sep]
145 val = line[sep+1:].strip()
146 if tag == 'parent':
147 entry[tag] = entry[tag] + [ val ]
148 else:
149 entry[tag] = val
150 entries.append(entry)
151
152 # Remove revision ids
153 for entry in entries:
154 entry['changeset'] = entry['changeset'].split(':')[1]
155 entry['parent'] = [ s.split(':')[1] for s in entry['parent'] ]
156
157 # Add missing parent info for consecutive entries
158 last_entry = []
159 for entry in reversed(entries):
160 if len(entry['parent']) == 0:
161 entry['parent'] = last_entry
162 last_entry = [ entry['changeset'] ]
163
164 # Convert to a dictionary indexed by changeset
165 entries = dict([(entry['changeset'], entry) for entry in entries])
166
167 # Convert the parents to direct entry references
168 for cs, entry in entries.iteritems():
169 entry['parent'] = [ entries[r] for r in entry['parent'] ]
170
171 return entries
172
173 def FindPreviousMerge(entry):
174 p = entry
175 while len(p['parent']) == 1:
176 p = p['parent'][0]
177 if len(p['parent']) != 2:
178 Fatal("Couldn't find previous merge for %s!" % entry['changeset'])
179 return p
180
181 if __name__ == '__main__':
182 sys.exit(main())
OLDNEW
« no previous file with comments | « tools/llvm/common-tools.sh ('k') | tools/llvm/gutman.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698