aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden
diff options
context:
space:
mode:
authorJacek Antonelli2010-03-07 19:20:40 -0600
committerJacek Antonelli2010-03-13 01:29:24 -0600
commitf1756949176ee999bae594c33d8b10a9f574fb7e (patch)
tree8427940ee9e12660fbb5c07a90718982021fbfd6 /linden
parentFixed a possible crash related to ShowLookAt targets. (diff)
downloadmeta-impy-f1756949176ee999bae594c33d8b10a9f574fb7e.zip
meta-impy-f1756949176ee999bae594c33d8b10a9f574fb7e.tar.gz
meta-impy-f1756949176ee999bae594c33d8b10a9f574fb7e.tar.bz2
meta-impy-f1756949176ee999bae594c33d8b10a9f574fb7e.tar.xz
ChangeLog.txt is now generated from the Git log at compile time.
It is no longer version controlled and should not be editted manually. Put '@nochangelog' in commit messages to omit them from the log. See linden/scripts/make_changelog.py for more information.
Diffstat (limited to 'linden')
-rw-r--r--linden/indra/newview/CMakeLists.txt8
-rwxr-xr-xlinden/scripts/make_changelog.py432
2 files changed, 440 insertions, 0 deletions
diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt
index 464bb83..514811d 100644
--- a/linden/indra/newview/CMakeLists.txt
+++ b/linden/indra/newview/CMakeLists.txt
@@ -1384,6 +1384,14 @@ check_message_template(${VIEWER_BINARY_NAME})
1384set(PACKAGE OFF CACHE BOOL 1384set(PACKAGE OFF CACHE BOOL
1385 "Add a package target that builds an installer package.") 1385 "Add a package target that builds an installer package.")
1386 1386
1387
1388add_custom_target(
1389 ChangeLog ALL
1390 COMMAND ${PYTHON_EXECUTABLE} ${SCRIPTS_DIR}/make_changelog.py
1391 COMMENT "Generating ChangeLog.txt."
1392 )
1393
1394
1387if (WINDOWS) 1395if (WINDOWS)
1388 if(MSVC71) 1396 if(MSVC71)
1389 set(release_flags "/MAP:Release/${VIEWER_BINARY_NAME}.map /MAPINFO:LINES") 1397 set(release_flags "/MAP:Release/${VIEWER_BINARY_NAME}.map /MAPINFO:LINES")
diff --git a/linden/scripts/make_changelog.py b/linden/scripts/make_changelog.py
new file mode 100755
index 0000000..759dffd
--- /dev/null
+++ b/linden/scripts/make_changelog.py
@@ -0,0 +1,432 @@
1#!/usr/bin/env python
2#
3# @file make_changelog.py
4# @brief Generates Imprudence's ChangeLog.txt from Git commit messages.
5#
6# Copyright (c) 2010, Jacek Antonelli
7#
8# The source code in this file is provided to you under the terms of
9# the GNU General Public License, version 2.0 ("GPL"). Terms of the
10# GPL can be found in doc/GPL-license.txt in this distribution, or
11# online at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
12#
13# By copying, modifying or distributing this software, you acknowledge
14# that you have read and understood your obligations described above,
15# and agree to abide by those obligations.
16#
17# ALL SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO
18# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
19# COMPLETENESS OR PERFORMANCE.
20#
21
22
23# This script generates ChangeLog.txt (in the the imprudence root
24# directory) from the commit messages in the git repository. It parses
25# the output from 'git log', then prints the log entries in a nicely
26# formatted way, omitting unimportant or unwanted commits.
27#
28# A commit will be omitted if any of the following are true:
29#
30# * It is listed in SPECIAL_COMMITS below with "-".
31# * It has "@nochangelog" in its commit message (but not
32# "@forcechangelog" or "@shortchangelog").
33# * It is a merge commit (i.e. has multiple parent commits).
34# * It is a plain SL source commit ("Second Life viewer sources ...").
35#
36# But even if the above are true, it WILL be included if any of the
37# following are true:
38#
39# * It is listed in SPECIAL_COMMITS below with "+" or "S".
40# * It has "@forcechangelog" or "@shortchangelog" in its commit
41# message (but not "@nochangelog").
42#
43# By default, the ChangeLog will list the files that were modified,
44# added, or deleted for each commit. But, that list will be omitted
45# (or summarized) if any of the following are true:
46#
47# * More than 10 files were changed.
48# * It is listed in SPECIAL_COMMITS below with "S".
49# * It has "@shortchangelog" in its commit message.
50#
51
52
53
54import commands, re, os.path, sys
55from string import Template
56
57
58SCRIPT_DIR = os.path.abspath( os.path.dirname( sys.argv[0] ) )
59ROOT_DIR = os.path.normpath( os.path.join(SCRIPT_DIR, "..", "..") )
60CHANGELOG = os.path.join(ROOT_DIR, "ChangeLog.txt")
61
62
63# Commit IDs that should be treated specially.
64#
65# IDs with "+" will always be included, even if they would have been
66# omitted for some other reason (such as being a merge commit).
67#
68# IDs with "-" will be omitted (equivalent to @nochangelog)
69#
70# IDs with "S" will always be included (like "+"), but will hide or
71# summarize the list of changed files (equivalent to @shortchangelog)
72
73SPECIAL_COMMITS = {
74
75 # Merge commits that ARE worth mentioning.
76 "13c27361136819af0d0a0f72eeb807f56829337f" : "+",
77 "499afbab7be4c4136eea0e1897319c3ac4e9799d" : "+",
78 "4bbee8774d743fb4787fc2435a20d89539011fa4" : "+",
79 "6a5aab98892df74f60743f5b789959c9593d6647" : "+",
80 "6e1e243da8c06ddd6847576c55e134d72ef42491" : "+",
81 "87c760f959788e3ec9dc06cbd2207d0242b6a4c9" : "+",
82 "8f50d81693ff9463ae49c36935977a2b70e6bf45" : "+",
83 "94a57bea1504f2f7024264b15c3ed532d49d3ab0" : "+",
84 "96aaf4408601768d1d277bd63e6a1c91295c4c5a" : "+",
85 "9a4f5702473e7540cde1bbff2d7189d9ed71fd86" : "+",
86
87 # Mention the first SL version Imprudence is based on (1.20.15)
88 "31ba61e675d42675c6c6cd1077a93e0c5e055114" : "S",
89
90 # Project early setup. Not worth mentioning.
91 "6f0d1dc6b922f1b103a8933a03c4ed5e10b290ef" : "-",
92 "993bca391adf825dcf139d516c17dfdca0832bc8" : "-",
93 "e8ca04117d66356e8fe514d617d1da2d9b49a927" : "-",
94 "ec8b17013071896e7228c7d0032d3bfc44697c3a" : "-",
95 "f258e5d9af1087cab2be36a8c143815300187d62" : "-",
96 "f37093d4dda55fd77bc9228c9fb359d46d4f1715" : "-",
97
98 # Whitespace and line ending changes. Not worth mentioning.
99 "285dcc2660ef0ed31bfbdc4f0a5cc53f40e90e36" : "-",
100 "44dc53ef5d8f770412c2f7675b9ebfdeb3c2b698" : "-",
101 "451aad0c993856f380d976de3d7fe343ad5f9811" : "-",
102 "45beb0b1d8a16522dfc33894f4b69ee9a4b33efc" : "-",
103 "567586af40a1683a3c89863c9dbedd2b3cc90897" : "-",
104 "5bd80f31b2a6d06f6b84e444ed84b744bfebc311" : "-",
105 "65272bae7013a785cb4e1dccb810e58e9f7fdfda" : "-",
106 "8186bd3db550d2a5cafd840679e8b13ff10a82b5" : "-",
107 "87494eab8a1221ccb35e91c14d242e4cfaab28c8" : "-",
108 "93eb46dcb67e35e99e3f68b4cb23ee9bf2fbb2d8" : "-",
109 "a86dba93c641056fc08ff9dc4bd173bc4b56036f" : "-",
110 "b055fc86474cce8854cadadccec61f10dc6ef003" : "-",
111 "c05810ec6ce1cb1fb40915b2b16f44c2600c6483" : "-",
112 "cf4ee03e4415d599c10729d920a1c085aed411ed" : "-",
113 "e20f3bb7c3310deca86cfc66af0a086261930bcf" : "-",
114
115 # ChangeLog edits. Not worth mentioning.
116 "0ee6701062d0506a725cd4ba9cd533ec4c46eb68" : "-",
117 "197b6a954d37e46af91a474de1565b43e24e8c60" : "-",
118 "2027db4808f36bcc230686f31dea3810d594701e" : "-",
119 "2583bbaf227abd654cd87760bf6c646909b38229" : "-",
120 "388810f1cb7505c7888f6aa77306554b99430202" : "-",
121 "6b270891b1b64e26a5c07e9239b925527e7be4c2" : "-",
122 "6e99cd9128a04ce8b5daa9b1c5c17c7b86e8a058" : "-",
123 "78cff2cb53235979d452b877192523a030686f89" : "-",
124 "818367f405a550e95c265d26c7011a5a1f892ec7" : "-",
125 "87c7622724089f7a06b6559c9e1103e2f7bac2ef" : "-",
126 "925975639a2438bc9bdf43a0ceaab1c4555052b0" : "-",
127 "96aaf4408601768d1d277bd63e6a1c91295c4c5a" : "-",
128 "9f89d959d4596a5e4918806efc2e5dd044cabc62" : "-",
129 "a03abda0f0671ce69b9579b9fcf3d9d499080a5d" : "-",
130 "b2efe398cd2a506fe47a6143ea54e08b1f4cbbc7" : "-",
131 "b31f72f11b75cf0c7965d8170600e1352988dc25" : "-",
132 "b33c4cfbbc49bb6c66e7bdd53d3a2245e1c6a2c9" : "-",
133 "b5068c60260646572d3dad166e11c943050b8bd6" : "-",
134 "cdd95787ae40cd1ea3776d2322ec529a5a232fc7" : "-",
135 "d53da842e2f259282fb83c01ea742d80f7d2735e" : "-",
136 "d6552c4c9c10a886ea19768e0097b7344809ea02" : "-",
137 "ded2589eae6e392d2ff973d882a0182d2af199cf" : "-",
138 "ea8040185053bd2807d0cfdf5cd018f08df10ed1" : "-",
139 "ebce3d7682489151a6fc48a923c7154dad401219" : "-",
140 "ed6a76513af6a7de5963517e19982293d418ddef" : "-",
141 "eeb428b559f482b03ac1002a391a5df3e1512e9a" : "-",
142 "f0acc222f33936756297a8240bcfc72c2f9ba891" : "-",
143
144 # Release notes edits. Not worth mentioning.
145 "08161bf33c3e17ec81c0d66cb7d2fda678ff6a17" : "-",
146 "4f1e0a28875a8c54790d07442bfc3875f903b3c2" : "-",
147 "60c7bcbed46bbc266beb642a71018b18c213078e" : "-",
148 "8a662850a3ddae4485270c59e9f93c95691f5050" : "-",
149 "c34a99c0b18d1122d5613c0048e572d70e7ce751" : "-",
150
151 # Duplicates of other commits. Not worth mentioning.
152 "23ab8d114f3038b8425613cd0c74adb160d0bf2f" : "-",
153 "3a84d8017df08447b14161cee3c24382f8f96013" : "-",
154 "6a7a1881a3fde403e9dacd638d10d457c50ab19e" : "-",
155 "d345613880689d38fe6418f47dc19ae855849f92" : "-",
156
157 # Miscellaneous insignificant things.
158 "16751a56c0c465f90cb14f65483f967acb1220ae" : "-",
159 "25919b3c9601918dbddaccb07ef48fc14a546cf1" : "-",
160 "25ee74981392a1f1fde299f8ecf243a6b257e3ae" : "-",
161 "5be6de589be48be699d8aa46593d0a0d3e88f46a" : "-",
162 "686b994f11a5e7ec2c11e40dc3ca8178c47decdf" : "-",
163 "9625d9f3253e0aa4ca8a68380c6303f0b8d36dbe" : "-",
164 "a4ecbdbba79e49ce5653101c6c71f8b5df7e0fc5" : "-",
165 "e563b107a2b58935ef8c3ab2cfdfdbc2d7cdfa2d" : "-",
166 "e7c2d187818158c1c27f87056fba82b0e8077263" : "-",
167
168 # Spammy and uninformative.
169 "7f090f7bec5264ca9e203c27dfb6b2992bb2bcbd" : "-",
170 "844025196a1b9a5944cac292dbc162bdd24ac5af" : "-",
171
172 # Tsk tsk, McCabe has a potty mouth.
173 "7624d729930c331494c7391e3fbc596b31309782" : "-",
174 "a67f7ec260b20474cee3c2edca3c3f4ea331c815" : "-",
175
176}
177
178
179
180class LogEntry:
181 "Stores and formats a Git log entry"
182
183 # A horizontal line to put between log entries
184 separator = "-" * 79
185
186
187 def __init__(self, git_text):
188 "Creates a LogEntry from a commit output from `git log`"
189
190 self.id = "" # commit id
191 self.merge = False # is a merge commit?
192 self.author_name = ""
193 self.author_mail = ""
194 self.author_date = ""
195 self.commit_name = "" # committer name
196 self.commit_mail = ""
197 self.commit_date = ""
198 self.message = [] # lines of the message
199 self.files = [] # modified/added/deleted files
200 self.special = "" # handle this commit in a special way?
201
202 lines = git_text.splitlines()
203
204 # First line is always commit id.
205 self.id = lines[0]
206
207 for line in lines[1:]:
208
209 # is it a merge?
210 if re.match("Merge: +([0-9a-f]+ *){2,}", line):
211 self.merge = True
212
213 # author name
214 match = re.match("Author: +([^<]+) <([^>]+)>", line)
215 if match:
216 self.author_name = match.group(1)
217 self.author_mail = match.group(2)
218
219 # author date
220 match = re.match("AuthorDate: +(.+)", line)
221 if match:
222 self.author_date = match.group(1)
223
224 # commit name
225 match = re.match("Commit: +([^<]+) <([^>]+)>", line)
226 if match:
227 self.commit_name = match.group(1)
228 self.commit_mail = match.group(2)
229
230 # commit date
231 match = re.match("CommitDate: +(.+)", line)
232 if match:
233 self.commit_date = match.group(1)
234
235 # message (and notes)
236 if re.match("[\t ]+", line):
237 self.message.append(line[4:])
238
239 # modified/added/deleted files (but ignore ChangeLog.txt)
240 if re.match("[MAD][\t ]+", line) and \
241 not re.match("[MAD][\t ]+ChangeLog.txt", line):
242 self.files.append(line)
243
244 self.author_name, self.author_mail = \
245 self.fix_name_email( self.author_name, self.author_mail )
246
247 self.commit_name, self.commit_mail = \
248 self.fix_name_email( self.commit_name, self.commit_mail )
249
250 try:
251 self.special = SPECIAL_COMMITS[self.id]
252 except KeyError:
253 pass
254
255 # If there's no special already, scan the message for @directives.
256 if not self.special:
257 for line in self.message:
258 # Omit commits with @nochangelog in the message
259 if("@nochangelog" in line):
260 self.special = "-"
261 # Don't show file changes for commits with @shortchangelog
262 elif("@shortchangelog" in line):
263 self.special = "S"
264 # Always include commits with @forcechangelog
265 elif("@forcechangelog" in line):
266 self.special = "+"
267
268
269 def fix_name_email( self, name, email ):
270 """Some commits have a bad name or email address.
271 This function returns the proper name and address."""
272
273 if email in ["Adric@.(none)", "hakushakukun@gmail.com"]:
274 return ["McCabe Maxsted", "hakushakukun@gmail.com"]
275
276 if email in ["Kakurady@.(none)", "kakurady@gmail.com"]:
277 return ["Kakurady (Geneko Nemeth)", "kakurady@gmail.com"]
278
279 # Nothing to fix.
280 return [name, email]
281
282
283 def should_be_included(self):
284 """Returns True if the commit should be included in the
285 ChangeLog, or False if it should be omitted."""
286
287 # Include commits marked with "+" or "S" in special_commits.txt
288 if self.special in ["+", "S"]:
289 return True
290
291 # Omit commits marked with "-" in special_commits.txt
292 if self.special == "-":
293 return False
294
295 # Omit merge commits
296 if self.merge:
297 return False
298
299 # Omit vanilla SL source commits
300 if self.message[0].startswith("Second Life viewer sources"):
301 return False
302
303 # Include everything else
304 return True
305
306
307 def format(self):
308 "Formats the LogEntry prettily."
309 texts=[LogEntry.separator]
310
311 texts.append("""
312Date: {ad} ({id})
313Author: {an} <{ae}>""".format(ad = self.author_date,
314 an = self.author_name,
315 ae = self.author_mail,
316 id = self.id[0:7]))
317
318 if self.commit_name != self.author_name:
319 texts.append("Committer: {cn} <{ce}>".format(
320 cn = self.commit_name,
321 ce = self.commit_mail))
322
323 texts.append("\n")
324
325 for line in self.message:
326 # Remove @...changelog directives
327 rxp = re.compile("@(short|no)changelog")
328 if rxp.search(line):
329 line = rxp.sub("", line)
330 # Skip this line if it was empty except for @...changelog
331 if not line.strip():
332 continue
333
334 # Skip modified/deleted/new file lines.
335 if re.match("[ \t]+(modified|deleted|new file): +.+", line):
336 continue
337
338 # Skip all the rest of the lines.
339 if re.match("Conflicts:$", line):
340 break
341
342 texts.append( (" "*2 + line.replace("\t"," "*4)).rstrip() )
343
344 # Delete all empty lines at the end
345 while not texts[-1].strip():
346 del texts[-1]
347
348 # Don't list files if it's a short changelog or there are more
349 # than ten files to list.
350 if self.special == "S" or len(self.files) > 10:
351 texts.append("\n (File changes omitted for brevity.)")
352 else:
353 if self.files:
354 texts.append("\n")
355 for line in self.files:
356 texts.append( " "*2 + line.replace("\t"," "*2) )
357
358 texts.append("\n")
359
360 return "\n".join(texts)
361
362
363
364
365def main():
366 commits = sys.argv[1:]
367 if commits:
368 commits = " ".join(commits)
369 else:
370 commits = "HEAD"
371
372
373 # Fetch the log entries from git in one big chunk.
374 cmd = "git log --pretty=fuller --name-status --date=short --date-order --show-notes {commits}".format(commits = commits)
375 status, output = commands.getstatusoutput(cmd)
376
377
378 # If the git command failed, write a placeholder ChangeLog.txt and exit.
379 if status != 0:
380 print "Could not generate ChangeLog.txt: " + output
381 with open(CHANGELOG, "w") as changelog:
382 changelog.write("\n (Imprudence must be compiled from a Git repository to generate a ChangeLog.)\n\n")
383 exit(0)
384
385
386 # Split it up into individual commits.
387 logs = re.compile("^commit ", re.MULTILINE).split(output)[1:]
388
389
390 # Introductory header that goes at the top of the ChangeLog.
391 header="""
392
393 CHANGELOG
394 for the Imprudence Viewer
395 http://imprudenceviewer.org
396
397
398 This is a log of revisions to the Imprudence Viewer source code.
399 If you are looking for an overview of new features and changes in
400 each release, please see RELEASE_NOTES.txt instead.
401
402 This file is automatically generated from the Git commit history.
403 Be aware that it is NOT ORDERED BY DATE, but rather by ancestry.
404 Some commits have been omitted from this list for brevity.
405
406 File changes are annotated as follows:
407
408 A = the file was added
409 M = the file was modified
410 D = the file was deleted
411
412 For a full history of the source code, including diffs, please see
413 the Git repository.
414
415
416"""
417
418 output = [header]
419
420 for log in logs:
421 entry = LogEntry(log)
422 if entry.should_be_included():
423 output.append( entry.format() )
424
425 text = "\n".join(output)
426
427 with open(CHANGELOG, "w") as changelog:
428 changelog.write(text)
429
430
431if __name__ == "__main__":
432 main()