| #!/usr/bin/env dart |
| |
| // Copyright (c) 2020, 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'; |
| |
| final commentLine = RegExp(r'^///?'); |
| final scriptLine = RegExp(r'^#\!'); |
| final languageMarker = RegExp(r"^\s*//\s*@dart\s*="); |
| |
| void main(List<String> args) { |
| if (args.isEmpty) { |
| print('Mark files passed on the command line or under a directory'); |
| print(' passed on the command line as opted out of null safety. Does'); |
| print(' not mark files under directories containing a pubspec.yaml file'); |
| print(' unless the file is specified explicitly in the argument list.'); |
| print(' Ignores files not ending in ".dart".'); |
| print('Usage: opt_files_out.dart <files or directories>'); |
| return; |
| } |
| for (var name in args) { |
| switch (FileSystemEntity.typeSync(name)) { |
| case FileSystemEntityType.directory: |
| markDirectory(Directory(name)); |
| break; |
| case FileSystemEntityType.file: |
| markFile(File(name)); |
| break; |
| default: |
| print("Ignoring unknown object $name"); |
| break; |
| } |
| } |
| } |
| |
| bool isPubSpec(FileSystemEntity entity) => |
| entity is File && entity.path.endsWith("pubspec.yaml"); |
| |
| void markEntity(FileSystemEntity entity) { |
| if (entity is File) { |
| markFile(entity); |
| } else if (entity is Directory) { |
| markDirectory(entity); |
| } else { |
| print("Ignoring unknown object ${entity.path}"); |
| } |
| } |
| |
| void markDirectory(Directory dir) { |
| var children = dir.listSync(); |
| if (children.any(isPubSpec)) { |
| print("Skipping files under ${dir.path}"); |
| return; |
| } |
| for (var child in children) { |
| markEntity(child); |
| } |
| } |
| |
| void markFile(File file) { |
| if (!file.path.endsWith(".dart")) { |
| return; |
| } |
| |
| List<String> lines; |
| try { |
| lines = file.readAsLinesSync(); |
| } catch (e) { |
| print("Failed to read file ${file.path}: $e"); |
| return; |
| } |
| if (lines.any((line) => line.startsWith(languageMarker))) { |
| print("Skipping already marked file ${file.path}"); |
| return; |
| } |
| var marked = markContents(lines); |
| try { |
| file.writeAsStringSync(marked); |
| } catch (e) { |
| print("Failed to write file ${file.path}: $e"); |
| return; |
| } |
| print("Marked ${file.path}"); |
| } |
| |
| String markContents(List<String> lines) { |
| var buffer = StringBuffer(); |
| var marked = false; |
| |
| for (var line in lines) { |
| // If the file has not yet been marked, and we have reached the |
| // first non-comment line, insert an opt out marker. |
| if (!marked && |
| (!commentLine.hasMatch(line)) && |
| (!scriptLine.hasMatch(line))) { |
| buffer.write('\n// @dart = 2.9\n'); |
| marked = true; |
| } |
| buffer.write('$line\n'); |
| } |
| |
| // In case of empty file, or file of all comments (who does that!?). |
| if (!marked) { |
| buffer.write('\n// @dart = 2.9\n'); |
| } |
| return buffer.toString(); |
| } |