From ee74bda4578f35c967cc5e5b631884031f6c0c1d Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 28 May 2024 13:58:14 +0200 Subject: [PATCH] Update `package:intl4x` (#842) * Update `package:intl4x` * Use const constructors * Add changelog * Fix missing exports * Fix imports * Rev version --- pkgs/intl4x/CHANGELOG.md | 5 + pkgs/intl4x/example/web/main.dart | 4 +- pkgs/intl4x/{ => hook}/build.dart | 190 ++++++++---------- pkgs/intl4x/lib/intl4x.dart | 1 + pkgs/intl4x/lib/src/bindings/List.g.dart | 1 - pkgs/intl4x/lib/src/bindings/Ordering.g.dart | 1 - .../src/bindings/WeekendContainsDay.g.dart | 1 + .../lib/src/collation/collation_4x.dart | 2 +- .../src/datetime_format/datetime_format.dart | 8 +- .../lib/src/list_format/list_format_4x.dart | 13 +- .../lib/src/number_format/number_format.dart | 8 +- .../lib/src/plural_rules/plural_rules_4x.dart | 3 +- pkgs/intl4x/pubspec.yaml | 8 +- 13 files changed, 111 insertions(+), 134 deletions(-) rename pkgs/intl4x/{ => hook}/build.dart (55%) delete mode 120000 pkgs/intl4x/lib/src/bindings/List.g.dart delete mode 120000 pkgs/intl4x/lib/src/bindings/Ordering.g.dart create mode 120000 pkgs/intl4x/lib/src/bindings/WeekendContainsDay.g.dart diff --git a/pkgs/intl4x/CHANGELOG.md b/pkgs/intl4x/CHANGELOG.md index 923b6baf..9c64489d 100644 --- a/pkgs/intl4x/CHANGELOG.md +++ b/pkgs/intl4x/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.9.0 + +- Update for `icu4x` and `build.dart` changes. +- Fix leaking API. + ## 0.8.2 - Add ICU4X support for number formatting. diff --git a/pkgs/intl4x/example/web/main.dart b/pkgs/intl4x/example/web/main.dart index b5dd1f88..d057d46b 100644 --- a/pkgs/intl4x/example/web/main.dart +++ b/pkgs/intl4x/example/web/main.dart @@ -10,11 +10,11 @@ import 'package:intl4x/number_format.dart'; void main() { num number = 300000; - var intl = Intl(ecmaPolicy: AlwaysEcma()); + var intl = Intl(ecmaPolicy: const AlwaysEcma()); String nf(num number) => intl .numberFormat(NumberFormatOptions.custom( style: CurrencyStyle(currency: 'USD'), - digits: Digits.withFractionDigits(minimum: 0, maximum: 2), + digits: const Digits.withFractionDigits(minimum: 0, maximum: 2), roundingMode: RoundingMode.halfCeil, )) .format(number); diff --git a/pkgs/intl4x/build.dart b/pkgs/intl4x/hook/build.dart similarity index 55% rename from pkgs/intl4x/build.dart rename to pkgs/intl4x/hook/build.dart index 5fe5416f..d7d9568d 100644 --- a/pkgs/intl4x/build.dart +++ b/pkgs/intl4x/hook/build.dart @@ -9,23 +9,16 @@ import 'package:native_assets_cli/native_assets_cli.dart'; import 'package:path/path.dart' as path; const crateName = 'icu_capi'; -const assetId = 'package:intl4x/src/bindings/lib.g.dart'; +const package = 'intl4x'; +const assetId = 'src/bindings/lib.g.dart'; void main(List args) async { - final config = await BuildConfig.fromArgs(args); - - final libFolder = path.join(config.outDir.path, 'release'); - Directory(libFolder).createSync(); - final libPath = path.join( - libFolder, - config.targetOs.dylibFileName(crateName.replaceAll('-', '_')), - ); - - final buildMode = switch (Platform.environment['ICU4X_BUILD_MODE']) { - 'local' => LocalMode(libPath), - 'checkout' => CheckoutMode(config, libPath), - 'fetch' || null => FetchMode(libPath), - String() => throw ArgumentError(''' + await build(args, (config, output) async { + final buildMode = switch (Platform.environment['ICU4X_BUILD_MODE']) { + 'local' => LocalMode(), + 'checkout' => CheckoutMode(config), + 'fetch' || null => FetchMode(), + String() => throw ArgumentError(''' Unknown build mode for icu4x. Set the `ICU4X_BUILD_MODE` environment variable with either `fetch`, `local`, or `checkout`. @@ -34,24 +27,28 @@ Unknown build mode for icu4x. Set the `ICU4X_BUILD_MODE` environment variable wi * checkout: Build a fresh library from a local git checkout of the icu4x repository at the environment variable `LOCAL_ICU4X_CHECKOUT`. '''), - }; + }; - await buildMode.build(); - - await BuildOutput( - assets: [ - Asset( - id: assetId, - linkMode: LinkMode.dynamic, - target: Target.current, - path: AssetAbsolutePath(Uri.file(libPath)), - ) - ], - dependencies: Dependencies([ - ...buildMode.dependencies, - Uri.file('build.dart'), - ]), - ).writeToFile(outDir: config.outDir); + final builtLibrary = await buildMode.build(); + + output.addAsset(NativeCodeAsset( + package: package, + name: assetId, + linkMode: DynamicLoadingBundled(), + architecture: config.targetArchitecture, + os: OS.current, + file: builtLibrary, + )); + + output.addDependencies( + [ + ...buildMode.dependencies, + config.packageRoot.resolve('hook/build.dart'), + //TODO: Fix this, currently causes a rebuild for checkout mode + //builtLibrary, + ], + ); + }); } void unzipFirstFile({required File input, required File output}) { @@ -69,16 +66,12 @@ void unzipFirstFile({required File input, required File output}) { sealed class BuildMode { List get dependencies; - Future build(); + Future build(); } final class FetchMode implements BuildMode { - final String libPath; - - FetchMode(this.libPath); - @override - Future build() async { + Future build() async { // TODO: Get a nicer CDN than a generated link to a privately owned repo. final request = await HttpClient().getUrl(Uri.parse( 'https://nightly.link/mosuem/i18n/workflows/intl4x_artifacts/main/lib-$platformName-latest.zip')); @@ -89,9 +82,11 @@ final class FetchMode implements BuildMode { zippedDynamicLibrary.createSync(); await response.pipe(zippedDynamicLibrary.openWrite()); - final dynamicLibrary = File(libPath); - dynamicLibrary.createSync(recursive: true); + final directory = await Directory.systemTemp.createTemp(); + final dynamicLibrary = File.fromUri(directory.uri.resolve('icu4xlib')); + await dynamicLibrary.create(); unzipFirstFile(input: zippedDynamicLibrary, output: dynamicLibrary); + return dynamicLibrary.uri; } String get platformName { @@ -109,16 +104,10 @@ final class FetchMode implements BuildMode { } final class LocalMode implements BuildMode { - final String libPath; - - LocalMode(this.libPath); - String get _localBinaryPath => Platform.environment['LOCAL_ICU4X_BINARY']!; @override - Future build() async { - await File(_localBinaryPath).copy(libPath); - } + Future build() async => Uri.file(_localBinaryPath); @override List get dependencies => [Uri.file(_localBinaryPath)]; @@ -126,39 +115,33 @@ final class LocalMode implements BuildMode { final class CheckoutMode implements BuildMode { final BuildConfig config; - final String libPath; - CheckoutMode(this.config, this.libPath); + + CheckoutMode(this.config); String? get workingDirectory => Platform.environment['LOCAL_ICU4X_CHECKOUT']; @override - Future build() async { + Future build() async { if (workingDirectory == null) { throw ArgumentError('Specify the ICU4X checkout folder' 'with the LOCAL_ICU4X_CHECKOUT variable'); } - final lib = await buildLib( - config, - workingDirectory!, - ); - await File(lib).copy(libPath); + return await buildLib(config, workingDirectory!); } @override - List get dependencies => Directory(workingDirectory!) - .listSync(recursive: true) - .whereType() - .map((e) => Uri.file(e.path)) - .toList(); + List get dependencies => [ + Uri.directory(workingDirectory!).resolve('Cargo.lock'), + ]; } -Future buildLib( - BuildConfig config, - String workingDirectory, -) async { - final rustTarget = - config.target.asRustTarget(config.targetIOSSdk == IOSSdk.iPhoneSimulator); - final isNoStd = config.target.isNoStdTarget; +Future buildLib(BuildConfig config, String workingDirectory) async { + final rustTarget = _asRustTarget( + config.targetOS, + config.targetArchitecture, + config.targetOS == OS.iOS && config.targetIOSSdk == IOSSdk.iPhoneSimulator, + ); + final isNoStd = _isNoStdTarget((config.targetOS, config.targetArchitecture)); if (!isNoStd) { final rustArguments = ['target', 'add', rustTarget]; @@ -195,10 +178,9 @@ Future buildLib( 'experimental_components', ]; final tempDir = Directory.systemTemp.createTempSync(); - final linkModeType = - config.linkModePreference.preferredLinkMode == LinkMode.static - ? 'staticlib' - : 'cdylib'; + final linkModeType = config.linkModePreference == LinkModePreference.static + ? 'staticlib' + : 'cdylib'; final arguments = [ if (isNoStd) '+nightly', 'rustc', @@ -234,44 +216,44 @@ Future buildLib( tempDir.path, rustTarget, 'release', - config.target.os.dylibFileName(crateName.replaceAll('-', '_')), + config.targetOS.dylibFileName(crateName.replaceAll('-', '_')), ); if (!File(dylibFilePath).existsSync()) { throw FileSystemException('Building the dylib failed', dylibFilePath); } - return dylibFilePath; + return Uri.file(dylibFilePath); } -extension on Target { - String asRustTarget(bool isSimulator) { - if (this == Target.iOSArm64 && isSimulator) { - return 'aarch64-apple-ios-sim'; - } - return switch (this) { - Target.androidArm => 'armv7-linux-androideabi', - Target.androidArm64 => 'aarch64-linux-android', - Target.androidIA32 => 'i686-linux-android', - Target.androidRiscv64 => 'riscv64-linux-android', - Target.androidX64 => 'x86_64-linux-android', - Target.fuchsiaArm64 => 'aarch64-unknown-fuchsia', - Target.fuchsiaX64 => 'x86_64-unknown-fuchsia', - Target.iOSArm64 => 'aarch64-apple-ios', - Target.iOSX64 => 'x86_64-apple-ios', - Target.linuxArm => 'armv7-unknown-linux-gnueabihf', - Target.linuxArm64 => 'aarch64-unknown-linux-gnu', - Target.linuxIA32 => 'i686-unknown-linux-gnu', - Target.linuxRiscv32 => 'riscv32gc-unknown-linux-gnu', - Target.linuxRiscv64 => 'riscv64gc-unknown-linux-gnu', - Target.linuxX64 => 'x86_64-unknown-linux-gnu', - Target.macOSArm64 => 'aarch64-apple-darwin', - Target.macOSX64 => 'x86_64-apple-darwin', - Target.windowsArm64 => 'aarch64-pc-windows-msvc', - Target.windowsIA32 => 'i686-pc-windows-msvc', - Target.windowsX64 => 'x86_64-pc-windows-msvc', - Target() => throw UnimplementedError('Target not available for rust'), - }; +String _asRustTarget(OS os, Architecture? architecture, bool isSimulator) { + if (os == OS.iOS && architecture == Architecture.arm64 && isSimulator) { + return 'aarch64-apple-ios-sim'; } - - bool get isNoStdTarget => - [Target.androidRiscv64, Target.linuxRiscv32].contains(this); + return switch ((os, architecture)) { + (OS.android, Architecture.arm) => 'armv7-linux-androideabi', + (OS.android, Architecture.arm64) => 'aarch64-linux-android', + (OS.android, Architecture.ia32) => 'i686-linux-android', + (OS.android, Architecture.riscv64) => 'riscv64-linux-android', + (OS.android, Architecture.x64) => 'x86_64-linux-android', + (OS.fuchsia, Architecture.arm64) => 'aarch64-unknown-fuchsia', + (OS.fuchsia, Architecture.x64) => 'x86_64-unknown-fuchsia', + (OS.iOS, Architecture.arm64) => 'aarch64-apple-ios', + (OS.iOS, Architecture.x64) => 'x86_64-apple-ios', + (OS.linux, Architecture.arm) => 'armv7-unknown-linux-gnueabihf', + (OS.linux, Architecture.arm64) => 'aarch64-unknown-linux-gnu', + (OS.linux, Architecture.ia32) => 'i686-unknown-linux-gnu', + (OS.linux, Architecture.riscv32) => 'riscv32gc-unknown-linux-gnu', + (OS.linux, Architecture.riscv64) => 'riscv64gc-unknown-linux-gnu', + (OS.linux, Architecture.x64) => 'x86_64-unknown-linux-gnu', + (OS.macOS, Architecture.arm64) => 'aarch64-apple-darwin', + (OS.macOS, Architecture.x64) => 'x86_64-apple-darwin', + (OS.windows, Architecture.arm64) => 'aarch64-pc-windows-msvc', + (OS.windows, Architecture.ia32) => 'i686-pc-windows-msvc', + (OS.windows, Architecture.x64) => 'x86_64-pc-windows-msvc', + (_, _) => throw UnimplementedError('Target not available for rust'), + }; } + +bool _isNoStdTarget((OS os, Architecture? architecture) arg) => [ + (OS.android, Architecture.riscv64), + (OS.linux, Architecture.riscv64) + ].contains(arg); diff --git a/pkgs/intl4x/lib/intl4x.dart b/pkgs/intl4x/lib/intl4x.dart index a263df37..32dc1912 100644 --- a/pkgs/intl4x/lib/intl4x.dart +++ b/pkgs/intl4x/lib/intl4x.dart @@ -23,6 +23,7 @@ import 'src/plural_rules/plural_rules.dart'; import 'src/plural_rules/plural_rules_impl.dart'; import 'src/plural_rules/plural_rules_options.dart'; +export 'src/data.dart'; export 'src/locale/locale.dart'; export 'src/plural_rules/plural_rules.dart'; diff --git a/pkgs/intl4x/lib/src/bindings/List.g.dart b/pkgs/intl4x/lib/src/bindings/List.g.dart deleted file mode 120000 index f15ae36c..00000000 --- a/pkgs/intl4x/lib/src/bindings/List.g.dart +++ /dev/null @@ -1 +0,0 @@ -../../../../../submodules/icu4x/ffi/capi/bindings/dart/List.g.dart \ No newline at end of file diff --git a/pkgs/intl4x/lib/src/bindings/Ordering.g.dart b/pkgs/intl4x/lib/src/bindings/Ordering.g.dart deleted file mode 120000 index d46d77c4..00000000 --- a/pkgs/intl4x/lib/src/bindings/Ordering.g.dart +++ /dev/null @@ -1 +0,0 @@ -../../../../../submodules/icu4x/ffi/capi/bindings/dart/Ordering.g.dart \ No newline at end of file diff --git a/pkgs/intl4x/lib/src/bindings/WeekendContainsDay.g.dart b/pkgs/intl4x/lib/src/bindings/WeekendContainsDay.g.dart new file mode 120000 index 00000000..b2d5bc61 --- /dev/null +++ b/pkgs/intl4x/lib/src/bindings/WeekendContainsDay.g.dart @@ -0,0 +1 @@ +../../../../../submodules/icu4x/ffi/capi/bindings/dart/WeekendContainsDay.g.dart \ No newline at end of file diff --git a/pkgs/intl4x/lib/src/collation/collation_4x.dart b/pkgs/intl4x/lib/src/collation/collation_4x.dart index 2a6d7691..54010697 100644 --- a/pkgs/intl4x/lib/src/collation/collation_4x.dart +++ b/pkgs/intl4x/lib/src/collation/collation_4x.dart @@ -25,7 +25,7 @@ class Collation4X extends CollationImpl { ); @override - int compareImpl(String a, String b) => _collator.compare(a, b).index; + int compareImpl(String a, String b) => _collator.compare(a, b); } extension on CollationOptions { diff --git a/pkgs/intl4x/lib/src/datetime_format/datetime_format.dart b/pkgs/intl4x/lib/src/datetime_format/datetime_format.dart index 2fd4dc95..05048583 100644 --- a/pkgs/intl4x/lib/src/datetime_format/datetime_format.dart +++ b/pkgs/intl4x/lib/src/datetime_format/datetime_format.dart @@ -19,15 +19,15 @@ import 'datetime_format_impl.dart'; /// .format(date); // Output: '4 mat.' /// ``` class DateTimeFormat { - final DateTimeFormatImpl impl; + final DateTimeFormatImpl _impl; - DateTimeFormat(this.impl); + DateTimeFormat(this._impl); String format(DateTime datetime) { if (isInTest) { - return '$datetime//${impl.locale}'; + return '$datetime//${_impl.locale}'; } else { - return impl.formatImpl(datetime); + return _impl.formatImpl(datetime); } } } diff --git a/pkgs/intl4x/lib/src/list_format/list_format_4x.dart b/pkgs/intl4x/lib/src/list_format/list_format_4x.dart index 577a388a..96871cb8 100644 --- a/pkgs/intl4x/lib/src/list_format/list_format_4x.dart +++ b/pkgs/intl4x/lib/src/list_format/list_format_4x.dart @@ -21,7 +21,7 @@ class ListFormat4X extends ListFormatImpl { @override String formatImpl(List list) { - return _formatter.format(list.to4X()); + return _formatter.format(list); } static icu.ListFormatter _getFormatter( @@ -49,14 +49,3 @@ extension on ListStyle { ListStyle.long => icu.ListLength.wide, }; } - -//TODO: Remove after https://github.com/rust-diplomat/diplomat/issues/378 -extension on List { - icu.List to4X() { - final list = icu.List.withCapacity(length); - for (final element in this) { - list.push(element); - } - return list; - } -} diff --git a/pkgs/intl4x/lib/src/number_format/number_format.dart b/pkgs/intl4x/lib/src/number_format/number_format.dart index 33076e0a..b54f5ae7 100644 --- a/pkgs/intl4x/lib/src/number_format/number_format.dart +++ b/pkgs/intl4x/lib/src/number_format/number_format.dart @@ -6,15 +6,15 @@ import '../test_checker.dart'; import 'number_format_impl.dart'; class NumberFormat { - final NumberFormatImpl impl; + final NumberFormatImpl _impl; - NumberFormat(this.impl); + NumberFormat(this._impl); String format(Object number) { if (isInTest) { - return '$number//${impl.locale}'; + return '$number//${_impl.locale}'; } else { - return impl.formatImpl(number); + return _impl.formatImpl(number); } } } diff --git a/pkgs/intl4x/lib/src/plural_rules/plural_rules_4x.dart b/pkgs/intl4x/lib/src/plural_rules/plural_rules_4x.dart index c78663b5..07cb3297 100644 --- a/pkgs/intl4x/lib/src/plural_rules/plural_rules_4x.dart +++ b/pkgs/intl4x/lib/src/plural_rules/plural_rules_4x.dart @@ -2,11 +2,12 @@ // 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 '../../intl4x.dart'; import '../bindings/lib.g.dart' as icu; import '../data.dart'; import '../data_4x.dart'; +import '../locale/locale.dart'; import '../locale/locale_4x.dart'; +import 'plural_rules.dart'; import 'plural_rules_impl.dart'; import 'plural_rules_options.dart'; diff --git a/pkgs/intl4x/pubspec.yaml b/pkgs/intl4x/pubspec.yaml index 42d68691..09af2d6d 100644 --- a/pkgs/intl4x/pubspec.yaml +++ b/pkgs/intl4x/pubspec.yaml @@ -1,7 +1,7 @@ name: intl4x description: >- A lightweight modular library for internationalization (i18n) functionality. -version: 0.8.2 +version: 0.9.0 repository: https://github.com/dart-lang/i18n/tree/main/pkgs/intl4x platforms: web: @@ -20,13 +20,13 @@ dependencies: ffi: ^2.1.0 js: ^0.7.1 meta: ^1.12.0 + native_assets_cli: ^0.6.0 dev_dependencies: archive: ^3.4.10 args: ^2.4.2 collection: ^1.18.0 - dart_flutter_team_lints: ^2.1.1 - lints: ^3.0.0 - native_assets_cli: ^0.4.2 + dart_flutter_team_lints: ^3.1.0 + lints: ^4.0.0 path: ^1.9.0 test: ^1.22.1