Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/flutterfire_cli/lib/src/commands/base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,13 @@ abstract class FlutterFireCommand extends Command<void> {
);
}

void commandRequiresFlutterApp() {
void commandRequiresFlutterApp({bool allowRuntimeApp = true}) {
if (flutterApp == null) {
throw FlutterAppRequiredException();
}
if (!allowRuntimeApp && flutterApp is FlutterRuntimeApp) {
throw FlutterAppRequiredException();
}
_warnUserIfRunningGlobally();
}

Expand Down
17 changes: 10 additions & 7 deletions packages/flutterfire_cli/lib/src/commands/update.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,28 +76,31 @@ class UpdateCommand extends FlutterFireCommand {
commandRequiresFlutterApp();

logger.stdout('Cleaning up current workspace ...');
await Process.run(
'flutter',
['clean'],
);
if (flutterApp!.cleanBaseCommand case final command?) {
await Process.run(
command,
['clean'],
);
}
await Process.run(
'rm',
['pubspec.lock'],
);

logger.stdout('Upgrading all firebase plugins to the latest version ...');
final command = flutterApp!.pubBaseCommand;
for (final package in flutterfirePackages) {
// We run each package individually because chaining them
// will fail at the first package not in the pubspec.
await Process.run(
'flutter',
command,
['pub', 'upgrade', '--major-versions', package],
);
}

logger.stdout("Running 'flutter pub get'...");
logger.stdout("Running '$command pub get'...");
await Process.run(
'flutter',
command,
['pub', 'get'],
);

Expand Down
23 changes: 20 additions & 3 deletions packages/flutterfire_cli/lib/src/common/package.dart
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,10 @@ class Package {

/// Returns whether this package is a Flutter app.
/// This is determined by ensuring all the following conditions are met:
/// a) the package depends on the Flutter SDK.
/// a) the package depends on the Flutter SDK or is a Flutter compatible package.
/// b) the package does not define itself as a Flutter plugin inside pubspec.yaml.
/// c) a lib/main.dart file exists in the package.
bool get isFlutterApp {
// Must directly depend on the Flutter SDK.
// Must directly depend on the Flutter SDK or be a Flutter compatible package.
if (!isFlutterPackage) return false;

// Must not have a Flutter plugin definition in it's pubspec.yaml.
Expand All @@ -90,6 +89,24 @@ class Package {
return true;
}

/// Returns whether this package is a runtime package.
///
/// These are packages that are compatible with Flutter plugins, even
/// if they don't depend on the Flutter SDK directly.
///
/// This is currently only true for packages that depend on Jaspr.
late final bool isRuntimePackage = dependencies.contains('jaspr');

bool get isRuntimeApp {
// Must not be a Flutter package.
if (isFlutterApp) return false;

// Must be a runtime package.
if (!isRuntimePackage) return false;

return true;
}

/// Returns whether this package is a Flutter plugin.
/// This is determined by whether the pubspec contains a flutter.plugin definition.
bool get isFlutterPlugin => pubSpec.flutter?.containsKey('plugin') ?? false;
Expand Down
200 changes: 139 additions & 61 deletions packages/flutterfire_cli/lib/src/flutter_app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import 'common/platform.dart';
import 'common/strings.dart';
import 'common/utils.dart';

class FlutterApp {
abstract class FlutterApp {
FlutterApp({
required this.package,
});
Expand All @@ -37,20 +37,103 @@ class FlutterApp {
throw FlutterAppRequiredException();
}
final package = await Package.load(appDirectory);
if (!package.isFlutterApp) {
return null;
if (package.isFlutterApp) {
return FlutterProjectApp(package: package);
}
return FlutterApp(
package: package,
if (package.isRuntimeApp) {
return FlutterRuntimeApp(package: package);
}
return null;
}

String? get iosBundleId;
String? get macosBundleId;
String? get androidApplicationId;

/// Returns whether the package depends on the given package.
bool dependsOnPackage(String packageName) {
return package.dependencies.contains(packageName) ||
package.devDependencies.contains(packageName);
}

/// Returns whether this Flutter app can run on Android.
bool get android;

/// Returns the directory where the Android platform specific project exists.
Directory get androidDirectory {
return _platformDirectory(kAndroid);
}

/// Returns whether this Flutter app can run on Web.
bool get web;

/// Returns the directory where the Web platform specific project exists.
Directory get webDirectory {
return _platformDirectory(kWeb);
}

/// Returns whether this Flutter app can run on Windows.
bool get windows;

/// Returns the directory where the Windows platform specific project exists.
Directory get windowsDirectory {
return _platformDirectory(kWindows);
}

/// Returns whether this Flutter app can run on MacOS.
bool get macos;

/// Returns the directory where the macOS platform specific project exists.
Directory get macosDirectory {
return _platformDirectory(kMacos);
}

/// Returns whether this Flutter app can run on iOS.
bool get ios;

/// Returns the directory where the iOS platform specific project exists.
Directory get iosDirectory {
return _platformDirectory(kIos);
}

/// Returns whether this Flutter app can run on Linux.
bool get linux;

/// Returns the directory where the Linux platform specific project exists.
Directory get linuxDirectory {
return _platformDirectory(kLinux);
}

Directory _platformDirectory(String platform) {
assert(
platform == kIos ||
platform == kAndroid ||
platform == kWeb ||
platform == kMacos ||
platform == kWindows ||
platform == kLinux,
);
return Directory(
'${package.path}${currentPlatform.pathSeparator}$platform',
);
}

String? get cleanBaseCommand;
String get pubBaseCommand;
}

class FlutterProjectApp extends FlutterApp {
FlutterProjectApp({
required super.package,
});

// Cached Android package name if available.
String? _androidApplicationId;

// Cached iOS bundle identifier if available.
String? _iosBundleId;

@override
String? get iosBundleId {
if (!ios) return null;
if (_iosBundleId != null) {
Expand All @@ -62,6 +145,7 @@ class FlutterApp {
// Cached macOS bundle identifier if available.
String? _macosBundleId;

@override
String? get macosBundleId {
if (!macos) return null;
if (_macosBundleId != null) {
Expand Down Expand Up @@ -109,6 +193,7 @@ class FlutterApp {
/// The Android Application (or Package Name) for this Flutter
/// application, or null if one could not be detected or the app
/// does not target Android as a supported platform.
@override
String? get androidApplicationId {
if (!android) return null;
if (_androidApplicationId != null) {
Expand Down Expand Up @@ -175,93 +260,86 @@ class FlutterApp {
return _androidApplicationId = applicationId;
}

/// Returns whether the package depends on the given package.
bool dependsOnPackage(String packageName) {
return package.dependencies.contains(packageName) ||
package.devDependencies.contains(packageName);
}

/// Returns whether this Flutter app can run on Android.
@override
bool get android {
if (!package.isFlutterApp) return false;
return _supportsPlatform(kAndroid);
}

/// Returns the directory where the Android platform specific project exists.
Directory get androidDirectory {
return _platformDirectory(kAndroid);
}

/// Returns whether this Flutter app can run on Web.
@override
bool get web {
if (!package.isFlutterApp) return false;
return _supportsPlatform(kWeb);
}

/// Returns the directory where the Web platform specific project exists.
Directory get webDirectory {
return _platformDirectory(kWeb);
}

/// Returns whether this Flutter app can run on Windows.
@override
bool get windows {
if (!package.isFlutterApp) return false;
return _supportsPlatform(kWindows);
}

/// Returns the directory where the Windows platform specific project exists.
Directory get windowsDirectory {
return _platformDirectory(kWindows);
}

/// Returns whether this Flutter app can run on MacOS.
@override
bool get macos {
if (!package.isFlutterApp) return false;
return _supportsPlatform(kMacos);
}

/// Returns the directory where the macOS platform specific project exists.
Directory get macosDirectory {
return _platformDirectory(kMacos);
}

/// Returns whether this Flutter app can run on iOS.
@override
bool get ios {
if (!package.isFlutterApp) return false;
return _supportsPlatform(kIos);
}

/// Returns the directory where the iOS platform specific project exists.
Directory get iosDirectory {
return _platformDirectory(kIos);
}

/// Returns whether this Flutter app can run on Linux.
@override
bool get linux {
if (!package.isFlutterApp) return false;
return _supportsPlatform(kLinux);
}

/// Returns the directory where the Linux platform specific project exists.
Directory get linuxDirectory {
return _platformDirectory(kLinux);
}

Directory _platformDirectory(String platform) {
assert(
platform == kIos ||
platform == kAndroid ||
platform == kWeb ||
platform == kMacos ||
platform == kWindows ||
platform == kLinux,
);
return Directory(
'${package.path}${currentPlatform.pathSeparator}$platform',
);
}

bool _supportsPlatform(String platform) {
return _platformDirectory(platform).existsSync();
}

@override
String? get cleanBaseCommand => 'flutter';

@override
String get pubBaseCommand => 'flutter';
}

class FlutterRuntimeApp extends FlutterApp {
FlutterRuntimeApp({required super.package});

@override
bool get android => false;

@override
String? get androidApplicationId => null;

@override
bool get ios => false;

@override
String? get iosBundleId => null;

@override
bool get linux => false;

@override
bool get macos => false;

@override
String? get macosBundleId => null;

@override
bool get web => true;

@override
bool get windows => false;

@override
String? get cleanBaseCommand => null;

@override
String get pubBaseCommand => 'dart';
}
Loading
Loading