globalSettings function

List<SettingDef> globalSettings()

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'),
        ],
      ),
    ];