#!/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 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 '); 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 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 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(); }