Merge lp:~widelands-dev/widelands/automate_clang-format into lp:widelands

Proposed by GunChleoc
Status: Merged
Merged at revision: 8200
Proposed branch: lp:~widelands-dev/widelands/automate_clang-format
Merge into: lp:widelands
Diff against target: 401 lines (+171/-123)
3 files modified
utils/fix_formatting.py (+48/-16)
utils/merge_and_push_translations.sh (+10/-0)
utils/update_authors.py (+113/-107)
To merge this branch: bzr merge lp:~widelands-dev/widelands/automate_clang-format
Reviewer Review Type Date Requested Status
SirVer Approve
GunChleoc Needs Resubmitting
Review via email: mp+312287@code.launchpad.net

Commit message

Moved utils/fix_lua_tabs.py to utils/fix_formatting.py and added calls to clang-format any pyformat.

Description of the change

I think it would be a good idea to automate clang-format - it is starting to cost me real time when I work on a branch and trunk hasn't been formatted properly.

Can this be added to the bunnybot merge command once we have this in trunk? I'm thinking bzr merge, clang-format, bzr commit here.

To post a comment you must log in.
Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 1679. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/180479785.
Appveyor build 1519. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_automate_clang_format-1519.

Revision history for this message
SirVer (sirver) wrote :

> Can this be added to the bunnybot merge command once we have this in trunk? I'm thinking bzr merge, clang-format, bzr commit here.

Yes, it probably can. If I can figure out how to install clang-format on the buildbot. I'll have a look.

A couple of nits inlined.

Revision history for this message
GunChleoc (gunchleoc) wrote :

Thanks - all fixed.

I was just thinking - we also have fix_lua_tabs.py, which is run when we update the translations.

How about having 1 central script "fix_formating.py" that does the following:

- fix_lua_tabs.py
- run_clang_format.py
- run pyformat over utils.

This script could then be called both by merge_and_push_translations.sh and bunnybot.

Revision history for this message
SirVer (sirver) wrote :

Sgtm.

> Am 03.12.2016 um 14:39 schrieb GunChleoc <email address hidden>:
>
> Thanks - all fixed.
>
> I was just thinking - we also have fix_lua_tabs.py, which is run when we update the translations.
>
> How about having 1 central script "fix_formating.py" that does the following:
>
> - fix_lua_tabs.py
> - run_clang_format.py
> - run pyformat over utils.
>
> This script could then be called both by merge_and_push_translations.sh and bunnybot.
> --
> https://code.launchpad.net/~widelands-dev/widelands/automate_clang-format/+merge/312287
> You are requested to review the proposed merge of lp:~widelands-dev/widelands/automate_clang-format into lp:widelands.

Revision history for this message
GunChleoc (gunchleoc) wrote :

Will do that in this branch then.

Revision history for this message
GunChleoc (gunchleoc) wrote :

Done. Never mind the big diff for udate_authors.py, the relevant bit is the removed call at the bottom. Pyformat already in action here ;)

review: Needs Resubmitting
Revision history for this message
SirVer (sirver) wrote :

pretty hard to review this diff with the formatting changes. I found two nits, I think otherwise this is ready to merge.

review: Approve
Revision history for this message
GunChleoc (gunchleoc) wrote :

Thanks for the review!

So, pyformat doesn't fix long lines, need to keep that in mind.

