1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'base/context.dart';
6
7/// The current [FeatureFlags] implementation.
8FeatureFlags get featureFlags => context.get<FeatureFlags>()!;
9
10/// The interface used to determine if a particular [Feature] is enabled.
11///
12/// The rest of the tools code should use this class instead of looking up
13/// features directly. To facilitate rolls to google3 and other clients, all
14/// flags should be provided with a default implementation here. Clients that
15/// use this class should extent instead of implement, so that new flags are
16/// picked up automatically.
17abstract class FeatureFlags {
18 /// const constructor so that subclasses can be const.
19 const FeatureFlags();
20
21 /// Whether flutter desktop for linux is enabled.
22 bool get isLinuxEnabled => false;
23
24 /// Whether flutter desktop for macOS is enabled.
25 bool get isMacOSEnabled => false;
26
27 /// Whether flutter web is enabled.
28 bool get isWebEnabled => false;
29
30 /// Whether flutter desktop for Windows is enabled.
31 bool get isWindowsEnabled => false;
32
33 /// Whether android is enabled.
34 bool get isAndroidEnabled => true;
35
36 /// Whether iOS is enabled.
37 bool get isIOSEnabled => true;
38
39 /// Whether fuchsia is enabled.
40 bool get isFuchsiaEnabled => true;
41
42 /// Whether custom devices are enabled.
43 bool get areCustomDevicesEnabled => false;
44
45 /// Whether animations are used in the command line interface.
46 bool get isCliAnimationEnabled => true;
47
48 /// Whether native assets compilation and bundling is enabled.
49 bool get isNativeAssetsEnabled => false;
50
51 /// Whether Swift Package Manager dependency management is enabled.
52 bool get isSwiftPackageManagerEnabled => false;
53
54 /// Whether explicit package dependency management is enabled.
55 bool get isExplicitPackageDependenciesEnabled => false;
56
57 /// Whether a particular feature is enabled for the current channel.
58 ///
59 /// Prefer using one of the specific getters above instead of this API.
60 bool isEnabled(Feature feature);
61}
62
63/// All current Flutter feature flags.
64const List<Feature> allFeatures = <Feature>[
65 flutterWebFeature,
66 flutterLinuxDesktopFeature,
67 flutterMacOSDesktopFeature,
68 flutterWindowsDesktopFeature,
69 flutterAndroidFeature,
70 flutterIOSFeature,
71 flutterFuchsiaFeature,
72 flutterCustomDevicesFeature,
73 cliAnimation,
74 nativeAssets,
75 swiftPackageManager,
76 explicitPackageDependencies,
77];
78
79/// All current Flutter feature flags that can be configured.
80///
81/// [Feature.configSetting] is not `null`.
82Iterable<Feature> get allConfigurableFeatures =>
83 allFeatures.where((Feature feature) => feature.configSetting != null);
84
85/// The [Feature] for flutter web.
86const Feature flutterWebFeature = Feature.fullyEnabled(
87 name: 'Flutter for web',
88 configSetting: 'enable-web',
89 environmentOverride: 'FLUTTER_WEB',
90);
91
92/// The [Feature] for macOS desktop.
93const Feature flutterMacOSDesktopFeature = Feature.fullyEnabled(
94 name: 'support for desktop on macOS',
95 configSetting: 'enable-macos-desktop',
96 environmentOverride: 'FLUTTER_MACOS',
97);
98
99/// The [Feature] for Linux desktop.
100const Feature flutterLinuxDesktopFeature = Feature.fullyEnabled(
101 name: 'support for desktop on Linux',
102 configSetting: 'enable-linux-desktop',
103 environmentOverride: 'FLUTTER_LINUX',
104);
105
106/// The [Feature] for Windows desktop.
107const Feature flutterWindowsDesktopFeature = Feature.fullyEnabled(
108 name: 'support for desktop on Windows',
109 configSetting: 'enable-windows-desktop',
110 environmentOverride: 'FLUTTER_WINDOWS',
111);
112
113/// The [Feature] for Android devices.
114const Feature flutterAndroidFeature = Feature.fullyEnabled(
115 name: 'Flutter for Android',
116 configSetting: 'enable-android',
117);
118
119/// The [Feature] for iOS devices.
120const Feature flutterIOSFeature = Feature.fullyEnabled(
121 name: 'Flutter for iOS',
122 configSetting: 'enable-ios',
123);
124
125/// The [Feature] for Fuchsia support.
126const Feature flutterFuchsiaFeature = Feature(
127 name: 'Flutter for Fuchsia',
128 configSetting: 'enable-fuchsia',
129 environmentOverride: 'FLUTTER_FUCHSIA',
130 master: FeatureChannelSetting(available: true),
131);
132
133const Feature flutterCustomDevicesFeature = Feature(
134 name: 'early support for custom device types',
135 configSetting: 'enable-custom-devices',
136 environmentOverride: 'FLUTTER_CUSTOM_DEVICES',
137 master: FeatureChannelSetting(available: true),
138 beta: FeatureChannelSetting(available: true),
139 stable: FeatureChannelSetting(available: true),
140);
141
142/// The [Feature] for CLI animations.
143///
144/// The TERM environment variable set to "dumb" turns this off.
145const Feature cliAnimation = Feature.fullyEnabled(
146 name: 'animations in the command line interface',
147 configSetting: 'cli-animations',
148);
149
150/// Enable native assets compilation and bundling.
151const Feature nativeAssets = Feature(
152 name: 'native assets compilation and bundling',
153 configSetting: 'enable-native-assets',
154 environmentOverride: 'FLUTTER_NATIVE_ASSETS',
155 master: FeatureChannelSetting(available: true),
156);
157
158/// Enable Swift Package Manager as a darwin dependency manager.
159const Feature swiftPackageManager = Feature(
160 name: 'support for Swift Package Manager for iOS and macOS',
161 configSetting: 'enable-swift-package-manager',
162 environmentOverride: 'FLUTTER_SWIFT_PACKAGE_MANAGER',
163 master: FeatureChannelSetting(available: true),
164 beta: FeatureChannelSetting(available: true),
165 stable: FeatureChannelSetting(available: true),
166);
167
168/// Enable explicit resolution and generation of package dependencies.
169const Feature explicitPackageDependencies = Feature.fullyEnabled(
170 name: 'support for dev_dependency plugins',
171 configSetting: 'explicit-package-dependencies',
172 extraHelpText:
173 'Plugins that are resolved as result of being in "dev_dependencies" of a '
174 'package are not included in release builds of an app. By enabling this '
175 'feature, the synthetic "package:flutter_gen" can no longer be generated '
176 'and the legacy ".flutter-plugins" tool artifact is no longer generated.\n'
177 '\n'
178 'See also:\n'
179 '* https://flutter.dev/to/flutter-plugins-configuration.\n'
180 '* https://flutter.dev/to/flutter-gen-deprecation.',
181);
182
183/// A [Feature] is a process for conditionally enabling tool features.
184///
185/// All settings are optional, and if not provided will generally default to
186/// a "safe" value, such as being off.
187///
188/// The top level feature settings can be provided to apply to all channels.
189/// Otherwise, more specific settings take precedence over higher level
190/// settings.
191class Feature {
192 /// Creates a [Feature].
193 const Feature({
194 required this.name,
195 this.environmentOverride,
196 this.configSetting,
197 this.extraHelpText,
198 this.master = const FeatureChannelSetting(),
199 this.beta = const FeatureChannelSetting(),
200 this.stable = const FeatureChannelSetting(),
201 });
202
203 /// Creates a [Feature] that is fully enabled across channels.
204 const Feature.fullyEnabled({
205 required this.name,
206 this.environmentOverride,
207 this.configSetting,
208 this.extraHelpText,
209 }) : master = const FeatureChannelSetting(available: true, enabledByDefault: true),
210 beta = const FeatureChannelSetting(available: true, enabledByDefault: true),
211 stable = const FeatureChannelSetting(available: true, enabledByDefault: true);
212
213 /// The user visible name for this feature.
214 final String name;
215
216 /// The settings for the master branch and other unknown channels.
217 final FeatureChannelSetting master;
218
219 /// The settings for the beta branch.
220 final FeatureChannelSetting beta;
221
222 /// The settings for the stable branch.
223 final FeatureChannelSetting stable;
224
225 /// The name of an environment variable that can override the setting.
226 ///
227 /// The environment variable needs to be set to the value 'true'. This is
228 /// only intended for usage by CI and not as an advertised method to enable
229 /// a feature.
230 ///
231 /// If not provided, defaults to `null` meaning there is no override.
232 final String? environmentOverride;
233
234 /// The name of a setting that can be used to enable this feature.
235 ///
236 /// If not provided, defaults to `null` meaning there is no config setting.
237 final String? configSetting;
238
239 /// Additional text to add to the end of the help message.
240 ///
241 /// If not provided, defaults to `null` meaning there is no additional text.
242 final String? extraHelpText;
243
244 /// A help message for the `flutter config` command, or null if unsupported.
245 String? generateHelpMessage() {
246 if (configSetting == null) {
247 return null;
248 }
249 final StringBuffer buffer = StringBuffer('Enable or disable $name.');
250 final List<String> channels = <String>[
251 if (master.available) 'master',
252 if (beta.available) 'beta',
253 if (stable.available) 'stable',
254 ];
255 // Add channel info for settings only on some channels.
256 if (channels.length == 1) {
257 buffer.write('\nThis setting applies only to the ${channels.single} channel.');
258 } else if (channels.length == 2) {
259 buffer.write('\nThis setting applies only to the ${channels.join(' and ')} channels.');
260 }
261 if (extraHelpText != null) {
262 buffer.write(' $extraHelpText');
263 }
264 return buffer.toString();
265 }
266
267 /// Retrieve the correct setting for the provided `channel`.
268 FeatureChannelSetting getSettingForChannel(String channel) {
269 return switch (channel) {
270 'stable' => stable,
271 'beta' => beta,
272 'master' || _ => master,
273 };
274 }
275}
276
277/// A description of the conditions to enable a feature for a particular channel.
278class FeatureChannelSetting {
279 const FeatureChannelSetting({this.available = false, this.enabledByDefault = false});
280
281 /// Whether the feature is available on this channel.
282 ///
283 /// If not provided, defaults to `false`. This implies that the feature
284 /// cannot be enabled even by the settings below.
285 final bool available;
286
287 /// Whether the feature is enabled by default.
288 ///
289 /// If not provided, defaults to `false`.
290 final bool enabledByDefault;
291}
292

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com