Skip to content

Remove package:cli_config & package:args dependencies in package:native_asset_cli #1598

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 25, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pkgs/native_assets_cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -8,6 +8,10 @@
- Remove v1.0 / v1.1 related serialization
- Update SDK constraint to 3.5.0+
- Remove (deprecated) support for accepting yaml as config
- Remove usage of `package:cli_config` and `package:args`: it minimizes
dependencies and it simplifies logic any hook has to do (as it no longer has
to look into environment variables, arguments and json file, determine which
has presence over other, etc)

## 0.8.0

4 changes: 3 additions & 1 deletion pkgs/native_assets_cli/lib/src/api/build_config.dart
Original file line number Diff line number Diff line change
@@ -2,12 +2,14 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:convert';
import 'dart:io';

import 'package:cli_config/cli_config.dart';
import 'package:collection/collection.dart';
import 'package:pub_semver/pub_semver.dart';

import '../args_parser.dart';
import '../json_utils.dart';
import '../model/hook.dart';
import '../model/metadata.dart';
import '../utils/json.dart';
3 changes: 1 addition & 2 deletions pkgs/native_assets_cli/lib/src/api/hook_config.dart
Original file line number Diff line number Diff line change
@@ -5,11 +5,11 @@
import 'dart:convert';
import 'dart:io';

import 'package:cli_config/cli_config.dart';
import 'package:collection/collection.dart';
import 'package:crypto/crypto.dart';
import 'package:pub_semver/pub_semver.dart';

import '../json_utils.dart';
import '../model/hook.dart';
import '../model/metadata.dart';
import '../model/target.dart';
@@ -22,7 +22,6 @@ import 'ios_sdk.dart';
import 'link_config.dart';
import 'link_mode_preference.dart';
import 'os.dart';

part '../model/hook_config.dart';

/// The shared properties of a [LinkConfig] and a [BuildConfig].
4 changes: 2 additions & 2 deletions pkgs/native_assets_cli/lib/src/api/link_config.dart
Original file line number Diff line number Diff line change
@@ -4,12 +4,12 @@
import 'dart:convert';
import 'dart:io';

import 'package:args/args.dart';
import 'package:cli_config/cli_config.dart';
import 'package:collection/collection.dart';
import 'package:meta/meta.dart';
import 'package:pub_semver/pub_semver.dart';

import '../args_parser.dart';
import '../json_utils.dart';
import '../model/hook.dart';
import '../utils/map.dart';
import 'architecture.dart';
18 changes: 18 additions & 0 deletions pkgs/native_assets_cli/lib/src/args_parser.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

String getConfigArgument(List<String> arguments) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could actually decide that instead of making this based on arguments we set a DART_BUILD_HOOK_CONFIG environment variable containing the configuration.

for (var i = 0; i < arguments.length; ++i) {
final argument = arguments[i];
if (argument.startsWith('--config=')) {
return argument.substring('--config='.length);
}
if (argument == '--config') {
if ((i + 1) < arguments.length) {
return arguments[i + 1];
}
}
}
throw StateError('No --config argument given.');
}
106 changes: 106 additions & 0 deletions pkgs/native_assets_cli/lib/src/json_utils.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:core';
import 'dart:core' as core;
import 'dart:io';

