nnbd migration (#52)

* nnbd migration

* bump to dev container

* updated version

* + notes
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 43245b0..0ed5c5a 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -14,7 +14,7 @@
     runs-on: ubuntu-latest
 
     container:
-      image:  google/dart:beta
+      image:  google/dart:dev
 
     steps:
       - uses: actions/checkout@v2
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7bbb72d..546b78e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 0.3.0-nullsafety
+- Updated to support 2.12.0 and null safety.
+
 ## 0.2.1
 
 ## 0.2.0
diff --git a/lib/cli_logging.dart b/lib/cli_logging.dart
index 44b8ca9..106d51e 100644
--- a/lib/cli_logging.dart
+++ b/lib/cli_logging.dart
@@ -13,10 +13,9 @@
 /// sequences.
 class Ansi {
   /// Return whether the current stdout terminal supports ANSI escape sequences.
-  static bool get terminalSupportsAnsi {
-    return io.stdout.supportsAnsiEscapes &&
-        io.stdioType(io.stdout) == io.StdioType.terminal;
-  }
+  static bool get terminalSupportsAnsi =>
+      io.stdout.supportsAnsiEscapes &&
+      io.stdioType(io.stdout) == io.StdioType.terminal;
 
   final bool useAnsi;
 
@@ -64,12 +63,12 @@
 /// standard status messages, trace level output, and indeterminate progress.
 abstract class Logger {
   /// Create a normal [Logger]; this logger will not display trace level output.
-  factory Logger.standard({Ansi ansi}) => StandardLogger(ansi: ansi);
+  factory Logger.standard({Ansi? ansi}) => StandardLogger(ansi: ansi);
 
   /// Create a [Logger] that will display trace level output.
   ///
   /// If [logTime] is `true`, this logger will display the time of the message.
-  factory Logger.verbose({Ansi ansi, bool logTime = true}) {
+  factory Logger.verbose({Ansi? ansi, bool logTime = true}) {
     return VerboseLogger(ansi: ansi, logTime: logTime);
   }
 
@@ -110,7 +109,7 @@
   Duration get elapsed => _stopwatch.elapsed;
 
   /// Finish the indeterminate progress display.
-  void finish({String message, bool showTiming});
+  void finish({String? message, bool showTiming = false});
 
   /// Cancel the indeterminate progress display.
   void cancel();
@@ -120,14 +119,12 @@
   @override
   Ansi ansi;
 
-  StandardLogger({this.ansi}) {
-    ansi ??= Ansi(Ansi.terminalSupportsAnsi);
-  }
+  StandardLogger({Ansi? ansi}) : ansi = ansi ?? Ansi(Ansi.terminalSupportsAnsi);
 
   @override
   bool get isVerbose => false;
 
-  Progress _currentProgress;
+  Progress? _currentProgress;
 
   @override
   void stderr(String message) {
@@ -161,8 +158,8 @@
   }
 
   void _cancelProgress() {
-    if (_currentProgress != null) {
-      var progress = _currentProgress;
+    var progress = _currentProgress;
+    if (progress != null) {
       _currentProgress = null;
       progress.cancel();
     }
@@ -170,11 +167,7 @@
 
   @override
   Progress progress(String message) {
-    if (_currentProgress != null) {
-      var progress = _currentProgress;
-      _currentProgress = null;
-      progress.cancel();
-    }
+    _cancelProgress();
 
     var progress = ansi.useAnsi
         ? AnsiProgress(ansi, message)
@@ -199,7 +192,7 @@
   void cancel() {}
 
   @override
-  void finish({String message, bool showTiming}) {}
+  void finish({String? message, bool showTiming = false}) {}
 }
 
 class AnsiProgress extends Progress {
@@ -208,7 +201,7 @@
   final Ansi ansi;
 
   int _index = 0;
-  Timer _timer;
+  late Timer _timer;
 
   AnsiProgress(this.ansi, String message) : super(message) {
     io.stdout.write('${message}...  '.padRight(40));
@@ -230,7 +223,7 @@
   }
 
   @override
-  void finish({String message, bool showTiming = false}) {
+  void finish({String? message, bool showTiming = false}) {
     if (_timer.isActive) {
       _timer.cancel();
       _updateDisplay(isFinal: true, message: message, showTiming: showTiming);
@@ -240,7 +233,7 @@
   void _updateDisplay(
       {bool isFinal = false,
       bool cancelled = false,
-      String message,
+      String? message,
       bool showTiming = false}) {
     var char = kAnimationItems[_index % kAnimationItems.length];
     if (isFinal || cancelled) {
@@ -265,12 +258,10 @@
   @override
   Ansi ansi;
   bool logTime;
-  Stopwatch _timer;
+  late Stopwatch _timer;
 
-  VerboseLogger({this.ansi, this.logTime}) {
-    ansi ??= Ansi(Ansi.terminalSupportsAnsi);
-    logTime ??= false;
-
+  VerboseLogger({Ansi? ansi, this.logTime = false})
+      : ansi = ansi ?? Ansi(Ansi.terminalSupportsAnsi) {
     _timer = Stopwatch()..start();
   }
 
diff --git a/lib/cli_util.dart b/lib/cli_util.dart
index 45c97f2..0cc408d 100644
--- a/lib/cli_util.dart
+++ b/lib/cli_util.dart
@@ -20,7 +20,7 @@
 ///
 /// Callers should generally prefer using the [getSdkPath] function.
 @Deprecated('Clients should generally prefer getSdkPath()')
-Directory getSdkDir([List<String> cliArgs]) {
+Directory getSdkDir([List<String>? cliArgs]) {
   // Look for --dart-sdk on the command line.
   if (cliArgs != null) {
     var index = cliArgs.indexOf('--dart-sdk');
@@ -37,8 +37,9 @@
   }
 
   // Look in env['DART_SDK']
-  if (Platform.environment['DART_SDK'] != null) {
-    return Directory(Platform.environment['DART_SDK']);
+  var sdkLocation = Platform.environment['DART_SDK'];
+  if (sdkLocation != null) {
+    return Directory(sdkLocation);
   }
 
   // Look relative to the dart executable.
diff --git a/pubspec.yaml b/pubspec.yaml
index e3ef70e..fbf3018 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,14 +1,15 @@
 name: cli_util
-version: 0.2.1-dev
+version: 0.3.0-nullsafety.0
 description: A library to help in building Dart command-line apps.
 homepage: https://github.com/dart-lang/cli_util
 
 environment:
-  sdk: '>=2.0.0 <3.0.0'
+  sdk: '>=2.12.0-0 <3.0.0'
 
 dependencies:
-  path: '>=1.0.0 <2.0.0'
+  meta: ^1.3.0-nullsafety
+  path: ^1.8.0-nullsafety
 
 dev_dependencies:
-  pedantic: ^1.0.0
-  test: ^1.0.0
+  pedantic: ^1.10.0-nullsafety
+  test: ^1.16.0-nullsafety