Add flutter support (#155)

* Add flutter support

* Add changelog

* Rev version

* Fix small bug in health
diff --git a/pkgs/base_repo b/pkgs/base_repo
new file mode 160000
index 0000000..65817bf
--- /dev/null
+++ b/pkgs/base_repo
@@ -0,0 +1 @@
+Subproject commit 65817bf10a4e5c45a99299aa4ae92a0993bf9847
diff --git a/pkgs/firehose/CHANGELOG.md b/pkgs/firehose/CHANGELOG.md
index 660431b..5d0a58f 100644
--- a/pkgs/firehose/CHANGELOG.md
+++ b/pkgs/firehose/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 0.3.26
+
+- Add support for Flutter package auto-publishing, fixing [#154](https://github.com/dart-lang/ecosystem/issues/154).
 ## 0.3.25
 
 - Switch to pub.dev API in `package:firehose`.
diff --git a/pkgs/firehose/lib/firehose.dart b/pkgs/firehose/lib/firehose.dart
index 55041ca..611d618 100644
--- a/pkgs/firehose/lib/firehose.dart
+++ b/pkgs/firehose/lib/firehose.dart
@@ -115,7 +115,7 @@
       print('Validating $package:${package.name}');
 
       print('pubspec:');
-      var pubspecVersion = package.pubspec.version;
+      var pubspecVersion = package.pubspec.version?.toString();
       if (pubspecVersion == null) {
         var result = Result.fail(
           package,
@@ -146,7 +146,7 @@
         var result = Result.info(package, 'already published at pub.dev');
         print(result);
         results.addResult(result);
-      } else if (package.pubspec.isPreRelease) {
+      } else if (package.pubspec.version!.isPreRelease) {
         var result = Result.info(
           package,
           'pre-release version (no publish necessary)',
@@ -154,8 +154,7 @@
         print(result);
         results.addResult(result);
       } else {
-        var code = await runCommand('dart',
-            args: ['pub', 'publish', '--dry-run'], cwd: package.directory);
+        final code = await _runPublish(package, dryRun: true, force: false);
 
         final ignoreWarnings = github.prLabels.contains(_ignoreWarningsLabel);
 
@@ -245,7 +244,7 @@
     print('');
 
     print('pubspec:');
-    var pubspecVersion = package.pubspec.version;
+    var pubspecVersion = package.pubspec.version?.toString();
     print('  version: $pubspecVersion');
 
     print('changelog:');
@@ -267,13 +266,35 @@
     await runCommand('dart', args: ['pub', 'get'], cwd: package.directory);
     print('');
 
-    var result = await runCommand('dart',
-        args: ['pub', 'publish', '--force'], cwd: package.directory);
+    var result = await _runPublish(package, dryRun: false, force: true);
     if (result != 0) {
       exitCode = result;
     }
     return result == 0;
   }
+
+  Future<int> _runPublish(
+    Package package, {
+    required bool dryRun,
+    required bool force,
+  }) async {
+    String command;
+    if (package.pubspec.dependencies.containsKey('flutter')) {
+      command = 'flutter';
+    } else {
+      command = 'dart';
+    }
+    return await runCommand(
+      command,
+      args: [
+        'pub',
+        'publish',
+        if (dryRun) '--dry-run',
+        if (force) '--force',
+      ],
+      cwd: package.directory,
+    );
+  }
 }
 
 class VerificationResults {
diff --git a/pkgs/firehose/lib/src/health/coverage.dart b/pkgs/firehose/lib/src/health/coverage.dart
index 018be80..4e0e4d3 100644
--- a/pkgs/firehose/lib/src/health/coverage.dart
+++ b/pkgs/firehose/lib/src/health/coverage.dart
@@ -31,6 +31,7 @@
 
     var filesOfInterest = files
         .where((file) => path.extension(file.filename) == '.dart')
+        .where((file) => file.status != FileStatus.removed)
         .where((file) => isInSomePackage(packages, file.relativePath))
         .where((file) => isNotATest(packages, file.relativePath))
         .toList();
diff --git a/pkgs/firehose/lib/src/pubspec.dart b/pkgs/firehose/lib/src/pubspec.dart
deleted file mode 100644
index 48b26ae..0000000
--- a/pkgs/firehose/lib/src/pubspec.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2023, 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:path/path.dart' as path;
-import 'package:pub_semver/pub_semver.dart';
-import 'package:yaml/yaml.dart' as yaml;
-
-class Pubspec {
-  final Directory directory;
-  late final Map _yaml;
-
-  Pubspec(this.directory) {
-    var file = File(path.join(directory.path, 'pubspec.yaml'));
-    _yaml = yaml.loadYaml(file.readAsStringSync()) as Map;
-  }
-
-  /// The package name.
-  String get name => _yaml['name'] as String;
-
-  /// The package version.
-  ///
-  /// Null if no version is specified.
-  String? get version => _yaml['version'] as String?;
-
-  /// Whether the pubspec semver version is a pre-release version
-  /// (`'1.2.3-foo'`).
-  bool get isPreRelease => Version.parse(version!).isPreRelease;
-}
diff --git a/pkgs/firehose/lib/src/repo.dart b/pkgs/firehose/lib/src/repo.dart
index 1e65c4d..511c06a 100644
--- a/pkgs/firehose/lib/src/repo.dart
+++ b/pkgs/firehose/lib/src/repo.dart
@@ -6,10 +6,10 @@
 
 import 'package:firehose/src/changelog.dart';
 import 'package:path/path.dart' as path;
+import 'package:pubspec_parse/pubspec_parse.dart';
 import 'package:yaml/yaml.dart' as yaml;
 
 import 'github.dart';
-import 'pubspec.dart';
 
 class Repository {
   final Directory baseDirectory;
@@ -90,13 +90,16 @@
   late final Changelog changelog;
 
   Package(this.directory, this.repository) {
-    pubspec = Pubspec(directory);
-    changelog = Changelog(File(path.join(directory.path, 'CHANGELOG.md')));
+    pubspec = Pubspec.parse(_getPackageFile('pubspec.yaml').readAsStringSync());
+    changelog = Changelog(_getPackageFile('CHANGELOG.md'));
   }
 
+  File _getPackageFile(String fileName) =>
+      File(path.join(directory.path, fileName));
+
   String get name => pubspec.name;
 
-  String? get version => pubspec.version;
+  String? get version => pubspec.version?.toString();
 
   @override
   String toString() {
diff --git a/pkgs/firehose/pubspec.yaml b/pkgs/firehose/pubspec.yaml
index b58a631..bc0c4e0 100644
--- a/pkgs/firehose/pubspec.yaml
+++ b/pkgs/firehose/pubspec.yaml
@@ -1,6 +1,6 @@
 name: firehose
 description: A tool to automate publishing of Pub packages from GitHub actions.
-version: 0.3.25
+version: 0.3.26
 repository: https://github.com/dart-lang/ecosystem/tree/main/pkgs/firehose
 
 environment:
@@ -16,6 +16,7 @@
   http: ^0.13.0
   path: ^1.8.0
   pub_semver: ^2.1.0
+  pubspec_parse: ^1.2.3
   yaml: ^3.1.0
 
 dev_dependencies:
diff --git a/pkgs/firehose/test/pubspec_test.dart b/pkgs/firehose/test/pubspec_test.dart
deleted file mode 100644
index e35c782..0000000
--- a/pkgs/firehose/test/pubspec_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2023, 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.
-@TestOn('vm')
-library;
-
-import 'dart:io';
-
-import 'package:firehose/src/pubspec.dart';
-import 'package:test/test.dart';
-
-void main() {
-  group('pubspec', () {
-    late Pubspec pubspec;
-
-    setUp(() {
-      pubspec = Pubspec(Directory.current);
-    });
-
-    test('name', () {
-      var name = pubspec.name;
-      expect(name, equals('firehose'));
-    });
-
-    test('version', () {
-      var version = pubspec.version;
-      expect(version, isNotNull);
-    });
-  });
-}