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 | |
5 | import 'base/context.dart'; |
6 | |
7 | /// The current [FeatureFlags] implementation. |
8 | FeatureFlags 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. |
17 | abstract 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. |
64 | const 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`. |
82 | Iterable<Feature> get allConfigurableFeatures => |
83 | allFeatures.where((Feature feature) => feature.configSetting != null); |
84 | |
85 | /// The [Feature] for flutter web. |
86 | const 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. |
93 | const 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. |
100 | const 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. |
107 | const 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. |
114 | const Feature flutterAndroidFeature = Feature.fullyEnabled( |
115 | name: 'Flutter for Android', |
116 | configSetting: 'enable-android', |
117 | ); |
118 | |
119 | /// The [Feature] for iOS devices. |
120 | const Feature flutterIOSFeature = Feature.fullyEnabled( |
121 | name: 'Flutter for iOS', |
122 | configSetting: 'enable-ios', |
123 | ); |
124 | |
125 | /// The [Feature] for Fuchsia support. |
126 | const Feature flutterFuchsiaFeature = Feature( |
127 | name: 'Flutter for Fuchsia', |
128 | configSetting: 'enable-fuchsia', |
129 | environmentOverride: 'FLUTTER_FUCHSIA', |
130 | master: FeatureChannelSetting(available: true), |
131 | ); |
132 | |
133 | const 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. |
145 | const 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. |
151 | const 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. |
159 | const 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. |
169 | const 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. |
191 | class 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. |
278 | class 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 |
Definitions
- featureFlags
- FeatureFlags
- FeatureFlags
- isLinuxEnabled
- isMacOSEnabled
- isWebEnabled
- isWindowsEnabled
- isAndroidEnabled
- isIOSEnabled
- isFuchsiaEnabled
- areCustomDevicesEnabled
- isCliAnimationEnabled
- isNativeAssetsEnabled
- isSwiftPackageManagerEnabled
- isExplicitPackageDependenciesEnabled
- isEnabled
- allFeatures
- allConfigurableFeatures
- flutterWebFeature
- flutterMacOSDesktopFeature
- flutterLinuxDesktopFeature
- flutterWindowsDesktopFeature
- flutterAndroidFeature
- flutterIOSFeature
- flutterFuchsiaFeature
- flutterCustomDevicesFeature
- cliAnimation
- nativeAssets
- swiftPackageManager
- explicitPackageDependencies
- Feature
- Feature
- fullyEnabled
- generateHelpMessage
- getSettingForChannel
- FeatureChannelSetting
Learn more about Flutter for embedded and desktop on industrialflutter.com