globalSettings function
All project wide settings, in the order shown in the menu.
Implementation
List<SettingDef> globalSettings() => [
SettingDef(
path: const ['output_dir'],
summary: 'Folder for builds and the ledger',
kind: SettingKind.text,
hint: 'Relative to the project, or absolute (e.g. ~/builds).',
current: (c) => c.outputDir,
preview: (c, x) => [
'builds go to ${c.outputRoot}',
..._layoutPreview(c, x).skip(1),
],
),
SettingDef(
path: const ['output_layout'],
summary: 'Folder structure inside the output folder',
kind: SettingKind.choice,
custom: true,
hint: 'Tokens: ${PathTemplate.tokens.map((t) => '{$t}').join(' ')}',
choices: [
for (final l in LayoutPreset.values)
SettingChoice(l.id, note: l.template),
],
current: (c) => c.outputLayout ?? 'by-flavor',
preview: (c, x) => _layoutPreview(c, x),
),
SettingDef(
path: const ['file_name'],
summary: 'Artifact file name (without extension)',
kind: SettingKind.choice,
custom: true,
hint: 'Same tokens as the layout; no "/" allowed.',
choices: const [
SettingChoice(BuildPaths.defaultFileName),
SettingChoice('{app}_{flavor}_{versionName}_{versionCode}'),
SettingChoice('{app}-{flavor}-{mode}-{version}'),
],
current: (c) => c.fileName ?? BuildPaths.defaultFileName,
preview: (c, x) {
final paths = BuildPaths(c.outputRoot,
layout: c.effectiveLayout, fileName: c.fileName);
final name = paths
.artifactFileName(x.naming(BuildMode.release, ArtifactType.aab));
return [name, 'artifact $name'];
},
),
SettingDef(
path: const ['ledger'],
summary: 'Ledger file',
kind: SettingKind.text,
hint: 'Empty keeps the default: <output folder>/ledger.json.',
current: (c) => _opt(c.ledgerFile),
preview: (c, x) => [_rel(c, c.ledgerPath), 'ledger ${c.ledgerPath}'],
),
SettingDef(
path: const ['flutter'],
summary: 'Command that runs Flutter',
kind: SettingKind.text,
hint: 'e.g. flutter, fvm flutter, /opt/flutter/bin/flutter',
current: (c) => c.flutter.join(' '),
preview: (c, x) => _commandPreview(c, x),
),
SettingDef(
path: const ['obfuscate'],
summary: 'Obfuscate release builds and keep Dart symbols',
kind: SettingKind.boolean,
current: (c) => '${c.obfuscate}',
preview: (c, x) => [
c.obfuscate
? 'adds --obfuscate; Dart symbols are stored'
: 'no obfuscation; no Dart symbols to store',
..._commandPreview(c, x),
],
),
SettingDef(
path: const ['split_per_abi'],
summary: 'Split APKs per CPU architecture',
kind: SettingKind.boolean,
current: (c) => '${c.splitPerAbi}',
preview: (c, x) => [
c.splitPerAbi
? 'APK builds make one file per ABI'
: 'APK builds make one universal file',
..._commandPreview(c, x),
],
),
SettingDef(
path: const ['extra_build_args'],
summary: 'Extra arguments for every flutter build',
kind: SettingKind.list,
hint: 'Space separated, e.g. --no-tree-shake-icons',
current: (c) => _list(c.extraBuildArgs),
preview: (c, x) => _commandPreview(c, x),
),
SettingDef(
path: const ['pre_build', 'clean'],
summary: 'Pre-tick "flutter clean" in the build menu',
kind: SettingKind.boolean,
current: (c) => '${c.preBuild.clean}',
preview: _preBuildPreview,
),
SettingDef(
path: const ['pre_build', 'build_runner'],
summary: 'Pre-tick build_runner in the build menu',
kind: SettingKind.boolean,
current: (c) => '${c.preBuild.buildRunner}',
preview: _preBuildPreview,
),
SettingDef(
path: const ['pre_build', 'gen_l10n'],
summary: 'Pre-tick "flutter gen-l10n" in the build menu',
kind: SettingKind.boolean,
current: (c) => '${c.preBuild.genL10n}',
preview: _preBuildPreview,
),
SettingDef(
path: const ['pre_build', 'build_runner_args'],
summary: 'Arguments for build_runner build',
kind: SettingKind.list,
hint: 'Space separated, e.g. --verbose (empty by default)',
current: (c) => _list(c.preBuild.buildRunnerArgs),
preview: _preBuildPreview,
),
SettingDef(
path: const ['play', 'default_track'],
summary: 'Google Play track used by default',
kind: SettingKind.choice,
choices: const [
SettingChoice('internal'),
SettingChoice('alpha'),
SettingChoice('beta'),
SettingChoice('production'),
],
custom: true,
current: (c) => c.play.defaultTrack,
preview: (c, x) => [
'uploads go to the "${c.play.defaultTrack}" track',
'release status ${c.play.defaultReleaseStatus}',
],
),
SettingDef(
path: const ['play', 'default_release_status'],
summary: 'Release status of a Play upload',
kind: SettingKind.choice,
choices: const [
SettingChoice('draft', note: 'saved in Play Console, not rolled out'),
SettingChoice('completed', note: 'rolled out to the whole track'),
SettingChoice('inProgress', note: 'staged rollout'),
],
current: (c) => c.play.defaultReleaseStatus,
preview: (c, x) => [
switch (c.play.defaultReleaseStatus) {
'draft' => 'a draft: you roll it out in Play Console',
'completed' => 'rolled out to everyone on the track',
'inProgress' => 'staged rollout (needs a user fraction)',
_ => 'custom status "${c.play.defaultReleaseStatus}"',
},
],
),
SettingDef(
path: const ['play', 'upload_mapping'],
summary: 'Upload R8 mapping.txt with the AAB',
kind: SettingKind.boolean,
current: (c) => '${c.play.uploadMapping}',
preview: (c, x) => [
c.play.uploadMapping
? 'mapping.txt is sent so Play de-obfuscates crashes'
: 'only the AAB is sent',
],
),
SettingDef(
path: const ['play', 'service_account_json'],
summary: 'Play service account key (JSON file)',
kind: SettingKind.text,
hint: 'A path, not the key itself. Env PLAY_SERVICE_ACCOUNT_JSON wins.',
current: (c) => _opt(c.play.serviceAccountJson),
preview: (c, x) {
final f = c.play.serviceAccountJson;
if (f == null) {
return ['no key: uploads only mark the ledger'];
}
return [
File(f).existsSync() ? 'key file found' : 'key file NOT found',
f,
];
},
),
SettingDef(
path: const ['crashlytics', 'enabled'],
summary: 'Offer Crashlytics in symbol uploads',
kind: SettingKind.boolean,
current: (c) => '${c.crashlytics.enabled}',
preview: (c, x) => [
c.crashlytics.enabled
? 'Crashlytics is offered, using "${c.crashlytics.cli.join(' ')}"'
: 'Crashlytics is hidden',
],
),
SettingDef(
path: const ['crashlytics', 'cli'],
summary: 'Firebase CLI command',
kind: SettingKind.text,
hint: 'e.g. firebase, npx firebase-tools',
current: (c) => c.crashlytics.cli.join(' '),
preview: (c, x) => [
'runs "${c.crashlytics.cli.join(' ')} '
'crashlytics:symbols:upload ..."'
],
),
SettingDef(
path: const ['sentry', 'enabled'],
summary: 'Offer Sentry in symbol uploads',
kind: SettingKind.boolean,
current: (c) => '${c.sentry.enabled}',
preview: (c, x) => [
c.sentry.enabled
? 'Sentry is offered, using "${c.sentry.cli.join(' ')}"'
: 'Sentry is hidden',
],
),
SettingDef(
path: const ['sentry', 'cli'],
summary: 'sentry-cli command',
kind: SettingKind.text,
current: (c) => c.sentry.cli.join(' '),
preview: (c, x) => ['runs "${c.sentry.cli.join(' ')} debug-files ..."'],
),
SettingDef(
path: const ['sentry', 'org'],
summary: 'Sentry organization',
kind: SettingKind.text,
hint: 'Env SENTRY_ORG wins.',
current: (c) => _opt(c.sentry.org),
preview: (c, x) => ['org ${_opt(c.sentry.org)}'],
),
SettingDef(
path: const ['sentry', 'project'],
summary: 'Sentry project',
kind: SettingKind.text,
hint: 'Env SENTRY_PROJECT wins; flavors can override it.',
current: (c) => _opt(c.sentry.project),
preview: (c, x) => ['project ${_opt(c.sentry.project)}'],
),
SettingDef(
path: const ['sentry', 'url'],
summary: 'Self-hosted Sentry URL',
kind: SettingKind.text,
hint: 'Leave empty for sentry.io. The auth token is never stored here: '
'set SENTRY_AUTH_TOKEN.',
current: (c) => c.sentry.url ?? 'sentry.io',
preview: (c, x) => ['server ${c.sentry.url ?? 'https://sentry.io'}'],
),
SettingDef(
path: const ['android', 'retrace'],
summary: 'Path to R8 retrace (Trace a crash)',
kind: SettingKind.text,
hint: 'Empty searches PATH and ANDROID_HOME.',
current: (c) => _opt(c.androidRetrace),
preview: (c, x) => [
c.androidRetrace == null
? 'found through PATH / ANDROID_HOME'
: (File(c.androidRetrace!).existsSync()
? 'file found'
: 'file NOT found'),
],
),
SettingDef(
path: const ['android', 'ndk_stack'],
summary: 'Path to ndk-stack (Trace a crash)',
kind: SettingKind.text,
hint: 'Empty searches PATH and ANDROID_NDK_HOME.',
current: (c) => _opt(c.androidNdkStack),
preview: (c, x) => [
c.androidNdkStack == null
? 'found through PATH / ANDROID_NDK_HOME'
: (File(c.androidNdkStack!).existsSync()
? 'file found'
: 'file NOT found'),
],
),
];