Skip to content
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

[native_assets_cli] Redesign API step 1 #946

Merged
merged 77 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
adbdd0f
[native_assets_cli] Redesign API
dcharkes Jan 18, 2024
6533972
Surpress deprecation warnings to appease CI
dcharkes Jan 22, 2024
cbdbc1e
changelog entries
dcharkes Jan 22, 2024
30964ac
Merge branch 'main' into native-assets-cli-build-output
dcharkes Jan 22, 2024
499feae
Address comments
dcharkes Jan 22, 2024
027fece
Remove `BuildState`
dcharkes Jan 23, 2024
e4d9b01
Sketch an `AssetDownloader`
dcharkes Jan 24, 2024
17d40dc
Merge branch 'main' into native-assets-cli-build-output
dcharkes Feb 15, 2024
5deb29c
Remove _2 fields
dcharkes Feb 15, 2024
a580dfb
changelogs
dcharkes Feb 15, 2024
b0d4cdc
cleanup
dcharkes Feb 15, 2024
12108ad
fix wrong deps version
dcharkes Feb 15, 2024
b0bc231
Add local asset example
dcharkes Feb 15, 2024
37de6cf
Add both singular and plural API
dcharkes Feb 15, 2024
cef032f
update examples
dcharkes Feb 16, 2024
09e5a3e
Use parts file for API
dcharkes Feb 16, 2024
7af60c0
Rename `Asset` to `CCodeAsset`
dcharkes Feb 16, 2024
e6794fb
Move c code assets
dcharkes Feb 16, 2024
e1e4f22
Add asset type to protocol
dcharkes Feb 16, 2024
8915b77
Parse assets based on asset type
dcharkes Feb 16, 2024
bee8f2d
Introduce `Asset` with `id` and `file`.
dcharkes Feb 19, 2024
9d9f894
Split `CCodeAsset.target` in `os` and `architecture`.
dcharkes Feb 19, 2024
624383f
Make build runner expand the architectures for CCodeAssets in dry run
dcharkes Feb 19, 2024
c772761
Rename `AssetPathType` to `DynamicLinking`
dcharkes Feb 19, 2024
6c5003b
Add a supported_asset_types to BuildConfig
dcharkes Feb 19, 2024
564eeee
Output older BuildOutput format if old BuildConfig was passed
dcharkes Feb 20, 2024
1f1509a
bump changelog
dcharkes Feb 20, 2024
dcd2165
Bump SDK constraint to use field promotion
dcharkes Feb 20, 2024
752dee9
Fix test on Windows
dcharkes Feb 20, 2024
ba4a81f
Make `BuildConfig.targetArchitecture` nullable instead of throw
dcharkes Feb 20, 2024
7a0c668
Increase test coverage
dcharkes Feb 20, 2024
e9a49a0
Add `DataAsset`s
dcharkes Feb 20, 2024
8170ef8
Fix windows test
dcharkes Feb 20, 2024
b8822ef
Fix test try 2
dcharkes Feb 20, 2024
81b7260
Iterate on documentation in public API
dcharkes Feb 21, 2024
8d5da09
Move Architecture and OS to their own files
dcharkes Feb 21, 2024
f539b85
Move c compiler config into its own file
dcharkes Feb 21, 2024
f1544e3
Mark all classes in the API final
dcharkes Feb 21, 2024
2958a2a
Another documentation round
dcharkes Feb 21, 2024
622b798
Cleanup Target.current use
dcharkes Feb 21, 2024
e488607
Migrate away from Target
dcharkes Feb 21, 2024
1154c95
Rename `TargetImpl` to `Target`
dcharkes Feb 21, 2024
51e71e6
Add changelog entries and bump version
dcharkes Feb 21, 2024
7ac882f
Use Dart casing `targetOs` -> `targetOS`
dcharkes Feb 21, 2024
300c206
data asset test coverage
dcharkes Feb 21, 2024
43ce175
Address comment
dcharkes Feb 23, 2024
f697827
Address comment
dcharkes Feb 23, 2024
5ba7e77
Address comments
dcharkes Feb 26, 2024
9992ce2
address comment
dcharkes Feb 27, 2024
21d5f83
address comment
dcharkes Feb 27, 2024
aa4d83e
Improve docs
dcharkes Feb 27, 2024
0ffe6e4
Make all asset ids use a `package:...`
dcharkes Feb 27, 2024
653dd16
cleanup
dcharkes Feb 27, 2024
a1a3554
address comments
dcharkes Feb 28, 2024
d82edcd
address comment
dcharkes Feb 28, 2024
84d77b4
Add Argument/State errors to DynamicLoading with LinkMode.static
dcharkes Feb 28, 2024
818ac15
More documentation for CCodeAssets and more errors
dcharkes Feb 28, 2024
03c44d2
Fix comment
dcharkes Feb 28, 2024
bc77f0d
Split up asset id into package and name in constructors
dcharkes Mar 4, 2024
4116376
Address comments
dcharkes Mar 4, 2024
ea8e581
Fix test
dcharkes Mar 4, 2024
9ed573f
Fix more tests
dcharkes Mar 4, 2024
230be89
address comment
dcharkes Mar 4, 2024
ab85d47
add test
dcharkes Mar 4, 2024
0ef0dcc
Remove `AssetDownloader` for now
dcharkes Mar 12, 2024
c66a963
Make BuildConfig loading sync
dcharkes Mar 12, 2024
7dab2e0
Remove unused imports
dcharkes Mar 12, 2024
8fa2b2e
Make `BuildConfig.fromArguments` the default constructor
dcharkes Mar 12, 2024
491cc25
Rename `CCodeAsset` to `NativeCodeAsset`
dcharkes Mar 12, 2024
0411dd9
Fix analysis
dcharkes Mar 12, 2024
88863be
Remove link between `LinkModePreference` and `LinkMode`
dcharkes Mar 12, 2024
05e473e
Rename `LinkMode.dynamic` -> `LinkMode.dynamicLoading`
dcharkes Mar 12, 2024
8134f46
Merge `DynamicLoadingMode` into `LinkMode`
dcharkes Mar 13, 2024
acd8a22
address comments
dcharkes Mar 14, 2024
81353f0
Pipe through `supportedAssetTypes`
dcharkes Mar 14, 2024
7e996d3
update example
dcharkes Mar 14, 2024
8dc1ef7
undo copyright comment change
dcharkes Mar 14, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
// 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.