extension JsonUtils on Map<String, Object?> {
String string(String key, {Iterable<String>? validValues}) {
final value = get<String>(key);
if (validValues != null && !validValues.contains(value)) {
throw FormatException('Json "$key" had value $value but expected one of '
'${validValues.join(',')}');
}
return value;
}

String? optionalString(String key) => getOptional<String>(key);

bool? optionalBool(String key) => getOptional<bool>(key);
core.int int(String key) => get<core.int>(key);
core.int? optionalInt(String key) => getOptional<core.int>(key);

Uri path(String key,
{required Uri baseUri,
bool resolveUri = true,
bool mustExist = false}) =>
_pathToUri(get<String>(key), baseUri: baseUri, resolveUri: resolveUri);

Uri? optionalPath(String key,
{required Uri baseUri, bool resolveUri = true, bool mustExist = false}) {
final value = getOptional<String>(key);
if (value == null) return null;
final uri = _pathToUri(value, baseUri: baseUri, resolveUri: resolveUri);
if (mustExist) {
_throwIfNotExists(key, uri);
}
return uri;
}

List<String>? optionalStringList(String key) {
final value = getOptional<List<Object?>>(key);
if (value == null) return null;
return value.cast<String>();
}

List<Object?> list(String key) => get<List<Object?>>(key);
List<Object?>? optionalList(String key) => getOptional<List<Object?>>(key);
Map<String, Object?>? optionalMap(String key) =>
getOptional<Map<String, Object?>>(key);

T get<T extends Object>(String key) {
final value = this[key];
if (value == null) {
throw FormatException('No value was provided for required key: $key');
}
if (value is T) return value;
throw FormatException(
'Unexpected value \'$value\' for key \'.$key\' in config file. '
'Expected a $T.');
}

T? getOptional<T extends Object>(String key) {
final value = this[key];
if (value is T?) return value;
throw FormatException(
'Unexpected value \'$value\' for key \'.$key\' in config file. '
'Expected a $T?.');
}
}

Uri _pathToUri(
String path, {
required core.bool resolveUri,
required Uri? baseUri,
}) {
final uri = _fileSystemPathToUri(path);
if (resolveUri && baseUri != null) {
return baseUri.resolveUri(uri);
}
return uri;
}

void _throwIfNotExists(String key, Uri value) {
final fileSystemEntity = value.fileSystemEntity;
if (!fileSystemEntity.existsSync()) {
throw FormatException("Path '$value' for key '$key' doesn't exist.");
}
}

extension on Uri {
FileSystemEntity get fileSystemEntity {
if (path.endsWith(Platform.pathSeparator) || path.endsWith('/')) {
return Directory.fromUri(this);
}
return File.fromUri(this);
}
}

Uri _fileSystemPathToUri(String path) {
if (path.endsWith(Platform.pathSeparator)) {
return Uri.directory(path);
}
return Uri.file(path);
}
42 changes: 17 additions & 25 deletions pkgs/native_assets_cli/lib/src/model/build_config.dart
Original file line number Diff line number Diff line change
@@ -97,37 +97,32 @@ final class BuildConfigImpl extends HookConfigImpl implements BuildConfig {
_supportedAssetTypesBackwardsCompatibility(supportedAssetTypes),
);

factory BuildConfigImpl._fromConfig(Config config) =>
_readFieldsFromConfig(config);

