diff --git a/.github/workflows/stevia_integration_test.yaml b/.github/workflows/stevia_integration_test.yaml index 89244eae..49de290b 100644 --- a/.github/workflows/stevia_integration_test.yaml +++ b/.github/workflows/stevia_integration_test.yaml @@ -40,7 +40,7 @@ jobs: - uses: actions/checkout@v4 - uses: futureware-tech/simulator-action@v4 with: - model: iPhone 14 + model: iPhone 16 - run: flutter pub get - run: flutter build ios --debug --no-codesign - run: flutter test integration_test diff --git a/flint/CHANGELOG.md b/flint/CHANGELOG.md index e4b585e0..06cdb31e 100644 --- a/flint/CHANGELOG.md +++ b/flint/CHANGELOG.md @@ -1,3 +1,12 @@ +# 2.11.0 (24/01/2025) +Core ruleset: +- Add `use_truncating_division` +- Add `invalid_runtime_check_with_js_interop_types` +- Add `missing_code_block_language_in_doc_comment` +- Add `unintended_html_in_doc_comment` +- Add `unnecessary_library_name` +- Remove deprecated `package_api_docs` + # 2.10.0 (25/05/2024) Flutter ruleset: - Add `diagnostic_describe_all_properties` diff --git a/flint/lib/analysis_options.dart.yaml b/flint/lib/analysis_options.dart.yaml index d44ebdb5..4426e44e 100644 --- a/flint/lib/analysis_options.dart.yaml +++ b/flint/lib/analysis_options.dart.yaml @@ -90,7 +90,6 @@ linter: - one_member_abstracts - only_throw_errors - overridden_fields - - package_api_docs - package_names - package_prefixed_library_names - prefer_adjacent_string_concatenation @@ -180,6 +179,11 @@ linter: - use_to_and_as_if_applicable - valid_regexps - void_checks + - use_truncating_division + - invalid_runtime_check_with_js_interop_types + - missing_code_block_language_in_doc_comment + - unintended_html_in_doc_comment + - unnecessary_library_name ignore: - always_declare_return_types - always_put_required_named_parameters @@ -214,4 +218,6 @@ ignore: - use_colored_box - use_decorated_box - use_full_hex_values_for_flutter_colors - - use_key_in_widget_constructors \ No newline at end of file + - use_key_in_widget_constructors + - document_ignores + - use_build_context_synchronously diff --git a/flint/pubspec.yaml b/flint/pubspec.yaml index fb2d47e1..d0ec16f1 100644 --- a/flint/pubspec.yaml +++ b/flint/pubspec.yaml @@ -1,12 +1,13 @@ name: flint description: Analyzer lints used internally in Forus Labs' Dart & Flutter projects. -version: 2.10.0 +version: 2.11.0 homepage: https://github.com/forus-labs/cauldron repository: https://github.com/forus-labs/cauldron topics: [lints] environment: - sdk: '>=3.4.0 <4.0.0' + sdk: '>=3.6.0 <4.0.0' +resolution: workspace dev_dependencies: html: ^0.15.0 diff --git a/flint/tool/update.dart b/flint/tool/update.dart index 0ec2dca7..507c05c0 100644 --- a/flint/tool/update.dart +++ b/flint/tool/update.dart @@ -11,20 +11,28 @@ Future> fetch() async { print('Fetching lint rules from $remote.'); final response = parse((await get(remote)).body); - return response.getElementsByClassName('code-block-body').single.innerHtml - .split(RegExp('[ ]+-[ ]+')) + + final rules = RegExp(r']*>(\w+)') + .allMatches(response.getElementsByTagName('code').last.innerHtml) + .map((m) => m.group(1)) .skip(1) - .where((element) => !element.startsWith('<')) - .map((e) => e.trim()) + .whereType() .toSet(); + + if (rules.isEmpty) { + throw StateError('No rules found.'); + } + + return rules; } Future<(Set released, Set removed)> process(Set remote) async { - final existing = { ...rules['linter']['rules'], ...rules['ignore'] }; + final existing = {...rules['linter']['rules'], ...rules['ignore']}; final released = {}; final experimental = {}; - final removed = {}; - + final removed = {}; + + print('Checking rules. This might take awhile.'); for (final rule in remote) { final response = await get(Uri.parse('https://dart.dev/tools/linter-rules/$rule')); if (response.statusCode == 404) { @@ -33,16 +41,20 @@ Future<(Set released, Set removed)> process(Set remote) } final content = parse(response.body) - .getElementsByClassName('content')[0] - .getElementsByTagName('p')[1] - .getElementsByTagName('em')[0] - .text; + .getElementsByClassName('content')[0] + .getElementsByTagName('p')[1] + .getElementsByTagName('em')[0] + .text; if (existing.contains(rule) && (content.contains('deprecated') || content.contains('removed'))) { removed.add(rule); - } else if (!existing.contains(rule) && !content.contains('experimental') && !content.contains('deprecated') && !content.contains('removed')) { + } else if (!existing.contains(rule) && + !content.contains('experimental') && + !content.contains('deprecated') && + !content.contains('removed')) { released.add(rule); - } if (!existing.contains(rule) && content.contains('experimental')) { + } + if (!existing.contains(rule) && content.contains('experimental')) { experimental.add(rule); } } @@ -68,7 +80,6 @@ void write((Set released, Set removed) rules) { print('https://dart.dev/tools/linter-rules/$rule'); options.writeAsStringSync(' - $rule\n', mode: FileMode.append); } - } else { print('No new stable lint rules released.'); } @@ -81,7 +92,6 @@ void write((Set released, Set removed) rules) { print('https://dart.dev/tools/linter-rules/$rule'); options.writeAsStringSync(' - $rule\n', mode: FileMode.append); } - } else { print('No new lint rules removed.'); } diff --git a/nitrogen/.gitignore b/nitrogen/.gitignore index 3cceda55..710a5229 100644 --- a/nitrogen/.gitignore +++ b/nitrogen/.gitignore @@ -5,3 +5,5 @@ # Avoid committing pubspec.lock for library packages; see # https://dart.dev/guides/libraries/private-files#pubspeclock. pubspec.lock +/.flutter-plugins +/.flutter-plugins-dependencies diff --git a/nitrogen/lib/src/libraries.dart b/nitrogen/lib/src/libraries.dart index 18f63533..c09df1b7 100644 --- a/nitrogen/lib/src/libraries.dart +++ b/nitrogen/lib/src/libraries.dart @@ -1,5 +1,6 @@ import 'package:code_builder/code_builder.dart'; import 'package:dart_style/dart_style.dart'; +import 'package:pub_semver/pub_semver.dart'; /// Provides utilities for working with libraries. extension Libraries on Library { @@ -23,7 +24,7 @@ extension Libraries on Library { static final importNitrogenTypes = Directive.import('package:nitrogen_types/nitrogen_types.dart'); static final _emitter = DartEmitter(orderDirectives: true, useNullSafetySyntax: true); - static final _formatter = DartFormatter(pageWidth: 160); + static final _formatter = DartFormatter(pageWidth: 160, languageVersion: Version(3, 6, 0)); /// Returns this library, formatted. String format() { diff --git a/nitrogen/pubspec.yaml b/nitrogen/pubspec.yaml index 74867a1d..e137a00e 100644 --- a/nitrogen/pubspec.yaml +++ b/nitrogen/pubspec.yaml @@ -7,28 +7,26 @@ homepage: https://github.com/forus-labs/cauldron/tree/master/nitrogen repository: https://github.com/forus-labs/cauldron/ environment: - sdk: '>=3.3.0 <4.0.0' - flutter: ">=3.22.0" + sdk: '>=3.6.0 <4.0.0' + flutter: ">=3.27.0" +resolution: workspace dependencies: build: ^2.4.1 build_runner: ^2.4.6 code_builder: ^4.10.0 - dart_style: ^2.3.6 + dart_style: ^3.0.0 flutter: sdk: flutter glob: ^2.1.2 meta: ^1.9.1 - nitrogen_types: ^0.3.0+1 + nitrogen_types: path: ^1.9.0 - sugar: ^3.0.0 + pub_semver: ^2.1.5 + sugar: yaml: ^3.1.2 dev_dependencies: build_test: ^2.2.2 - flint: ^2.7.0 - import_sorter: ^4.6.0 + flint: test: ^1.25.2 - -import_sorter: - comments: false diff --git a/nitrogen/test/src/generators/asset_generator_test.dart b/nitrogen/test/src/generators/asset_generator_test.dart index 87e8449a..0a8f2a4c 100644 --- a/nitrogen/test/src/generators/asset_generator_test.dart +++ b/nitrogen/test/src/generators/asset_generator_test.dart @@ -1,6 +1,7 @@ import 'package:code_builder/code_builder.dart'; import 'package:dart_style/dart_style.dart'; import 'package:nitrogen_types/assets.dart'; +import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; import 'package:nitrogen/src/file_system.dart'; @@ -256,7 +257,7 @@ class $PrefixPathToDirectory { '''; void main() { - final formatter = DartFormatter(pageWidth: 160); + final formatter = DartFormatter(pageWidth: 160, languageVersion: Version(3, 6, 0)); final emitter = DartEmitter(useNullSafetySyntax: true); final subdirectory = AssetDirectory(['path', 'to', 'directory', 'subdirectory']); diff --git a/nitrogen_flutter_svg/pubspec.yaml b/nitrogen_flutter_svg/pubspec.yaml index abaff3f1..1967e3e9 100644 --- a/nitrogen_flutter_svg/pubspec.yaml +++ b/nitrogen_flutter_svg/pubspec.yaml @@ -6,13 +6,14 @@ homepage: https://github.com/forus-labs/cauldron/nitrogen repository: https://github.com/forus-labs/cauldron/ environment: - sdk: '>=3.3.0 <4.0.0' + sdk: '>=3.6.0 <4.0.0' +resolution: workspace dependencies: flutter: sdk: flutter flutter_svg: ^2.0.9 - nitrogen_types: ^0.3.0+1 + nitrogen_types: dev_dependencies: - flint: ^2.7.0 + flint: diff --git a/nitrogen_lottie/pubspec.yaml b/nitrogen_lottie/pubspec.yaml index 943d4337..0b9b1072 100644 --- a/nitrogen_lottie/pubspec.yaml +++ b/nitrogen_lottie/pubspec.yaml @@ -6,14 +6,15 @@ homepage: https://github.com/forus-labs/cauldron/nitrogen repository: https://github.com/forus-labs/cauldron/ environment: - sdk: '>=3.3.0 <4.0.0' - flutter: ">=3.3.0" + sdk: '>=3.6.0 <4.0.0' + flutter: ">=3.27.0" +resolution: workspace dependencies: flutter: sdk: flutter lottie: ^3.1.0 - nitrogen_types: ^0.3.0+1 + nitrogen_types: dev_dependencies: - flint: ^2.7.0 + flint: diff --git a/nitrogen_types/lib/assets.dart b/nitrogen_types/lib/assets.dart index 4a252885..9d59f59b 100644 --- a/nitrogen_types/lib/assets.dart +++ b/nitrogen_types/lib/assets.dart @@ -1,4 +1,4 @@ /// This library exports only the assets. It is used by Nitrogen since builders cannot import Flutter. -library nitrogen_types.assets; +library; -export 'src/assets.dart'; \ No newline at end of file +export 'src/assets.dart'; diff --git a/nitrogen_types/lib/nitrogen_types.dart b/nitrogen_types/lib/nitrogen_types.dart index 42707d13..8ec51d6e 100644 --- a/nitrogen_types/lib/nitrogen_types.dart +++ b/nitrogen_types/lib/nitrogen_types.dart @@ -1,6 +1,6 @@ /// The companion library for [Nitrogen](https://github.com/forus-labs/cauldron/nitrogen), a type-safe asset generation /// tool. -library nitrogen_types; +library; export 'src/assets.dart'; export 'src/image_asset_extension.dart'; diff --git a/nitrogen_types/pubspec.yaml b/nitrogen_types/pubspec.yaml index 9887399c..4e4abd15 100644 --- a/nitrogen_types/pubspec.yaml +++ b/nitrogen_types/pubspec.yaml @@ -6,12 +6,13 @@ homepage: https://github.com/forus-labs/cauldron/tree/master/nitrogen repository: https://github.com/forus-labs/cauldron/ environment: - sdk: '>=3.3.0 <4.0.0' - flutter: ">=3.3.0" + sdk: '>=3.6.0 <4.0.0' + flutter: ">=3.27.0" +resolution: workspace dependencies: flutter: sdk: flutter dev_dependencies: - flint: ^2.7.0 + flint: diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 00000000..bac8272a --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,14 @@ +name: _ +environment: + sdk: ">=3.6.0 <4.0.0" +workspace: + - flint + - nitrogen + - nitrogen_flutter_svg + - nitrogen_lottie + - nitrogen_types + - stevia + - sugar + +dev_dependencies: + flint: ^2.8.1 diff --git a/stevia/README.md b/stevia/README.md index e79d990c..18da6f02 100644 --- a/stevia/README.md +++ b/stevia/README.md @@ -1,7 +1,7 @@ # Stevia - Assorted utilities for Flutter Stevia contains utilities for working with Flutter that includes haptic feedback and timezone utilities for Android & iOS. -It is currently under active development. +It is under development ```YAML dependencies: diff --git a/stevia/lib/services.dart b/stevia/lib/services.dart index 4b2a032d..95c7b330 100644 --- a/stevia/lib/services.dart +++ b/stevia/lib/services.dart @@ -10,7 +10,7 @@ /// Controllers that simply the implementation of timers. /// /// * [TimerController] -library stevia.services; +library; import 'package:stevia/services.dart'; diff --git a/stevia/lib/services_haptic.dart b/stevia/lib/services_haptic.dart index 1b0ca983..28b2b12a 100644 --- a/stevia/lib/services_haptic.dart +++ b/stevia/lib/services_haptic.dart @@ -50,7 +50,7 @@ /// [Haptic.heavy]. /// /// TL;DR: Haptic feedback on Android devices is a mess. -library stevia.services.haptic; +library; import 'package:stevia/src/services/haptic/haptic.dart'; diff --git a/stevia/lib/services_time.dart b/stevia/lib/services_time.dart index 142c2cd4..308e2f6a 100644 --- a/stevia/lib/services_time.dart +++ b/stevia/lib/services_time.dart @@ -25,7 +25,7 @@ /// /// After setting [Timezone.platformTimezoneProvider], [ZonedDateTime.now] and other current timezone dependent functions /// will return the current platform's timezone on Android and iOS. -library stevia.services.time; +library; import 'package:sugar/sugar.dart'; import 'package:stevia/src/services/time/flutter_timezone_provider.dart'; diff --git a/stevia/lib/src/services/haptic/platform_haptic.dart b/stevia/lib/src/services/haptic/platform_haptic.dart index 9c138ec2..66927e00 100644 --- a/stevia/lib/src/services/haptic/platform_haptic.dart +++ b/stevia/lib/src/services/haptic/platform_haptic.dart @@ -11,7 +11,7 @@ import 'package:stevia/src/services/haptic/haptic_pattern.dart'; static final Object _token = Object(); /// Creates a [PlatformHaptic] for the current platform. - factory PlatformHaptic.platform() => switch (const Runtime().type) { + factory PlatformHaptic.platform() => switch (const System().type) { PlatformType.android => AndroidHaptic(), PlatformType.ios => IOSHaptic(), _ => PlatformHaptic(), diff --git a/stevia/lib/src/services/time/flutter_timezone_provider.dart b/stevia/lib/src/services/time/flutter_timezone_provider.dart index 9b16a2de..0d15a148 100644 --- a/stevia/lib/src/services/time/flutter_timezone_provider.dart +++ b/stevia/lib/src/services/time/flutter_timezone_provider.dart @@ -27,7 +27,7 @@ import 'package:sugar/sugar.dart'; /// } /// ``` Future flutterPlatformTimezoneProvider() async { - switch (const Runtime().type) { + switch (const System().type) { case PlatformType.android || PlatformType.ios: final platform = await PlatformTimezone.of(); return () => platform.current; diff --git a/stevia/lib/src/widgets/async/future/future_result_dialog.dart b/stevia/lib/src/widgets/async/future/future_result_dialog.dart index eeb88829..614ff5dd 100644 --- a/stevia/lib/src/widgets/async/future/future_result_dialog.dart +++ b/stevia/lib/src/widgets/async/future/future_result_dialog.dart @@ -14,12 +14,12 @@ part of 'future_builder.dart'; /// The result of the given [future] is always returned. It is assumed that [future] will never throw an error. Doing so /// will result in undefined behaviour. /// -/// ## Working with [showsFutureResultDialog]: +/// ## Working with [showFutureResultDialog]: /// /// To show a dialog that is automatically dismissed after the [future] is completed: /// ```dart /// FloatingActionButton( -/// onPressed: () => showsFutureResultDialog( +/// onPressed: () => showFutureResultDialog( /// context: context, /// future: () async { /// await Future.delayed(const Duration(seconds: 5)); @@ -34,7 +34,7 @@ part of 'future_builder.dart'; /// To show a dialog that appears after the [future] has successfully completed: /// ```dart /// FloatingActionButton( -/// onPressed: () => showsFutureResultDialog( +/// onPressed: () => showFutureResultDialog( /// context: context, /// future: () async { /// await Future.delayed(const Duration(seconds: 5); diff --git a/stevia/lib/src/widgets/resizable/resizable_box.dart b/stevia/lib/src/widgets/resizable/resizable_box.dart index ae178be7..7ddf4432 100644 --- a/stevia/lib/src/widgets/resizable/resizable_box.dart +++ b/stevia/lib/src/widgets/resizable/resizable_box.dart @@ -246,7 +246,7 @@ class _HorizontalResizableBox extends ResizableBox { super.onResizeEnd, { super.key, }): assert( - children.sum((e) => e.initialSize).approximately(width, 0.1), + children.sum((e) => e.initialSize).around(width, 0.1), 'The sum of the initial sizes of all children, ${children.sum((e) => e.initialSize)}, is not equal to the width of the RegionBox, $width.', ), super._(); @@ -292,7 +292,7 @@ class _VerticalResizableBox extends ResizableBox { super.onResizeEnd, { super.key, }): assert( - children.sum((e) => e.initialSize).approximately(height, 0.1), + children.sum((e) => e.initialSize).around(height, 0.1), 'The sum of the initial sizes of all children, ${children.sum((e) => e.initialSize)}, is not equal to the height of the RegionBox, $height.', ), super._(); diff --git a/stevia/lib/stevia.dart b/stevia/lib/stevia.dart index 4d49b34a..ff1156da 100644 --- a/stevia/lib/stevia.dart +++ b/stevia/lib/stevia.dart @@ -9,7 +9,7 @@ /// /// It is recommended to treat this library as an index and browse through the individual libraries. Trying to understand /// stevia by browsing through the aggregated classes can be overwhelming. -library stevia; +library; export 'package:stevia/services.dart'; export 'package:stevia/widgets.dart'; diff --git a/stevia/lib/widgets.dart b/stevia/lib/widgets.dart index 25ffb583..db34e69f 100644 --- a/stevia/lib/widgets.dart +++ b/stevia/lib/widgets.dart @@ -16,7 +16,7 @@ /// Widgets that contain children which can be resized either horizontally or vertically. /// /// * [ResizableBox] -library stevia.widgets; +library; import 'package:stevia/widgets.dart'; diff --git a/stevia/pubspec.yaml b/stevia/pubspec.yaml index 7b7280e5..34068cf9 100644 --- a/stevia/pubspec.yaml +++ b/stevia/pubspec.yaml @@ -4,8 +4,9 @@ version: 0.1.0 homepage: https://github.com/forus-labs/cauldron environment: - sdk: '>=3.0.0 <4.0.0' - flutter: ">=3.3.0" + sdk: '>=3.6.0 <4.0.0' + flutter: ">=3.27.0" +resolution: workspace dependencies: flutter: @@ -14,12 +15,12 @@ dependencies: lottie: ^3.0.0 meta: ^1.9.1 plugin_platform_interface: ^2.0.2 - sugar: ^3.0.0+1 + sugar: dev_dependencies: build_runner: ^2.4.6 fake_async: ^1.3.1 - flint: ^2.7.0 + flint: flutter_test: sdk: flutter mockito: ^5.4.2 diff --git a/sugar/CHANGELOG.md b/sugar/CHANGELOG.md index 508f897b..907a1257 100644 --- a/sugar/CHANGELOG.md +++ b/sugar/CHANGELOG.md @@ -1,5 +1,8 @@ ## 4.0.0 (Next) +Sugar 4 plans to deduplicate efforts with other more well-established "extended std library" packages such as +`dart:collection`. This means the removal of duplicated APIs such as `reverse(...)`. + ## `sugar.collection` - Add `Lists.toggleAll(...)` - Add `SplayTreeMaps.firstValueAfter(...)` @@ -32,7 +35,8 @@ - Change `LocalDateTime.now(...)` to be stubbable - Change `LocalTime.now(...)` to be stubbable - Change `OffsetTime.now(...)` to be stubbable -- Change IANA database from `2023c` to `2024b` +- **Breaking** Change `Offset` to `TimezoneOffset` to avoid naming conflict with Flutter's `Offset` +- Change IANA database from `2023c` to `2025a` - Fix `Etc/*` timezones not returning correct string representation ## 3.1.0 (19/06/2023) diff --git a/sugar/lib/collection.dart b/sugar/lib/collection.dart index 2e7cb776..15de0bfc 100644 --- a/sugar/lib/collection.dart +++ b/sugar/lib/collection.dart @@ -9,7 +9,7 @@ /// * Move operations that move elements between collections such as [MovableList.move]. /// /// See `sugar.collection.aggregate` for aggregation related utilities. -library sugar.collection; +library; import 'package:sugar/src/collection/iterables.dart'; import 'package:sugar/src/collection/lists.dart'; diff --git a/sugar/lib/collection_aggregate.dart b/sugar/lib/collection_aggregate.dart index 7c9618c5..9636f00a 100644 --- a/sugar/lib/collection_aggregate.dart +++ b/sugar/lib/collection_aggregate.dart @@ -10,7 +10,7 @@ /// Most functions in this library produce a new collection rather than modify the collection in-place. /// /// See `sugar.collection` for other non-aggregating collection utilities. -library sugar.collection.aggregate; +library; import 'package:sugar/src/collection/aggregate/group_iterables.dart'; import 'package:sugar/src/collection/aggregate/order_iterables.dart'; diff --git a/sugar/lib/core.dart b/sugar/lib/core.dart index 1acc355f..02cd732b 100644 --- a/sugar/lib/core.dart +++ b/sugar/lib/core.dart @@ -51,7 +51,7 @@ /// * [NullableObjects] /// * [Disposable] /// * [StringBuffers] -library sugar.core; +library; import 'package:sugar/src/core/annotations.dart'; import 'package:sugar/src/core/booleans.dart'; diff --git a/sugar/lib/core_range.dart b/sugar/lib/core_range.dart index 1fb2240c..7eb33c91 100644 --- a/sugar/lib/core_range.dart +++ b/sugar/lib/core_range.dart @@ -43,7 +43,7 @@ /// print(hoursInDay.contains(12); // true /// print(hoursInDay.contains(24); // false /// ``` -library sugar.core.range; +library; import 'package:sugar/src/core/range/range.dart'; diff --git a/sugar/lib/core_system.dart b/sugar/lib/core_system.dart index 68d81df9..52353dfa 100644 --- a/sugar/lib/core_system.dart +++ b/sugar/lib/core_system.dart @@ -26,7 +26,7 @@ /// print(const FakeSystem(PlatformType.android).android); true /// print(const FakeSystem(PlatformType.android).web); false /// ``` -library sugar.core.runtime; +library; import 'package:sugar/src/core/system/abstract_system.dart'; import 'package:sugar/src/core/system/fake_system.dart'; diff --git a/sugar/lib/crdt.dart b/sugar/lib/crdt.dart index ed198b6e..94534979 100644 --- a/sugar/lib/crdt.dart +++ b/sugar/lib/crdt.dart @@ -4,7 +4,7 @@ /// /// This includes: /// * [Sil], a sequence CRDT for unique elements. -library sugar.crdt; +library; import 'package:sugar/crdt.dart'; diff --git a/sugar/lib/math.dart b/sugar/lib/math.dart index cfe6f306..29d333c5 100644 --- a/sugar/lib/math.dart +++ b/sugar/lib/math.dart @@ -14,7 +14,7 @@ /// ## Random /// * [Randoms] - functions for using [Random] /// * [FakeRandom] - a fake [Random] implementation for testing -library sugar.math; +library; import 'dart:math'; diff --git a/sugar/lib/src/collection/algorithms.dart b/sugar/lib/src/collection/algorithms.dart index 8b24b505..6a0e6060 100644 --- a/sugar/lib/src/collection/algorithms.dart +++ b/sugar/lib/src/collection/algorithms.dart @@ -53,25 +53,3 @@ import 'package:sugar/core.dart'; return result; } - -/// Reverses a list, or part of between [start], inclusive and [end], exclusive, in-place. -/// -/// ## Contract -/// `0 <= start < end <= list's length`. Throws a [RangeError] otherwise. -/// -/// ## Example -/// ```dart -/// final list = [0, 1, 2, 3, 4]; -/// reverse(list, 1, 5); -/// -/// print(list); // [0, 4, 3, 2, 1] -/// ``` -@Possible({RangeError}) -void reverse(List list, [int start = 0, int? end]) { - var last = RangeError.checkValidRange(start, end, list.length) - 1; - for (; start < last; start++, last--) { - final (a, b) = (list[start], list[last]); - list[start] = b; - list[last] = a; - } -} diff --git a/sugar/lib/src/time/offset_time.dart b/sugar/lib/src/time/offset_time.dart index 23c271a0..28657e77 100644 --- a/sugar/lib/src/time/offset_time.dart +++ b/sugar/lib/src/time/offset_time.dart @@ -288,7 +288,7 @@ final class OffsetTime extends Time { /// Returns true if other is a [OffsetTime] at the same moment and in the same timezone. /// - /// ``` + /// ```dart /// final foo = OffsetTime(Offset(4), 12); // 12:00+04:00 /// final bar = OffsetTime(Offset(0), 8); // 08:00Z /// diff --git a/sugar/lib/src/time/zone/platform/web_timezone.dart b/sugar/lib/src/time/zone/platform/web_timezone.dart index ce39aa31..54a66583 100644 --- a/sugar/lib/src/time/zone/platform/web_timezone.dart +++ b/sugar/lib/src/time/zone/platform/web_timezone.dart @@ -1,6 +1,6 @@ /// Inter-op bindings for [`Intl.DateFormat().resolvedOptions().timeZone`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/resolvedOptions#description). @JS('Intl') -@internal library intl; +@internal library; import 'dart:js_interop'; import 'package:meta/meta.dart'; diff --git a/sugar/lib/src/time/zoned_date_time.dart b/sugar/lib/src/time/zoned_date_time.dart index e38d6d1f..0a68463a 100644 --- a/sugar/lib/src/time/zoned_date_time.dart +++ b/sugar/lib/src/time/zoned_date_time.dart @@ -477,7 +477,7 @@ final class ZonedDateTime extends DateTimeBase { /// Returns true if other is a [ZonedDateTime] at the same moment and in the same timezone. /// - /// ``` + /// ```dart /// final singapore = ZonedDateTime('Asia/Singapore', 2023, 5, 11, 13, 11); /// final tokyo = ZonedDateTime('Asia/Tokyo', 2023, 5, 11, 14, 11); /// diff --git a/sugar/lib/sugar.dart b/sugar/lib/sugar.dart index dc7513dc..11889936 100644 --- a/sugar/lib/sugar.dart +++ b/sugar/lib/sugar.dart @@ -9,7 +9,7 @@ /// /// It is recommended to treat this library as an index and browse through the individual libraries. Trying to understand /// Sugar by browsing through the aggregated classes can be overwhelming. -library sugar; +library; export 'collection.dart'; export 'collection_aggregate.dart'; diff --git a/sugar/lib/time.dart b/sugar/lib/time.dart index ac97c9de..e966db67 100644 --- a/sugar/lib/time.dart +++ b/sugar/lib/time.dart @@ -36,7 +36,7 @@ /// datetime.add(Duration(days: 1)); // 2023-03-13 01:00 [America/Detroit] /// datetime + Period(days: 1); // 2023-03-13 00:00 [America/Detroit] /// ``` -library sugar.time; +library; import 'package:sugar/src/time/date.dart'; import 'package:sugar/src/time/date_time.dart'; diff --git a/sugar/lib/time_interop.dart b/sugar/lib/time_interop.dart index 7263931c..d52d080f 100644 --- a/sugar/lib/time_interop.dart +++ b/sugar/lib/time_interop.dart @@ -4,7 +4,7 @@ /// /// This library should be used when it is not feasible to use the types in `sugar.time`. All functions are either /// extensions on [DateTime] or accept the units of time. -library sugar.time.interop; +library; export 'src/time/interop/date.dart'; export 'src/time/interop/date_time.dart'; diff --git a/sugar/lib/time_zone.dart b/sugar/lib/time_zone.dart index 11a1b0e9..77bdb646 100644 --- a/sugar/lib/time_zone.dart +++ b/sugar/lib/time_zone.dart @@ -4,7 +4,7 @@ /// /// The transition rules are derived from the [IANA TZ database](https://www.iana.org/time-zones). The supported database /// version is currently 2024a. -library sugar.time.zone; +library; export 'src/time/zone/timezone.dart'; export 'src/time/zone/timezone_provider.dart'; diff --git a/sugar/pubspec.yaml b/sugar/pubspec.yaml index 748fb4fd..1a5247a6 100644 --- a/sugar/pubspec.yaml +++ b/sugar/pubspec.yaml @@ -9,7 +9,8 @@ issue_tracker: https://github.com/forus-labs/cauldron/issues documentation: https://pub.dev/documentation/sugar/latest/ environment: - sdk: '>=3.5.0 <4.0.0' + sdk: '>=3.6.0 <4.0.0' +resolution: workspace dependencies: ffi: ^2.0.1 @@ -20,10 +21,6 @@ dev_dependencies: coverage: ^1.6.3 flint: ^2.9.0 http: ^1.0.0 - import_sorter: ^4.6.0 path: ^1.8.3 test: ^1.25.0 timezone: ^0.10.0 - -import_sorter: - comments: false diff --git a/tool/sort.dart b/tool/sort.dart new file mode 100644 index 00000000..81b74464 --- /dev/null +++ b/tool/sort.dart @@ -0,0 +1,162 @@ +import 'dart:io'; + +void main(List args) { + final currentPath = Directory.current.path; + final [packageName, ...] = args; + + // Getting all the dart files for the project + final files = dartFiles(currentPath)..remove('$currentPath/lib/generated_plugin_registrant.dart'); + + // Sorting and writing to files + for (final file in files.values) { + final sortedFile = sortImports(file.readAsLinesSync(), packageName); + file.writeAsStringSync(sortedFile); + } + + stdout.write('Sorted files\n'); +} + +/// Get all the dart files for the project and the contents. +Map dartFiles(String currentPath) { + final dartFiles = {}; + final allContents = [ + ..._readDir(currentPath, 'lib'), + ..._readDir(currentPath, 'bin'), + ..._readDir(currentPath, 'test'), + ..._readDir(currentPath, 'tests'), + ..._readDir(currentPath, 'test_driver'), + ..._readDir(currentPath, 'integration_test'), + ]; + + for (final file in allContents.whereType().where((file) => file.path.endsWith('.dart'))) { + dartFiles[file.path] = file; + } + + return dartFiles; +} + +List _readDir(String currentPath, String name) { + if (Directory('$currentPath/$name') case final directory when directory.existsSync()) { + return directory.listSync(recursive: true); + } + return []; +} + +/// Sort the imports. +String sortImports(List lines, String packageName, {String? filePath}) { + final beforeImportLines = []; + final afterImportLines = []; + + final dartImports = []; + final flutterImports = []; + final packageImports = []; + final projectRelativeImports = []; + final projectImports = []; + + bool noImports() => + dartImports.isEmpty && + flutterImports.isEmpty && + packageImports.isEmpty && + projectImports.isEmpty && + projectRelativeImports.isEmpty; + + var isMultiLineString = false; + + for (final line in lines) { + // Check if line is in multiline string + if (_timesContained(line, "'''") == 1 || _timesContained(line, '"""') == 1) { + isMultiLineString = !isMultiLineString; + } + + // If line is an import line + if (line.startsWith('import ') && line.endsWith(';') && !isMultiLineString) { + if (line.contains('dart:')) { + dartImports.add(line); + } else if (line.contains('package:flutter/')) { + flutterImports.add(line); + } else if (line.contains('package:$packageName/')) { + projectImports.add(line); + } else if (line.contains('package:')) { + packageImports.add(line); + } else { + projectRelativeImports.add(line); + } + } else if (noImports()) { + beforeImportLines.add(line); + } else { + afterImportLines.add(line); + } + } + + // If no imports return original string of lines + if (noImports()) { + var joinedLines = lines.join('\n'); + if (joinedLines.endsWith('\n') && !joinedLines.endsWith('\n\n')) { + joinedLines += '\n'; + } else if (!joinedLines.endsWith('\n')) { + joinedLines += '\n'; + } + return joinedLines; + } + + // Remove spaces + if (beforeImportLines.isNotEmpty) { + if (beforeImportLines.last.trim() == '') { + beforeImportLines.removeLast(); + } + } + + final sortedLines = [...beforeImportLines]; + + // Adding content conditionally + if (beforeImportLines.isNotEmpty) { + sortedLines.add(''); + } + if (dartImports.isNotEmpty) { + dartImports.sort(); + sortedLines.addAll(dartImports); + } + if (flutterImports.isNotEmpty) { + if (dartImports.isNotEmpty) sortedLines.add(''); + flutterImports.sort(); + sortedLines.addAll(flutterImports); + } + if (packageImports.isNotEmpty) { + if (dartImports.isNotEmpty || flutterImports.isNotEmpty) { + sortedLines.add(''); + } + packageImports.sort(); + sortedLines.addAll(packageImports); + } + if (projectImports.isNotEmpty || projectRelativeImports.isNotEmpty) { + if (dartImports.isNotEmpty || flutterImports.isNotEmpty || packageImports.isNotEmpty) { + sortedLines.add(''); + } + projectImports.sort(); + projectRelativeImports.sort(); + sortedLines.addAll(projectImports); + sortedLines.addAll(projectRelativeImports); + } + + sortedLines.add(''); + + var addedCode = false; + for (final line in afterImportLines) { + if (line != '') { + sortedLines.add(line); + addedCode = true; + } + if (addedCode && line == '') { + sortedLines.add(line); + } + } + sortedLines.add(''); + + final sortedFile = sortedLines.join('\n'); + + return sortedFile; +} + +/// Get the number of times a string contains another +/// string +int _timesContained(String string, String looking) => string.split(looking).length - 1;