OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 import 'package:path/path.dart' as p; | |
6 | |
7 import 'editable_status_file.dart'; | |
8 import 'fork.dart'; | |
9 import 'io.dart'; | |
10 import 'test_directories.dart'; | |
11 | |
12 /// Migrates the status file entries that match [files]. | |
13 void migrateStatusEntries(List<Fork> files) { | |
14 var entriesToMove = new EntrySet(); | |
15 | |
16 _collectEntries(files, entriesToMove, isOne: true); | |
17 _collectEntries(files, entriesToMove, isOne: false); | |
18 | |
19 for (var statusFile in entriesToMove.statusFiles) { | |
20 var sections = entriesToMove.sections(statusFile); | |
21 _addEntries(statusFile, sections); | |
22 } | |
23 | |
24 // TODO(rnystrom): Should this log any output? | |
bkonyi
2017/07/27 22:02:00
I'm not sure if it would be worth still outputting
Bob Nystrom
2017/07/27 22:58:19
You'll see the actual diff of the changes when you
| |
25 } | |
26 | |
27 /// Tracks a set of entries to add to a set of Dart 2.0 status files. | |
28 class EntrySet { | |
29 /// Keys are the names of the Dart 2.0 status file that will receive the | |
30 /// entries. The value for each key is a map of section headers to the list | |
31 /// of entries to add under that section. | |
32 final Map<String, Map<String, List<String>>> _files = {}; | |
33 | |
34 Iterable<String> get statusFiles => _files.keys; | |
35 | |
36 void add(String fromDir, String header, String entry) { | |
37 var toDir = toTwoDirectory(fromDir); | |
38 var sections = _files.putIfAbsent(p.join(toDir, "$toDir.status"), () => {}); | |
39 var entries = sections.putIfAbsent(header, () => []); | |
40 entries.add(entry); | |
41 } | |
42 | |
43 Map<String, List<String>> sections(String file) => _files[file]; | |
44 } | |
45 | |
46 /// Removes entries from the 1.0 and strong status files that correspond to | |
47 /// the list of [files] being migrated. | |
48 /// | |
49 /// Adds moved entries to [entriesToMove]. | |
50 void _collectEntries(List<Fork> files, EntrySet entriesToMove, {bool isOne}) { | |
51 // Map the files to the way they will appear in the status file. | |
52 var filePaths = files | |
53 .map((fork) => p.withoutExtension(isOne ? fork.onePath : fork.strongPath)) | |
54 .toList(); | |
55 | |
56 for (var fromDir in isOne ? oneRootDirs : strongRootDirs) { | |
57 for (var path in listFiles(fromDir, extension: ".status")) { | |
58 var editable = new EditableStatusFile(path); | |
59 | |
60 var deleteLines = <int>[]; | |
61 for (var section in editable.statusFile.sections) { | |
62 // TODO(rnystrom): For now, we don't support entries in the initial | |
bkonyi
2017/07/27 22:02:01
I haven't run into this case yet myself, and I thi
Bob Nystrom
2017/07/27 22:58:19
There are definitely ones like that, but not too m
| |
63 // implicit section at the top of the file. Do we need to? | |
64 if (section.condition == null) continue; | |
65 | |
66 for (var entry in section.entries) { | |
67 var entryPath = p.join(fromDir, entry.path); | |
68 | |
69 for (var filePath in filePaths) { | |
70 // We only support entries that precisely match the file being | |
71 // migrated, or a multitest within that. In both cases, the entry | |
72 // path will begin with the full path of the file. We don't migrate | |
73 // directory or glob patterns because those may also match other | |
74 // files that have not been migrated yet. | |
75 // TODO(rnystrom): It would be good to detect when a glob matches | |
76 // a migrated file and let the user know that they may need to | |
77 // manually handle it. | |
78 if (!entryPath.startsWith(filePath)) continue; | |
79 | |
80 // Remove it from this status file. | |
81 deleteLines.add(entry.lineNumber - 1); | |
82 | |
83 // And add it to the 2.0 one. | |
84 entriesToMove.add(fromDir, editable.lineAt(section.lineNumber), | |
85 editable.lineAt(entry.lineNumber)); | |
86 } | |
87 } | |
88 } | |
89 | |
90 // TODO(rnystrom): If all of the entries are deleted from a section, it | |
91 // would be nice to delete the section header too. | |
bkonyi
2017/07/27 22:02:00
Agreed.
Bob Nystrom
2017/07/27 22:58:19
Acknowledged.
| |
92 editable.delete(deleteLines); | |
93 } | |
94 } | |
95 } | |
96 | |
97 /// Adds all of [entries] to the status file at [path]. | |
98 /// | |
99 /// If the status file already has a section that matches a header in [entries], | |
100 /// then adds those entries to the end of that section. Otherwise, appends a | |
101 /// new section to the end of the file. | |
102 void _addEntries(String path, Map<String, List<String>> entries) { | |
103 var editable = new EditableStatusFile(p.join(testRoot, path)); | |
104 | |
105 for (var header in entries.keys) { | |
106 var found = false; | |
107 | |
108 // Look for an existing section with the same header to add it to. | |
109 for (var section in editable.statusFile.sections) { | |
110 // TODO(bob): Handle adding stuff to the empty section. | |
bkonyi
2017/07/27 22:02:01
// TODO(rnystrom): ...
Bob Nystrom
2017/07/27 22:58:19
Oops, don't need that anymore. Deleted.
| |
111 if (section.lineNumber == -1) continue; | |
112 | |
113 if (header == editable.lineAt(section.lineNumber)) { | |
114 var line = section.lineNumber; | |
115 // Add after existing entries, if there are any. | |
116 if (section.entries.isNotEmpty) { | |
117 line = section.entries.last.lineNumber; | |
118 } | |
119 | |
120 editable.insert(line, entries[header]); | |
121 found = true; | |
122 break; | |
123 } | |
124 } | |
125 | |
126 if (!found) { | |
127 // This section doesn't exist in the status file, so add it. | |
128 editable.append(header, entries[header]); | |
129 } | |
130 } | |
131 } | |
OLD | NEW |