@bunnybot merge

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== renamed file 'utils/fix_lua_tabs.py' => 'utils/fix_formatting.py'
2--- utils/fix_lua_tabs.py 2015-10-31 12:11:44 +0000
3+++ utils/fix_formatting.py 2016-12-04 06:44:59 +0000
4@@ -2,29 +2,38 @@
5 # -*- coding: utf-8 -*-
6
7
8-"""The code base had inconsistent usage of tabs/spaces for indenting in Lua
9+"""The code base had inconsistent usage of tabs/spaces for indenting in Lua.
10+
11 files. Spaces were more prominent - and I prefer them over tabs. So I wrote
12 this small script to fix leading tabs in Lua files to spaces.
13
14 It also saves files in unix file endings ("\r\n") and strips empty lines at the
15 end of files and whitespace characters at the end of lines.
16+
17+After fixing the Lua tabs, this script also executes clang-format over the src
18+directory and pyformat over the utils directory.
19+
20 """
21
22 import argparse
23 import os
24 import re
25 import sys
26+from subprocess import call
27
28 LEADING_TABS = re.compile(r'^\s*\t+\s*')
29 PYTHON3 = sys.version_info >= (3, 0)
30 SPACES_PER_TAB = 3
31
32+
33 def parse_args():
34- p = argparse.ArgumentParser(description=
35- "Fix common whitespace errors in Lua files. Recurses over all Lua files."
36- )
37+ p = argparse.ArgumentParser(
38+ description='Fix common whitespace errors in Lua files, run clang-format'
39+ ' over the code base and pyformat over the utils directory.'
40+ ' Recurses over all relevant files.')
41 return p.parse_args()
42
43+
44 def read_text_file(filename):
45 """Reads the contens of a text file."""
46 if PYTHON3:
47@@ -32,6 +41,7 @@
48 else:
49 return open(filename, 'r').read().decode('utf-8')
50
51+
52 def write_text_file(filename, content):
53 """Writes 'content' into a text file."""
54 if PYTHON3:
55@@ -39,30 +49,52 @@
56 else:
57 open(filename, 'w').write(content.encode('utf-8'))
58
59-def find_lua_files():
60- for (dirpath, _, filenames) in os.walk("."):
61+
62+def find_files(startpath, extensions):
63+ for (dirpath, _, filenames) in os.walk(startpath):
64 for filename in filenames:
65- if os.path.splitext(filename)[-1].lower() == ".lua":
66+ if os.path.splitext(filename)[-1].lower() in extensions:
67 yield os.path.join(dirpath, filename)
68
69+
70 def main():
71 parse_args()
72
73- if not os.path.isdir("src") or not os.path.isdir("utils"):
74- print("CWD is not the root of the repository.")
75+ if not os.path.isdir('src') or not os.path.isdir('utils'):
76+ print('CWD is not the root of the repository.')
77 return 1
78
79- for filename in find_lua_files():
80- print "Fixing %r" % filename
81- lines = read_text_file(filename).strip().split("\n")
82+ sys.stdout.write('Fixing Lua tabs ')
83+ for filename in find_files('.', ['.lua']):
84+ sys.stdout.write('.')
85+ sys.stdout.flush()
86+ lines = read_text_file(filename).strip().split('\n')
87 new_lines = []
88 for line in lines:
89 m = LEADING_TABS.match(line)
90 if m is not None:
91- line = line[m.start():m.end()].expandtabs(SPACES_PER_TAB) + line[m.end():]
92- new_lines.append(line.rstrip() + "\n")
93- write_text_file(filename, "".join(new_lines))
94+ line = line[m.start():m.end()].expandtabs(
95+ SPACES_PER_TAB) + line[m.end():]
96+ new_lines.append(line.rstrip() + '\n')
97+ write_text_file(filename, ''.join(new_lines))
98+ print(' done.')
99+
100+ sys.stdout.write('\nFormatting C++ ')
101+ for filename in find_files('./src', ['.cc', '.h']):
102+ sys.stdout.write('.')
103+ sys.stdout.flush()
104+ call(['clang-format', '-i', filename])
105+ print(' done.')
106+
107+ sys.stdout.write('\nFormatting Python utils ')
108+ for filename in find_files('./utils', ['.py']):
109+ sys.stdout.write('.')
110+ sys.stdout.flush()
111+ call(['pyformat', '-i', filename])
112+ print(' done.')
113+
114+ print 'Formatting finished.'
115 return 0
116
117-if __name__ == "__main__":
118+if __name__ == '__main__':
119 sys.exit(main())
120
121=== modified file 'utils/merge_and_push_translations.sh'
122--- utils/merge_and_push_translations.sh 2016-07-25 11:47:16 +0000
123+++ utils/merge_and_push_translations.sh 2016-12-04 06:44:59 +0000
124@@ -57,6 +57,16 @@
125 exit 1;
126 fi
127
128+# Fix formatting
129+utils/fix_formatting.py
130+if [ $? -eq 0 ]
131+then
132+ echo "Fixed formatting";
133+else
134+ echo "Failed to fix formatting";
135+ exit 1;
136+fi
137+
138 # Fix line breaks.
139 # TODO(GunChleoc): We hope that Transifex will fix these already.
140 # This script can be removed if we don't get any errors in the future.
141
142=== modified file 'utils/update_authors.py'
143--- utils/update_authors.py 2016-11-12 17:59:50 +0000
144+++ utils/update_authors.py 2016-12-04 06:44:59 +0000
145@@ -13,25 +13,26 @@
146 # and writes the translator and developer credits to ./txts/developers.lua
147 # The locale information is written to ../data/i18n/locales.lua.
148
149-base_path = os.path.abspath(os.path.join(os.path.dirname(__file__),os.path.pardir))
150-
151-print("Reading locales from JSON:")
152-
153-source_path = os.path.normpath(base_path + "/data/i18n/locales")
154+base_path = os.path.abspath(os.path.join(
155+ os.path.dirname(__file__), os.path.pardir))
156+
157+print('Reading locales from JSON:')
158+
159+source_path = os.path.normpath(base_path + '/data/i18n/locales')
160
161 if (not os.path.isdir(source_path)):
162- print("Error: Path " + source_path + " not found.")
163- sys.exit(1)
164+ print('Error: Path ' + source_path + ' not found.')
165+ sys.exit(1)
166
167 # Each language's translators live in a separate file, so we list the dir
168 source_files = sorted(os.listdir(source_path), key=str.lower)
169
170-lua_locales = "-- This file is generated by utils/update_authors.py.\n"
171-lua_locales += "-- The locale data is managed in Transifex.\n\n"
172-lua_locales += "return {\n"
173-lua_locales += "\t-- Locales are identified by their ISO code.\n"
174+lua_locales = '-- This file is generated by utils/update_authors.py.\n'
175+lua_locales += '-- The locale data is managed in Transifex.\n\n'
176+lua_locales += 'return {\n'
177+lua_locales += '\t-- Locales are identified by their ISO code.\n'
178 lua_locales += ' \ten = {\n'
179-lua_locales += "\t\t-- Used to display the locale in the Options menu.\n"
180+lua_locales += '\t\t-- Used to display the locale in the Options menu.\n'
181 lua_locales += '\t\tname = "English",\n\n'
182 lua_locales += "\t\t-- Defines the language's position on the list in the Options menu.\n"
183 lua_locales += '\t\tsort_name = "English",\n\n'
184@@ -39,117 +40,122 @@
185 lua_locales += '\t\tfont = "default"\n'
186 lua_locales += '\t},\n'
187
188-lua_translators = ""
189-lua_translators += "function translators() return {" # developers
190+lua_translators = ''
191+lua_translators += 'function translators() return {' # developers
192
193 for source_filename in source_files:
194- # Only json files, and not the template file please
195- if source_filename.endswith(".json") and source_filename != "locales_translators.json":
196- source_file = open(source_path + "/" + source_filename, "r")
197- translators = json.load(source_file)
198- locale_message = "- Added"
199-
200- # Parsing translator credits
201- # Make sure we don't pick up untranslated stuff
202- if translators["translator-list"] != 'translator-credits':
203- locale_message += " translators and"
204- lua_translators += '{' # entry
205- lua_translators += 'heading = "' + translators["your-language-name"]
206- if translators["your-language-name-in-english"] != 'English' and translators["your-language-name-in-english"] != translators["your-language-name"] :
207- lua_translators += ' (' + translators["your-language-name-in-english"] + ')'
208- lua_translators += '",'
209- lua_translators += 'entries = {' # entries
210- lua_translators += '{' # entry
211- lua_translators += 'members = {' # members
212- for transl_name in translators["translator-list"].split("\n"):
213- lua_translators += '"' + transl_name + '",'
214- lua_translators += "}," # members
215- lua_translators += "}," # entry
216- lua_translators += "}," # entries
217- lua_translators += "}," # entry
218-
219- # Parsing locale info
220- # Make sure we don't pick up untranslated stuff
221- locale_code = source_filename.split(".json")[0]
222- locale_message += " locale info for " + locale_code
223- lua_locales += '\n\t' + locale_code + ' = {\n' # entry with locale code
224-
225- if translators["your-language-name"] != 'English' or locale_code == 'en':
226- lua_locales += '\t\tname = "' + translators["your-language-name"] + '",\n'
227- else:
228- lua_locales += '\t\tname = "' + locale_code + '",\n'
229-
230- if translators["language-sort-name"] != 'English' or locale_code == 'en':
231- lua_locales += '\t\tsort_name = "' + translators["language-sort-name"] + '",\n'
232- else:
233- lua_locales += '\t\tsort_name = "' + locale_code + '",\n'
234-
235- lua_locales += '\t\tfont = "' + translators["font-set"] + '"\n'
236- lua_locales += "\t},\n" # entry
237- print(locale_message)
238-lua_locales += "}\n"
239-
240-lua_translators += "} end" # developers
241-
242-print("Writing locales\n")
243-dest_filename = "locales.lua"
244-dest_filepath = os.path.normpath(base_path + "/data/i18n") + "/" + dest_filename
245+ # Only json files, and not the template file please
246+ if source_filename.endswith('.json') and source_filename != 'locales_translators.json':
247+ source_file = open(source_path + '/' + source_filename, 'r')
248+ translators = json.load(source_file)
249+ locale_message = '- Added'
250+
251+ # Parsing translator credits
252+ # Make sure we don't pick up untranslated stuff
253+ if translators['translator-list'] != 'translator-credits':
254+ locale_message += ' translators and'
255+ lua_translators += '{' # entry
256+ lua_translators += 'heading = "' + \
257+ translators['your-language-name']
258+ if translators['your-language-name-in-english'] != 'English' and translators['your-language-name-in-english'] != translators['your-language-name']:
259+ lua_translators += ' (' + \
260+ translators['your-language-name-in-english'] + ')'
261+ lua_translators += '",'
262+ lua_translators += 'entries = {' # entries
263+ lua_translators += '{' # entry
264+ lua_translators += 'members = {' # members
265+ for transl_name in translators['translator-list'].split('\n'):
266+ lua_translators += '"' + transl_name + '",'
267+ lua_translators += '},' # members
268+ lua_translators += '},' # entry
269+ lua_translators += '},' # entries
270+ lua_translators += '},' # entry
271+
272+ # Parsing locale info
273+ # Make sure we don't pick up untranslated stuff
274+ locale_code = source_filename.split('.json')[0]
275+ locale_message += ' locale info for ' + locale_code
276+ lua_locales += '\n\t' + locale_code + \
277+ ' = {\n' # entry with locale code
278+
279+ if translators['your-language-name'] != 'English' or locale_code == 'en':
280+ lua_locales += '\t\tname = "' + \
281+ translators['your-language-name'] + '",\n'
282+ else:
283+ lua_locales += '\t\tname = "' + locale_code + '",\n'
284+
285+ if translators['language-sort-name'] != 'English' or locale_code == 'en':
286+ lua_locales += '\t\tsort_name = "' + \
287+ translators['language-sort-name'] + '",\n'
288+ else:
289+ lua_locales += '\t\tsort_name = "' + locale_code + '",\n'
290+
291+ lua_locales += '\t\tfont = "' + translators['font-set'] + '"\n'
292+ lua_locales += '\t},\n' # entry
293+ print(locale_message)
294+lua_locales += '}\n'
295+
296+lua_translators += '} end' # developers
297+
298+print('Writing locales\n')
299+dest_filename = 'locales.lua'
300+dest_filepath = os.path.normpath(
301+ base_path + '/data/i18n') + '/' + dest_filename
302 dest_file = codecs.open(dest_filepath, encoding='utf-8', mode='w')
303 dest_file.write(lua_locales)
304
305-print("Writing translators\n")
306-dest_filename = "translators_data.lua"
307-dest_filepath = os.path.normpath(base_path + "/data/txts") + "/" + dest_filename
308+print('Writing translators\n')
309+dest_filename = 'translators_data.lua'
310+dest_filepath = os.path.normpath(
311+ base_path + '/data/txts') + '/' + dest_filename
312 dest_file = codecs.open(dest_filepath, encoding='utf-8', mode='w')
313 dest_file.write(lua_translators)
314
315-print("Reading developers from JSON")
316-source_path = os.path.normpath(base_path + "/data/txts")
317+print('Reading developers from JSON')
318+source_path = os.path.normpath(base_path + '/data/txts')
319
320 if (not os.path.isdir(source_path)):
321- print("Error: Path " + source_path + " not found.")
322- sys.exit(1)
323+ print('Error: Path ' + source_path + ' not found.')
324+ sys.exit(1)
325
326-source_file = open(source_path + "/developers.json", "r")
327-developers = json.load(source_file)["developers"]
328+source_file = open(source_path + '/developers.json', 'r')
329+developers = json.load(source_file)['developers']
330
331 lua_string = """-- Do not edit this file - it is automatically generated
332 -- by utils/update_authors.py from developers.json.
333 """
334-lua_string += "function developers() return {" # developers
335+lua_string += 'function developers() return {' # developers
336
337 for category in developers:
338- print("- Adding " + category["heading"])
339- if category["heading"] != "Translators": # Unused hook for adding translators
340- lua_string += '{' # category
341- lua_string += 'heading = _"' + category["heading"] + '",' # This will be localized
342- lua_string += 'image = "' + category["image"] + '",'
343-
344- lua_string += 'entries = {' # entries
345-
346- for subcategory in category["entries"]:
347- lua_string += '{' # entry
348- if 'subheading' in subcategory:
349- lua_string += 'subheading = _"' + subcategory["subheading"] + '",' # This will be localized
350-
351- lua_string += 'members = {' # members
352- for member in subcategory["members"]:
353- lua_string += '"' + member + '",'
354- lua_string += "}," # members
355-
356- lua_string += "}," # entry
357- lua_string += "}," # entries
358-
359- lua_string += "}," # category
360-lua_string += "} end\n" # developers
361-
362-print("Writing developers")
363-dest_filename = "developers.lua"
364-dest_filepath = source_path + "/" + dest_filename
365+ print('- Adding ' + category['heading'])
366+ if category['heading'] != 'Translators': # Unused hook for adding translators
367+ lua_string += '{' # category
368+ lua_string += 'heading = _"' + \
369+ category['heading'] + '",' # This will be localized
370+ lua_string += 'image = "' + category['image'] + '",'
371+
372+ lua_string += 'entries = {' # entries
373+
374+ for subcategory in category['entries']:
375+ lua_string += '{' # entry
376+ if 'subheading' in subcategory:
377+ lua_string += 'subheading = _"' + \
378+ subcategory['subheading'] + '",' # This will be localized
379+
380+ lua_string += 'members = {' # members
381+ for member in subcategory['members']:
382+ lua_string += '"' + member + '",'
383+ lua_string += '},' # members
384+
385+ lua_string += '},' # entry
386+ lua_string += '},' # entries
387+
388+ lua_string += '},' # category
389+lua_string += '} end\n' # developers
390+
391+print('Writing developers')
392+dest_filename = 'developers.lua'
393+dest_filepath = source_path + '/' + dest_filename
394 dest_file = codecs.open(dest_filepath, encoding='utf-8', mode='w')
395 dest_file.write(lua_string)
396-
397-print("Fixing the formatting")
398-import fix_lua_tabs
399-fix_lua_tabs.main()
400-print("Done.")
401+print('Done.')

Subscribers

People subscribed via source and target branches

to status/vote changes: