Unverified Commit 99b44599 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Allow disabling experimental commands, devices on stable branch (#30153)

parent 294d7ea0
......@@ -31,6 +31,9 @@ class BuildWebCommand extends BuildSubCommand {
@override
bool get hidden => true;
@override
bool get isExperimental => true;
@override
final String description = '(EXPERIMENTAL) build a web application bundle.';
......
......@@ -3,11 +3,12 @@
// found in the LICENSE file.
import 'base/platform.dart';
import 'version.dart';
// Only launch or display desktop embedding devices if
// `FLUTTER_DESKTOP_EMBEDDING` environment variable is set to true.
bool get flutterDesktopEnabled {
_flutterDesktopEnabled ??= platform.environment['FLUTTER_DESKTOP_EMBEDDING']?.toLowerCase() == 'true';
return _flutterDesktopEnabled;
return _flutterDesktopEnabled && !FlutterVersion.instance.isStable;
}
bool _flutterDesktopEnabled;
......@@ -27,6 +27,7 @@ import '../doctor.dart';
import '../globals.dart';
import '../project.dart';
import '../usage.dart';
import '../version.dart';
import 'flutter_command_runner.dart';
export '../cache.dart' show DevelopmentArtifact;
......@@ -464,6 +465,11 @@ abstract class FlutterCommand extends Command<void> {
}
}
/// Whether this feature should not be usable on stable branches.
///
/// Defaults to false, meaning it is usable.
bool get isExperimental => false;
/// Additional usage values to be sent with the usage ping.
Future<Map<String, String>> get usageValues async => const <String, String>{};
......@@ -635,6 +641,12 @@ abstract class FlutterCommand extends Command<void> {
@protected
@mustCallSuper
Future<void> validateCommand() async {
// If we're on a stable branch, then don't allow the usage of
// "experimental" features.
if (isExperimental && FlutterVersion.instance.isStable) {
throwToolExit('Experimental feature $name is not supported on stable branches');
}
if (_requiresPubspecYaml && !PackageMap.isUsingCustomPackagesPath) {
// Don't expect a pubspec.yaml file if the user passed in an explicit .packages file path.
if (!fs.isFileSync('pubspec.yaml')) {
......
......@@ -32,6 +32,11 @@ class FlutterVersion {
return _repositoryUrl;
}
/// Whether we are currently on the stable branch.
bool get isStable {
return getBranchName() == 'stable';
}
static const Set<String> officialChannels = <String>{
'master',
'dev',
......
......@@ -13,6 +13,7 @@ import '../build_info.dart';
import '../device.dart';
import '../globals.dart';
import '../project.dart';
import '../version.dart';
import '../web/compile.dart';
ChromeLauncher get chromeLauncher => context[ChromeLauncher];
......@@ -21,7 +22,7 @@ ChromeLauncher get chromeLauncher => context[ChromeLauncher];
/// environment variable is set to true.
bool get flutterWebEnabled {
_flutterWebEnabled = platform.environment['FLUTTER_WEB']?.toLowerCase() == 'true';
return _flutterWebEnabled;
return _flutterWebEnabled && !FlutterVersion.instance.isStable;
}
bool _flutterWebEnabled;
......
......@@ -7,6 +7,7 @@ import 'package:flutter_tools/src/base/time.dart';
import 'package:flutter_tools/src/usage.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/runner/flutter_command.dart';
import 'package:flutter_tools/src/version.dart';
import 'package:mockito/mockito.dart';
import '../src/common.dart';
......@@ -155,4 +156,43 @@ void main() {
});
});
group('Experimental commands', () {
final MockVersion stableVersion = MockVersion();
final MockVersion betaVersion = MockVersion();
final FakeCommand fakeCommand = FakeCommand();
when(stableVersion.isStable).thenReturn(true);
when(betaVersion.isStable).thenReturn(false);
testUsingContext('Can be disabled on stable branch', () async {
expect(() => fakeCommand.run(), throwsA(isA<ToolExit>()));
}, overrides: <Type, Generator>{
FlutterVersion: () => stableVersion,
});
testUsingContext('Works normally on regular branches', () async {
expect(fakeCommand.run(), completes);
}, overrides: <Type, Generator>{
FlutterVersion: () => betaVersion,
});
});
}
class FakeCommand extends FlutterCommand {
@override
String get description => null;
@override
String get name => 'fake';
@override
bool get isExperimental => true;
@override
Future<FlutterCommandResult> runCommand() async {
return null;
}
}
class MockVersion extends Mock implements FlutterVersion {}
......@@ -304,7 +304,10 @@ class MockXcodeProjectInterpreter implements XcodeProjectInterpreter {
}
}
class MockFlutterVersion extends Mock implements FlutterVersion {}
class MockFlutterVersion extends Mock implements FlutterVersion {
@override
bool get isStable => false;
}
class MockClock extends Mock implements SystemClock {}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment