Chromium Code Reviews| Index: tools/migration/lib/src/editable_status_file.dart |
| diff --git a/tools/migration/lib/src/editable_status_file.dart b/tools/migration/lib/src/editable_status_file.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..7a3795266da73de500e6aa935e8105b866912f84 |
| --- /dev/null |
| +++ b/tools/migration/lib/src/editable_status_file.dart |
| @@ -0,0 +1,109 @@ |
| +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +import 'dart:io'; |
| + |
| +import 'package:status_file/status_file.dart'; |
| + |
| +import 'io.dart'; |
| +import 'log.dart'; |
| + |
| +// TODO(rnystrom): This file is kind of a hack. The problem is that a parsed |
| +// StatusFile doesn't contain all of the original information in the source |
| +// text. Comments and whitespace are lost. That means a StatusFile itself |
| +// couldn't be modified and saved back to disc. |
| +// |
| +// Instead, this wraps a StatusFile and also lets you modify entire lines in |
| +// it, including their comments. Ideally, StatusFile would include parsed |
| +// comments and we would canonicalize other whitespace so that you could |
| +// modify a StatusFile object then save it back to disc. |
| +class EditableStatusFile { |
|
bkonyi
2017/07/27 22:02:00
Do we maybe want to add this to package:status_fil
Bob Nystrom
2017/07/27 22:58:19
Eventually, maybe. But it's pretty hacky so I didn
|
| + final String path; |
| + |
| + StatusFile _statusFile; |
| + StatusFile get statusFile { |
| + if (_statusFile == null) { |
| + _statusFile = new StatusFile.read(path); |
| + } |
| + |
| + return _statusFile; |
| + } |
| + |
| + List<String> _lines; |
| + |
| + EditableStatusFile(this.path); |
| + |
| + /// Gets the line at the given one-based index. |
| + String lineAt(int line) { |
| + _ensureLines(); |
| + return _lines[line - 1]; |
| + } |
| + |
| + /// Delete the numbered [lines] from the file. |
| + void delete(List<int> lines) { |
| + if (lines.isEmpty) return; |
| + |
| + if (dryRun) { |
| + print("Delete lines ${lines.join(', ')} from $path."); |
| + return; |
| + } |
| + |
| + _ensureLines(); |
| + |
| + var deleted = 0; |
| + for (var line in lines) { |
| + // Adjust index because previous lines have already been removed, shifting |
| + // the subsequent line numbers. |
| + _lines.removeAt(line - deleted); |
| + deleted++; |
| + } |
| + |
| + _save(); |
| + } |
| + |
| + /// Insert [entries] at [line] in the file. |
| + void insert(int line, List<String> entries) { |
| + if (dryRun) { |
| + print("Insert ${bold(path)}, insert at line $line:"); |
| + entries.forEach(print); |
| + return; |
| + } |
| + |
| + _ensureLines(); |
| + _lines.insertAll(line, entries); |
| + _save(); |
| + } |
| + |
| + /// Adds [header] followed by [entries] to the end of the file. |
| + void append(String header, List<String> entries) { |
| + if (dryRun) { |
| + print("To ${bold(path)}, append:"); |
| + print(header); |
| + entries.forEach(print); |
| + return; |
| + } |
| + |
| + _ensureLines(); |
| + _lines.add(""); |
| + |
| + _lines.add(header); |
| + _lines.addAll(entries); |
| + _save(); |
| + } |
| + |
| + void _ensureLines() { |
| + if (_lines == null) { |
| + _lines = new File(path).readAsLinesSync(); |
| + } |
| + } |
| + |
| + void _save() { |
| + new File(path).writeAsStringSync(_lines.join("\n") + "\n"); |
| + |
| + // It needs to be reparsed now since the lines have changed. |
| + // TODO(rnystrom): This is kind of hacky and slow, but it gets the job done. |
| + _statusFile = null; |
| + _lines = null; |
| + } |
| +} |