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

Side by Side Diff: tools/migration/bin/migrate_batch.dart

Issue 2989033002: Migrate status file entries when migrating files. Yay! (Closed)
Patch Set: Created 3 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
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /// Given the beginning and ending file names in a batch, does as much automated 5 /// Given the beginning and ending file names in a batch, does as much automated
6 /// migration and possible and prints out the remaining manual steps required. 6 /// migration and possible and prints out the remaining manual steps required.
7 /// 7 ///
8 /// This should be safe to run, and safe to re-run on an in-progress chunk. 8 /// This should be safe to run, and safe to re-run on an in-progress chunk.
9 /// However, it has not been thoroughly tested, so run at your own risk. 9 /// However, it has not been thoroughly tested, so run at your own risk.
10 10
11 import 'dart:io'; 11 import 'dart:io';
12 12
13 import 'package:path/path.dart' as p; 13 import 'package:path/path.dart' as p;
14 import 'package:status_file/status_file.dart';
15 14
16 import 'package:migration/src/fork.dart'; 15 import 'package:migration/src/fork.dart';
17 import 'package:migration/src/io.dart'; 16 import 'package:migration/src/io.dart';
18 import 'package:migration/src/log.dart'; 17 import 'package:migration/src/log.dart';
18 import 'package:migration/src/migrate_statuses.dart';
19 import 'package:migration/src/test_directories.dart';
19 20
20 const simpleDirs = const ["corelib", "language", "lib"]; 21 const simpleDirs = const ["corelib", "language", "lib"];
21 22
22 void main(List<String> arguments) { 23 void main(List<String> arguments) {
23 if (arguments.contains("--dry-run")) { 24 if (arguments.contains("--dry-run")) {
24 dryRun = true; 25 dryRun = true;
25 arguments = arguments.where((argument) => argument != "--dry-run").toList(); 26 arguments = arguments.where((argument) => argument != "--dry-run").toList();
26 } 27 }
27 28
28 if (arguments.length != 2) { 29 if (arguments.length != 2) {
29 stderr.writeln( 30 stderr.writeln(
30 "Usage: dart migrate_batch.dart [--dry-run] <first file> <last file>"); 31 "Usage: dart migrate_batch.dart [--dry-run] <first file> <last file>");
31 stderr.writeln(); 32 stderr.writeln();
32 stderr.writeln("Example:"); 33 stderr.writeln("Example:");
33 stderr.writeln(); 34 stderr.writeln();
34 stderr.writeln( 35 stderr.writeln(
35 " \$ dart migrate_batch.dart corelib/map_to_string corelib/queue"); 36 " \$ dart migrate_batch.dart corelib/map_to_string corelib/queue");
36 exit(1); 37 exit(1);
37 } 38 }
38 39
39 var tests = scanTests(); 40 var tests = scanTests();
40 41
41 var startIndex = findFork(tests, arguments[0]); 42 var startIndex = findFork(tests, arguments[0]);
42 var endIndex = findFork(tests, arguments[1]); 43 var endIndex = findFork(tests, arguments[1]);
43 44
44 if (startIndex == null || endIndex == null) exit(1); 45 if (startIndex == null || endIndex == null) exit(1);
45 46
46 var first = tests[startIndex].twoPath; 47 tests = tests.sublist(startIndex, endIndex + 1);
47 var last = tests[endIndex].twoPath;
48 48
49 // Make the range half-inclusive to simplify the math below. 49 if (tests.isEmpty) {
50 endIndex++;
51
52 if (endIndex - startIndex == 0) {
53 print(bold("No tests in range.")); 50 print(bold("No tests in range."));
54 return; 51 return;
55 } 52 }
56 53
57 print("Migrating ${bold(endIndex - startIndex)} tests from ${bold(first)} " 54 var s = tests.length == 1 ? "" : "s";
55 var first = tests.first.twoPath;
56 var last = tests.last.twoPath;
57 print("Migrating ${bold(tests.length)} test$s from ${bold(first)} "
bkonyi 2017/07/27 22:02:00 Did you mean to put 'test$s'?
Bob Nystrom 2017/07/27 22:58:19 Yup. See the "s" variable above. It will print "te
58 "to ${bold(last)}..."); 58 "to ${bold(last)}...");
59 print(""); 59 print("");
60 60
61 var allTodos = <String, List<String>>{}; 61 var allTodos = <String, List<String>>{};
62 tests = tests.sublist(startIndex, endIndex);
63 var migratedTests = 0; 62 var migratedTests = 0;
64 var unmigratedTests = 0; 63 var unmigratedTests = 0;
65 for (var test in tests) { 64 for (var test in tests) {
66 var todos = test.migrate(); 65 var todos = test.migrate();
67 if (todos.isEmpty) { 66 if (todos.isEmpty) {
68 migratedTests++; 67 migratedTests++;
69 } else { 68 } else {
70 unmigratedTests++; 69 unmigratedTests++;
71 allTodos[test.twoPath] = todos; 70 allTodos[test.twoPath] = todos;
72 } 71 }
73 } 72 }
74 73
75 // Print status file entries. 74 migrateStatusEntries(tests);
76 var statusFileEntries = new StringBuffer();
77 var statusFiles = loadStatusFiles();
78 for (var statusFile in statusFiles) {
79 printStatusFileEntries(statusFileEntries, tests, statusFile);
80 }
81 75
82 new File("statuses.migration") 76 // Tell the user what's left to do.
83 .writeAsStringSync(statusFileEntries.toString());
84 print("Wrote relevant test status file entries to 'statuses.migration'.");
85
86 // Tell the user what's left TODO.
87 print(""); 77 print("");
88 var summary = ""; 78 var summary = "";
89 79
90 if (migratedTests > 0) { 80 if (migratedTests > 0) {
91 var s = migratedTests == 1 ? "" : "s"; 81 var s = migratedTests == 1 ? "" : "s";
92 summary += "Successfully migrated ${green(migratedTests)} test$s. "; 82 summary += "Successfully migrated ${green(migratedTests)} test$s. ";
93 } 83 }
94 84
95 if (unmigratedTests > 0) { 85 if (unmigratedTests > 0) {
96 var s = unmigratedTests == 1 ? "" : "s"; 86 var s = unmigratedTests == 1 ? "" : "s";
97 summary += "Need manual work on ${red(unmigratedTests)} test$s:"; 87 summary += "Need manual work on ${red(unmigratedTests)} test$s:";
98 } 88 }
99 89
100 print(summary); 90 print(summary);
101 var todoTests = allTodos.keys.toList(); 91 var todoTests = allTodos.keys.toList();
102 todoTests.sort(); 92 todoTests.sort();
103 for (var todoTest in todoTests) { 93 for (var todoTest in todoTests) {
104 print("- ${bold(todoTest)}:"); 94 print("- ${bold(todoTest)}:");
105 allTodos[todoTest].forEach(todo); 95 allTodos[todoTest].forEach(todo);
106 } 96 }
107 } 97 }
108 98
109 /// Returns a [String] of the relevant status file entries associated with the
110 /// tests in [tests] found in [statusFile].
111 void printStatusFileEntries(
112 StringBuffer statusFileEntries, List<Fork> tests, StatusFile statusFile) {
113 var filteredStatusFile = new StatusFile(statusFile.path);
114 var testNames = <String>[];
115 for (var test in tests) {
116 testNames.add(test.twoPath.split("/").last.split(".")[0]);
117 }
118 for (var section in statusFile.sections) {
119 StatusSection currentSection;
120 for (var entry in section.entries) {
121 for (var testName in testNames) {
122 if (entry.path.contains(testName)) {
123 if (currentSection == null) {
124 currentSection = new StatusSection(section.condition);
125 }
126 currentSection.entries.add(entry);
127 }
128 }
129 }
130 if (currentSection != null) {
131 filteredStatusFile.sections.add(currentSection);
132 }
133 }
134 if (!filteredStatusFile.isEmpty) {
135 statusFileEntries.writeln("Entries for status file ${statusFile.path}:");
136 statusFileEntries.writeln(filteredStatusFile);
137 }
138 }
139
140 int findFork(List<Fork> forks, String description) { 99 int findFork(List<Fork> forks, String description) {
141 var matches = <int>[]; 100 var matches = <int>[];
142 101
143 for (var i = 0; i < forks.length; i++) { 102 for (var i = 0; i < forks.length; i++) {
144 if (forks[i].twoPath.contains(description)) matches.add(i); 103 if (forks[i].twoPath.contains(description)) matches.add(i);
145 } 104 }
146 105
147 if (matches.isEmpty) { 106 if (matches.isEmpty) {
148 print('Could not find a test matching "${bold(description)}".'); 107 print('Could not find a test matching "${bold(description)}".');
149 return null; 108 return null;
(...skipping 10 matching lines...) Expand all
160 } 119 }
161 } 120 }
162 121
163 /// Loads all of the unforked test files. 122 /// Loads all of the unforked test files.
164 /// 123 ///
165 /// Creates an list of [Fork]s, ordered by their destination paths. Handles 124 /// Creates an list of [Fork]s, ordered by their destination paths. Handles
166 /// tests that only appear in one fork or the other, or both. 125 /// tests that only appear in one fork or the other, or both.
167 List<Fork> scanTests() { 126 List<Fork> scanTests() {
168 var tests = <String, Fork>{}; 127 var tests = <String, Fork>{};
169 128
170 addFromDirectory(String fromDir, String twoDir) { 129 for (var fromDir in fromRootDirs) {
130 var twoDir = toTwoDirectory(fromDir);
171 for (var path in listFiles(fromDir)) { 131 for (var path in listFiles(fromDir)) {
172 var fromPath = p.relative(path, from: testRoot); 132 var fromPath = p.relative(path, from: testRoot);
173 var twoPath = p.join(twoDir, p.relative(fromPath, from: fromDir)); 133 var twoPath = p.join(twoDir, p.relative(fromPath, from: fromDir));
174 134
175 var fork = tests.putIfAbsent(twoPath, () => new Fork(twoPath)); 135 tests.putIfAbsent(twoPath, () => new Fork(twoPath));
176 if (fromDir.contains("_strong")) {
177 fork.strongPath = fromPath;
178 } else {
179 fork.onePath = fromPath;
180 }
181 } 136 }
182 } 137 }
183 138
184 addFromDirectory("corelib", "corelib_2");
185 addFromDirectory("corelib_strong", "corelib_2");
186 addFromDirectory("html", "lib_2/html");
187 addFromDirectory("isolate", "lib_2/isolate");
188 addFromDirectory("language", "language_2");
189 addFromDirectory("language_strong", "language_2");
190 addFromDirectory("lib", "lib_2");
191 addFromDirectory("lib_strong", "lib_2");
192
193 // Include tests that have already been migrated too so we can show what 139 // Include tests that have already been migrated too so we can show what
194 // works remains to be done in them. 140 // works remains to be done in them.
195 const twoDirs = const [ 141 for (var dir in twoRootDirs) {
196 "corelib_2",
197 "lib_2",
198 "language_2",
199 ];
200
201 for (var dir in twoDirs) {
202 for (var path in listFiles(dir)) { 142 for (var path in listFiles(dir)) {
203 var twoPath = p.relative(path, from: testRoot); 143 var twoPath = p.relative(path, from: testRoot);
204 tests.putIfAbsent(twoPath, () => new Fork(twoPath)); 144 tests.putIfAbsent(twoPath, () => new Fork(twoPath));
205 } 145 }
206 } 146 }
207 147
208 var sorted = tests.values.toList(); 148 var sorted = tests.values.toList();
209 sorted.sort((a, b) => a.twoPath.compareTo(b.twoPath)); 149 sorted.sort((a, b) => a.twoPath.compareTo(b.twoPath));
210 return sorted; 150 return sorted;
211 } 151 }
212
213 List<StatusFile> loadStatusFiles() {
214 var statusFiles = <StatusFile>[];
215
216 addStatusFile(String fromDir) {
217 for (var path in listFiles(fromDir, extension: ".status")) {
218 statusFiles.add(new StatusFile.read(path));
219 }
220 }
221
222 addStatusFile("corelib");
223 addStatusFile("corelib_strong");
224 addStatusFile("html");
225 addStatusFile("isolate");
226 addStatusFile("language");
227 addStatusFile("language_strong");
228 addStatusFile("lib");
229 addStatusFile("lib_strong");
230 return statusFiles;
231 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698