static BuildConfigImpl fromArguments(
List<String> args, {
List<String> arguments, {
Map<String, String>? environment,
Uri? workingDirectory,
}) {
// TODO(https://github.com/dart-lang/native/issues/1000): At some point,
// migrate away from package:cli_config, to get rid of package:yaml
// dependency.
final config = Config.fromArgumentsSync(
arguments: args,
environment: environment,
workingDirectory: workingDirectory,
);
return BuildConfigImpl._fromConfig(config);
final configPath = getConfigArgument(arguments);
final bytes = File(configPath).readAsBytesSync();
final linkConfigJson = const Utf8Decoder()
.fuse(const JsonDecoder())
.convert(bytes) as Map<String, Object?>;
return fromJson(linkConfigJson, baseUri: Uri.parse(configPath));
}

static const dependencyMetadataConfigKey = 'dependency_metadata';

static const linkingEnabledKey = 'linking_enabled';

static BuildConfigImpl _readFieldsFromConfig(Config config) {
static BuildConfigImpl fromJson(Map<String, dynamic> config, {Uri? baseUri}) {
baseUri ??= Uri.base;
final dryRun = HookConfigImpl.parseDryRun(config) ?? false;
final targetOS = HookConfigImpl.parseTargetOS(config);
return BuildConfigImpl(
outputDirectory: HookConfigImpl.parseOutDir(config),
outputDirectoryShared: HookConfigImpl.parseOutDirShared(config),
outputDirectory: HookConfigImpl.parseOutDir(baseUri, config),
outputDirectoryShared: HookConfigImpl.parseOutDirShared(baseUri, config),
packageName: HookConfigImpl.parsePackageName(config),
packageRoot: HookConfigImpl.parsePackageRoot(config),
packageRoot: HookConfigImpl.parsePackageRoot(baseUri, config),
buildMode: HookConfigImpl.parseBuildMode(config, dryRun),
targetOS: targetOS,
targetArchitecture:
@@ -136,7 +131,7 @@ final class BuildConfigImpl extends HookConfigImpl implements BuildConfig {
dependencyMetadata: parseDependencyMetadata(config),
linkingEnabled: parseHasLinkPhase(config),
version: HookConfigImpl.parseVersion(config),
cCompiler: HookConfigImpl.parseCCompiler(config, dryRun),
cCompiler: HookConfigImpl.parseCCompiler(baseUri, config, dryRun),
supportedAssetTypes: HookConfigImpl.parseSupportedAssetTypes(config),
targetAndroidNdkApi:
HookConfigImpl.parseTargetAndroidNdkApi(config, dryRun, targetOS),
@@ -149,9 +144,9 @@ final class BuildConfigImpl extends HookConfigImpl implements BuildConfig {
);
}

static Map<String, Metadata>? parseDependencyMetadata(Config config) {
final fileValue =
config.valueOf<Map<Object?, Object?>?>(dependencyMetadataConfigKey);
static Map<String, Metadata>? parseDependencyMetadata(
Map<String, Object?> config) {
final fileValue = config.optionalMap(dependencyMetadataConfigKey);
if (fileValue == null) {
return null;
}
@@ -174,12 +169,9 @@ final class BuildConfigImpl extends HookConfigImpl implements BuildConfig {
).sortOnKey();
}

static bool? parseHasLinkPhase(Config config) =>
static bool? parseHasLinkPhase(Map<String, Object?> config) =>
config.optionalBool(linkingEnabledKey);

static BuildConfigImpl fromJson(Map<String, dynamic> buildConfigJson) =>
BuildConfigImpl._fromConfig(Config(fileParsed: buildConfigJson));

@override
Map<String, Object> toJson() => {
...hookToJson(),
182 changes: 103 additions & 79 deletions pkgs/native_assets_cli/lib/src/model/hook_config.dart
Original file line number Diff line number Diff line change
@@ -204,7 +204,7 @@ abstract class HookConfigImpl implements HookConfig {
}.sortOnKey();
}

static Version parseVersion(Config config) {
static Version parseVersion(Map<String, Object?> config) {
final version = Version.parse(config.string('version'));
if (version.major > latestVersion.major) {
throw FormatException(
@@ -223,34 +223,35 @@ abstract class HookConfigImpl implements HookConfig {
return version;
}

static bool? parseDryRun(Config config) =>
static bool? parseDryRun(Map<String, Object?> config) =>
config.optionalBool(dryRunConfigKey);

static Uri parseOutDir(Config config) =>
config.path(outDirConfigKey, mustExist: true);
static Uri parseOutDir(Uri baseUri, Map<String, Object?> config) =>
config.path(outDirConfigKey, baseUri: baseUri, mustExist: true);

static Uri parseOutDirShared(Config config) {
final configResult =
config.optionalPath(outDirSharedConfigKey, mustExist: true);
static Uri parseOutDirShared(Uri baseUri, Map<String, Object?> config) {
final configResult = config.optionalPath(outDirSharedConfigKey,
baseUri: baseUri, mustExist: true);
if (configResult != null) {
return configResult;
}
// Backwards compatibility, create a directory next to the output dir.
// This is will not be shared so caching doesn't work, but it will make
// the newer hooks not crash.
final outDir = config.path(outDirConfigKey);
final outDir = config.path(outDirConfigKey, baseUri: baseUri);
final outDirShared = outDir.resolve('../out_shared/');
Directory.fromUri(outDirShared).createSync();
return outDirShared;
}

static String parsePackageName(Config config) =>
static String parsePackageName(Map<String, Object?> config) =>
config.string(packageNameConfigKey);

static Uri parsePackageRoot(Config config) =>
config.path(packageRootConfigKey, mustExist: true);
static Uri parsePackageRoot(Uri baseUri, Map<String, Object?> config) =>
config.path(packageRootConfigKey, baseUri: baseUri, mustExist: true);

static BuildModeImpl? parseBuildMode(Config config, bool dryRun) {
static BuildModeImpl? parseBuildMode(
Map<String, Object?> config, bool dryRun) {
if (dryRun) {
_throwIfNotNullInDryRun<String>(config, BuildModeImpl.configKey);
return null;
@@ -264,23 +265,24 @@ abstract class HookConfigImpl implements HookConfig {
}
}

static LinkModePreferenceImpl parseLinkModePreference(Config config) =>
static LinkModePreferenceImpl parseLinkModePreference(
Map<String, Object?> config) =>
LinkModePreferenceImpl.fromString(
config.string(
LinkModePreferenceImpl.configKey,
validValues: LinkModePreferenceImpl.values.map((e) => e.toString()),
),
);

static OSImpl parseTargetOS(Config config) => OSImpl.fromString(
static OSImpl parseTargetOS(Map<String, Object?> config) => OSImpl.fromString(
config.string(
OSImpl.configKey,
validValues: OSImpl.values.map((e) => '$e'),
),
);

static ArchitectureImpl? parseTargetArchitecture(
Config config,
Map<String, Object?> config,
bool dryRun,
OSImpl? targetOS,
) {
@@ -305,7 +307,7 @@ abstract class HookConfigImpl implements HookConfig {
}

static IOSSdkImpl? parseTargetIOSSdk(
Config config, bool dryRun, OSImpl? targetOS) {
Map<String, Object?> config, bool dryRun, OSImpl? targetOS) {
if (dryRun) {
_throwIfNotNullInDryRun<String>(config, IOSSdkImpl.configKey);
return null;
@@ -322,7 +324,7 @@ abstract class HookConfigImpl implements HookConfig {
}

static int? parseTargetAndroidNdkApi(
Config config,
Map<String, Object?> config,
bool dryRun,
OSImpl? targetOS,
) {
@@ -337,7 +339,7 @@ abstract class HookConfigImpl implements HookConfig {
}

static int? parseTargetIosVersion(
Config config,
Map<String, Object?> config,
bool dryRun,
OSImpl? targetOS,
) {
@@ -352,7 +354,7 @@ abstract class HookConfigImpl implements HookConfig {
}

static int? parseTargetMacOSVersion(
Config config,
Map<String, Object?> config,
bool dryRun,
OSImpl? targetOS,
) {
@@ -366,84 +368,106 @@ abstract class HookConfigImpl implements HookConfig {
}
}

static Uri? _parseArchiver(Config config, bool dryRun) {
if (dryRun) {
_throwIfNotNullInDryRun<int>(config, CCompilerConfigImpl.arConfigKeyFull);
return null;
} else {
return config.optionalPath(
CCompilerConfigImpl.arConfigKeyFull,
static Uri? _parseArchiver(Uri baseUri, Map<String, Object?> config) =>
config.optionalPath(
CCompilerConfigImpl.arConfigKey,
baseUri: baseUri,
mustExist: true,
);
}
}

static Uri? _parseCompiler(Config config, bool dryRun) {
if (dryRun) {
_throwIfNotNullInDryRun<int>(config, CCompilerConfigImpl.ccConfigKeyFull);
return null;
} else {
return config.optionalPath(
CCompilerConfigImpl.ccConfigKeyFull,
static Uri? _parseCompiler(Uri baseUri, Map<String, Object?> config) =>
config.optionalPath(
CCompilerConfigImpl.ccConfigKey,
baseUri: baseUri,
mustExist: true,
);
}
}

static Uri? _parseLinker(Config config, bool dryRun) {
if (dryRun) {
_throwIfNotNullInDryRun<int>(config, CCompilerConfigImpl.ccConfigKeyFull);
return null;
} else {
return config.optionalPath(
CCompilerConfigImpl.ldConfigKeyFull,
static Uri? _parseLinker(Uri baseUri, Map<String, Object?> config) =>
config.optionalPath(
CCompilerConfigImpl.ldConfigKey,
baseUri: baseUri,
mustExist: true,
);
}
}

static Uri? _parseEnvScript(Config config, bool dryRun, Uri? compiler) {
if (dryRun) {
_throwIfNotNullInDryRun<int>(config, CCompilerConfigImpl.ccConfigKeyFull);
return null;
} else {
return (compiler != null && compiler.toFilePath().endsWith('cl.exe'))
? config.path(CCompilerConfigImpl.envScriptConfigKeyFull,
mustExist: true)
static Uri? _parseEnvScript(
Uri baseUri, Map<String, Object?> config, Uri? compiler) =>
(compiler != null && compiler.toFilePath().endsWith('cl.exe'))
? config.path(CCompilerConfigImpl.envScriptConfigKey,
baseUri: baseUri, mustExist: true)
: null;
}
}

static List<String>? _parseEnvScriptArgs(Config config, bool dryRun) {
if (dryRun) {
_throwIfNotNullInDryRun<int>(config, CCompilerConfigImpl.ccConfigKeyFull);
return null;
} else {
return config.optionalStringList(
CCompilerConfigImpl.envScriptArgsConfigKeyFull,
splitEnvironmentPattern: ' ',
);
}
}
static List<String>? _parseEnvScriptArgs(Map<String, Object?> config) =>
config.optionalStringList(CCompilerConfigImpl.envScriptArgsConfigKey);

static List<String> parseSupportedAssetTypes(Config config) =>
static List<String> parseSupportedAssetTypes(Map<String, Object?> config) =>
config.optionalStringList(supportedAssetTypesKey) ??
[NativeCodeAsset.type];

static CCompilerConfigImpl parseCCompiler(Config config, bool dryRun) {
final parseCompiler = _parseCompiler(config, dryRun);
final cCompiler = CCompilerConfigImpl(
archiver: _parseArchiver(config, dryRun),
compiler: parseCompiler,
envScript: _parseEnvScript(config, dryRun, parseCompiler),
envScriptArgs: _parseEnvScriptArgs(config, dryRun),
linker: _parseLinker(config, dryRun),
static CCompilerConfigImpl parseCCompiler(
Uri baseUri, Map<String, Object?> config, bool dryRun) {
if (dryRun) {
_throwIfNotNullInDryRun<int>(config, CCompilerConfigImpl.configKey);
}

final cCompilerJson =
config.getOptional<Map<String, Object?>>(CCompilerConfigImpl.configKey);

Uri? archiver;
Uri? compiler;
Uri? linker;
Uri? envScript;
List<String>? envScriptArgs;
if (cCompilerJson != null) {
compiler = _parseCompiler(baseUri, cCompilerJson);
archiver = _parseArchiver(baseUri, cCompilerJson);
envScript = _parseEnvScript(baseUri, cCompilerJson, compiler);
envScriptArgs = _parseEnvScriptArgs(cCompilerJson);
linker = _parseLinker(baseUri, cCompilerJson);
}

// If the bundling tool didn't specify a C compiler we fallback to
// identifying the C compiler based on specific environment variables.
{
final env = Platform.environment;
String? unparseKey(String key) => key.replaceAll('.', '__').toUpperCase();
String? lookup(String key) => env[unparseKey(key)];
Uri? lookupUri(String key) {
final value = lookup(key);
return value != null ? Uri.file(value) : null;
}

List<String>? lookupList(String key) {
final value = lookup(key);
if (value == null) return null;
final list = value
.split(' ')
.map((arg) => arg.trim())
.where((arg) => arg.isNotEmpty)
.toList();
if (list.isEmpty) return null;
return list;
}

archiver ??= lookupUri(CCompilerConfigImpl.arConfigKeyFull);
compiler ??= lookupUri(CCompilerConfigImpl.ccConfigKeyFull);
linker ??= lookupUri(CCompilerConfigImpl.ldConfigKeyFull);
envScript ??= lookupUri(CCompilerConfigImpl.envScriptConfigKeyFull);
envScriptArgs ??=
lookupList(CCompilerConfigImpl.envScriptArgsConfigKeyFull);
}

return CCompilerConfigImpl(
archiver: archiver,
compiler: compiler,
envScript: envScript,
envScriptArgs: envScriptArgs,
linker: linker,
);
return cCompiler;
}

static void _throwIfNotNullInDryRun<T>(Config config, String key) {
final object = config.valueOf<T?>(key);
static void _throwIfNotNullInDryRun<T extends Object>(
Map<String, Object?> config, String key) {
final object = config.getOptional<T>(key);
if (object != null) {
throw const FormatException('''This field is not available in dry runs.
In Flutter projects, native builds are generated per OS which target multiple
39 changes: 18 additions & 21 deletions pkgs/native_assets_cli/lib/src/model/link_config.dart
Original file line number Diff line number Diff line change
@@ -78,34 +78,30 @@ class LinkConfigImpl extends HookConfigImpl implements LinkConfig {
}.sortOnKey();

static LinkConfig fromArguments(List<String> arguments) {
final argParser = ArgParser()..addOption('config');

final results = argParser.parse(arguments);
final linkConfigContents =
File(results['config'] as String).readAsStringSync();
final linkConfigJson =
jsonDecode(linkConfigContents) as Map<String, dynamic>;

return fromJson(linkConfigJson);
final configPath = getConfigArgument(arguments);
final bytes = File(configPath).readAsBytesSync();
final linkConfigJson = const Utf8Decoder()
.fuse(const JsonDecoder())
.convert(bytes) as Map<String, Object?>;
return fromJson(linkConfigJson, baseUri: Uri.parse(configPath));
}

static LinkConfigImpl fromJson(Map<String, dynamic> linkConfigJson) {
final config =
Config.fromConfigFileContents(fileContents: jsonEncode(linkConfigJson));
static LinkConfigImpl fromJson(Map<String, Object?> config, {Uri? baseUri}) {
baseUri = Uri.base;
final dryRun = HookConfigImpl.parseDryRun(config) ?? false;
final targetOS = HookConfigImpl.parseTargetOS(config);
return LinkConfigImpl(
outputDirectory: HookConfigImpl.parseOutDir(config),
outputDirectoryShared: HookConfigImpl.parseOutDirShared(config),
outputDirectory: HookConfigImpl.parseOutDir(baseUri, config),
outputDirectoryShared: HookConfigImpl.parseOutDirShared(baseUri, config),
packageName: HookConfigImpl.parsePackageName(config),
packageRoot: HookConfigImpl.parsePackageRoot(config),
packageRoot: HookConfigImpl.parsePackageRoot(baseUri, config),
buildMode: HookConfigImpl.parseBuildMode(config, dryRun),
targetOS: targetOS,
targetArchitecture:
HookConfigImpl.parseTargetArchitecture(config, dryRun, targetOS),
linkModePreference: HookConfigImpl.parseLinkModePreference(config),
version: HookConfigImpl.parseVersion(config),
cCompiler: HookConfigImpl.parseCCompiler(config, dryRun),
cCompiler: HookConfigImpl.parseCCompiler(baseUri, config, dryRun),
supportedAssetTypes: HookConfigImpl.parseSupportedAssetTypes(config),
targetAndroidNdkApi:
HookConfigImpl.parseTargetAndroidNdkApi(config, dryRun, targetOS),
@@ -115,16 +111,17 @@ class LinkConfigImpl extends HookConfigImpl implements LinkConfig {
targetMacOSVersion:
HookConfigImpl.parseTargetMacOSVersion(config, dryRun, targetOS),
assets: parseAssets(config),
recordedUsagesFile: parseRecordedUsagesUri(config),
recordedUsagesFile: parseRecordedUsagesUri(baseUri, config),
dryRun: dryRun,
);
}

static Uri? parseRecordedUsagesUri(Config config) =>
config.optionalPath(resourceIdentifierKey);
static Uri? parseRecordedUsagesUri(
Uri baseUri, Map<String, Object?> config) =>
config.optionalPath(resourceIdentifierKey, baseUri: baseUri);

static List<AssetImpl> parseAssets(Config config) =>
AssetImpl.listFromJson(config.valueOf(assetsKey));
static List<AssetImpl> parseAssets(Map<String, Object?> config) =>
AssetImpl.listFromJson(config.optionalList(assetsKey));

@override
bool operator ==(Object other) {
2 changes: 0 additions & 2 deletions pkgs/native_assets_cli/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -16,8 +16,6 @@ environment:
sdk: '>=3.5.0 <4.0.0'

dependencies:
args: ^2.4.2
cli_config: ^0.2.0
collection: ^1.17.1
crypto: ^3.0.3
logging: ^1.2.0