import 'package:meta/meta.dart';
import 'base/config.dart';
import 'base/context.dart';
import 'base/platform.dart';
import 'version.dart';
FeatureFlags get featureFlags => context.get<FeatureFlags>();
class FeatureFlags {
const FeatureFlags();
bool get isLinuxEnabled => _isEnabled(flutterLinuxDesktopFeature);
bool get isMacOSEnabled => _isEnabled(flutterMacOSDesktopFeature);
bool get isWebEnabled => _isEnabled(flutterWebFeature);
bool get isWindowsEnabled => _isEnabled(flutterWindowsDesktopFeature);
bool get isPluginAsAarEnabled => _isEnabled(flutterBuildPluginAsAarFeature);
static bool _isEnabled(Feature feature) {
final String currentChannel = FlutterVersion.instance.channel;
final FeatureChannelSetting featureSetting = feature.getSettingForChannel(currentChannel);
if (!featureSetting.available) {
return false;
}
bool isEnabled = featureSetting.enabledByDefault;
if (feature.configSetting != null) {
final bool configOverride = Config.instance.getValue(feature.configSetting);
if (configOverride != null) {
isEnabled = configOverride;
}
}
if (feature.environmentOverride != null) {
if (platform.environment[feature.environmentOverride]?.toLowerCase() == 'true') {
isEnabled = true;
}
}
return isEnabled;
}
}
const List<Feature> allFeatures = <Feature>[
flutterWebFeature,
flutterLinuxDesktopFeature,
flutterMacOSDesktopFeature,
flutterWindowsDesktopFeature,
flutterBuildPluginAsAarFeature,
];
const Feature flutterWebFeature = Feature(
name: 'Flutter for web',
configSetting: 'enable-web',
environmentOverride: 'FLUTTER_WEB',
master: FeatureChannelSetting(
available: true,
enabledByDefault: false,
),
dev: FeatureChannelSetting(
available: true,
enabledByDefault: false,
),
);
const Feature flutterMacOSDesktopFeature = Feature(
name: 'Flutter for desktop on macOS',
configSetting: 'enable-macos-desktop',
environmentOverride: 'ENABLE_FLUTTER_DESKTOP',
master: FeatureChannelSetting(
available: true,
enabledByDefault: false,
),
);
const Feature flutterLinuxDesktopFeature = Feature(
name: 'Flutter for desktop on Linux',
configSetting: 'enable-linux-desktop',
environmentOverride: 'ENABLE_FLUTTER_DESKTOP',
master: FeatureChannelSetting(
available: true,
enabledByDefault: false,
),
);
const Feature flutterWindowsDesktopFeature = Feature(
name: 'Flutter for desktop on Windows',
configSetting: 'enable-windows-desktop',
environmentOverride: 'ENABLE_FLUTTER_DESKTOP',
master: FeatureChannelSetting(
available: true,
enabledByDefault: false,
),
);
const Feature flutterBuildPluginAsAarFeature = Feature(
name: 'Build plugins independently as AARs in app projects',
configSetting: 'enable-build-plugin-as-aar',
master: FeatureChannelSetting(
available: true,
enabledByDefault: false,
),
);
class Feature {
const Feature({
@required this.name,
this.environmentOverride,
this.configSetting,
this.master = const FeatureChannelSetting(),
this.dev = const FeatureChannelSetting(),
this.beta = const FeatureChannelSetting(),
this.stable = const FeatureChannelSetting(),
});
final String name;
final FeatureChannelSetting master;
final FeatureChannelSetting dev;
final FeatureChannelSetting beta;
final FeatureChannelSetting stable;
final String environmentOverride;
final String configSetting;
String generateHelpMessage() {
if (configSetting == null) {
return null;
}
final StringBuffer buffer = StringBuffer('Enable or disable $name. '
'This setting will take effect on ');
final List<String> channels = <String>[
if (master.available) 'master',
if (dev.available) 'dev',
if (beta.available) 'beta',
if (stable.available) 'stable',
];
if (channels.length == 1) {
buffer.write('the ${channels.single} channel.');
} else if (channels.length == 2) {
buffer.write('the ${channels.join(' and ')} channels.');
} else {
final String prefix = (channels.toList()
..removeLast()).join(', ');
buffer.write('the $prefix, and ${channels.last} channels.');
}
return buffer.toString();
}
FeatureChannelSetting getSettingForChannel(String channel) {
switch (channel) {
case 'stable':
return stable;
case 'beta':
return beta;
case 'dev':
return dev;
case 'master':
default:
return master;
}
}
}
class FeatureChannelSetting {
const FeatureChannelSetting({
this.available = false,
this.enabledByDefault = false,
});
final bool available;
final bool enabledByDefault;
}