// TODO(https://github.com/dart-lang/native/issues/882): A new version of
// `package:native_assets_cli` needs to be published first.
// ignore_for_file: deprecated_member_use

import 'package:cli_config/cli_config.dart';
import 'package:native_assets_cli/native_assets_cli.dart';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
// 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.

// TODO(https://github.com/dart-lang/native/issues/882): A new version of
// `package:native_assets_cli` needs to be published first.
// ignore_for_file: deprecated_member_use

import 'package:native_assets_cli/native_assets_cli.dart';

void main(List<String> args) async {
Expand Down
4 changes: 4 additions & 0 deletions pkgs/native_assets_cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.4.3-wip

- New API.

## 0.4.2

- Fix dartdoc generation. Hide the implementation details.
Expand Down
1 change: 1 addition & 0 deletions pkgs/native_assets_cli/lib/native_assets_cli.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
library native_assets_cli;

export 'src/api/asset.dart';
export 'src/api/build.dart';
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
export 'src/api/build_config.dart';
export 'src/api/build_mode.dart';
export 'src/api/build_output.dart';
Expand Down
80 changes: 80 additions & 0 deletions pkgs/native_assets_cli/lib/src/api/build.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// 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 'build_config.dart';
import 'build_output.dart';

/// Run a native assets build.
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
///
/// Example using `package:native_toolchain_c`:
///
/// ```dart
/// void main(List<String> args) =>
/// build(args, (buildConfig, buildOutput) async {
/// final cbuilder = CBuilder.library(
/// name: packageName,
/// assetId: 'package:$packageName/$packageName.dart',
/// sources: [
/// 'src/$packageName.c',
/// ],
/// );
/// await cbuilder.run(
/// buildConfig: buildConfig,
/// buildOutput: buildOutput,
/// logger: Logger('')
/// ..level = Level.ALL
/// ..onRecord.listen((record) => print(record.message)),
/// );
/// });
/// ```
///
/// Example outputting assets manually:
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
///
/// ```dart
/// void main(List<String> args) =>
/// build(args, (config, output) async {
/// if (config.linkModePreference == LinkModePreference.static) {
/// // Simulate that this script only supports dynamic libraries.
/// throw UnsupportedError(
/// 'LinkModePreference.static is not supported.',
/// );
/// }
///
/// final Iterable<Target> targets;
/// final packageName = config.packageName;
/// final assetPath = config.outDir.resolve(
/// config.targetOs.dylibFileName(packageName),
/// );
/// if (config.dryRun) {
/// // Dry run invocations report assets for all architectures for that OS.
/// targets = Target.values.where(
/// (element) => element.os == config.targetOs,
/// );
/// } else {
/// targets = [config.target];
///
/// // Insert code that downloads or builds the asset to `assetPath`.
/// }
///
/// for (final target in targets) {
/// output.addAssets([
/// Asset(
/// id: 'library:${packageName}/src/some_file.dart',
/// linkMode: LinkMode.dynamic,
/// target: target,
/// path: AssetAbsolutePath(assetPath),
/// )
/// ]);
/// }
/// });
/// ```
Future<void> build(
List<String> commandlineArguments,
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
Future<void> Function(BuildConfig, BuildOutput) builder,
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
) async {
final config = await BuildConfig.fromArgs(commandlineArguments);
final output = BuildOutput();
await builder(config, output);
await output.writeToFile(outDir: config.outDir);
}
47 changes: 36 additions & 11 deletions pkgs/native_assets_cli/lib/src/api/build_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,20 @@ import '../model/build_config.dart' as model;
import '../model/build_mode.dart' as model;
import '../model/ios_sdk.dart' as model;
import '../model/link_mode_preference.dart' as model;
import '../model/metadata.dart' as model;
import '../model/target.dart' as model;
import 'build_mode.dart';
import 'ios_sdk.dart';
import 'link_mode_preference.dart';
import 'metadata.dart';
import 'target.dart';

/// The configuration for a `build.dart` invocation.
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
///
/// A package can choose to have a toplevel `build.dart` script. If such a
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
/// script exists, it will be automatically run, by the Flutter and Dart SDK
/// tools. The script will then be run with specific commandline arguments,
/// which [BuildConfig] can parse and provide more convenient access to.
abstract class BuildConfig {
/// The folder in which all output and intermediate artifacts should be
/// placed.
Expand All @@ -34,12 +41,12 @@ abstract class BuildConfig {

/// The target being compiled for.
///
/// Not available in [dryRun].
/// Not available during a [dryRun].
Target get target;

/// The architecture being compiled for.
///
/// Not available in [dryRun].
/// Not available during a [dryRun].
Architecture get targetArchitecture;

/// The operating system being compiled for.
Expand All @@ -49,15 +56,15 @@ abstract class BuildConfig {
///
/// Required when [targetOs] equals [OS.iOS].
///
/// Not available in [dryRun].s
/// Not available during a [dryRun].
IOSSdk? get targetIOSSdk;
dcharkes marked this conversation as resolved.
Show resolved Hide resolved

/// When compiling for Android, the minimum Android SDK API version to that
/// the compiled code will be compatible with.
///
/// Required when [targetOs] equals [OS.android].
///
/// Not available in [dryRun].
/// Not available during a [dryRun].
///
/// For more information about the Android API version, refer to
/// [`minSdkVersion`](https://developer.android.com/ndk/guides/sdk-versions#minsdkversion)
Expand All @@ -73,25 +80,36 @@ abstract class BuildConfig {
///
/// The key in the nested map is the key for the metadata from the dependency.
///
/// Not available in [dryRun].
/// Not available during a [dryRun].
@Deprecated('Use getMetadata.')
Map<String, Metadata>? get dependencyMetadata;

/// Get the metadata from a direct dependency.
///
/// The [packageName] of is the package name of the direct dependency.
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
///
/// Returns `null` if metadata was not provided.
///
/// Not available during a [dryRun].
Object? metadata(String packageName, String key);

dcharkes marked this conversation as resolved.
Show resolved Hide resolved
/// The configuration for invoking the C compiler.
///
/// Not available in [dryRun].
/// Not available during a [dryRun].
CCompilerConfig get cCompiler;

/// Don't run the build, only report the native assets produced.
/// Whether the current run is a "dry run".
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
///
/// If so, the build won't actually be run, but will report the native assets
/// which would have been produced.
bool get dryRun;
dcharkes marked this conversation as resolved.
Show resolved Hide resolved

/// The build mode that the code should be compiled in.
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
///
/// Not available in [dryRun].
/// Not available during a [dryRun].
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
BuildMode get buildMode;

/// The underlying config.
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
///
/// Can be used for easier access to values on [dependencyMetadata].
Config get config;

/// The version of [BuildConfig].
Expand All @@ -115,7 +133,9 @@ abstract class BuildConfig {
int? targetAndroidNdkApi,
CCompilerConfig? cCompiler,
required LinkModePreference linkModePreference,
@Deprecated('Use dependencyMetadata2.')
Map<String, Metadata>? dependencyMetadata,
Map<String, Map<String, Object>>? dependencyMetadata2,
}) =>
model.BuildConfig(
outDir: outDir,
Expand All @@ -128,7 +148,12 @@ abstract class BuildConfig {
targetAndroidNdkApi: targetAndroidNdkApi,
cCompiler: cCompiler as model.CCompilerConfig?,
linkModePreference: linkModePreference as model.LinkModePreference,
dependencyMetadata: dependencyMetadata?.cast(),
dependencyMetadata: dependencyMetadata2 != null
? {
for (final entry in dependencyMetadata2.entries)
entry.key: model.Metadata(entry.value.cast())
}
: dependencyMetadata?.cast(),
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
);

factory BuildConfig.dryRun({
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
94 changes: 85 additions & 9 deletions pkgs/native_assets_cli/lib/src/api/build_output.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,105 @@ import '../model/metadata.dart' as model;
import 'asset.dart';
import 'dependencies.dart';
import 'metadata.dart';
import 'target.dart';

/// The output of a `build.dart` invocation.
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
///
/// A package can choose to have a toplevel `build.dart` script. If such a
/// script exists, it will be automatically run, by the Flutter and Dart SDK
/// tools. The script is expect to produce a specific output which [BuildOutput]
/// can produce.
abstract class BuildOutput {
/// Time the build this output belongs to started.
// Start time for the build of this output.
///
/// Rounded down to whole seconds, because [File.lastModified] is rounded
/// to whole seconds and caching logic compares these timestamps.
/// The [timestamp] is rounded down to whole seconds, because
/// [File.lastModified] is rounded to whole seconds and caching logic compares
/// these timestamps.
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
DateTime get timestamp;

@Deprecated('Use assets2')
List<Asset> get assets;
dcharkes marked this conversation as resolved.
Show resolved Hide resolved

/// The assets produced by this build.
///
/// In dry runs, the assets for all [Architecture]s for the [OS] specified in
/// the dry run must be provided.
// TODO: Rename to `assets` after removing old one.
Iterable<Asset> get assets2;

@Deprecated('Use dependencies2')
Dependencies get dependencies;

/// The files used by this build.
///
/// If any of the files in [dependencies2] are modified after [timestamp], the
/// build will be re-run.
// TODO: Rename to `dependencies` after removing old one.
Iterable<Uri> get dependencies2;

@Deprecated('Use getMetadata')
Metadata get metadata;

/// Metadata can to be passed to `build.dart` invocations of dependent
/// packages.
// TODO(dacoharkes): Rename to metadata.
Object? metadata2(String key);

/// Create a build output.
///
/// The [timestamp] must be before any any [dependencies2] are read by the
/// build this output belongs to. If the [BuildOutput] object is created at
/// the beginning of the `build.dart` script, it can be omitted and will
/// default to [DateTime.now]. The [timestamp] is rounded down to whole
/// seconds, because [File.lastModified] is rounded to whole seconds and
/// caching logic compares these timestamps.
///
/// The [Asset]s produced by this build or dry-run can be provided to the
/// constructor as [assets], or can be added later using [addAssets]. In dry
/// runs, the assets for all [Architecture]s for the [OS] specified in the dry
/// run must be provided.
///
/// The files used by this build must be passed in [dependencies2] or
/// [addDependencies]. If any of these files are modified after [timestamp],
/// the build will be re-run.
///
/// Metadata can be passed to `build.dart` invocations of dependent packages
/// via [metadata2] or [addMetadata].
factory BuildOutput({
DateTime? timestamp,
List<Asset>? assets,
Dependencies? dependencies,
Metadata? metadata,
Iterable<Asset>? assets,
@Deprecated('Use addDependencies.') Dependencies? dependencies,
Iterable<Uri>? dependencies2,
@Deprecated('Use addMetadata.') Metadata? metadata,
Map<String, Object>? metadata2,
}) =>
model.BuildOutput(
timestamp: timestamp,
assets: assets?.map((e) => e as model.Asset).toList(),
dependencies: dependencies as model.Dependencies?,
metadata: metadata as model.Metadata?,
assets: assets?.cast<model.Asset>().toList(),
dependencies: dependencies2 != null
? model.Dependencies(dependencies2.toList())
: dependencies as model.Dependencies?,
metadata: metadata2 != null
? model.Metadata(metadata2)
: metadata as model.Metadata?,
);

/// Adds [Asset]s produced by this build or dry run.
///
/// In dry runs, the assets for all [Architecture]s for the [OS] specified in
/// the dry run must be provided.
dcharkes marked this conversation as resolved.
Show resolved Hide resolved
void addAssets(Iterable<Asset> assets);

/// Adds files used by this build.
///
/// If any of the files are modified after [timestamp], the build will be
/// re-run.
void addDependencies(Iterable<Uri> dependencies);

/// Adds metadata to be passed to `build.dart` invocations of dependent
/// packages.
void addMetadata(String key, Object value);

/// The version of [BuildOutput].
///
/// This class is used in the protocol between the Dart and Flutter SDKs
Expand All @@ -47,5 +122,6 @@ abstract class BuildOutput {
/// representation in the protocol.
static Version get version => model.BuildOutput.version;

/// Write out this build output to a file inside [outDir].
Future<void> writeToFile({required Uri outDir});
}
1 change: 1 addition & 0 deletions pkgs/native_assets_cli/lib/src/api/dependencies.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import '../model/dependencies.dart' as model;

@Deprecated('Use the methods on BuildOutput.')
abstract class Dependencies {
/// The dependencies a build relied on.
List<Uri> get dependencies;
Expand Down
1 change: 1 addition & 0 deletions pkgs/native_assets_cli/lib/src/api/metadata.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import '../model/metadata.dart' as model;

@Deprecated('Use the methods on BuildConfig and BuildOutput.')
abstract class Metadata {
Map<String, Object> get metadata;

Expand Down
Loading
Loading