OLD | NEW |
| (Empty) |
1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 """ Changes builder names in the expected factory configurations. """ | |
6 | |
7 | |
8 import os | |
9 import json | |
10 import re | |
11 import subprocess | |
12 import sys | |
13 | |
14 | |
15 EXPECTED_DIR = os.path.join(os.path.dirname(__file__), 'expected') | |
16 if os.name == 'nt': | |
17 SVN = 'svn.bat' | |
18 else: | |
19 SVN = 'svn' | |
20 | |
21 | |
22 def CheckName(builder_name): | |
23 """ Make sure that the builder name contains no illegal characters. """ | |
24 if not re.match('^[\w\-_\.]+$', builder_name): | |
25 raise ValueError('"%s" is not a valid builder name.' % builder_name) | |
26 | |
27 | |
28 def ExistingBuilders(): | |
29 """ List the existing set of builder names. """ | |
30 builders = os.listdir(EXPECTED_DIR) | |
31 builders.sort() | |
32 for builder_file in builders: | |
33 if not builder_file.startswith('.'): | |
34 yield builder_file | |
35 | |
36 | |
37 def CreateMappingTemplate(mapping_file): | |
38 """ Creates a JSON file containing a template for mapping old builder names to | |
39 new builder names. """ | |
40 mapping = {} | |
41 for builder_file in ExistingBuilders(): | |
42 mapping[builder_file] = '' | |
43 with open(mapping_file, 'w') as f: | |
44 json.dump(mapping, f, indent=4, sort_keys=True) | |
45 print 'Created mapping template file in %s' % mapping_file | |
46 | |
47 | |
48 def Rename(old_name, new_name): | |
49 """ "Rename" a builder. Runs "svn mv" to create the new expectations file, | |
50 then replaces all instances of the old builder name with the new in that file. | |
51 """ | |
52 print 'Changing "%s" to "%s".' % (old_name, new_name) | |
53 old_file_path = os.path.join(EXPECTED_DIR, old_name) | |
54 new_file_path = os.path.join(EXPECTED_DIR, new_name) | |
55 | |
56 # Verify the new file names. | |
57 CheckName(old_name) | |
58 CheckName(new_name) | |
59 if not os.path.isfile(old_file_path): | |
60 raise Exception('Config file for "%s" does not exist!' % old_file_path) | |
61 if os.path.isfile(new_file_path): | |
62 raise Exception('Config file for "%s" already exists!' % new_file_path) | |
63 | |
64 # Read the old builder configuration. | |
65 with open(old_file_path) as old_file: | |
66 old_file_contents = old_file.read() | |
67 | |
68 # Use "svn mv" to create the new file so that the diff only shows the changes. | |
69 subprocess.call([SVN, 'mv', old_file_path, new_file_path]) | |
70 | |
71 # Replace any instances of old_name with new_name in file_contents. | |
72 new_file_contents = old_file_contents.replace(old_name, new_name) | |
73 | |
74 # Write the new builder configuration. | |
75 with open(new_file_path, 'w') as new_file: | |
76 new_file.write(new_file_contents) | |
77 | |
78 | |
79 def Usage(err_msg=None): | |
80 if err_msg: | |
81 print 'Error: %s\n' % err_msg | |
82 print """rename_builders.py: Rename builders and update expectations files. | |
83 | |
84 Options: | |
85 -h, --help Display this message. | |
86 -t, --create-mapping-template Create a JSON template file for the mapping. | |
87 | |
88 Example usage: | |
89 | |
90 Create a mapping template file to be filled in manually. File name is optional, | |
91 default is "mapping.json". | |
92 $ rename_builders.py -t [filename] | |
93 | |
94 Map builders using a mapping file. | |
95 $ rename_builders.py <filename> | |
96 | |
97 Interactive. Given each old builder name, prompts for the new name. | |
98 $ rename_builders.py | |
99 | |
100 """ | |
101 sys.exit(1) | |
102 | |
103 | |
104 def main(argv): | |
105 if len(argv) > 1: | |
106 if argv[1] == '--help' or argv[1] == '-h': | |
107 Usage() | |
108 if argv[1] == '--create-mapping-template' or argv[1] == '-t': | |
109 if len(argv) == 3: | |
110 mapping_file = argv[2] | |
111 elif len(argv) == 2: | |
112 mapping_file = 'mapping.json' | |
113 else: | |
114 Usage('Too many arguments provided.') | |
115 CreateMappingTemplate(mapping_file) | |
116 return | |
117 else: | |
118 if len(argv) != 2: | |
119 Usage('Too many arguments provided.') | |
120 if not os.path.isfile(argv[1]): | |
121 Usage('Please provide a mapping file.') | |
122 with open(argv[1]) as f: | |
123 mapping = json.load(f) | |
124 for builder_file in ExistingBuilders(): | |
125 if not builder_file in mapping: | |
126 raise Exception('Your mapping file contains no mapping for "%s"' % \ | |
127 builder_file) | |
128 else: | |
129 print ('No mapping file provided. Next time you can provide a ' | |
130 'JSON-formatted file which maps old names to new names.') | |
131 mapping = {} | |
132 for builder_file in ExistingBuilders(): | |
133 new_name = raw_input('New name for %s: ' % builder_file) | |
134 mapping[builder_file] = new_name | |
135 break | |
136 | |
137 for old_name, new_name in mapping.iteritems(): | |
138 Rename(old_name, new_name) | |
139 | |
140 | |
141 if '__main__' == __name__: | |
142 sys.exit(main(sys.argv)) | |
OLD | NEW |