@_nazmiforreal/flutter-ota 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -13
- package/bin/{flutter-patcher-linux-x64 → flutter-ota-linux-x64} +0 -0
- package/bin/{flutter-patcher.js → flutter-ota.js} +4 -4
- package/dart-src/packages/cli-tools/bin/{flutter_patcher.dart → flutter_ota_kit.dart} +2 -2
- package/dart-src/packages/cli-tools/lib/{flutter_patcher_cli.dart → flutter_ota_kit_cli.dart} +5 -3
- package/dart-src/packages/cli-tools/lib/src/backend.dart +6 -25
- package/dart-src/packages/cli-tools/lib/src/cli_base.dart +10 -4
- package/dart-src/packages/cli-tools/lib/src/commands/build.dart +5 -3
- package/dart-src/packages/cli-tools/lib/src/commands/bundle.dart +279 -10
- package/dart-src/packages/cli-tools/lib/src/commands/channel.dart +7 -7
- package/dart-src/packages/cli-tools/lib/src/commands/config_command.dart +5 -5
- package/dart-src/packages/cli-tools/lib/src/commands/console.dart +4 -4
- package/dart-src/packages/cli-tools/lib/src/commands/deploy.dart +4 -4
- package/dart-src/packages/cli-tools/lib/src/commands/doctor.dart +3 -3
- package/dart-src/packages/cli-tools/lib/src/commands/fingerprint.dart +1 -1
- package/dart-src/packages/cli-tools/lib/src/commands/init.dart +294 -45
- package/dart-src/packages/cli-tools/lib/src/commands/keys.dart +1 -1
- package/dart-src/packages/cli-tools/lib/src/commands/migrate.dart +59 -24
- package/dart-src/packages/cli-tools/lib/src/commands/rollback.dart +5 -5
- package/dart-src/packages/cli-tools/lib/src/commands/storage.dart +117 -0
- package/dart-src/packages/cli-tools/lib/src/config.dart +29 -78
- package/dart-src/packages/cli-tools/lib/src/operations.dart +4 -4
- package/dart-src/packages/cli-tools/lib/src/pack.dart +12 -6
- package/dart-src/packages/cli-tools/lib/src/runner.dart +21 -3
- package/dart-src/packages/cli-tools/lib/src/ui/ui.dart +2 -2
- package/dart-src/packages/cli-tools/lib/src/verbose.dart +3 -0
- package/dart-src/packages/cli-tools/migrations/aws/README.md +7 -0
- package/dart-src/packages/cli-tools/migrations/postgres/bundles.sql +45 -0
- package/dart-src/packages/cli-tools/migrations/postgres/get_target_app_version_list.sql +21 -0
- package/dart-src/packages/cli-tools/migrations/postgres/get_update_info_by_app_version.sql +126 -0
- package/dart-src/packages/cli-tools/migrations/postgres/get_update_info_by_fingerprint_hash.sql +125 -0
- package/dart-src/packages/cli-tools/migrations/postgres/hash_user_id.sql +30 -0
- package/dart-src/packages/cli-tools/migrations/postgres/is_device_eligible.sql +237 -0
- package/dart-src/packages/cli-tools/migrations/supabase/20260520014100_hot-updater_rls.sql +11 -0
- package/dart-src/packages/cli-tools/pubspec.yaml +8 -10
- package/dart-src/packages/cli-tools/test/backends_test.dart +4 -4
- package/dart-src/packages/cli-tools/test/build_pack_test.dart +1 -1
- package/dart-src/packages/cli-tools/test/cli_test.dart +3 -3
- package/dart-src/packages/cli-tools/test/mocks/mock_aws_s3_client.dart +2 -2
- package/dart-src/packages/cli-tools/test/mocks/mock_d1_client.dart +2 -2
- package/dart-src/packages/cli-tools/test/mocks/mock_postgres_client.dart +7 -7
- package/dart-src/packages/core/lib/{flutter_patcher_core.dart → flutter_ota_kit_core.dart} +1 -1
- package/dart-src/packages/core/pubspec.yaml +2 -2
- package/dart-src/packages/core/test/rollout_test.dart +1 -1
- package/dart-src/packages/core/test/semver_test.dart +1 -1
- package/dart-src/packages/core/test/types_test.dart +2 -2
- package/dart-src/packages/core/test/uuid_test.dart +1 -1
- package/dart-src/packages/core/tool/dbg.dart +1 -1
- package/dart-src/plugins/aws/lib/{flutter_patcher_aws.dart → flutter_ota_kit_aws.dart} +0 -2
- package/dart-src/plugins/aws/lib/src/aws_cloudfront_client.dart +1 -1
- package/dart-src/plugins/aws/lib/src/aws_database.dart +1 -1
- package/dart-src/plugins/aws/lib/src/aws_s3_client.dart +1 -1
- package/dart-src/plugins/aws/lib/src/aws_storage.dart +1 -1
- package/dart-src/plugins/aws/lib/src/aws_storage_profile.dart +25 -3
- package/dart-src/plugins/aws/lib/src/with_cloudfront_signed_url.dart +1 -1
- package/dart-src/plugins/aws/pubspec.yaml +4 -4
- package/dart-src/plugins/aws/test/aws_database_test.dart +3 -3
- package/dart-src/plugins/aws/test/aws_storage_test.dart +2 -2
- package/dart-src/plugins/aws/test/mock_aws_s3_client.dart +2 -2
- package/dart-src/plugins/cloudflare/lib/src/cloudflare_worker_database.dart +1 -1
- package/dart-src/plugins/cloudflare/lib/src/d1_build_where.dart +1 -1
- package/dart-src/plugins/cloudflare/lib/src/d1_bundle_mapper.dart +1 -1
- package/dart-src/plugins/cloudflare/lib/src/d1_database.dart +1 -1
- package/dart-src/plugins/cloudflare/lib/src/d1_database_plugin.dart +2 -2
- package/dart-src/plugins/cloudflare/lib/src/r2_s3_client.dart +1 -1
- package/dart-src/plugins/cloudflare/lib/src/r2_storage.dart +1 -1
- package/dart-src/plugins/cloudflare/lib/src/r2_storage_profile.dart +1 -1
- package/dart-src/plugins/cloudflare/pubspec.yaml +4 -4
- package/dart-src/plugins/cloudflare/test/cloudflare_worker_database_test.dart +2 -2
- package/dart-src/plugins/cloudflare/test/d1_bundle_mapper_test.dart +2 -2
- package/dart-src/plugins/cloudflare/test/d1_database_test.dart +2 -2
- package/dart-src/plugins/cloudflare/test/mock_d1_client.dart +2 -2
- package/dart-src/plugins/cloudflare/test/mock_r2_client.dart +2 -2
- package/dart-src/plugins/cloudflare/test/r2_storage_test.dart +2 -2
- package/dart-src/plugins/plugin-core/lib/{flutter_patcher_plugin_core.dart → flutter_ota_kit_plugin_core.dart} +1 -1
- package/dart-src/plugins/plugin-core/lib/src/create_blob_database_plugin.dart +1 -1
- package/dart-src/plugins/plugin-core/lib/src/filter_compatible_app_versions.dart +1 -1
- package/dart-src/plugins/plugin-core/lib/src/get_update_info.dart +1 -1
- package/dart-src/plugins/plugin-core/lib/src/request_update_bundle_state.dart +1 -1
- package/dart-src/plugins/plugin-core/lib/src/resolve_update_info_from_bundles.dart +1 -1
- package/dart-src/plugins/plugin-core/lib/src/types.dart +2 -2
- package/dart-src/plugins/plugin-core/pubspec.yaml +3 -3
- package/dart-src/plugins/plugin-core/test/asset_storage_layout_test.dart +3 -3
- package/dart-src/plugins/plugin-core/test/bundle_unit_of_work_store_test.dart +2 -2
- package/dart-src/plugins/plugin-core/test/bundle_unit_of_work_test.dart +2 -2
- package/dart-src/plugins/plugin-core/test/create_blob_database_plugin_test.dart +2 -2
- package/dart-src/plugins/plugin-core/test/create_database_plugin_test.dart +5 -5
- package/dart-src/plugins/plugin-core/test/create_storage_plugin_test.dart +2 -2
- package/dart-src/plugins/plugin-core/test/generate_min_bundle_id_test.dart +2 -2
- package/dart-src/plugins/plugin-core/test/get_update_info_test.dart +2 -2
- package/dart-src/plugins/plugin-core/test/helpers_test.dart +2 -2
- package/dart-src/plugins/plugin-core/test/query_bundles_test.dart +2 -2
- package/dart-src/plugins/plugin-core/test/request_update_bundle_state_test.dart +3 -3
- package/dart-src/plugins/plugin-core/test/uuidv7_test.dart +1 -1
- package/dart-src/plugins/postgres/lib/{flutter_patcher_postgres.dart → flutter_ota_kit_postgres.dart} +1 -1
- package/dart-src/plugins/postgres/lib/src/postgres_bundle_mapper.dart +1 -1
- package/dart-src/plugins/postgres/lib/src/postgres_database.dart +2 -2
- package/dart-src/plugins/postgres/lib/src/postgres_get_update_info.dart +2 -2
- package/dart-src/plugins/postgres/lib/src/postgres_storage.dart +9 -9
- package/dart-src/plugins/postgres/lib/src/postgres_types.dart +1 -1
- package/dart-src/plugins/postgres/pubspec.yaml +4 -4
- package/dart-src/plugins/postgres/test/mock_postgres_client.dart +2 -2
- package/dart-src/plugins/postgres/test/postgres_bundle_mapper_test.dart +2 -2
- package/dart-src/plugins/postgres/test/postgres_database_test.dart +2 -2
- package/dart-src/plugins/supabase/lib/edge.dart +1 -1
- package/dart-src/plugins/supabase/lib/{flutter_patcher_supabase.dart → flutter_ota_kit_supabase.dart} +1 -1
- package/dart-src/plugins/supabase/lib/src/supabase_bundle_mapper.dart +1 -1
- package/dart-src/plugins/supabase/lib/src/supabase_client_http.dart +5 -1
- package/dart-src/plugins/supabase/lib/src/supabase_database.dart +2 -2
- package/dart-src/plugins/supabase/lib/src/supabase_edge_function_database.dart +1 -1
- package/dart-src/plugins/supabase/lib/src/supabase_edge_function_storage.dart +1 -1
- package/dart-src/plugins/supabase/lib/src/supabase_storage.dart +2 -5
- package/dart-src/plugins/supabase/pubspec.yaml +4 -4
- package/dart-src/plugins/supabase/test/mock_supabase_client.dart +5 -5
- package/dart-src/plugins/supabase/test/supabase_bundle_mapper_test.dart +3 -3
- package/dart-src/plugins/supabase/test/supabase_database_test.dart +3 -3
- package/dart-src/plugins/supabase/test/supabase_storage_test.dart +2 -2
- package/migrations/aws/README.md +7 -0
- package/migrations/cloudflare/0001_hot-updater_init.sql +16 -0
- package/migrations/cloudflare/0002_hot-updater_0.13.0.sql +8 -0
- package/migrations/cloudflare/0003_hot-updater_0.18.0.sql +38 -0
- package/migrations/cloudflare/0004_hot-updater_0.29.0.sql +11 -0
- package/migrations/cloudflare/0005_hot-updater_0.31.0.sql +24 -0
- package/migrations/cloudflare/bundles.sql +42 -0
- package/migrations/postgres/bundles.sql +45 -0
- package/migrations/postgres/get_target_app_version_list.sql +21 -0
- package/migrations/postgres/get_update_info_by_app_version.sql +126 -0
- package/migrations/postgres/get_update_info_by_fingerprint_hash.sql +125 -0
- package/migrations/postgres/hash_user_id.sql +30 -0
- package/migrations/postgres/is_device_eligible.sql +237 -0
- package/package.json +4 -4
- package/scripts/postinstall.js +15 -15
- package/scripts/vendor.sh +1 -1
- package/dart-src/packages/cli-tools/.dart_tool/package_config.json +0 -496
- package/dart-src/packages/cli-tools/.dart_tool/package_graph.json +0 -743
- package/dart-src/packages/cli-tools/pubspec.lock +0 -638
- package/dart-src/packages/cli-tools/test/standalone_backend_test.dart +0 -315
- package/dart-src/plugins/aws/lib/src/aws_lambda_edge_storage.dart +0 -72
- package/dart-src/plugins/aws/test/aws_lambda_edge_storage_test.dart +0 -190
- package/dart-src/plugins/standalone/.gitkeep +0 -0
- package/dart-src/plugins/standalone/lib/flutter_patcher_standalone.dart +0 -12
- package/dart-src/plugins/standalone/lib/src/standalone_config.dart +0 -107
- package/dart-src/plugins/standalone/lib/src/standalone_database.dart +0 -233
- package/dart-src/plugins/standalone/lib/src/standalone_storage.dart +0 -175
- package/dart-src/plugins/standalone/pubspec.yaml +0 -18
- package/dart-src/plugins/standalone/test/standalone_test.dart +0 -264
- /package/dart-src/plugins/cloudflare/lib/{flutter_patcher_cloudflare.dart → flutter_ota_kit_cloudflare.dart} +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# flutter-
|
|
1
|
+
# flutter-ota (flutter-ota CLI)
|
|
2
2
|
|
|
3
|
-
Command-line interface for [
|
|
3
|
+
Command-line interface for [flutter_ota_kit](https://github.com/HYPER12755/flutter_ota_kit) — a multi-backend OTA ("code push") toolkit for Flutter Android, hot-updater compatible.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -8,30 +8,30 @@ Command-line interface for [flutter_patcher](https://github.com/HYPER12755/flutt
|
|
|
8
8
|
npm i -g @_nazmiforreal/flutter-ota
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
This installs the `flutter-
|
|
11
|
+
This installs the `flutter-ota` command. A prebuilt Linux binary ships with the package; on other platforms it falls back to `dart compile exe` (requires the [Dart SDK](https://dart.dev)).
|
|
12
12
|
|
|
13
13
|
## Usage
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
flutter-
|
|
17
|
-
flutter-
|
|
18
|
-
flutter-
|
|
16
|
+
flutter-ota --help
|
|
17
|
+
flutter-ota keys # generate an Ed25519 keypair
|
|
18
|
+
flutter-ota build -a app-release.apk \
|
|
19
19
|
--version 1.0.0 --target-version-code 1 # -> dist/patch.zip (all ABIs)
|
|
20
|
-
flutter-
|
|
21
|
-
--channel production --backend
|
|
20
|
+
flutter-ota deploy --source dist \
|
|
21
|
+
--channel production --backend supabase \
|
|
22
22
|
--key <PRIVATE_KEY_BASE64> # upload + sign a bundle
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
### Backends
|
|
26
26
|
|
|
27
|
-
`--backend supabase|postgres|cloudflare|aws
|
|
28
|
-
Each resolves its own env / `.
|
|
27
|
+
`--backend supabase|postgres|cloudflare|aws`.
|
|
28
|
+
Each resolves its own env / `.flutter_ota_kit/config.json` (global: `~/.flutter_ota_kit/config.json`).
|
|
29
29
|
|
|
30
30
|
### Commands
|
|
31
31
|
|
|
32
|
-
`init`, `build`, `deploy`, `bundle` (list/delete/promote),
|
|
33
|
-
(get/set
|
|
34
|
-
`
|
|
32
|
+
`init`, `build`, `deploy`, `bundle` (list/show/delete/disable/enable/force/promote/update),
|
|
33
|
+
`rollback`, `channel` (list/get/set), `fingerprint`, `doctor`, `migrate`, `config`
|
|
34
|
+
(get/set/list), `keys`, `console`, `storage` (list/delete).
|
|
35
35
|
|
|
36
36
|
## License
|
|
37
37
|
|
|
Binary file
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
// Launcher for the flutter_patcher CLI.
|
|
5
5
|
//
|
|
6
|
-
// Resolves a platform+arch-specific prebuilt binary (`flutter-
|
|
6
|
+
// Resolves a platform+arch-specific prebuilt binary (`flutter-ota-<os>-<arch>`)
|
|
7
7
|
// shipped next to this script, falling back to `dart run` of the bundled Dart
|
|
8
8
|
// source when no prebuilt exists for the current architecture (e.g. a user on
|
|
9
9
|
// arm64 with only an x64 binary present). This keeps the package installable on
|
|
@@ -28,7 +28,7 @@ const platformName = platform();
|
|
|
28
28
|
const archName = arch();
|
|
29
29
|
const ext = process.platform === 'win32' ? '.exe' : '';
|
|
30
30
|
const binDir = __dirname;
|
|
31
|
-
const binName = `flutter-
|
|
31
|
+
const binName = `flutter-ota-${platformName}-${archName}${ext}`;
|
|
32
32
|
const binPath = path.join(binDir, binName);
|
|
33
33
|
|
|
34
34
|
const sourceEntry = path.join(
|
|
@@ -66,7 +66,7 @@ if (fs.existsSync(binPath)) {
|
|
|
66
66
|
const getRes = spawnSync('dart', ['pub', 'get'], { stdio: 'inherit', cwd: cliDir });
|
|
67
67
|
if (getRes.status !== 0) {
|
|
68
68
|
console.error(
|
|
69
|
-
'flutter-
|
|
69
|
+
'flutter-ota: `dart pub get` failed. Install dependencies or build ' +
|
|
70
70
|
`a prebuilt manually:\n cd ${cliDir} && dart compile exe ` +
|
|
71
71
|
`bin/flutter_patcher.dart -o ${binPath}`,
|
|
72
72
|
);
|
|
@@ -77,7 +77,7 @@ if (fs.existsSync(binPath)) {
|
|
|
77
77
|
run('dart', [sourceEntry, ...process.argv.slice(2)]);
|
|
78
78
|
} else {
|
|
79
79
|
console.error(
|
|
80
|
-
`flutter-
|
|
80
|
+
`flutter-ota: no prebuilt binary for ${platformName}-${archName} and ` +
|
|
81
81
|
'the Dart SDK was not found. Install Dart (https://dart.dev) or use a ' +
|
|
82
82
|
'platform/arch with a shipped prebuilt binary.',
|
|
83
83
|
);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import 'dart:io';
|
|
2
2
|
|
|
3
|
-
import 'package:
|
|
3
|
+
import 'package:flutter_ota_kit_cli/flutter_ota_kit_cli.dart';
|
|
4
4
|
|
|
5
|
-
/// `
|
|
5
|
+
/// `flutter_ota_kit` executable entry point.
|
|
6
6
|
Future<void> main(List<String> args) async {
|
|
7
7
|
final code = await run(args);
|
|
8
8
|
if (code != 0) exitCode = code;
|
package/dart-src/packages/cli-tools/lib/{flutter_patcher_cli.dart → flutter_ota_kit_cli.dart}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
///
|
|
1
|
+
/// flutter_ota_kit_cli — command-line interface for flutter_ota_kit.
|
|
2
2
|
///
|
|
3
3
|
/// Faithful Dart port of hot-updater's `@hot-updater/cli`: deploy bundles,
|
|
4
4
|
/// manage channels/rollbacks, run migrations, and inspect the backend.
|
|
@@ -42,12 +42,13 @@ import 'src/commands/init.dart';
|
|
|
42
42
|
import 'src/commands/keys.dart';
|
|
43
43
|
import 'src/commands/migrate.dart';
|
|
44
44
|
import 'src/commands/rollback.dart';
|
|
45
|
+
import 'src/commands/storage.dart';
|
|
45
46
|
|
|
46
47
|
/// Entry point: build the command runner and dispatch [args].
|
|
47
48
|
Future<int> run(List<String> args) async {
|
|
48
49
|
final runner = FlutterPatcherRunner(
|
|
49
|
-
'
|
|
50
|
-
'
|
|
50
|
+
'flutter_ota_kit',
|
|
51
|
+
'flutter_ota_kit CLI — OTA code push for Flutter (hot-updater compatible).',
|
|
51
52
|
)
|
|
52
53
|
..addCommand(InitCommand())
|
|
53
54
|
..addCommand(ConfigCommand())
|
|
@@ -59,6 +60,7 @@ Future<int> run(List<String> args) async {
|
|
|
59
60
|
..addCommand(BundleCommand())
|
|
60
61
|
..addCommand(RollbackCommand())
|
|
61
62
|
..addCommand(ChannelCommand())
|
|
63
|
+
..addCommand(StorageCommand())
|
|
62
64
|
..addCommand(MigrateCommand())
|
|
63
65
|
..addCommand(ConsoleCommand());
|
|
64
66
|
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import 'package:
|
|
2
|
-
import 'package:
|
|
3
|
-
import 'package:
|
|
4
|
-
import 'package:
|
|
5
|
-
import 'package:
|
|
6
|
-
import 'package:flutter_patcher_supabase/flutter_patcher_supabase.dart';
|
|
1
|
+
import 'package:flutter_ota_kit_aws/flutter_ota_kit_aws.dart';
|
|
2
|
+
import 'package:flutter_ota_kit_cloudflare/flutter_ota_kit_cloudflare.dart';
|
|
3
|
+
import 'package:flutter_ota_kit_plugin_core/flutter_ota_kit_plugin_core.dart';
|
|
4
|
+
import 'package:flutter_ota_kit_postgres/flutter_ota_kit_postgres.dart';
|
|
5
|
+
import 'package:flutter_ota_kit_supabase/flutter_ota_kit_supabase.dart';
|
|
7
6
|
|
|
8
7
|
import 'config.dart';
|
|
9
8
|
|
|
@@ -48,7 +47,6 @@ Backend resolveBackend(
|
|
|
48
47
|
AwsCloudFrontClientLike Function(S3DatabaseConfig config)?
|
|
49
48
|
awsCloudFrontClientFactory,
|
|
50
49
|
AwsS3ClientLike Function(AwsS3StorageConfig config)? awsStorageClientFactory,
|
|
51
|
-
StandaloneClientFactory? standaloneClientFactory,
|
|
52
50
|
}) {
|
|
53
51
|
switch (config.provider) {
|
|
54
52
|
case 'supabase':
|
|
@@ -136,27 +134,10 @@ Backend resolveBackend(
|
|
|
136
134
|
basePath: storageConfig.basePath,
|
|
137
135
|
);
|
|
138
136
|
|
|
139
|
-
case 'standalone':
|
|
140
|
-
final dbConfig = resolveStandaloneDatabaseConfig(
|
|
141
|
-
config,
|
|
142
|
-
clientFactory: standaloneClientFactory,
|
|
143
|
-
);
|
|
144
|
-
final storageConfig = resolveStandaloneStorageConfig(
|
|
145
|
-
config,
|
|
146
|
-
clientFactory: standaloneClientFactory,
|
|
147
|
-
);
|
|
148
|
-
final db = standaloneRepository(dbConfig)();
|
|
149
|
-
final storage = standaloneStorage(storageConfig);
|
|
150
|
-
final node = storage.profiles.node;
|
|
151
|
-
if (node == null) {
|
|
152
|
-
throw StateError('Standalone storage plugin exposes no node profile.');
|
|
153
|
-
}
|
|
154
|
-
return Backend(db: db, storage: node);
|
|
155
|
-
|
|
156
137
|
default:
|
|
157
138
|
throw UnsupportedError(
|
|
158
139
|
'Provider "${config.provider}" is not supported. '
|
|
159
|
-
'Supported: supabase, postgres, cloudflare, aws
|
|
140
|
+
'Supported: supabase, postgres, cloudflare, aws.',
|
|
160
141
|
);
|
|
161
142
|
}
|
|
162
143
|
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import 'dart:io';
|
|
2
|
+
|
|
1
3
|
import 'package:args/args.dart';
|
|
2
4
|
|
|
3
5
|
import 'backend.dart';
|
|
4
6
|
import 'config.dart';
|
|
5
7
|
import 'pack.dart';
|
|
6
8
|
import 'ui/ui.dart';
|
|
9
|
+
import 'verbose.dart';
|
|
7
10
|
|
|
8
11
|
export 'runner.dart';
|
|
9
12
|
|
|
@@ -12,14 +15,17 @@ Future<int> runGuarded(Future<void> Function() body) async {
|
|
|
12
15
|
try {
|
|
13
16
|
await body();
|
|
14
17
|
return 0;
|
|
15
|
-
} on StateError catch (e) {
|
|
18
|
+
} on StateError catch (e, st) {
|
|
16
19
|
err(e.message);
|
|
20
|
+
if (verboseMode) stderr.writeln(st);
|
|
17
21
|
return 1;
|
|
18
|
-
} on PackException catch (e) {
|
|
22
|
+
} on PackException catch (e, st) {
|
|
19
23
|
err(e.message);
|
|
24
|
+
if (verboseMode) stderr.writeln(st);
|
|
20
25
|
return e.exitCode;
|
|
21
|
-
} catch (e) {
|
|
26
|
+
} catch (e, st) {
|
|
22
27
|
err(e.toString());
|
|
28
|
+
if (verboseMode) stderr.writeln(st);
|
|
23
29
|
return 1;
|
|
24
30
|
}
|
|
25
31
|
}
|
|
@@ -29,7 +35,7 @@ Backend requireBackend(FlutterPatcherConfig? config, {Backend? override}) {
|
|
|
29
35
|
if (override != null) return override;
|
|
30
36
|
if (config == null) {
|
|
31
37
|
throw StateError(
|
|
32
|
-
'No configuration found. Run `
|
|
38
|
+
'No configuration found. Run `flutter_ota_kit init` or set '
|
|
33
39
|
'SUPABASE_URL / SUPABASE_SERVICE_ROLE_KEY.',
|
|
34
40
|
);
|
|
35
41
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import 'package:
|
|
1
|
+
import 'package:flutter_ota_kit_cli/flutter_ota_kit_cli.dart';
|
|
2
2
|
|
|
3
3
|
import '../ui/ui.dart';
|
|
4
4
|
|
|
5
|
-
/// `
|
|
5
|
+
/// `flutter_ota_kit build` — package a release APK into a device-compatible
|
|
6
6
|
/// OTA patch (`dist/patch.zip`) that the `deploy` command can publish.
|
|
7
7
|
///
|
|
8
8
|
/// Includes every ABI found in the APK so a single bundle installs on all
|
|
@@ -25,11 +25,13 @@ class BuildCommand extends FlutterPatcherCommand {
|
|
|
25
25
|
)
|
|
26
26
|
..addOption(
|
|
27
27
|
'target-version-code',
|
|
28
|
+
abbr: 't',
|
|
28
29
|
help: 'Host APK versionCode this patch targets (integer).',
|
|
29
30
|
)
|
|
30
31
|
..addOption(
|
|
31
32
|
'abi',
|
|
32
|
-
help: '
|
|
33
|
+
help: 'Restrict the patch to a single ABI (e.g. arm64-v8a). '
|
|
34
|
+
'Default: all ABIs found in the APK are included.',
|
|
33
35
|
)
|
|
34
36
|
..addOption(
|
|
35
37
|
'out',
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import 'package:args/args.dart';
|
|
2
|
-
import 'package:
|
|
2
|
+
import 'package:flutter_ota_kit_cli/flutter_ota_kit_cli.dart';
|
|
3
3
|
|
|
4
4
|
import '../ui/ui.dart';
|
|
5
5
|
|
|
6
|
-
/// `
|
|
6
|
+
/// `flutter_ota_kit bundle` — manage bundles entirely from the CLI (no direct
|
|
7
|
+
/// DB access needed; the CLI talks to the backend through its plugins).
|
|
7
8
|
class BundleCommand extends FlutterPatcherCommand {
|
|
8
|
-
BundleCommand({this.config, this.backendOverride})
|
|
9
|
+
BundleCommand({this.config, this.backendOverride}) {
|
|
10
|
+
addSubcommand(BundleListCommand(config: config, backendOverride: backendOverride));
|
|
11
|
+
addSubcommand(BundleShowCommand(config: config, backendOverride: backendOverride));
|
|
12
|
+
addSubcommand(BundleDeleteCommand(config: config, backendOverride: backendOverride));
|
|
13
|
+
addSubcommand(BundleDisableCommand(config: config, backendOverride: backendOverride));
|
|
14
|
+
addSubcommand(BundleEnableCommand(config: config, backendOverride: backendOverride));
|
|
15
|
+
addSubcommand(BundleForceCommand(config: config, backendOverride: backendOverride));
|
|
16
|
+
addSubcommand(BundlePromoteCommand(config: config, backendOverride: backendOverride));
|
|
17
|
+
addSubcommand(BundleUpdateCommand(config: config, backendOverride: backendOverride));
|
|
18
|
+
}
|
|
9
19
|
|
|
10
20
|
final FlutterPatcherConfig? config;
|
|
11
21
|
final Backend? backendOverride;
|
|
@@ -14,16 +24,22 @@ class BundleCommand extends FlutterPatcherCommand {
|
|
|
14
24
|
String get name => 'bundle';
|
|
15
25
|
|
|
16
26
|
@override
|
|
17
|
-
String get description =>
|
|
27
|
+
String get description =>
|
|
28
|
+
'Manage bundles (list / show / delete / disable / enable / force / promote).';
|
|
18
29
|
|
|
19
30
|
@override
|
|
20
31
|
Future<int> run() => runGuarded(() async {
|
|
21
32
|
print(description);
|
|
22
33
|
print('');
|
|
23
34
|
print('Subcommands:');
|
|
24
|
-
print(' list
|
|
25
|
-
print('
|
|
26
|
-
print('
|
|
35
|
+
print(' list List bundles (filters: --channel/-c, --platform/-p, --enabled, --limit/-l)');
|
|
36
|
+
print(' show --id <id> Show a single bundle\'s details');
|
|
37
|
+
print(' delete --id <id> Delete a bundle');
|
|
38
|
+
print(' disable --id <id> Disable a bundle (stop serving it)');
|
|
39
|
+
print(' enable --id <id> Enable a bundle');
|
|
40
|
+
print(' force --id <id> Force an update onto clients (--off to clear)');
|
|
41
|
+
print(' promote --id <id> -c Promote a bundle to a channel');
|
|
42
|
+
print(' update --id <id> ... Edit metadata (--message/--target-version/--enabled/--force)');
|
|
27
43
|
});
|
|
28
44
|
}
|
|
29
45
|
|
|
@@ -81,6 +97,7 @@ class BundleListCommand extends FlutterPatcherCommand {
|
|
|
81
97
|
b.enabled ? green('yes') : yellow('no'),
|
|
82
98
|
))
|
|
83
99
|
..add(kv('platform', b.platform.value))
|
|
100
|
+
..add(kv('force', b.shouldForceUpdate ? green('yes') : yellow('no')))
|
|
84
101
|
..add(kv('target', target));
|
|
85
102
|
if (b.message != null) lines.add(kv('message', b.message!));
|
|
86
103
|
if (b.metadata?.signature != null) {
|
|
@@ -93,6 +110,53 @@ class BundleListCommand extends FlutterPatcherCommand {
|
|
|
93
110
|
});
|
|
94
111
|
}
|
|
95
112
|
|
|
113
|
+
class BundleShowCommand extends FlutterPatcherCommand {
|
|
114
|
+
BundleShowCommand({this.config, this.backendOverride});
|
|
115
|
+
|
|
116
|
+
final FlutterPatcherConfig? config;
|
|
117
|
+
final Backend? backendOverride;
|
|
118
|
+
|
|
119
|
+
@override
|
|
120
|
+
String get name => 'show';
|
|
121
|
+
|
|
122
|
+
@override
|
|
123
|
+
String get description => 'Show a single bundle\'s details.';
|
|
124
|
+
|
|
125
|
+
@override
|
|
126
|
+
ArgParser get argParser => ArgParser()
|
|
127
|
+
..addOption('backend', abbr: 'b', help: 'Backend provider.')
|
|
128
|
+
..addOption('id', help: 'Bundle id.');
|
|
129
|
+
|
|
130
|
+
@override
|
|
131
|
+
Future<int> run() => runGuarded(() async {
|
|
132
|
+
final id = argResults!['id'] as String?;
|
|
133
|
+
if (id == null || id.isEmpty) {
|
|
134
|
+
throw PackException('Usage: flutter_ota_kit bundle show --id <id>', 64);
|
|
135
|
+
}
|
|
136
|
+
final cfg = effectiveConfig(config ?? loadConfig(), argResults!);
|
|
137
|
+
final backend = requireBackend(cfg, override: backendOverride);
|
|
138
|
+
banner('bundle · show');
|
|
139
|
+
final b = await backend.db.getBundleById(id);
|
|
140
|
+
if (b == null) {
|
|
141
|
+
step('(not found)');
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
final lines = <String>[
|
|
145
|
+
kv('id', cyan(b.id)),
|
|
146
|
+
kv('channel', b.channel),
|
|
147
|
+
kv('enabled', b.enabled ? green('yes') : yellow('no')),
|
|
148
|
+
kv('platform', b.platform.value),
|
|
149
|
+
kv('force', b.shouldForceUpdate ? green('yes') : yellow('no')),
|
|
150
|
+
kv('target', b.targetAppVersion ?? b.fingerprintHash ?? dim('-')),
|
|
151
|
+
];
|
|
152
|
+
if (b.message != null) lines.add(kv('message', b.message!));
|
|
153
|
+
if (b.metadata?.signature != null) {
|
|
154
|
+
lines.add(kv('signature', green('✓ signed')));
|
|
155
|
+
}
|
|
156
|
+
box('bundle', lines);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
96
160
|
class BundleDeleteCommand extends FlutterPatcherCommand {
|
|
97
161
|
BundleDeleteCommand({this.config, this.backendOverride});
|
|
98
162
|
|
|
@@ -108,22 +172,154 @@ class BundleDeleteCommand extends FlutterPatcherCommand {
|
|
|
108
172
|
@override
|
|
109
173
|
ArgParser get argParser => ArgParser()
|
|
110
174
|
..addOption('backend', abbr: 'b', help: 'Backend provider.')
|
|
111
|
-
..addOption('id', help: 'Bundle id.')
|
|
175
|
+
..addOption('id', help: 'Bundle id.')
|
|
176
|
+
..addFlag('keep-storage', help: 'Do not delete the storage object.', negatable: false);
|
|
112
177
|
|
|
113
178
|
@override
|
|
114
179
|
Future<int> run() => runGuarded(() async {
|
|
115
180
|
final id = argResults!['id'] as String?;
|
|
116
181
|
if (id == null || id.isEmpty) {
|
|
117
|
-
throw PackException('Usage:
|
|
182
|
+
throw PackException('Usage: flutter_ota_kit bundle delete --id <id>', 64);
|
|
118
183
|
}
|
|
119
184
|
final cfg = effectiveConfig(config ?? loadConfig(), argResults!);
|
|
120
185
|
final backend = requireBackend(cfg, override: backendOverride);
|
|
121
186
|
banner('bundle · delete');
|
|
187
|
+
final existing = await backend.db.getBundleById(id);
|
|
188
|
+
if (existing == null) {
|
|
189
|
+
throw StateError('Bundle "$id" not found.');
|
|
190
|
+
}
|
|
191
|
+
final keepStorage = argResults!['keep-storage'] as bool;
|
|
122
192
|
await spinner(
|
|
123
193
|
() => deleteBundle(backend, id),
|
|
124
194
|
'Deleting bundle $id',
|
|
125
195
|
done: 'Deleted',
|
|
126
196
|
);
|
|
197
|
+
if (!keepStorage && existing.storageUri.isNotEmpty) {
|
|
198
|
+
await spinner(
|
|
199
|
+
() => backend.storage.delete(existing.storageUri),
|
|
200
|
+
'Removing storage object',
|
|
201
|
+
done: 'Storage removed',
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
class BundleDisableCommand extends FlutterPatcherCommand {
|
|
208
|
+
BundleDisableCommand({this.config, this.backendOverride});
|
|
209
|
+
|
|
210
|
+
final FlutterPatcherConfig? config;
|
|
211
|
+
final Backend? backendOverride;
|
|
212
|
+
|
|
213
|
+
@override
|
|
214
|
+
String get name => 'disable';
|
|
215
|
+
|
|
216
|
+
@override
|
|
217
|
+
String get description => 'Disable a bundle (stop serving it).';
|
|
218
|
+
|
|
219
|
+
@override
|
|
220
|
+
ArgParser get argParser => ArgParser()
|
|
221
|
+
..addOption('backend', abbr: 'b', help: 'Backend provider.')
|
|
222
|
+
..addOption('id', help: 'Bundle id.');
|
|
223
|
+
|
|
224
|
+
@override
|
|
225
|
+
Future<int> run() => runGuarded(() async {
|
|
226
|
+
final id = argResults!['id'] as String?;
|
|
227
|
+
if (id == null || id.isEmpty) {
|
|
228
|
+
throw PackException('Usage: flutter_ota_kit bundle disable --id <id>', 64);
|
|
229
|
+
}
|
|
230
|
+
final cfg = effectiveConfig(config ?? loadConfig(), argResults!);
|
|
231
|
+
final backend = requireBackend(cfg, override: backendOverride);
|
|
232
|
+
banner('bundle · disable');
|
|
233
|
+
await spinner(
|
|
234
|
+
() async {
|
|
235
|
+
await backend.db.updateBundle(id, {'enabled': false});
|
|
236
|
+
await backend.db.commitBundle();
|
|
237
|
+
},
|
|
238
|
+
'Disabling bundle $id',
|
|
239
|
+
done: 'Disabled',
|
|
240
|
+
);
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
class BundleEnableCommand extends FlutterPatcherCommand {
|
|
245
|
+
BundleEnableCommand({this.config, this.backendOverride});
|
|
246
|
+
|
|
247
|
+
final FlutterPatcherConfig? config;
|
|
248
|
+
final Backend? backendOverride;
|
|
249
|
+
|
|
250
|
+
@override
|
|
251
|
+
String get name => 'enable';
|
|
252
|
+
|
|
253
|
+
@override
|
|
254
|
+
String get description => 'Enable a bundle.';
|
|
255
|
+
|
|
256
|
+
@override
|
|
257
|
+
ArgParser get argParser => ArgParser()
|
|
258
|
+
..addOption('backend', abbr: 'b', help: 'Backend provider.')
|
|
259
|
+
..addOption('id', help: 'Bundle id.');
|
|
260
|
+
|
|
261
|
+
@override
|
|
262
|
+
Future<int> run() => runGuarded(() async {
|
|
263
|
+
final id = argResults!['id'] as String?;
|
|
264
|
+
if (id == null || id.isEmpty) {
|
|
265
|
+
throw PackException('Usage: flutter_ota_kit bundle enable --id <id>', 64);
|
|
266
|
+
}
|
|
267
|
+
final cfg = effectiveConfig(config ?? loadConfig(), argResults!);
|
|
268
|
+
final backend = requireBackend(cfg, override: backendOverride);
|
|
269
|
+
banner('bundle · enable');
|
|
270
|
+
await spinner(
|
|
271
|
+
() async {
|
|
272
|
+
await backend.db.updateBundle(id, {'enabled': true});
|
|
273
|
+
await backend.db.commitBundle();
|
|
274
|
+
},
|
|
275
|
+
'Enabling bundle $id',
|
|
276
|
+
done: 'Enabled',
|
|
277
|
+
);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
class BundleForceCommand extends FlutterPatcherCommand {
|
|
282
|
+
BundleForceCommand({this.config, this.backendOverride});
|
|
283
|
+
|
|
284
|
+
final FlutterPatcherConfig? config;
|
|
285
|
+
final Backend? backendOverride;
|
|
286
|
+
|
|
287
|
+
@override
|
|
288
|
+
String get name => 'force';
|
|
289
|
+
|
|
290
|
+
@override
|
|
291
|
+
String get description => 'Force an update onto clients (--off to clear).';
|
|
292
|
+
|
|
293
|
+
@override
|
|
294
|
+
ArgParser get argParser => ArgParser()
|
|
295
|
+
..addOption('backend', abbr: 'b', help: 'Backend provider.')
|
|
296
|
+
..addOption('id', help: 'Bundle id.')
|
|
297
|
+
..addFlag('off', help: 'Clear the force-update flag instead of setting it.');
|
|
298
|
+
|
|
299
|
+
@override
|
|
300
|
+
Future<int> run() => runGuarded(() async {
|
|
301
|
+
final id = argResults!['id'] as String?;
|
|
302
|
+
if (id == null || id.isEmpty) {
|
|
303
|
+
throw PackException(
|
|
304
|
+
'Usage: flutter_ota_kit bundle force --id <id> [--off]',
|
|
305
|
+
64,
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
final off = argResults!['off'] as bool;
|
|
309
|
+
final cfg = effectiveConfig(config ?? loadConfig(), argResults!);
|
|
310
|
+
final backend = requireBackend(cfg, override: backendOverride);
|
|
311
|
+
banner('bundle · force');
|
|
312
|
+
await spinner(
|
|
313
|
+
() async {
|
|
314
|
+
await backend.db.updateBundle(id, {
|
|
315
|
+
'shouldForceUpdate': !off,
|
|
316
|
+
if (!off) 'enabled': true,
|
|
317
|
+
});
|
|
318
|
+
await backend.db.commitBundle();
|
|
319
|
+
},
|
|
320
|
+
off ? 'Clearing force flag on $id' : 'Forcing update for $id',
|
|
321
|
+
done: off ? 'Cleared' : 'Forced',
|
|
322
|
+
);
|
|
127
323
|
});
|
|
128
324
|
}
|
|
129
325
|
|
|
@@ -151,7 +347,7 @@ class BundlePromoteCommand extends FlutterPatcherCommand {
|
|
|
151
347
|
final channel = argResults!['channel'] as String?;
|
|
152
348
|
if (id == null || id.isEmpty || channel == null || channel.isEmpty) {
|
|
153
349
|
throw PackException(
|
|
154
|
-
'Usage:
|
|
350
|
+
'Usage: flutter_ota_kit bundle promote --id <id> --channel <channel>',
|
|
155
351
|
64,
|
|
156
352
|
);
|
|
157
353
|
}
|
|
@@ -169,3 +365,76 @@ class BundlePromoteCommand extends FlutterPatcherCommand {
|
|
|
169
365
|
]);
|
|
170
366
|
});
|
|
171
367
|
}
|
|
368
|
+
|
|
369
|
+
class BundleUpdateCommand extends FlutterPatcherCommand {
|
|
370
|
+
BundleUpdateCommand({this.config, this.backendOverride});
|
|
371
|
+
|
|
372
|
+
final FlutterPatcherConfig? config;
|
|
373
|
+
final Backend? backendOverride;
|
|
374
|
+
|
|
375
|
+
@override
|
|
376
|
+
String get name => 'update';
|
|
377
|
+
|
|
378
|
+
@override
|
|
379
|
+
String get description =>
|
|
380
|
+
'Edit a bundle\'s metadata (message / target version / enabled / force).';
|
|
381
|
+
|
|
382
|
+
@override
|
|
383
|
+
ArgParser get argParser => ArgParser()
|
|
384
|
+
..addOption('backend', abbr: 'b', help: 'Backend provider.')
|
|
385
|
+
..addOption('id', help: 'Bundle id.')
|
|
386
|
+
..addOption('message', abbr: 'm', help: 'New release message.')
|
|
387
|
+
..addOption('target-version', help: 'New target app version (e.g. 1.0.0).')
|
|
388
|
+
..addOption('enabled', help: 'Set enabled (true/false).')
|
|
389
|
+
..addOption('force', abbr: 'f', help: 'Set force-update (true/false).');
|
|
390
|
+
|
|
391
|
+
@override
|
|
392
|
+
Future<int> run() => runGuarded(() async {
|
|
393
|
+
final id = argResults!['id'] as String?;
|
|
394
|
+
if (id == null || id.isEmpty) {
|
|
395
|
+
throw PackException(
|
|
396
|
+
'Usage: flutter-ota bundle update --id <id> '
|
|
397
|
+
'[--message <m>] [--target-version <v>] [--enabled true|false] '
|
|
398
|
+
'[--force true|false]',
|
|
399
|
+
64,
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
final patch = <String, Object?>{};
|
|
403
|
+
final message = argResults!['message'] as String?;
|
|
404
|
+
if (message != null) patch['message'] = message;
|
|
405
|
+
final target = argResults!['target-version'] as String?;
|
|
406
|
+
if (target != null) patch['targetAppVersion'] = target;
|
|
407
|
+
final enabled = argResults!['enabled'] as String?;
|
|
408
|
+
if (enabled != null) {
|
|
409
|
+
patch['enabled'] = enabled == 'true' || enabled == '1';
|
|
410
|
+
}
|
|
411
|
+
final force = argResults!['force'] as String?;
|
|
412
|
+
if (force != null) {
|
|
413
|
+
patch['shouldForceUpdate'] = force == 'true' || force == '1';
|
|
414
|
+
}
|
|
415
|
+
if (patch.isEmpty) {
|
|
416
|
+
throw PackException('Nothing to update — pass at least one flag.', 64);
|
|
417
|
+
}
|
|
418
|
+
final cfg = effectiveConfig(config ?? loadConfig(), argResults!);
|
|
419
|
+
final backend = requireBackend(cfg, override: backendOverride);
|
|
420
|
+
banner('bundle · update');
|
|
421
|
+
await spinner(
|
|
422
|
+
() async {
|
|
423
|
+
await backend.db.updateBundle(id, patch);
|
|
424
|
+
await backend.db.commitBundle();
|
|
425
|
+
},
|
|
426
|
+
'Updating $id',
|
|
427
|
+
done: 'Updated',
|
|
428
|
+
);
|
|
429
|
+
final b = await backend.db.getBundleById(id);
|
|
430
|
+
if (b != null) {
|
|
431
|
+
box('bundle', [
|
|
432
|
+
kv('id', cyan(b.id)),
|
|
433
|
+
kv('enabled', b.enabled ? green('yes') : yellow('no')),
|
|
434
|
+
kv('force', b.shouldForceUpdate ? green('yes') : yellow('no')),
|
|
435
|
+
kv('target', b.targetAppVersion ?? dim('-')),
|
|
436
|
+
if (b.message != null) kv('message', b.message!),
|
|
437
|
+
]);
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import 'package:args/args.dart';
|
|
2
|
-
import 'package:
|
|
2
|
+
import 'package:flutter_ota_kit_cli/flutter_ota_kit_cli.dart';
|
|
3
3
|
|
|
4
4
|
import '../ui/ui.dart';
|
|
5
5
|
|
|
6
|
-
/// `
|
|
6
|
+
/// `flutter_ota_kit channel` — manage channels.
|
|
7
7
|
class ChannelCommand extends FlutterPatcherCommand {
|
|
8
8
|
final FlutterPatcherConfig? config;
|
|
9
9
|
final Backend? backendOverride;
|
|
@@ -76,13 +76,13 @@ class ChannelGetCommand extends FlutterPatcherCommand {
|
|
|
76
76
|
@override
|
|
77
77
|
ArgParser get argParser => ArgParser()
|
|
78
78
|
..addOption('backend', abbr: 'b', help: 'Backend provider.')
|
|
79
|
-
..addOption('channel', help: 'Channel.');
|
|
79
|
+
..addOption('channel', abbr: 'c', help: 'Channel.');
|
|
80
80
|
|
|
81
81
|
@override
|
|
82
82
|
Future<int> run() => runGuarded(() async {
|
|
83
83
|
final channel = argResults!['channel'] as String?;
|
|
84
84
|
if (channel == null || channel.isEmpty) {
|
|
85
|
-
throw PackException('Usage:
|
|
85
|
+
throw PackException('Usage: flutter_ota_kit channel get --channel <channel>', 64);
|
|
86
86
|
}
|
|
87
87
|
final cfg = effectiveConfig(config ?? loadConfig(), argResults!);
|
|
88
88
|
final backend = requireBackend(cfg, override: backendOverride);
|
|
@@ -117,8 +117,8 @@ class ChannelSetCommand extends FlutterPatcherCommand {
|
|
|
117
117
|
@override
|
|
118
118
|
ArgParser get argParser => ArgParser()
|
|
119
119
|
..addOption('backend', abbr: 'b', help: 'Backend provider.')
|
|
120
|
-
..addOption('channel', help: 'Channel.')
|
|
121
|
-
..addOption('bundle-id', help: 'Bundle id.');
|
|
120
|
+
..addOption('channel', abbr: 'c', help: 'Channel.')
|
|
121
|
+
..addOption('bundle-id', abbr: 'i', help: 'Bundle id.');
|
|
122
122
|
|
|
123
123
|
@override
|
|
124
124
|
Future<int> run() => runGuarded(() async {
|
|
@@ -129,7 +129,7 @@ class ChannelSetCommand extends FlutterPatcherCommand {
|
|
|
129
129
|
bundleId == null ||
|
|
130
130
|
bundleId.isEmpty) {
|
|
131
131
|
throw PackException(
|
|
132
|
-
'Usage:
|
|
132
|
+
'Usage: flutter_ota_kit channel set --channel <c> --bundle-id <id>',
|
|
133
133
|
64,
|
|
134
134
|
);
|
|
135
135
|
}
|