Repository: letsar/kiwi Branch: master Commit: 6efb0c49735f Files: 124 Total size: 155.9 KB Directory structure: gitextract_p5l6yl9r/ ├── .github/ │ ├── dependabot.yml │ ├── no-response.yml │ └── workflows/ │ ├── build_all.yml │ ├── changelog.yml │ ├── dart_kiwi_example.yml │ ├── flutter_kiwi_example.yml │ ├── kiwi.yml │ └── kiwi_generator.yml ├── .gitignore ├── LICENSE ├── README.md ├── examples/ │ ├── dart_kiwi/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── bin/ │ │ │ └── dart_kiwi.dart │ │ ├── example.iml │ │ ├── lib/ │ │ │ └── src/ │ │ │ ├── models/ │ │ │ │ ├── coffee_maker.dart │ │ │ │ ├── electric_heater.dart │ │ │ │ ├── heater.dart │ │ │ │ ├── model.dart │ │ │ │ ├── pump.dart │ │ │ │ └── thermosiphon.dart │ │ │ └── modules/ │ │ │ ├── drip_coffee_module.dart │ │ │ └── drip_coffee_module.g.dart │ │ └── pubspec.yaml │ └── flutter_kiwi/ │ ├── .gitignore │ ├── .metadata │ ├── README.md │ ├── android/ │ │ ├── .gitignore │ │ ├── app/ │ │ │ ├── build.gradle │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── AndroidManifest.xml │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── example/ │ │ │ │ └── flutterexample/ │ │ │ │ └── MainActivity.java │ │ │ └── res/ │ │ │ ├── drawable/ │ │ │ │ └── launch_background.xml │ │ │ └── values/ │ │ │ └── styles.xml │ │ ├── build.gradle │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradle.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ ├── flutter_example.iml │ ├── flutter_example_android.iml │ ├── ios/ │ │ ├── .gitignore │ │ ├── Flutter/ │ │ │ ├── AppFrameworkInfo.plist │ │ │ ├── Debug.xcconfig │ │ │ └── Release.xcconfig │ │ ├── Runner/ │ │ │ ├── AppDelegate.h │ │ │ ├── AppDelegate.m │ │ │ ├── Assets.xcassets/ │ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ │ └── Contents.json │ │ │ │ └── LaunchImage.imageset/ │ │ │ │ ├── Contents.json │ │ │ │ └── README.md │ │ │ ├── Base.lproj/ │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ └── Main.storyboard │ │ │ ├── Info.plist │ │ │ └── main.m │ │ ├── Runner.xcodeproj/ │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace/ │ │ │ │ └── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ └── xcschemes/ │ │ │ └── Runner.xcscheme │ │ └── Runner.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── lib/ │ │ ├── di/ │ │ │ ├── test01.dart │ │ │ └── test01.g.dart │ │ ├── main.dart │ │ ├── screens/ │ │ │ ├── error_screen.dart │ │ │ ├── main_screen.dart │ │ │ ├── resolve_screen.dart │ │ │ └── scoped_screen.dart │ │ └── widgets/ │ │ └── error_widget.dart │ └── pubspec.yaml ├── packages/ │ ├── kiwi/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── example/ │ │ │ └── kiwi_example.dart │ │ ├── kiwi.iml │ │ ├── lib/ │ │ │ ├── kiwi.dart │ │ │ └── src/ │ │ │ ├── annotations.dart │ │ │ ├── kiwi_container.dart │ │ │ └── model/ │ │ │ └── exception/ │ │ │ ├── kiwi_error.dart │ │ │ └── not_registered_error.dart │ │ ├── mono_pkg.yaml │ │ ├── pubspec.yaml │ │ └── test/ │ │ └── kiwi_test.dart │ └── kiwi_generator/ │ ├── .gitignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── analysis_options.yaml │ ├── build.yaml │ ├── example/ │ │ ├── kiwi_generator_example.dart │ │ └── kiwi_generator_example.g.dart │ ├── kiwi_generator.iml │ ├── lib/ │ │ ├── builder.dart │ │ ├── kiwi_generator.dart │ │ └── src/ │ │ ├── kiwi_injector_generator.dart │ │ ├── model/ │ │ │ └── kiwi_generator_error.dart │ │ └── util/ │ │ └── list_extensions.dart │ ├── mono_pkg.yaml │ ├── pubspec.yaml │ └── test/ │ ├── inputs/ │ │ ├── abstract_class.dart │ │ ├── abstract_class_without_abstract_method.dart │ │ ├── abstract_class_without_method.dart │ │ ├── complex_factory.dart │ │ ├── complex_factory_with_abstract_method_without_register_annotation.dart │ │ ├── complex_singleton.dart │ │ ├── simple_factory.dart │ │ ├── simple_singleton.dart │ │ ├── unknown_ctor_factory.dart │ │ └── unknown_ctor_singleton.dart │ ├── kiwi_generator_test.dart │ └── utils/ │ ├── analysis.dart │ └── test_helper.dart └── tools/ ├── all.sh ├── analyze.sh ├── build.sh ├── fix.sh ├── format.sh ├── kiwi_cli_actions/ │ ├── bin/ │ │ └── kiwi_cli_actions.dart │ ├── lib/ │ │ └── changelog_checker.dart │ └── pubspec.yaml ├── packages_get.sh └── test.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: - package-ecosystem: "pub" directory: "/packages/kiwi" schedule: interval: "daily" labels: - "pub.dev" - "kiwi" - "dependencies" - package-ecosystem: "pub" directory: "/packages/kiwi_generator" schedule: interval: "daily" labels: - "pub.dev" - "kiwi generator" - "dependencies" - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" labels: - "github actions" - "dependencies" ================================================ FILE: .github/no-response.yml ================================================ daysUntilClose: 14 responseRequiredLabel: "waiting for customer response" closeComment: > This issue has been automatically closed because there has been no response. If there is extra information in the future this ticket will be reopenend. ================================================ FILE: .github/workflows/build_all.yml ================================================ name: build_all on: push: branches: [ 'master', 'stable' ] pull_request: branches: [ 'master', 'stable' ] jobs: flutter: runs-on: ubuntu-latest strategy: matrix: version: [ stable ] steps: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2.18.0 with: channel: ${{ matrix.version }} - name: Build & format for flutter_kiwi example run: | cd examples/flutter_kiwi flutter packages get flutter packages pub run build_runner build --delete-conflicting-outputs dart format . - name: Use verify-changed-files to check if any of the above files changed. uses: tj-actions/verify-changed-files@v20 - name: Run step only when any of the above files change. if: steps.verify-changed-files.outputs.files_changed == 'true' run: | echo "Changed files: ${{ steps.verify-changed-files.outputs.changed_files }}" dart: runs-on: ubuntu-latest strategy: matrix: sdk: [ stable, beta, dev ] steps: - uses: actions/checkout@v4 - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} - name: Build & format for kiwi_generator run: | cd packages/kiwi_generator dart pub get dart run build_runner build --delete-conflicting-outputs dart format . - name: Build & format for dart_kiwi example run: | cd examples/dart_kiwi dart pub get dart run build_runner build --delete-conflicting-outputs dart format . - name: Use verify-changed-files to check if any of the above files changed. uses: tj-actions/verify-changed-files@v20 - name: Run step only when any of the above files change. if: steps.verify-changed-files.outputs.files_changed == 'true' run: | echo "Changed files: ${{ steps.verify-changed-files.outputs.changed_files }}" ================================================ FILE: .github/workflows/changelog.yml ================================================ name: changelog on: push: branches: [ 'master', 'stable' ] pull_request: branches: [ 'master', 'stable' ] jobs: check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dart-lang/setup-dart@v1 with: sdk: 'stable' - name: Check changelog run: | cd tools/kiwi_cli_actions dart pub get dart run ================================================ FILE: .github/workflows/dart_kiwi_example.yml ================================================ name: dart_kiwi_example on: push: branches: [ 'master', 'stable' ] pull_request: branches: [ 'master', 'stable' ] jobs: check: runs-on: ubuntu-latest defaults: run: working-directory: examples/dart_kiwi steps: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2.18.0 with: channel: 'stable' - run: flutter packages get - run: flutter analyze - run: dart format -o none --set-exit-if-changed . ================================================ FILE: .github/workflows/flutter_kiwi_example.yml ================================================ name: flutter_kiwi_example on: push: branches: [ 'master', 'stable' ] pull_request: branches: [ 'master', 'stable' ] jobs: check: runs-on: ubuntu-latest defaults: run: working-directory: examples/flutter_kiwi steps: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2.18.0 with: channel: 'stable' - run: flutter packages get - run: flutter analyze - run: dart format -o none --set-exit-if-changed . ================================================ FILE: .github/workflows/kiwi.yml ================================================ name: kiwi on: push: branches: [ 'master', 'stable' ] pull_request: branches: [ 'master', 'stable' ] jobs: check: runs-on: ubuntu-latest strategy: matrix: sdk: [ stable, beta, dev ] defaults: run: working-directory: packages/kiwi steps: - uses: actions/checkout@v4 - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} - run: dart pub get - run: dart analyze --fatal-warnings . - run: dart format -o none --set-exit-if-changed . - run: dart test ================================================ FILE: .github/workflows/kiwi_generator.yml ================================================ name: kiwi_generator on: push: branches: [ 'master', 'stable' ] pull_request: branches: [ 'master', 'stable' ] jobs: check: runs-on: ubuntu-latest strategy: matrix: sdk: [ stable, beta, dev ] defaults: run: working-directory: packages/kiwi_generator steps: - uses: actions/checkout@v4 - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} - run: dart pub get - run: dart analyze --fatal-warnings . - run: dart format -o none --set-exit-if-changed . - run: dart test ================================================ FILE: .gitignore ================================================ # See https://www.dartlang.org/guides/libraries/private-files # Files and directories created by pub .dart_tool/ .packages .pub/ build/ # If you're building an application, you may want to check-in your pubspec.lock pubspec.lock # Directory created by dartdoc # If you don't generate documentation locally you can remove this line. doc/api/ .idea/ .vscode/ ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2018 Romain Rastel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # kiwi [![kiwi](https://github.com/gbtb16/kiwi/actions/workflows/kiwi.yml/badge.svg?branch=master)](https://github.com/gbtb16/kiwi/actions/workflows/kiwi.yml) [![kiwi_generator](https://github.com/gbtb16/kiwi/actions/workflows/kiwi_generator.yml/badge.svg?branch=master)](https://github.com/gbtb16/kiwi/actions/workflows/kiwi_generator.yml) [![dart_kiwi_example](https://github.com/gbtb16/kiwi/actions/workflows/dart_kiwi_example.yml/badge.svg?branch=master)](https://github.com/gbtb16/kiwi/actions/workflows/dart_kiwi_example.yml) [![flutter_kiwi_example](https://github.com/gbtb16/kiwi/actions/workflows/flutter_kiwi_example.yml/badge.svg?branch=master)](https://github.com/gbtb16/kiwi/actions/workflows/flutter_kiwi_example.yml) ![Logo](https://raw.githubusercontent.com/gbtb16/kiwi/master/images/logo.png) A simple yet efficient IoC container for Dart and Flutter, coupled with a powerful generator to allow you to write less code. The container does not rely on reflection, it's just a `Map`, so it's fast. While using the generator, only constructor injection is supported. ## Kiwi [![Pub](https://img.shields.io/pub/v/kiwi.svg)](https://pub.dartlang.org/packages/kiwi) [Source Code](https://github.com/gbtb16/kiwi/tree/master/packages/kiwi) The core package providing the IoC container and the annotations which has no dependencies. Import it into your pubspec `dependencies:` section. ## Kiwi Generator [![Pub](https://img.shields.io/pub/v/kiwi_generator.svg)](https://pub.dartlang.org/packages/kiwi_generator) [Source Code](https://github.com/gbtb16/kiwi/tree/master/packages/kiwi_generator) The package providing the generator. Import it into your pubspec `dev_dependencies:` section. ## Dart Kiwi Example [Source Code](https://github.com/gbtb16/kiwi/tree/master/examples/dart_kiwi) An example showing how to setup `kiwi` and `kiwi_generator` inside a Dart CLI project. ## Flutter Kiwi Example [Source Code](https://github.com/gbtb16/kiwi/tree/master/examples/flutter_kiwi) An example showing how to setup `kiwi` and `kiwi_generator` inside a Flutter project. ## Contributions Feel free to contribute to this project. If you find a bug or want a feature, but don't know how to fix/implement it, please fill an [issue](https://github.com/gbtb16/kiwi/issues). If you fixed a bug or implemented a new feature, please send a [pull request](https://github.com/gbtb16/kiwi/pulls). ================================================ FILE: examples/dart_kiwi/.gitignore ================================================ # Files and directories created by pub .dart_tool/ .packages # Remove the following pattern if you wish to check in your lock file pubspec.lock # Conventional directory for build outputs build/ # Directory created by dartdoc doc/api/ ================================================ FILE: examples/dart_kiwi/CHANGELOG.md ================================================ ## 0.1.0 * Initial Open Source release. ================================================ FILE: examples/dart_kiwi/README.md ================================================ # Dart Example An example of how to use [kiwi](https://github.com/gbtb16/kiwi/tree/master/kiwi) coupled with [kiwi_generator](https://github.com/gbtb16/kiwi/tree/master/kiwi_generator). This is an adaptation of the "Coffee" [example from Google/Inject](https://github.com/google/inject.dart/tree/master/example/coffee). To launch the generator, execute the following command: ```bash pub run build_runner build ``` ================================================ FILE: examples/dart_kiwi/analysis_options.yaml ================================================ analyzer: # exclude: # - path/to/excluded/files/** # Lint rules and documentation, see http://dart-lang.github.io/linter/lints linter: rules: - cancel_subscriptions - hash_and_equals - collection_methods_unrelated_type - test_types_in_equals - unrelated_type_equality_checks - valid_regexps ================================================ FILE: examples/dart_kiwi/bin/dart_kiwi.dart ================================================ import 'package:dart_kiwi/src/models/coffee_maker.dart'; import 'package:dart_kiwi/src/modules/drip_coffee_module.dart'; import 'package:kiwi/kiwi.dart'; void main(List arguments) async { CoffeeInjector coffeeInjector = getCoffeeInjector(); coffeeInjector.configure(); final container = KiwiContainer(); CoffeeMaker coffeeMaker = container(); coffeeMaker.brew(); } ================================================ FILE: examples/dart_kiwi/example.iml ================================================ ================================================ FILE: examples/dart_kiwi/lib/src/models/coffee_maker.dart ================================================ import 'package:dart_kiwi/src/models/heater.dart'; import 'package:dart_kiwi/src/models/model.dart'; import 'package:dart_kiwi/src/models/pump.dart'; class CoffeeMaker { final Heater _heater; final Pump _pump; final Model _model; const CoffeeMaker( this._heater, this._pump, this._model, ); void brew() { _heater.on(); _pump.pump(); print(' [_]P coffee! [_]P'); print(' Thanks for using $_model'); _heater.off(); } } ================================================ FILE: examples/dart_kiwi/lib/src/models/electric_heater.dart ================================================ import 'package:dart_kiwi/src/models/heater.dart'; class PowerOutlet { const PowerOutlet(); } class Electricity { const Electricity(PowerOutlet outlet); } class ElectricHeater implements Heater { ElectricHeater(Electricity electricity); bool _heating = false; @override void on() { print('heating'); _heating = true; } @override void off() { _heating = false; } @override bool get isHot => _heating; } ================================================ FILE: examples/dart_kiwi/lib/src/models/heater.dart ================================================ abstract interface class Heater { void on(); void off(); bool get isHot; } ================================================ FILE: examples/dart_kiwi/lib/src/models/model.dart ================================================ class Model { const Model( this.brand, this.name, ); final String name; final String brand; @override String toString() => '$name by $brand'; } ================================================ FILE: examples/dart_kiwi/lib/src/models/pump.dart ================================================ abstract interface class Pump { void pump(); } ================================================ FILE: examples/dart_kiwi/lib/src/models/thermosiphon.dart ================================================ import 'package:dart_kiwi/src/models/heater.dart'; import 'package:dart_kiwi/src/models/pump.dart'; class Thermosiphon implements Pump { final Heater _heater; const Thermosiphon(this._heater); @override void pump() { if (_heater.isHot) { print('pumping water'); } } } ================================================ FILE: examples/dart_kiwi/lib/src/modules/drip_coffee_module.dart ================================================ import 'package:dart_kiwi/src/models/coffee_maker.dart'; import 'package:dart_kiwi/src/models/electric_heater.dart'; import 'package:dart_kiwi/src/models/heater.dart'; import 'package:dart_kiwi/src/models/model.dart'; import 'package:dart_kiwi/src/models/pump.dart'; import 'package:dart_kiwi/src/models/thermosiphon.dart'; import 'package:kiwi/kiwi.dart'; part 'drip_coffee_module.g.dart'; abstract class CoffeeInjector { void configure() { _configureInstances(); _configureFactories(); } void _configureInstances() { final container = KiwiContainer(); container.registerInstance(Model('DartCoffee', 'DripCoffeeStandard')); } @Register.factory(PowerOutlet) @Register.singleton(Electricity) @Register.singleton(Heater, from: ElectricHeater) @Register.singleton(Pump, from: Thermosiphon) @Register.factory(CoffeeMaker) void _configureFactories(); } CoffeeInjector getCoffeeInjector() => _$CoffeeInjector(); ================================================ FILE: examples/dart_kiwi/lib/src/modules/drip_coffee_module.g.dart ================================================ // GENERATED CODE - DO NOT MODIFY BY HAND part of 'drip_coffee_module.dart'; // ************************************************************************** // KiwiInjectorGenerator // ************************************************************************** class _$CoffeeInjector extends CoffeeInjector { @override void _configureFactories() { final KiwiContainer container = KiwiContainer(); container ..registerFactory((c) => PowerOutlet()) ..registerSingleton((c) => Electricity(c.resolve())) ..registerSingleton( (c) => ElectricHeater(c.resolve())) ..registerSingleton((c) => Thermosiphon(c.resolve())) ..registerFactory((c) => CoffeeMaker( c.resolve(), c.resolve(), c.resolve())); } } ================================================ FILE: examples/dart_kiwi/pubspec.yaml ================================================ name: dart_kiwi description: A sample command-line application as an example for kiwi. version: 1.0.0+2 publish_to: none environment: sdk: '>=3.0.0 <4.0.0' dependencies: kiwi: ^5.0.0 dependency_overrides: kiwi: path: ../../packages/kiwi/ kiwi_generator: path: ../../packages/kiwi_generator/ dev_dependencies: test: ^1.23.1 build_runner: ^2.3.3 kiwi_generator: ^4.2.0 ================================================ FILE: examples/flutter_kiwi/.gitignore ================================================ .DS_Store .dart_tool/ .packages .pub/ build/ .flutter-plugins **/ios/Flutter/flutter_export_environment.sh ================================================ FILE: examples/flutter_kiwi/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: 3b309bda072a6b326e8aa4591a5836af600923ce channel: beta ================================================ FILE: examples/flutter_kiwi/README.md ================================================ # flutter_example An example for **kiwi**, just to demonstrate how it can be used with Flutter. To launch the generator, execute the following command: ```bash flutter packages pub run build_runner build ``` ================================================ FILE: examples/flutter_kiwi/android/.gitignore ================================================ *.iml *.class .gradle /local.properties /.idea/workspace.xml /.idea/libraries .DS_Store /build /captures GeneratedPluginRegistrant.java ================================================ FILE: examples/flutter_kiwi/android/app/build.gradle ================================================ def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { compileSdkVersion 30 lintOptions { disable 'InvalidPackage' } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.flutterexample" minSdkVersion 16 targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } } } flutter { source '../..' } dependencies { testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.1.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' } ================================================ FILE: examples/flutter_kiwi/android/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: examples/flutter_kiwi/android/app/src/main/java/com/example/flutterexample/MainActivity.java ================================================ package com.example.flutterexample; import io.flutter.embedding.android.FlutterActivity; public class MainActivity extends FlutterActivity { } ================================================ FILE: examples/flutter_kiwi/android/app/src/main/res/drawable/launch_background.xml ================================================ ================================================ FILE: examples/flutter_kiwi/android/app/src/main/res/values/styles.xml ================================================ ================================================ FILE: examples/flutter_kiwi/android/build.gradle ================================================ buildscript { repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:4.1.0' } } allprojects { repositories { google() jcenter() } } rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" } subprojects { project.evaluationDependsOn(':app') } task clean(type: Delete) { delete rootProject.buildDir } ================================================ FILE: examples/flutter_kiwi/android/gradle/wrapper/gradle-wrapper.properties ================================================ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists ================================================ FILE: examples/flutter_kiwi/android/gradle.properties ================================================ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true ================================================ FILE: examples/flutter_kiwi/android/gradlew ================================================ #!/usr/bin/env bash ############################################################################## ## ## Gradle start up script for UN*X ## ############################################################################## # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS="" APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" warn ( ) { echo "$*" } die ( ) { echo echo "$*" echo exit 1 } # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false case "`uname`" in CYGWIN* ) cygwin=true ;; Darwin* ) darwin=true ;; MINGW* ) msys=true ;; esac # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" # Need this for relative symlinks. while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done SAVED="`pwd`" cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" cd "$SAVED" >/dev/null CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD="java" which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi # Increase the maximum file descriptors if we can. if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi ulimit -n $MAX_FD if [ $? -ne 0 ] ; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" fi fi # For Darwin, add options to specify how the application appears in the dock if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi # For Cygwin, switch paths to Windows format before running java if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi i=$((i+1)) done case $i in (0) set -- ;; (1) set -- "$args0" ;; (2) set -- "$args0" "$args1" ;; (3) set -- "$args0" "$args1" "$args2" ;; (4) set -- "$args0" "$args1" "$args2" "$args3" ;; (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules function splitJvmOpts() { JVM_OPTS=("$@") } eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" ================================================ FILE: examples/flutter_kiwi/android/gradlew.bat ================================================ @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS= set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if "%ERRORLEVEL%" == "0" goto init echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :init @rem Get command-line arguments, handling Windowz variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. set CMD_LINE_ARGS= set _SKIP=2 :win9xME_args_slurp if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* goto execute :4NT_args @rem Get arguments from the 4NT Shell from JP Software set CMD_LINE_ARGS=%$ :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal :omega ================================================ FILE: examples/flutter_kiwi/android/settings.gradle ================================================ include ':app' def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() def plugins = new Properties() def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') if (pluginsFile.exists()) { pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } } plugins.each { name, path -> def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() include ":$name" project(":$name").projectDir = pluginDirectory } ================================================ FILE: examples/flutter_kiwi/flutter_example.iml ================================================ ================================================ FILE: examples/flutter_kiwi/flutter_example_android.iml ================================================ ================================================ FILE: examples/flutter_kiwi/ios/.gitignore ================================================ .idea/ .vagrant/ .sconsign.dblite .svn/ .DS_Store *.swp profile DerivedData/ build/ GeneratedPluginRegistrant.h GeneratedPluginRegistrant.m .generated/ *.pbxuser *.mode1v3 *.mode2v3 *.perspectivev3 !default.pbxuser !default.mode1v3 !default.mode2v3 !default.perspectivev3 xcuserdata *.moved-aside *.pyc *sync/ Icon? .tags* /Flutter/app.flx /Flutter/app.zip /Flutter/flutter_assets/ /Flutter/App.framework /Flutter/Flutter.framework /Flutter/Generated.xcconfig /ServiceDefinitions.json Pods/ .symlinks/ ================================================ FILE: examples/flutter_kiwi/ios/Flutter/AppFrameworkInfo.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable App CFBundleIdentifier io.flutter.flutter.app CFBundleInfoDictionaryVersion 6.0 CFBundleName App CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 MinimumOSVersion 9.0 ================================================ FILE: examples/flutter_kiwi/ios/Flutter/Debug.xcconfig ================================================ #include "Generated.xcconfig" ================================================ FILE: examples/flutter_kiwi/ios/Flutter/Release.xcconfig ================================================ #include "Generated.xcconfig" ================================================ FILE: examples/flutter_kiwi/ios/Runner/AppDelegate.h ================================================ #import #import @interface AppDelegate : FlutterAppDelegate @end ================================================ FILE: examples/flutter_kiwi/ios/Runner/AppDelegate.m ================================================ #include "AppDelegate.h" #include "GeneratedPluginRegistrant.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; // Override point for customization after application launch. return [super application:application didFinishLaunchingWithOptions:launchOptions]; } @end ================================================ FILE: examples/flutter_kiwi/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "size" : "20x20", "idiom" : "iphone", "filename" : "Icon-App-20x20@2x.png", "scale" : "2x" }, { "size" : "20x20", "idiom" : "iphone", "filename" : "Icon-App-20x20@3x.png", "scale" : "3x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-App-29x29@1x.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-App-29x29@2x.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-App-29x29@3x.png", "scale" : "3x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "Icon-App-40x40@2x.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "Icon-App-40x40@3x.png", "scale" : "3x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "Icon-App-60x60@2x.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "Icon-App-60x60@3x.png", "scale" : "3x" }, { "size" : "20x20", "idiom" : "ipad", "filename" : "Icon-App-20x20@1x.png", "scale" : "1x" }, { "size" : "20x20", "idiom" : "ipad", "filename" : "Icon-App-20x20@2x.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "ipad", "filename" : "Icon-App-29x29@1x.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "ipad", "filename" : "Icon-App-29x29@2x.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "ipad", "filename" : "Icon-App-40x40@1x.png", "scale" : "1x" }, { "size" : "40x40", "idiom" : "ipad", "filename" : "Icon-App-40x40@2x.png", "scale" : "2x" }, { "size" : "76x76", "idiom" : "ipad", "filename" : "Icon-App-76x76@1x.png", "scale" : "1x" }, { "size" : "76x76", "idiom" : "ipad", "filename" : "Icon-App-76x76@2x.png", "scale" : "2x" }, { "size" : "83.5x83.5", "idiom" : "ipad", "filename" : "Icon-App-83.5x83.5@2x.png", "scale" : "2x" }, { "size" : "1024x1024", "idiom" : "ios-marketing", "filename" : "Icon-App-1024x1024@1x.png", "scale" : "1x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: examples/flutter_kiwi/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "LaunchImage.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "LaunchImage@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "LaunchImage@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: examples/flutter_kiwi/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md ================================================ # Launch Screen Assets You can customize the launch screen with your own desired assets by replacing the image files in this directory. You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. ================================================ FILE: examples/flutter_kiwi/ios/Runner/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: examples/flutter_kiwi/ios/Runner/Base.lproj/Main.storyboard ================================================ ================================================ FILE: examples/flutter_kiwi/ios/Runner/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName flutter_example CFBundlePackageType APPL CFBundleShortVersionString $(FLUTTER_BUILD_NAME) CFBundleSignature ???? CFBundleVersion $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIViewControllerBasedStatusBarAppearance ================================================ FILE: examples/flutter_kiwi/ios/Runner/main.m ================================================ #import #import #import "AppDelegate.h" int main(int argc, char* argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } ================================================ FILE: examples/flutter_kiwi/ios/Runner.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ 9705A1C41CF9048500538489 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 9740EEB31CF90195004384FC /* Generated.xcconfig */, ); name = Flutter; sourceTree = ""; }; 97C146E51CF9000F007C117D = { isa = PBXGroup; children = ( 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, ); sourceTree = ""; }; 97C146EF1CF9000F007C117D /* Products */ = { isa = PBXGroup; children = ( 97C146EE1CF9000F007C117D /* Runner.app */, ); name = Products; sourceTree = ""; }; 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 97C147021CF9000F007C117D /* Info.plist */, 97C146F11CF9000F007C117D /* Supporting Files */, 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, ); path = Runner; sourceTree = ""; }; 97C146F11CF9000F007C117D /* Supporting Files */ = { isa = PBXGroup; children = ( 97C146F21CF9000F007C117D /* main.m */, ); name = "Supporting Files"; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 97C146ED1CF9000F007C117D /* Runner */ = { isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, ); buildRules = ( ); dependencies = ( ); name = Runner; productName = Runner; productReference = 97C146EE1CF9000F007C117D /* Runner.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0910; ORGANIZATIONNAME = "The Chromium Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; }; }; }; buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 97C146E51CF9000F007C117D; productRefGroup = 97C146EF1CF9000F007C117D /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 97C146ED1CF9000F007C117D /* Runner */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 97C146EC1CF9000F007C117D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Thin Binary"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Run Script"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 97C146EA1CF9000F007C117D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 97C146F31CF9000F007C117D /* main.m in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 97C146FA1CF9000F007C117D /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( 97C146FB1CF9000F007C117D /* Base */, ); name = Main.storyboard; sourceTree = ""; }; 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( 97C147001CF9000F007C117D /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; 97C147041CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; 97C147061CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterExample; PRODUCT_NAME = "$(TARGET_NAME)"; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; }; 97C147071CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterExample; PRODUCT_NAME = "$(TARGET_NAME)"; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( 97C147031CF9000F007C117D /* Debug */, 97C147041CF9000F007C117D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( 97C147061CF9000F007C117D /* Debug */, 97C147071CF9000F007C117D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; } ================================================ FILE: examples/flutter_kiwi/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: examples/flutter_kiwi/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme ================================================ ================================================ FILE: examples/flutter_kiwi/ios/Runner.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: examples/flutter_kiwi/lib/di/test01.dart ================================================ import 'package:kiwi/kiwi.dart'; part 'test01.g.dart'; abstract class Injector { @Register.factory(Test) @Register.factory(Counter) @Register.singleton(Counter, name: 'display') void configure(); } class Test {} class Counter { int _value = 0; Counter(Test test); int get value => _value; void add() => _value++; } class Di { static void setup() { var injector = _$Injector(); injector.configure(); } } ================================================ FILE: examples/flutter_kiwi/lib/di/test01.g.dart ================================================ // GENERATED CODE - DO NOT MODIFY BY HAND part of 'test01.dart'; // ************************************************************************** // KiwiInjectorGenerator // ************************************************************************** class _$Injector extends Injector { @override void configure() { final KiwiContainer container = KiwiContainer(); container ..registerFactory((c) => Test()) ..registerFactory((c) => Counter(c.resolve())) ..registerSingleton((c) => Counter(c.resolve()), name: 'display'); } } ================================================ FILE: examples/flutter_kiwi/lib/main.dart ================================================ import 'package:flutter/material.dart'; import 'package:flutter_kiwi/screens/main_screen.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Kiwi Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: const MainScreen(), ); } } ================================================ FILE: examples/flutter_kiwi/lib/screens/error_screen.dart ================================================ import 'package:flutter/material.dart'; import 'package:flutter_kiwi/di/test01.dart'; import 'package:flutter_kiwi/widgets/error_widget.dart'; import 'package:kiwi/kiwi.dart'; class ErrorScreen extends StatefulWidget { @override _ErrorScreenState createState() => _ErrorScreenState(); } class _ErrorScreenState extends State { @override void initState() { super.initState(); Di.setup(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Error Screen'), ), body: ListView( children: [ Container(height: 16), Container( height: 600, child: ErrorContainer( error: () => KiwiContainer().resolve(), ), ), Container(height: 16), Container( height: 600, child: ErrorContainer( error: () => KiwiContainer().resolve('named'), ), ), ], ), ); } } ================================================ FILE: examples/flutter_kiwi/lib/screens/main_screen.dart ================================================ import 'package:flutter/material.dart'; import 'package:flutter_kiwi/screens/error_screen.dart'; import 'package:flutter_kiwi/screens/resolve_screen.dart'; import 'package:flutter_kiwi/screens/scoped_screen.dart'; import 'package:kiwi/kiwi.dart'; class MainScreen extends StatelessWidget { const MainScreen({super.key}); @override Widget build(BuildContext context) { final theme = Theme.of(context); return Scaffold( appBar: AppBar( title: Text('Main Screen'), ), body: ListView( children: [ Container(height: 16), MaterialButton( color: Theme.of(context).primaryColor, onPressed: () async { await Navigator.of(context).push( MaterialPageRoute(builder: (context) => ResolveScreen())); KiwiContainer().clear(); }, child: Text( 'Resolve Screen', style: theme.textTheme.bodyLarge?.copyWith( color: theme.colorScheme.onSecondary, ), ), ), MaterialButton( color: Theme.of(context).primaryColor, onPressed: () async { await Navigator.of(context) .push(MaterialPageRoute(builder: (context) => ErrorScreen())); KiwiContainer().clear(); }, child: Text( 'Error Screen', style: theme.textTheme.bodyLarge?.copyWith( color: theme.colorScheme.onSecondary, ), ), ), MaterialButton( color: Theme.of(context).primaryColor, onPressed: () async { await Navigator.of(context).push( MaterialPageRoute(builder: (context) => ScopedScreen())); KiwiContainer().clear(); }, child: Text( 'Scoped Container Screen', style: theme.textTheme.bodyLarge?.copyWith( color: theme.colorScheme.onSecondary, ), ), ), ], ), ); } } ================================================ FILE: examples/flutter_kiwi/lib/screens/resolve_screen.dart ================================================ import 'package:flutter/material.dart'; import 'package:flutter_kiwi/di/test01.dart'; import 'package:kiwi/kiwi.dart'; class ResolveScreen extends StatefulWidget { @override _ResolveScreenState createState() => new _ResolveScreenState(); } class _ResolveScreenState extends State { @override void initState() { super.initState(); Di.setup(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Resolve Screen'), ), body: Center( child: ListView( children: [ Container(height: 16), Text( 'Counter instances:', textAlign: TextAlign.center, ), Text( KiwiContainer().resolve('display').value.toString(), style: Theme.of(context).textTheme.headlineMedium, textAlign: TextAlign.center, ), Text( KiwiContainer().resolve().value.toString(), style: Theme.of(context).textTheme.headlineMedium, textAlign: TextAlign.center, ), Text( KiwiContainer().resolve().toString(), style: Theme.of(context).textTheme.headlineMedium, textAlign: TextAlign.center, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: Icon(Icons.add), ), ); } void _incrementCounter() { setState(() => KiwiContainer().resolve('display').add()); } } ================================================ FILE: examples/flutter_kiwi/lib/screens/scoped_screen.dart ================================================ import 'package:flutter/material.dart'; import 'package:kiwi/kiwi.dart'; class ScopedScreen extends StatefulWidget { @override _ScopedScreenState createState() => _ScopedScreenState(); } class _ScopedScreenState extends State { final container1 = KiwiContainer.scoped(); final container2 = KiwiContainer.scoped(); @override void initState() { super.initState(); container1.registerInstance('TEST CONTAINER 1'); container2.registerInstance('TEST CONTAINER 2'); container2.registerInstance('TEST CONTAINER 2 NAMED', name: 'named'); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Error Screen'), ), body: ListView( children: [ Container(height: 16), Text(container1.resolve()), Container(height: 16), Text(container2.resolve()), Container(height: 16), Text(container2.resolve('named')), Container(height: 16), ], ), ); } } ================================================ FILE: examples/flutter_kiwi/lib/widgets/error_widget.dart ================================================ import 'package:flutter/material.dart'; class ErrorContainer extends StatelessWidget { final VoidCallback error; const ErrorContainer({ required this.error, }); @override Widget build(BuildContext context) { error(); return Container(); } } ================================================ FILE: examples/flutter_kiwi/pubspec.yaml ================================================ name: flutter_kiwi description: A Flutter example for kiwi. version: 1.0.0+2 publish_to: none environment: sdk: ">=3.0.0 <4.0.0" dependencies: flutter: sdk: flutter kiwi: ^5.0.0 dependency_overrides: kiwi: path: ../../packages/kiwi/ kiwi_generator: path: ../../packages/kiwi_generator/ dev_dependencies: flutter_test: sdk: flutter build_runner: ^2.3.3 kiwi_generator: ^4.2.0 flutter: uses-material-design: true ================================================ FILE: packages/kiwi/.gitignore ================================================ # Files and directories created by pub .dart_tool/ .packages # Remove the following pattern if you wish to check in your lock file pubspec.lock # Conventional directory for build outputs build/ # Directory created by dartdoc doc/api/ .vscode/ .idea/ ================================================ FILE: packages/kiwi/CHANGELOG.md ================================================ # 5.0.1 - Fix a problem with pub.dev scores. # 5.0.0 Now Kiwi it's a Brazilian package! 🇧🇷 ♥ Thank you ([@vanlooverenkoen](https://github.com/vanlooverenkoen)) for your contribution and trust in our work. He continued his active and dedicated work on the Kiwi package up to version `4.1.0`. - feature: it's now possible to create a scoped container with providers copied from a parent, without a direct reference. ([PR #101](https://github.com/gbtb16/kiwi/pull/101)) - feature: it's now possible to check if the instance or builder is registered. ([PR #103](https://github.com/gbtb16/kiwi/pull/103)) - feature: it's now possible to list all providers. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - feature: it's now possible to list all named providers. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - feature: it's now possible to list all unnamed providers. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - feature: it's now possible to convert the _Provider class to String. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - refactor: the package structure has been refactored to be in line with the market. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - refactor: implemented new dart format rule for line length (160) of package development. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - refactor: the _providers now has a more verbose implementation, and it's now easy to read. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - refactor: for the new implementations, new tests have been created. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - refactor: github actions have been updated. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - refactor: github project labels have been updated. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - refactor: the Dart CLI tools in the package have been updated. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - fix: typedefs have been updated. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - fix: pub.dev points now sound great (150/150). ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - fix: dependabot has been updated. ([PR #107](https://github.com/gbtb16/kiwi/pull/107)) - chore: other minimalist changes. # 4.1.0 ## Updated - Dependencies - Moved from travis to github actions # 4.0.3 ### Updated - Dependencies # 4.0.2 ## Updated - Dependencies - Example to use Android X - Travis Dart format ## Added - Error's are now exported as well # 4.0.1 ### Fixed - Dart constraint issue for kiwi # 4.0.0 ## BREAKING - Support for kiwi_generator 4.0.0 - Dart 2.14 min requirement ## Updated dependencies # 3.0.0 ### Added - Nullsafety codebase migration ## Updated dependencies - Updated dependencies to make sure we can still build with new dependencies. # 2.1.1 ## Updated - Description to make the kiwi package easy to find in pub.dev # 2.1.0 ## Added - No response bot to git - Android v2 embedding for the example project # 2.0.1 ## Updated - Updated dependencies # 2.0.0 ## BREAKING CHANGE - \#9 Removed the unused T generic for some functions # 1.1.0 ## Added - \#34 resolveAs() added for testing only ## Updated - \#32 better error handling - Flutter example improvements - Updated documentation # 1.0.0 ## BREAKING CHANGE - renamed `Container` to `KiwiContainer` so it is easier for Flutter devs to import the KiwiContainer # 0.3.3 ## Fixed - Updated homepage # 0.3.2 ## Fixed - Fixed pub.dev score # 0.3.1 ## Fixed - Fixed pub.dev score # 0.3.0 ## Fixed - Upgrade dependencies - Fixed formatting errors - Fixed pub.dev score # 0.2.0 ## Added - Scoped constructor for the Container class. - Upgrade test dependency # 0.1.0 - Initial Open Source release. ================================================ FILE: packages/kiwi/LICENSE ================================================ MIT License Copyright (c) 2018 Romain Rastel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: packages/kiwi/README.md ================================================ # kiwi [![Pub](https://img.shields.io/pub/v/kiwi.svg)](https://pub.dartlang.org/packages/kiwi) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/RomainRastel) ![Logo](https://raw.githubusercontent.com/gbtb16/kiwi/master/images/logo.png) A simple yet efficient IoC container for Dart and Flutter. The container does not rely on reflection, it's just a `Map`, so it's fast. **IMPORTANT: Dart2 is required to use this package.** This package can be used with, or without code generation. While code generation allows you to code faster, it comes with extra configuration on you side (to be setup only one time). This section is only about **kiwi** which contains the IoC container and the annotations. If you are looking for the kiwi_generator configuration, you can find documentation [here](https://github.com/gbtb16/kiwi/tree/master/packages/kiwi_generator). ## Configuration Add `kiwi` to `pubspec.yaml` under the `dependencies` field. The latest version is [![Pub](https://img.shields.io/pub/v/kiwi.svg)](https://pub.dartlang.org/packages/kiwi) ```yaml dependencies: kiwi: ^latest_version ``` ## Import In your library add the following import: ```dart import 'package:kiwi/kiwi.dart'; ``` ## Usage The core of **kiwi** is the `KiwiContainer` class. This is where all your instances and factories are stored. The `KiwiContainer` is implemented as a singleton, you can access the single instance like this: ```dart KiwiContainer container = KiwiContainer(); ``` **Note:** I promise you, even if this is looking like a constructor, you will always end up with the same instance :wink:. If you want different containers, you can create scoped ones easily: ```dart KiwiContainer container = KiwiContainer.scoped(); ``` It works like a lot of IoC containers: you can register a factory under a type, and then resolve the type to get a value. ### Registering You can register 3 kinds of objects: #### Instances **Kiwi** can register simple instances like that: ```dart container.registerInstance(Sith('Anakin', 'Skywalker')); ``` You can also give a name to a specific instance: ```dart container.registerInstance(Sith('Anakin', 'Skywalker'), name: 'DartVader'); ``` By default instances are registered under their type. If you want to register an instance under a supertype: you have only need to add the super type in the generics. The subtype will be detected automatically: ```dart container.registerInstance(Sith('Anakin', 'Skywalker'), name: 'DartVader'); ``` In the above example `Character` is a supertype of `Sith`. #### Factories ```dart container.registerFactory((c) => Sith('Anakin', 'Skywalker')); ``` You can also give a name to a specific factory: ```dart container.registerFactory((c) => Sith('Anakin', 'Skywalker'), name: 'DartVader'); ``` By default factories are registered under the return type of the factory. If you want to register an factory under a supertype, you have to specify both of them: ```dart container.registerFactory((c) => Sith('Anakin', 'Skywalker'), name: 'DartVader'); ``` **Note:** the `c` parameter is the instance of the `KiwiContainer`, we will see later how it can be useful. #### Singletons Singletons are registered like factories but they are called only once: the first time we get their value. ```dart container.registerSingleton((c) => Sith('Anakin', 'Skywalker')); ``` ### Resolving You can get the instance registered for a type like this: ```dart Sith theSith = container.resolve(); ``` If it was registered under a name, you can get its value like this: ```dart Sith theSith = container.resolve('DartVader'); ``` If it was registered with a superclass, you can get its value like this: ```dart Sith theSith = container.resolveAs(); ``` If it was registered with a superclass under a name, you can get its value like this: ```dart Sith theSith = container.resolveAs('DartVader'); ``` The `KiwiContainer` is a callable class. You can also resolve a type like that: ```dart Sith theSith = container('DartVader'); ``` ## Usage with dependencies If you have a service that depends on another, you have to add the dependency in the constructor. For registering the service, you can then use the `c` parameter we saw earlier to resolve the value. ```dart class Service {} class ServiceA extends Service {} class ServiceB extends Service { ServiceB(ServiceA serviceA); } ... // Registers a complex factory by resolving the dependency // when the type is resolved. KiwiContainer container = KiwiContainer(); container.registerFactory((c) => ServiceB(c.resolve())); ``` For services with a lot of dependencies, it can be tedious to write that sort of code. That's why **kiwi** comes with a generator :smiley:! ## Unregistering You can unregister a factory/instance at any time: ```dart // Unregisters the Sith type. container.unregister(); // Unregister the Sith type that was registered under the name DartVader. container.unregister('DartVader'); ``` ## Cleaning You can remove all the registered types by calling the `clear` method: ```dart container.clear(); ``` ## Ignoring KiwiErrors in development mode By default **kiwi** throws an `KiwiError` in the following cases: * if you register the same type under the same name a second time. * if you try to resolve a type that was not previously registered. * if you try to unregister a type that was not previously registered. This helps you to prevent potential errors in production, however you might want to ignore these KiwiErrors. To do this you can set `true` to the `silent` property of the `KiwiContainer`: ```dart container.silent = true; ``` In production, or when `silent` is `true`, you will get `null` if you try to resolve a type that was not previously registered. ## Changelog Please see the [Changelog](https://github.com/gbtb16/kiwi/blob/master/packages/kiwi/CHANGELOG.md) page to know what's recently changed. ================================================ FILE: packages/kiwi/analysis_options.yaml ================================================ analyzer: # exclude: # - path/to/excluded/files/** # Lint rules and documentation, see http://dart-lang.github.io/linter/lints linter: rules: - cancel_subscriptions - hash_and_equals - collection_methods_unrelated_type - test_types_in_equals - unrelated_type_equality_checks - valid_regexps ================================================ FILE: packages/kiwi/example/kiwi_example.dart ================================================ import 'package:kiwi/kiwi.dart'; main() { KiwiContainer container = KiwiContainer(); container.registerInstance(Logger()); container.registerSingleton((c) => Logger(), name: 'namedLogger'); container.registerFactory( (c) => ServiceA(logger: c.resolve('namedLogger'))); final comumLogger = container.resolve(); final namedLogger = container.resolve('namedLogger'); final serviceA = container.resolve(); print(comumLogger.toString()); // Hey, I'm a logger! print(namedLogger.toString()); // Hey, I'm a logger! print(serviceA.toString()); // Hey, I'm a service A! } class Service { const Service(); @override String toString() { return 'Hey, I\'m a service!'; } } class ServiceA extends Service { final Logger logger; const ServiceA({required this.logger}); @override String toString() { return 'Hey, I\'m a service A!'; } } class Logger { const Logger(); @override String toString() { return 'Hey, I\'m a logger!'; } } ================================================ FILE: packages/kiwi/kiwi.iml ================================================ ================================================ FILE: packages/kiwi/lib/kiwi.dart ================================================ library kiwi; export 'src/annotations.dart'; export 'src/kiwi_container.dart'; export 'src/model/exception/kiwi_error.dart'; export 'src/model/exception/not_registered_error.dart'; ================================================ FILE: packages/kiwi/lib/src/annotations.dart ================================================ import 'package:kiwi/kiwi.dart'; /// An annotation that generates code for registering factories /// using the kiwi container. class Register { /// Create an annotation that will generate a `registerFactory` method. const Register.factory( this.type, { this.name, this.from, this.resolvers, this.constructorName, }) : oneTime = null; /// Create an annotation that will generate a `registerSingleton` method. const Register.singleton( this.type, { this.name, this.from, this.resolvers, this.constructorName, }) : oneTime = true; /// The type to register. final Type type; /// The type to create when requesting [type]. final Type? from; /// The name under which the factory will be registered /// /// You must provide the same name in [KiwiContainer.resolve] /// to get the same factory. final String? name; /// A map that give for a type, the name under which it should be resolved /// /// For example if you have registered a type T under the name /// 'myType', you have to specify it in this map in order /// to use it instead of the default value for the type T. final Map? resolvers; /// The name of the constructor to use inside the factory. final String? constructorName; /// Whether the factory has to be created only one time. final bool? oneTime; } ================================================ FILE: packages/kiwi/lib/src/kiwi_container.dart ================================================ import 'package:kiwi/src/model/exception/kiwi_error.dart'; import 'package:kiwi/src/model/exception/not_registered_error.dart'; import 'package:meta/meta.dart'; /// Signature for a builder which creates an object of type [T]. typedef FactoryBuilder = T Function(KiwiContainer container); /// Signature for the generic provider name. typedef _ProviderName = String; /// Signature for the generic provider value. typedef _ProviderValue = Map>; /// A simple service container. class KiwiContainer { /// Creates a scoped container. /// /// If [parent] is set, the new scoped instance will include its providers. KiwiContainer.scoped({ KiwiContainer? parent, }) : _providers = <_ProviderName?, _ProviderValue>{ if (parent != null) ...parent._providers.map( // [Map.from] is needed to create a copy of value and not use its reference, // because if only value is passed, everything included in the parent will be // added to the new instance at any time, even after this scoped instance has been created. (key, value) => MapEntry(key, Map.from(value)), ), }; static final KiwiContainer _instance = KiwiContainer.scoped(); /// Always returns a singleton representing the only container to be alive. factory KiwiContainer() => _instance; /// Map of all instances and builders registered in the container. final Map<_ProviderName?, _ProviderValue> _providers; /// All providers registered in the container, /// including named our unnamed instances and builders. /// /// Instances and builders can be named or unnamed. /// /// Example: /// ```dart /// { /// "int-instance": {int: 1}, /// null: {Character: Character('Anakin', 'Skywaker')}, /// }; /// ``` Map<_ProviderName?, _ProviderValue> get providers => _providers; /// All named providers values registered in the container. /// /// Example: /// ```dart /// { /// "int-instance": {int: 1}, /// "character-builder": {Character: Character('Anakin', 'Skywaker')}, /// }; /// ``` Map<_ProviderName?, _ProviderValue> get namedProviders { return Map<_ProviderName?, _ProviderValue>.from(_providers) ..removeWhere((key, value) => key == null); } /// All unnamed providers values registered in the container. /// /// Example: /// ```dart /// { /// null: {double: 2.0}, /// null: {Vehicle: Car('Chevrolet Opala SS')}, /// }; /// ``` Map<_ProviderName?, _ProviderValue> get unnamedProviders { return Map<_ProviderName?, _ProviderValue>.from(_providers) ..removeWhere((key, value) => key != null); } /// Whether ignoring KiwiErrors in the following cases: /// * if you register the same type under the same name a second time. /// * if you try to resolve a type that was not previously registered. /// * if you try to unregister a type that was not previously registered. /// /// Defaults to false. bool silent = false; /// Registers an instance into the container. /// /// An instance of type [S] can be registered. /// /// If [name] is set, the instance will be registered under this name. /// To retrieve the same instance, the same name should be provided /// to [KiwiContainer.resolve]. void registerInstance( S instance, { String? name, }) { _setProvider(name, _Provider.instance(instance)); } /// Registers a factory into the container. /// /// A factory returning an object of type [S] can be registered. /// /// If [name] is set, the factory will be registered under this name. /// To retrieve the same factory, the same name should be provided /// to [KiwiContainer.resolve]. void registerFactory( FactoryBuilder factory, { String? name, }) { _setProvider(name, _Provider.factory(factory)); } /// Registers a factory that will be called only only when /// accessing it for the first time, into the container. /// /// A factory returning an object of type [S] can be registered. /// /// If [name] is set, the factory will be registered under this name. /// To retrieve the same factory, the same name should be provided /// to [KiwiContainer.resolve]. void registerSingleton( FactoryBuilder factory, { String? name, }) { _setProvider(name, _Provider.singleton(factory)); } /// Removes the entry previously registered for the type [T]. /// /// If [name] is set, removes the one registered for that name. void unregister([String? name]) { if (!silent && !(_providers[name]?.containsKey(T) ?? false)) { throw KiwiError( 'Failed to unregister `$T`:\n\nThe type `$T` was not registered${name == null ? '' : ' for the name `$name`'}\n\nMake sure `$T` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.'); } _providers[name]?.remove(T); } /// Attemps to resolve the type [T]. /// /// If [name] is set, the instance or builder registered with this /// name will be get. /// /// See also: /// /// * [KiwiContainer.registerFactory] for register a builder function. /// * [KiwiContainer.registerInstance] for register an instance. T resolve([String? name]) { final providers = _providers[name] ?? _ProviderValue.from({}); if (!silent && !(providers.containsKey(T))) { throw NotRegisteredKiwiError( 'Failed to resolve `$T`:\n\nThe type `$T` was not registered${name == null ? '' : ' for the name `$name`'}\n\nMake sure `$T` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.'); } final value = providers[T]?.get(this); if (value == null) { throw NotRegisteredKiwiError( 'Failed to resolve `$T`:\n\nThe type `$T` was not registered${name == null ? '' : ' for the name `$name`'}\n\nMake sure `$T` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.'); } if (value is T) return value as T; throw NotRegisteredKiwiError( 'Failed to resolve `$T`:\n\nValue was not registered as `$T`\n\nThe type `$T` was not registered${name == null ? '' : ' for the name `$name`'}\n\nMake sure `$T` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.'); } /// Attemps to resolve the type [S] and tries to cast it to T. /// /// If [name] is set, the instance or builder registered with this /// name will be get. /// /// This method is only available for Testing. /// /// See also: /// /// * [KiwiContainer.resolve] for resolving the object itself. /// * [KiwiContainer.registerFactory] for register a builder function. /// * [KiwiContainer.registerInstance] for register an instance. @visibleForTesting T? resolveAs([String? name]) { final object = resolve(name); if (!silent && !(object is T)) { throw KiwiError( 'Failed to resolve `$S` as `$T`:\n\nThe type `$S` as `$T` was not registered${name == null ? '' : ' for the name `$name`'}\n\nMake sure `$T` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.'); } if (object == null) return null; if (object is T) return object as T; return null; } T call([String? name]) => resolve(name); /// Returns if an instance or builder of type [T] is registered. /// /// If an instance or builder of type [T] is registered with a name, /// and the name is not passed to [isRegistered], returns false. bool isRegistered({String? name}) { return (_providers.containsKey(name) && _providers[name]!.containsKey(T)); } /// Removes all instances and builders from the container. /// /// After this, the container is empty. void clear() { _providers.clear(); } void _setProvider(String? name, _Provider provider) { if (!silent && isRegistered(name: name)) { throw KiwiError( 'The type `$T` was already registered${name == null ? '' : ' for the name `$name`'}'); } _providers.putIfAbsent(name, () => _ProviderValue.from({}))[T] = provider as _Provider; } } class _Provider { final FactoryBuilder? _instanceBuilder; T? object; bool _oneTime = false; _Provider.instance(this.object) : _instanceBuilder = null, _oneTime = false; _Provider.factory(this._instanceBuilder) : _oneTime = false; _Provider.singleton(this._instanceBuilder) : _oneTime = true; T? get(KiwiContainer container) { final instanceBuilder = _instanceBuilder; if (_oneTime && instanceBuilder != null) { object = instanceBuilder(container); _oneTime = false; } if (object != null) { return object; } if (instanceBuilder != null) { return instanceBuilder(container); } return null; } @override String toString() { return ''' _Provider( _instanceBuilder: $_instanceBuilder, object: $object, _oneTime: $_oneTime, ); '''; } } ================================================ FILE: packages/kiwi/lib/src/model/exception/kiwi_error.dart ================================================ class KiwiError extends Error { final String message; KiwiError(this.message); @override String toString() { return 'KiwiError:\n\n\n$message\n\n\n'; } } ================================================ FILE: packages/kiwi/lib/src/model/exception/not_registered_error.dart ================================================ import 'package:kiwi/src/model/exception/kiwi_error.dart'; class NotRegisteredKiwiError extends KiwiError { NotRegisteredKiwiError(String message) : super(message); @override String toString() { return 'Not Registered KiwiError:\n\n\n$message\n\n\n'; } } ================================================ FILE: packages/kiwi/mono_pkg.yaml ================================================ # See https://github.com/dart-lang/mono_repo for details dart: - stable - dev stages: - analyze: - dartfmt - dartanalyzer: --fatal-infos --fatal-warnings . - unit_test: - test ================================================ FILE: packages/kiwi/pubspec.yaml ================================================ name: kiwi description: A simple yet efficient dependency injection container for Dart and Flutter (can be coupled with the kiwi_generator package). version: 5.0.1 homepage: https://github.com/gbtb16/kiwi/tree/master/packages/kiwi repository: https://github.com/gbtb16/kiwi/tree/master/packages/kiwi issue_tracker: https://github.com/gbtb16/kiwi/issues environment: sdk: ">=2.14.0 <4.0.0" dependencies: meta: ^1.8.0 dev_dependencies: test: ^1.25.1 topics: - deep-linking - dependency-injector - containers ================================================ FILE: packages/kiwi/test/kiwi_test.dart ================================================ import 'package:kiwi/kiwi.dart'; import 'package:test/test.dart'; void main() { KiwiContainer container = KiwiContainer(); group('Silent=true tests', () { setUp(() { container.clear(); container.silent = true; }); test('containers should be the same', () { KiwiContainer c1 = KiwiContainer(); KiwiContainer c2 = KiwiContainer(); expect(c1, c2); }); test('KiwiContainer.scope should be a different object', () { KiwiContainer c1 = KiwiContainer(); KiwiContainer c2 = KiwiContainer(); KiwiContainer c3 = KiwiContainer.scoped(); KiwiContainer c4 = KiwiContainer.scoped(); expect(c1, c2); expect(c1, isNot(c3)); expect(c1, isNot(c4)); expect(c2, isNot(c3)); expect(c2, isNot(c4)); expect(c3, isNot(c4)); }); test('instances should be resolved', () { var person = Character('Anakin', 'Skywalker'); container.registerInstance(5); container.registerInstance(6, name: 'named'); container.registerInstance(7); container.registerInstance(person); expect(container.resolve(), 5); expect(container.resolve('named'), 6); expect(container.resolve(), 7); expect( () => container.resolve('named'), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'Not Registered KiwiError:\n\n\nFailed to resolve `num`:\n\nThe type `num` was not registered for the name `named`\n\nMake sure `num` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); }); test('instances should be resolveAs', () { final sith = Sith('Anakin', 'Skywalker', 'DarthVader'); container.registerSingleton((c) => sith); expect(container.resolveAs(), sith); expect( () => container.resolveAs('named'), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'Not Registered KiwiError:\n\n\nFailed to resolve `Character`:\n\nThe type `Character` was not registered for the name `named`\n\nMake sure `Character` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); }); test('container should resolve when called', () { var person = Character('Anakin', 'Skywalker'); container.registerInstance(5); container.registerInstance(6, name: 'named'); container.registerInstance(7); container.registerInstance(person); expect(container(), 5); expect(container('named'), 6); expect(container(), 7); expect( () => container.resolve('named'), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'Not Registered KiwiError:\n\n\nFailed to resolve `num`:\n\nThe type `num` was not registered for the name `named`\n\nMake sure `num` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); expect(container(), person); }); test('instances can be overridden', () { container.registerInstance(5); expect(container.resolve(), 5); container.registerInstance(6); expect(container.resolve(), 6); }); test('builders should be resolved', () { container.registerSingleton((c) => 5); container.registerFactory( (c) => const Sith('Anakin', 'Skywalker', 'DarthVader')); container.registerFactory((c) => const Character('Anakin', 'Skywalker')); container.registerFactory( (c) => const Sith('Anakin', 'Skywalker', 'DarthVader'), name: 'named'); expect(container.resolve(), 5); expect(container.resolve(), const Sith('Anakin', 'Skywalker', 'DarthVader')); expect(container.resolve(), const Character('Anakin', 'Skywalker')); expect(container.resolve('named'), const Sith('Anakin', 'Skywalker', 'DarthVader')); }); test('builders should always be created', () { container.registerFactory((c) => Character('Anakin', 'Skywalker')); expect(container.resolve(), isNot(same(container.resolve()))); }); test('one time builders should be resolved', () { container.registerSingleton((c) => 5); container.registerSingleton( (c) => const Sith('Anakin', 'Skywalker', 'DarthVader')); container.registerSingleton( (c) => const Character('Anakin', 'Skywalker')); expect(container.resolve(), 5); expect(container.resolve(), const Sith('Anakin', 'Skywalker', 'DarthVader')); expect(container.resolve(), const Character('Anakin', 'Skywalker')); }); test('one time builders should be created one time only', () { container.registerSingleton((c) => Character('Anakin', 'Skywalker')); expect(container.resolve(), container.resolve()); }); test('unregister should remove items from container', () { container.registerInstance(5); container.registerInstance(6, name: 'named'); expect(container.resolve(), 5); expect(container.resolve('named'), 6); container.unregister(); expect( () => container.resolve(), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'Not Registered KiwiError:\n\n\nFailed to resolve `int`:\n\nThe type `int` was not registered\n\nMake sure `int` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); container.unregister('named'); expect( () => container.resolve('named'), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'Not Registered KiwiError:\n\n\nFailed to resolve `int`:\n\nThe type `int` was not registered for the name `named`\n\nMake sure `int` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); }); }); group('Silent=false tests', () { setUp(() { container.clear(); container.silent = false; }); test('instances cannot be overridden', () { container.registerInstance(5); expect(container.resolve(), 5); container.registerInstance(8, name: 'name'); expect(container.resolve('name'), 8); expect( () => container.registerInstance(6), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'KiwiError:\n\n\nThe type `int` was already registered\n\n\n', ))); expect( () => container.registerInstance(9, name: 'name'), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'KiwiError:\n\n\nThe type `int` was already registered for the name `name`\n\n\n', ))); }); test('values should exist when unregistering', () { expect( () => container.unregister(), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'KiwiError:\n\n\nFailed to unregister `int`:\n\nThe type `int` was not registered\n\nMake sure `int` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); expect( () => container.unregister('name'), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'KiwiError:\n\n\nFailed to unregister `int`:\n\nThe type `int` was not registered for the name `name`\n\nMake sure `int` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); }); test('values should exist when resolving', () { expect( () => container.resolve(), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'Not Registered KiwiError:\n\n\nFailed to resolve `int`:\n\nThe type `int` was not registered\n\nMake sure `int` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); expect( () => container.resolve('name'), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'Not Registered KiwiError:\n\n\nFailed to resolve `int`:\n\nThe type `int` was not registered for the name `name`\n\nMake sure `int` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); }); test('values should exist when resolving as', () { var person = Character('Anakin', 'Skywalker'); container.registerInstance(person); container.registerInstance(person, name: 'named'); expect( () => container.resolveAs(), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'KiwiError:\n\n\nFailed to resolve `Character` as `Sith`:\n\nThe type `Character` as `Sith` was not registered\n\nMake sure `Sith` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); expect( () => container.resolveAs('named'), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'KiwiError:\n\n\nFailed to resolve `Character` as `Sith`:\n\nThe type `Character` as `Sith` was not registered for the name `named`\n\nMake sure `Sith` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); }); test('Parented [KiwiContainer.scoped] should inherit global registrations', () { container.registerInstance(5); container.registerInstance(6, name: 'named'); container.registerInstance(7); final character = Character('Gabriel', 'Kiwilied'); container.registerFactory((c) => character); final scoped = KiwiContainer.scoped(parent: container); // The scoped instance and global container must be different. expect(scoped, isNot(container)); expect(scoped.resolve(), 5); expect(scoped.resolve('named'), 6); expect(scoped.resolve(), 7); expect(scoped.resolve(), character); }); test('Parented [KiwiContainer.scoped] should inherit registrations', () { final firstScoped = KiwiContainer.scoped(); firstScoped.registerInstance(5); firstScoped.registerInstance(6, name: 'named'); firstScoped.registerInstance(7); final character = Character('Gabriel', 'Kiwilied'); firstScoped.registerFactory((c) => character); final secondScoped = KiwiContainer.scoped(parent: firstScoped); // The scoped instances must be different. expect(secondScoped, isNot(firstScoped)); expect(secondScoped.resolve(), 5); expect(secondScoped.resolve('named'), 6); expect(secondScoped.resolve(), 7); expect(secondScoped.resolve(), character); }); test('Parented [KiwiContainer.scoped] should be impacted by parent', () { final firstScoped = KiwiContainer.scoped(); firstScoped.registerInstance(5); firstScoped.registerInstance(6, name: 'named'); firstScoped.registerInstance(7); final character = Character('Gabriel', 'Kiwilied'); firstScoped.registerFactory((c) => character); final secondScoped = KiwiContainer.scoped(parent: firstScoped); firstScoped.registerInstance(26, name: 'exclusive_to_parent'); firstScoped.registerInstance('random_string'); expect(firstScoped.resolve(), 5); expect(firstScoped.resolve('named'), 6); expect(firstScoped.resolve(), 7); expect(firstScoped.resolve(), character); // The instances registered in [firstScoped] after creation of [secondScoped]. expect(firstScoped.resolve('exclusive_to_parent'), 26); expect(firstScoped.resolve(), 'random_string'); expect(secondScoped.resolve(), 5); expect(secondScoped.resolve('named'), 6); expect(secondScoped.resolve(), character); // The [secondScoped] must not have the [firstScoped] instances registered after [secondScoped] creation. expect( () => secondScoped.resolve('exclusive_to_parent'), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'Not Registered KiwiError:\n\n\nFailed to resolve `int`:\n\nThe type `int` was not registered for the name `exclusive_to_parent`\n\nMake sure `int` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); expect( () => secondScoped.resolve(), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'Not Registered KiwiError:\n\n\nFailed to resolve `String`:\n\nThe type `String` was not registered\n\nMake sure `String` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); }); test('Parented [KiwiContainer.scoped] should not impact parent', () { final firstScoped = KiwiContainer.scoped(); firstScoped.registerInstance(5); firstScoped.registerInstance(6, name: 'named'); firstScoped.registerInstance(7); final character = Character('Gabriel', 'Kiwilied'); firstScoped.registerFactory((c) => character); final secondScoped = KiwiContainer.scoped(parent: firstScoped); secondScoped.registerInstance(27, name: 'exclusive_to_scoped'); secondScoped.registerInstance('random_string'); expect(firstScoped.resolve(), 5); expect(firstScoped.resolve('named'), 6); expect(firstScoped.resolve(), 7); expect(firstScoped.resolve(), character); expect(secondScoped.resolve(), 5); expect(secondScoped.resolve('named'), 6); expect(secondScoped.resolve(), 7); expect(secondScoped.resolve(), character); // The instances registered in [secondScoped] after your creation. expect(secondScoped.resolve('exclusive_to_scoped'), 27); expect(secondScoped.resolve(), 'random_string'); // The [firstScoped] must not have the [secondScoped] instances registered only in [secondScoped]. expect( () => firstScoped.resolve('exclusive_to_scoped'), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'Not Registered KiwiError:\n\n\nFailed to resolve `int`:\n\nThe type `int` was not registered for the name `exclusive_to_scoped`\n\nMake sure `int` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); expect( () => firstScoped.resolve(), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'Not Registered KiwiError:\n\n\nFailed to resolve `String`:\n\nThe type `String` was not registered\n\nMake sure `String` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); }); test('Unparented [KiwiContainer.scoped] should not be resolved', () { final scoped = KiwiContainer.scoped(parent: container); expect( () => scoped.resolve(), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'Not Registered KiwiError:\n\n\nFailed to resolve `int`:\n\nThe type `int` was not registered\n\nMake sure `int` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); }); test('checks that the instances are registered', () { final scoped = KiwiContainer.scoped(); // Unnamed instances expect(scoped.isRegistered(), false); scoped.registerInstance(5); expect(scoped.isRegistered(), true); expect(scoped.resolve(), 5); scoped.unregister(); expect(scoped.isRegistered(), false); expect( () => container.resolve(), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'Not Registered KiwiError:\n\n\nFailed to resolve `int`:\n\nThe type `int` was not registered\n\nMake sure `int` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); // Named instances expect(scoped.isRegistered(name: 'named_string_instance'), false); scoped.registerInstance('random_string', name: 'named_string_instance'); expect(scoped.isRegistered(), false); // [isRegistered] cannot be true if String it is named and is tested unnamed. expect(scoped.isRegistered(name: 'named_string_instance'), true); expect(scoped.resolve('named_string_instance'), 'random_string'); scoped.unregister('named_string_instance'); expect(scoped.isRegistered(), false); expect( () => container.resolve(), throwsA(TypeMatcher().having( (f) => f.toString(), 'toString()', 'Not Registered KiwiError:\n\n\nFailed to resolve `String`:\n\nThe type `String` was not registered\n\nMake sure `String` is added to your KiwiContainer and rerun build_runner build\n(If you are using the kiwi_generator)\n\nWhen using Flutter, most of the time a hot restart is required to setup the KiwiContainer again.\n\n\n', ))); }); test('Should be return all providers', () { final scoped = KiwiContainer.scoped(); expect(scoped.providers.length, 0); scoped.registerInstance(1, name: 'int-instance'); scoped.registerInstance(2.0); expect(scoped.providers.length, 2); }); test('Should be return all named providers', () { final scoped = KiwiContainer.scoped(); expect(scoped.namedProviders.length, 0); expect(scoped.unnamedProviders.length, 0); scoped.registerInstance(1, name: 'int-instance'); expect(scoped.namedProviders.length, 1); expect(scoped.unnamedProviders.length, 0); }); test('Should be return all unnamed providers', () { final scoped = KiwiContainer.scoped(); expect(scoped.namedProviders.length, 0); expect(scoped.unnamedProviders.length, 0); scoped.registerInstance(1); expect(scoped.namedProviders.length, 0); expect(scoped.unnamedProviders.length, 1); }); test('Should be return all named and unnamed providers', () { final scoped = KiwiContainer.scoped(); expect(scoped.namedProviders.length, 0); expect(scoped.unnamedProviders.length, 0); scoped.registerInstance(1); scoped.registerInstance(2.0, name: 'double-instance'); expect(scoped.namedProviders.length, 1); expect(scoped.unnamedProviders.length, 1); }); }); } class Character { const Character( this.firstName, this.lastName, ); final String firstName; final String lastName; } class Sith extends Character { const Sith( String firstName, String lastName, this.id, ) : super(firstName, lastName); final String id; } ================================================ FILE: packages/kiwi_generator/.gitignore ================================================ # Files and directories created by pub .dart_tool/ .packages # Remove the following pattern if you wish to check in your lock file pubspec.lock # Conventional directory for build outputs build/ # Directory created by dartdoc doc/api/ ================================================ FILE: packages/kiwi_generator/CHANGELOG.md ================================================ # 4.2.1 - kiwi version has been updated to `5.0.1`. # 4.2.0 Now Kiwi it's a Brazilian package! 🇧🇷 ♥ Thank you ([@vanlooverenkoen](https://github.com/vanlooverenkoen)) for your contribution and trust in our work. He continued his active and dedicated work on the Kiwi Generator package up to version `4.2.0`. - BREAKING: kiwi version has been updated to `5.0.0`. - refactor: the package structure has been refactored to be in line with the market. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - refactor: implemented new dart format rule for line length (160) of package development. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - refactor: github actions have been updated. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - refactor: github project labels have been updated. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - refactor: the Dart CLI tools in the package have been updated. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - fix: build_runner version has been updated. ([PR #102](https://github.com/gbtb16/kiwi/pull/102)) - fix: typedefs have been updated. ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - fix: pub.dev points now sound great (150/150). ([PR #106](https://github.com/gbtb16/kiwi/pull/106)) - fix: dependabot has been updated. ([PR #107](https://github.com/gbtb16/kiwi/pull/107)) - chore: other minimalist changes. - chore: update `analyzer` dependency to `6.0.0`. # 4.1.0 ### Updated - Dependencies - Moved from travis to github actions # 4.0.3 ## Updated - Dependencies # 4.0.2 ## Updated - Dependencies # 4.0.1 ## Fixed - Dart constraint issue for kiwi # 4.0.0 ## BREAKING - Updated to analyzer 2.0.0 - Dart 2.14 min requirement ## Updated dependencies # 3.0.1 ## Updated - Generated core is now using the cascade operator ## Fixed - Using build_runner 2.0.4 with kiwi # 3.0.0 ## Added - Nullsafety codebase migration ## Updated dependencies - Updated dependencies to make sure we can still build with new dependencies. # 2.1.1 ## Updated - Kiwi version to 2.1.1 # 2.1.0 ## Updated - Updated the documentation for the use of subclasses & subclasses with generics - Updated dependencies ## Added - No response bot to git - Android v2 embedding for the example project ## Fixed - \#44 Fixed a bug where the @override was never generated - \#45 Fixed a bug where a file that contained a abstract void method without @register would be skipped. This is not the case anymore. # 2.0.1 ## Fixed - \#49 Fixed a bug that prepares for nullability. In this release we do not yet support nullability. But #51 is tracking nullability support # 2.0.0 ## BREAKING CHANGE - \#9 Removed the unused T generic for some functions ## Added - \#19 added support for scopes with the kiwi_generator # 1.0.0 ## BREAKING CHANGE - renamed `Container` to `KiwiContainer` so it is easier for Flutter devs to import the KiwiContainer (kiwi: 1.0.0 required) # 0.5.2 ## Fixed - Updated homepage # 0.5.1 ### Fixed - Fixed pub.dev score # 0.5.0 ## Fixed - Upgrade dependencies - Fixed formatting errors - Fixed pub.dev score # 0.4.0 - Upgrade dependencies # 0.3.1 ## Fixed - Upgrade dependencies and fix a deprecated error. # 0.3.0 ## Fixed - Upgrade dependencies # 0.2.0 ## Fixed - Upgrade dependencies # 0.1.1 ### Fixed - The generator no longer generates a `.g.dart` file for abstract classes without abstract methods. # 0.1.0 - Initial Open Source release. ================================================ FILE: packages/kiwi_generator/LICENSE ================================================ MIT License Copyright (c) 2018 Romain Rastel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: packages/kiwi_generator/README.md ================================================ # kiwi_generator [![Pub](https://img.shields.io/pub/v/kiwi_generator.svg)](https://pub.dartlang.org/packages/kiwi_generator) ![Logo](https://raw.githubusercontent.com/gbtb16/kiwi/master/images/logo.png) Generates dependency injection code using the [kiwi](https://github.com/gbtb16/packages/kiwi) package to reduce development time. ## Configuration 1. Add `kiwi` to `pubspec.yaml` under the `dependencies:` section. The latest version is [![Pub](https://img.shields.io/pub/v/kiwi.svg)](https://pub.dartlang.org/packages/kiwi) ```yaml dependencies: kiwi: ^latest_version ``` 2. Add [build_runner](https://github.com/dart-lang/build/tree/master/build_runner) and `kiwi_generator` under the `dev_dependencies:` section of the `pubspec.yaml` file. The latest version is [![Pub](https://img.shields.io/pub/v/kiwi_generator.svg)](https://pub.dartlang.org/packages/kiwi_generator) ```yaml dev_dependencies: build_runner: ^2.3.3 kiwi_generator: ^latest_version ``` ## Usage In your library add the following import: ```dart import 'package:kiwi/kiwi.dart'; ``` Create an abstract class with an abstract method: ```dart abstract class Injector { void configure(); } ``` Annotate the abstract method with the **kiwi** `Register` annotations. ```dart abstract class Injector { @Register.singleton(ServiceA) @Register.factory(Service, from: ServiceB) @Register.factory(ServiceB, name: 'factoryB') @Register.factory(ServiceC, resolvers: {ServiceB: 'factoryB'}) void configure(); } ``` Include the part directive indicating the file that will be generated (typically the same file with a `.g` extension before `.dart`): ```dart part 'test01.g.dart'; ``` Run build_runner: ```bash pub run build_runner build ``` For Flutter the command is different though: ```bash flutter packages pub run build_runner build ``` **Note:** On first attempt to run this command you might encounter a conflict error. If so, please add the --delete-conflicting-outputs argument to your command: ```bash flutter packages pub run build_runner build --delete-conflicting-outputs ``` (This additional argument allows the command to overwrite the `.g.dart` file if necessary.) You can also use the `watch` command instead of `build`. This will generate your file when it's saved. ```bash pub run build_runner watch ``` A concrete class named `_$TheNameOfYourAbstractClass` will be generated and you can call the method where you like. For example you can create a function in your library which will call it: ```dart void setup() { var injector = _$Injector(); injector.configure(); } ``` Or you can create a function that will return the concrecte injector and use it elsewhere: ```dart Injector getInjector() => _$Injector(); ``` ## Annotations There is only one annotation, called `Register`, with two constructors: `factory` and `singleton`. There are no constructor for registering instances because only `const` instances are supported in metadata. And it would'nt be easier to create an annotation than registering directly with a container. If you want to register a singleton (the factory will be called only one time, when accessing it for the first time): ```dart @Register.singleton(ServiceA) ``` If you want to register a factory: ```dart @Register.factory(ServiceA) ``` Both constructors have the same parameters: **Parameter**|**Type**|**Required**|**Description** -----|:-----:|:-----:|----- `type`|Type|Yes|This is the type to register `name`|String|No|This is the name under which the factory will be registered `from`|Type|No|The type to create when requesting `type`, if different of `type`. `constructorName`|String|No|The name of the constructor to use inside the factory `resolvers`|Map|No|A map that give for a type, the name under which it should be resolved ## Short example This code: ```dart import 'package:kiwi/kiwi.dart'; part 'test01.g.dart'; abstract class Injector { @Register.singleton(ServiceA) @Register.factory(Service, from: ServiceB) @Register.factory(ServiceB, name: 'factoryB') @Register.factory(ServiceC, resolvers: {ServiceB: 'factoryB'}) void common(); @Register.factory(ServiceC) void development(); @Register.factory(ServiceC, constructorName: 'other') void production(); } class Service {} class ServiceA extends Service {} class ServiceB extends Service { ServiceB(ServiceA serviceA); } class ServiceC extends Service { ServiceC(ServiceA serviceA, ServiceB serviceB); ServiceC.other(ServiceB serviceA); } void setup(bool isProduction) { var injector = _$Injector(); injector.common(); if (isProduction) { injector.production(); } else { injector.development(); } } ``` Will produce this: ```dart // GENERATED CODE - DO NOT MODIFY BY HAND part of 'test01.dart'; // ************************************************************************** // InjectorGenerator // ************************************************************************** class _$Injector extends Injector { void common() { final KiwiContainer container = KiwiContainer(); container.registerSingleton((c) => ServiceA()); container .registerFactory((c) => ServiceB(c())); container.registerFactory((c) => ServiceB(c()), name: 'factoryB'); container.registerFactory( (c) => ServiceC(c(), c('factoryB'))); } void development() { final KiwiContainer container = KiwiContainer(); container.registerFactory((c) => ServiceC(c(), c())); } void production() { final KiwiContainer container = KiwiContainer(); container.registerFactory((c) => ServiceC.other(c())); } } ``` ## Changelog Please see the [Changelog](https://github.com/gbtb16/kiwi/blob/master/packages/kiwi_generator/CHANGELOG.md) page to know what's recently changed. ================================================ FILE: packages/kiwi_generator/analysis_options.yaml ================================================ analyzer: # exclude: # - path/to/excluded/files/** # Lint rules and documentation, see http://dart-lang.github.io/linter/lints linter: rules: - cancel_subscriptions - hash_and_equals - collection_methods_unrelated_type - test_types_in_equals - unrelated_type_equality_checks - valid_regexps ================================================ FILE: packages/kiwi_generator/build.yaml ================================================ targets: $default: builders: kiwi: generate_for: - example/kiwi_generator_example.dart # Read about `build.yaml` at https://pub.dartlang.org/packages/build_config builders: kiwi|kiwi: import: "package:kiwi_generator/builder.dart" builder_factories: ["buildKiwi"] build_extensions: {".dart": [".kiwi.g.part"]} auto_apply: dependents build_to: cache applies_builders: ["source_gen|combining_builder"] ================================================ FILE: packages/kiwi_generator/example/kiwi_generator_example.dart ================================================ import 'package:kiwi/kiwi.dart'; part 'kiwi_generator_example.g.dart'; abstract class Injector { @Register.singleton(ServiceA) @Register.factory(Service, from: ServiceB) @Register.factory(ServiceB, name: 'factoryB') @Register.factory(ServiceC, resolvers: {ServiceB: 'factoryB'}) void configureWithScopedContainer(KiwiContainer scopedContainer); @Register.factory(ServiceC, resolvers: {ServiceB: 'factoryB'}) void configureWithScopedContainer2([KiwiContainer scopedContainer]); @Register.factory(ServiceC, resolvers: {ServiceB: 'factoryB'}) void configureWithScopedContainer3({KiwiContainer scopedContainer}); @Register.factory(ServiceC, resolvers: {ServiceB: 'factoryB'}) void configureWithScopedContainer4({KiwiContainer scopedContainer}); @Register.singleton(ServiceA) @Register.factory(Service, from: ServiceB) @Register.factory(ServiceB, name: 'factoryB') @Register.factory(ServiceC, resolvers: {ServiceB: 'factoryB'}) void configure(); void methodWithoutAnnotations(); void configureInjector() {} } void setup() { final injector = _$Injector(); injector.configure(); } class Service { const Service(); } class ServiceA extends Service { const ServiceA(); } class ServiceB extends Service { const ServiceB(ServiceA serviceA); } class ServiceC extends Service { const ServiceC(ServiceA serviceA, ServiceB serviceB); const ServiceC.other(ServiceA serviceA); } ================================================ FILE: packages/kiwi_generator/example/kiwi_generator_example.g.dart ================================================ // GENERATED CODE - DO NOT MODIFY BY HAND part of 'kiwi_generator_example.dart'; // ************************************************************************** // KiwiInjectorGenerator // ************************************************************************** class _$Injector extends Injector { @override void configureWithScopedContainer(KiwiContainer? scopedContainer) { final KiwiContainer container = scopedContainer ?? KiwiContainer(); container ..registerSingleton((c) => ServiceA()) ..registerFactory((c) => ServiceB(c.resolve())) ..registerFactory((c) => ServiceB(c.resolve()), name: 'factoryB') ..registerFactory((c) => ServiceC(c.resolve(), c.resolve('factoryB'))); } @override void configureWithScopedContainer2([KiwiContainer? scopedContainer = null]) { final KiwiContainer container = scopedContainer ?? KiwiContainer(); container.registerFactory((c) => ServiceC(c.resolve(), c.resolve('factoryB'))); } @override void configureWithScopedContainer3({KiwiContainer? scopedContainer = null}) { final KiwiContainer container = scopedContainer ?? KiwiContainer(); container.registerFactory((c) => ServiceC(c.resolve(), c.resolve('factoryB'))); } @override void configureWithScopedContainer4({KiwiContainer? scopedContainer = null}) { final KiwiContainer container = scopedContainer ?? KiwiContainer(); container.registerFactory((c) => ServiceC(c.resolve(), c.resolve('factoryB'))); } @override void configure() { final KiwiContainer container = KiwiContainer(); container ..registerSingleton((c) => ServiceA()) ..registerFactory((c) => ServiceB(c.resolve())) ..registerFactory((c) => ServiceB(c.resolve()), name: 'factoryB') ..registerFactory((c) => ServiceC(c.resolve(), c.resolve('factoryB'))); } @override void methodWithoutAnnotations() {} } ================================================ FILE: packages/kiwi_generator/kiwi_generator.iml ================================================ ================================================ FILE: packages/kiwi_generator/lib/builder.dart ================================================ /// Configuration for using `package:build`-compatible build systems. /// /// This library is **not** intended to be imported by typical end-users unless /// you are creating a custom compilation pipeline. /// /// See [package:build_runner](https://pub.dartlang.org/packages/build_runner) /// for more information. library builder; import 'package:build/build.dart'; import 'package:source_gen/source_gen.dart'; import 'src/kiwi_injector_generator.dart'; Builder buildKiwi([BuilderOptions? options = null]) { return SharedPartBuilder(const [ KiwiInjectorGenerator(), ], 'kiwi'); } ================================================ FILE: packages/kiwi_generator/lib/kiwi_generator.dart ================================================ library kiwi_generator; export 'src/kiwi_injector_generator.dart'; ================================================ FILE: packages/kiwi_generator/lib/src/kiwi_injector_generator.dart ================================================ import 'package:analyzer/dart/constant/value.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:build/build.dart'; import 'package:build/src/builder/build_step.dart'; import 'package:built_collection/built_collection.dart'; import 'package:code_builder/code_builder.dart'; import 'package:dart_style/dart_style.dart'; import 'package:kiwi/kiwi.dart'; import 'package:kiwi_generator/src/model/kiwi_generator_error.dart'; import 'package:kiwi_generator/src/util/list_extensions.dart'; import 'package:source_gen/source_gen.dart'; const TypeChecker _registerTypeChecker = TypeChecker.fromRuntime(Register); bool _isRegisterMethod(MethodElement method) => (method.returnType is VoidType && _registerTypeChecker.hasAnnotationOfExact(method)); class KiwiInjectorGenerator extends Generator { const KiwiInjectorGenerator(); @override String? generate(LibraryReader library, BuildStep? buildStep) { try { // An injector is an abstract class where all abstract methods are // annotated with Register. final injectors = library.classes .where((c) => c.isAbstract && c.methods.where((m) => m.isAbstract).isNotEmpty && c.methods .where((m) => m.isAbstract && _isRegisterMethod(m)) .isNotEmpty) .toList(); if (injectors.isEmpty) { return null; } final file = Library((lb) => lb ..body.addAll( injectors.map((i) => _generateInjector(i, library, buildStep)))); final DartEmitter emitter = DartEmitter(allocator: Allocator()); return DartFormatter().format('${file.accept(emitter)}'); } catch (e) { if (e is KiwiGeneratorError || e is UnresolvedAnnotationException) { rethrow; } else if (e is Error) { throw KiwiGeneratorError( 'Something went wrong with the KiwiGenerator. Please create a new ticket with a copy of your error to https://github.com/gbtb16/kiwi/issues/new', error: e); } else { throw KiwiGeneratorError( 'Something went wrong with the KiwiGenerator. Please create a new ticket with a copy of your error to https://github.com/gbtb16/kiwi/issues/new'); } } } Class _generateInjector( ClassElement injector, LibraryReader library, BuildStep? buildStep) { return Class((cb) => cb ..name = '_\$${injector.name}' ..extend = refer(injector.name) ..methods.addAll(_generateInjectorMethods(injector))); } List _generateInjectorMethods(ClassElement injector) { return injector.methods .where((m) => m.isAbstract) .map((m) => _generateInjectorMethod(m)) .toList(); } Method _generateInjectorMethod(MethodElement method) { if (method.parameters.length > 1) { throw KiwiGeneratorError( 'Only 1 parameter is supported `KiwiContainer scopedContainer`, ${method.name} contains ${method.parameters.length} param(s)'); } final scopedContainerParam = method.parameters.singleOrNullWhere( (element) => element.name == 'scopedContainer' && element.type.getDisplayString(withNullability: true) == 'KiwiContainer', ); return Method.returnsVoid((mb) { var scopedContainer = ''; if (scopedContainerParam != null) { if (scopedContainerParam.isOptional) { mb.optionalParameters = ListBuilder([ Parameter((builder) => builder ..name = scopedContainerParam.name ..named = scopedContainerParam.isNamed ..required = scopedContainerParam.isRequiredNamed ..defaultTo = Code('null') ..type = Reference('KiwiContainer?')) ]); } else { mb.requiredParameters = ListBuilder([ Parameter((builder) => builder ..name = scopedContainerParam.name ..named = scopedContainerParam.isNamed ..required = scopedContainerParam.isRequiredNamed ..defaultTo = Code('null') ..type = Reference('KiwiContainer?')) ]); } scopedContainer = '${scopedContainerParam.name} ?? '; } else if (method.parameters.isNotEmpty) { throw KiwiGeneratorError( 'Only 1 parameter is supported `KiwiContainer scopedContainer`, ${method.name} contains ${method.parameters.length} param(s) and `KiwiContainer scopedContainer` is not included'); } final registers = _generateRegisters(method); mb ..name = method.name ..annotations.add(refer('override')); if (registers == null) { mb..body = Block(); } else { mb ..body = Block((bb) => bb ..statements.add(Code( 'final KiwiContainer container = ${scopedContainer}KiwiContainer();')) ..addExpression(registers)); } }); } Expression? _generateRegisters(MethodElement method) { final annotations = _registerTypeChecker.annotationsOfExact(method); return annotations.isEmpty ? null : annotations.fold( Reference('container'), (expr, annotation) => _generateRegister( expr, AnnotatedElement(ConstantReader(annotation), method), ), ); } Expression _generateRegister( Expression registerExpression, AnnotatedElement annotatedMethod) { final ConstantReader annotation = annotatedMethod.annotation; final DartObject registerObject = annotation.objectValue; final String? name = registerObject.getField('name')?.toStringValue(); final DartType? type = registerObject.getField('type')?.toTypeValue(); final DartType? concrete = registerObject.getField('from')?.toTypeValue(); final String? constructorName = registerObject.getField('constructorName')?.toStringValue(); final DartType? concreteType = concrete ?? type; // TODO: Implement null type check if (concreteType == null) { throw KiwiGeneratorError( 'null can not be registered because there is no type for null'); } final String className = concreteType.getDisplayString(withNullability: false); final String typeParameters = concrete == null ? '' : '<${type?.getDisplayString(withNullability: false)}>'; final String nameArgument = name == null ? '' : ", name: '$name'"; final String constructorNameArgument = constructorName == null ? '' : '.$constructorName'; final ClassElement? clazz = concreteType.element?.library?.getClass(className); if (clazz == null) { throw KiwiGeneratorError('$className not found'); } final bool oneTime = registerObject.getField('oneTime')?.toBoolValue() ?? false; final Map? resolvers = _computeResolvers(registerObject.getField('resolvers')?.toMapValue()); final String methodSuffix = oneTime ? 'Singleton' : 'Factory'; final constructor = constructorName == null ? clazz.unnamedConstructor : clazz.getNamedConstructor(constructorName); if (constructor == null) { throw KiwiGeneratorError( 'the constructor ${clazz.name}.$constructorName does not exist'); } final String factoryParameters = _generateRegisterArguments( constructor, resolvers, ).join(', '); return registerExpression.cascade( 'register$methodSuffix$typeParameters((c) => $className$constructorNameArgument($factoryParameters)$nameArgument)'); } List _generateRegisterArguments( ConstructorElement constructor, Map? resolvers, ) { return constructor.parameters .map((p) => _generateRegisterArgument(p, resolvers)) .toList(); } String _generateRegisterArgument( ParameterElement parameter, Map? resolvers, ) { final List dartTypes = resolvers == null ? [] : resolvers.keys .where((e) => e?.getDisplayString(withNullability: false) == parameter.type.getDisplayString(withNullability: false)) .where((e) => e != null) .map((e) => e!) .toList(); final String nameArgument = dartTypes.isEmpty || resolvers == null ? '' : "'${resolvers[dartTypes.first]}'"; return '${parameter.isNamed ? parameter.name + ': ' : ''}c.resolve<${parameter.type.getDisplayString(withNullability: false)}>($nameArgument)'; } Map? _computeResolvers( Map? resolvers, ) { return resolvers?.map((key, value) => MapEntry( key?.toTypeValue(), value?.toStringValue())); } } ================================================ FILE: packages/kiwi_generator/lib/src/model/kiwi_generator_error.dart ================================================ class KiwiGeneratorError extends Error { final String message; final Error? error; KiwiGeneratorError( this.message, { this.error, }); @override String toString() { var toString = '\nKiwiGeneratorError\n\n$message\n\n'; final internalError = error; if (internalError != null) { toString += '============\n${internalError.toString()}\n${internalError.stackTrace}\n============\n\n'; } return toString; } } ================================================ FILE: packages/kiwi_generator/lib/src/util/list_extensions.dart ================================================ extension ListExtension on List { T? singleOrNullWhere(bool test(T element)) { late T result; bool foundMatching = false; for (T element in this) { if (test(element)) { if (foundMatching) { throw Exception('No many results'); } result = element; foundMatching = true; } } if (foundMatching) return result; return null; } } ================================================ FILE: packages/kiwi_generator/mono_pkg.yaml ================================================ # See https://github.com/dart-lang/mono_repo for details dart: - stable - dev stages: - analyze: - dartfmt - dartanalyzer: --fatal-infos --fatal-warnings . - unit_test: - test ================================================ FILE: packages/kiwi_generator/pubspec.yaml ================================================ name: kiwi_generator description: Generates dependency injection code using the kiwi package to reduce development time. version: 4.2.1 homepage: https://github.com/gbtb16/kiwi/tree/master/packages/kiwi_generator repository: https://github.com/gbtb16/kiwi/tree/master/packages/kiwi_generator issue_tracker: https://github.com/gbtb16/kiwi/issues environment: sdk: '>=2.14.0 <4.0.0' dependencies: analyzer: ^6.0.0 build: ^2.4.1 build_config: ^1.1.1 built_collection: ^5.1.1 code_builder: ^4.10.0 dart_style: ^2.2.4 kiwi: ^5.0.1 path: ^1.8.3 source_gen: ">=1.5.0 <3.0.0" dev_dependencies: build_runner: ^2.3.3 build_test: ^2.1.6 test: ^1.25.1 topics: - kiwi - automatic-generator - dependency-injector ================================================ FILE: packages/kiwi_generator/test/inputs/abstract_class.dart ================================================ abstract class WithoutRegister { void setup(); } ================================================ FILE: packages/kiwi_generator/test/inputs/abstract_class_without_abstract_method.dart ================================================ abstract class WithoutRegister { void setup() {} } ================================================ FILE: packages/kiwi_generator/test/inputs/abstract_class_without_method.dart ================================================ abstract class WithoutRegister {} ================================================ FILE: packages/kiwi_generator/test/inputs/complex_factory.dart ================================================ import 'package:kiwi/kiwi.dart'; abstract class Injector { @Register.factory(ServiceA) @Register.factory(Service, from: ServiceB) @Register.factory(ServiceB, name: 'factoryB') @Register.factory(ServiceC, resolvers: {ServiceB: 'factoryB'}) @Register.factory(ServiceC, constructorName: 'other') void configure(); } class Service {} class ServiceA extends Service {} class ServiceB extends Service { ServiceB(ServiceA serviceA); } class ServiceC extends Service { ServiceC(ServiceA serviceA, ServiceB serviceB); ServiceC.other(ServiceB serviceA); } ================================================ FILE: packages/kiwi_generator/test/inputs/complex_factory_with_abstract_method_without_register_annotation.dart ================================================ import 'package:kiwi/kiwi.dart'; abstract class Injector { @Register.factory(ServiceA) @Register.factory(Service, from: ServiceB) @Register.factory(ServiceB, name: 'factoryB') @Register.factory(ServiceC, resolvers: {ServiceB: 'factoryB'}) @Register.factory(ServiceC, constructorName: 'other') void configure(); void abstractMethodWithoutAnnotation(); } class Service {} class ServiceA extends Service {} class ServiceB extends Service { ServiceB(ServiceA serviceA); } class ServiceC extends Service { ServiceC(ServiceA serviceA, ServiceB serviceB); ServiceC.other(ServiceB serviceA); } ================================================ FILE: packages/kiwi_generator/test/inputs/complex_singleton.dart ================================================ import 'package:kiwi/kiwi.dart'; abstract class Injector { @Register.singleton(ServiceA) @Register.singleton(Service, from: ServiceB) @Register.singleton(ServiceB, name: 'factoryB') @Register.singleton(ServiceC, resolvers: {ServiceB: 'factoryB'}) @Register.singleton(ServiceC, constructorName: 'other') void configure(); } class Service {} class ServiceA extends Service {} class ServiceB extends Service { ServiceB(ServiceA serviceA); } class ServiceC extends Service { ServiceC(ServiceA serviceA, ServiceB serviceB); ServiceC.other(ServiceB serviceA); } ================================================ FILE: packages/kiwi_generator/test/inputs/simple_factory.dart ================================================ import 'package:kiwi/kiwi.dart'; abstract class Injector { @Register.factory(ServiceA) @Register.factory(ServiceB, from: null) @Register.factory(ServiceB, name: null) @Register.factory(Service, from: ServiceB) @Register.factory(ServiceA, name: 'factoryA') @Register.factory(Service, from: ServiceB, name: 'factoryB') void configure(); } class Service { const Service(); } class ServiceA extends Service { const ServiceA(); } class ServiceB extends Service { const ServiceB(); } ================================================ FILE: packages/kiwi_generator/test/inputs/simple_singleton.dart ================================================ import 'package:kiwi/kiwi.dart'; abstract class Injector { @Register.singleton(ServiceA) @Register.singleton(ServiceB, from: null) @Register.singleton(ServiceB, name: null) @Register.singleton(Service, from: ServiceB) @Register.singleton(ServiceA, name: 'singletonA') @Register.singleton(Service, from: ServiceB, name: 'singletonB') void configure(); } class Service {} class ServiceA extends Service {} class ServiceB extends Service {} ================================================ FILE: packages/kiwi_generator/test/inputs/unknown_ctor_factory.dart ================================================ import 'package:kiwi/kiwi.dart'; abstract class Injector { @Register.factory(Service, constructorName: 'unknown') void configure(); } class Service { Service.other(); } ================================================ FILE: packages/kiwi_generator/test/inputs/unknown_ctor_singleton.dart ================================================ import 'package:kiwi/kiwi.dart'; abstract class Injector { @Register.factory(Service, constructorName: 'unknown') void configure(); } class Service { Service.other(); } ================================================ FILE: packages/kiwi_generator/test/kiwi_generator_test.dart ================================================ import 'package:kiwi_generator/src/model/kiwi_generator_error.dart'; import 'package:test/test.dart'; import 'utils/test_helper.dart'; void main() async { group('Register.factory', () { test('simple', () async { await testKiwi( 'simple_factory', _outputSimpleFactory, ); }); test('complex', () async { await testKiwi( 'complex_factory', _outputComplexFactory, ); }); test('abstract class without abstract method', () async { await testKiwi( 'complex_factory_with_abstract_method_without_register_annotation', _outputComplexFactoryWithAbstractMethodWithoutAnnotation, ); }); test('unknown constructor', () async { await testKiwiException( 'unknown_ctor_factory', const TypeMatcher().having( (f) => f.toString(), 'toString()', '\nKiwiGeneratorError\n\nthe constructor Service.unknown does not exist\n\n', ), ); }); }); group('Register.singleton', () { test('simple', () async { await testKiwi( 'simple_singleton', _outputSimpleSingleton, ); }); test('complex', () async { await testKiwi( 'complex_singleton', _outputComplexSingleton, ); }); test('unknown constructor', () async { await testKiwiException( 'unknown_ctor_singleton', const TypeMatcher().having( (f) => f.toString(), 'toString()', '\nKiwiGeneratorError\n\nthe constructor Service.unknown does not exist\n\n', ), ); }); }); group('Generates null', () { test('abstract class', () async { await testKiwi( 'abstract_class', null, ); }); test('abstract class without method', () async { await testKiwi( 'abstract_class_without_method', null, ); }); test('abstract class without abstract method', () async { await testKiwi( 'abstract_class_without_abstract_method', null, ); }); }); } const _outputSimpleFactory = r''' class _$Injector extends Injector { @override void configure() { final KiwiContainer container = KiwiContainer(); container ..registerFactory((c) => ServiceA()) ..registerFactory((c) => ServiceB()) ..registerFactory((c) => ServiceB()) ..registerFactory((c) => ServiceB()) ..registerFactory((c) => ServiceA(), name: 'factoryA') ..registerFactory((c) => ServiceB(), name: 'factoryB'); } } '''; const _outputComplexFactory = r''' class _$Injector extends Injector { @override void configure() { final KiwiContainer container = KiwiContainer(); container ..registerFactory((c) => ServiceA()) ..registerFactory((c) => ServiceB(c.resolve())) ..registerFactory((c) => ServiceB(c.resolve()), name: 'factoryB') ..registerFactory((c) => ServiceC(c.resolve(), c.resolve('factoryB'))) ..registerFactory((c) => ServiceC.other(c.resolve())); } } '''; const _outputComplexFactoryWithAbstractMethodWithoutAnnotation = r''' class _$Injector extends Injector { @override void configure() { final KiwiContainer container = KiwiContainer(); container ..registerFactory((c) => ServiceA()) ..registerFactory((c) => ServiceB(c.resolve())) ..registerFactory((c) => ServiceB(c.resolve()), name: 'factoryB') ..registerFactory((c) => ServiceC(c.resolve(), c.resolve('factoryB'))) ..registerFactory((c) => ServiceC.other(c.resolve())); } @override void abstractMethodWithoutAnnotation() {} } '''; const _outputSimpleSingleton = r''' class _$Injector extends Injector { @override void configure() { final KiwiContainer container = KiwiContainer(); container ..registerSingleton((c) => ServiceA()) ..registerSingleton((c) => ServiceB()) ..registerSingleton((c) => ServiceB()) ..registerSingleton((c) => ServiceB()) ..registerSingleton((c) => ServiceA(), name: 'singletonA') ..registerSingleton((c) => ServiceB(), name: 'singletonB'); } } '''; const _outputComplexSingleton = r''' class _$Injector extends Injector { @override void configure() { final KiwiContainer container = KiwiContainer(); container ..registerSingleton((c) => ServiceA()) ..registerSingleton((c) => ServiceB(c.resolve())) ..registerSingleton((c) => ServiceB(c.resolve()), name: 'factoryB') ..registerSingleton((c) => ServiceC(c.resolve(), c.resolve('factoryB'))) ..registerSingleton((c) => ServiceC.other(c.resolve())); } } '''; ================================================ FILE: packages/kiwi_generator/test/utils/analysis.dart ================================================ import 'dart:async'; import 'dart:io'; import 'package:build/build.dart'; import 'package:build_test/build_test.dart'; import 'package:path/path.dart' as p; import 'package:source_gen/source_gen.dart'; Future resolveCompilationUnit(String sourceFile) async { final files = [ File(sourceFile), ]; final fileMap = Map.fromEntries( files.map( (f) => MapEntry( 'a|lib/${p.basename(f.path)}', f.readAsStringSync(), ), ), ); final library = await resolveSources(fileMap, (item) async { final assetId = AssetId.parse(fileMap.keys.first); return await item.libraryFor(assetId); }); return LibraryReader(library); } ================================================ FILE: packages/kiwi_generator/test/utils/test_helper.dart ================================================ import 'dart:async'; import 'package:kiwi_generator/kiwi_generator.dart'; import 'package:test/test.dart'; import 'analysis.dart'; final KiwiInjectorGenerator _injectorGenerator = const KiwiInjectorGenerator(); Future testKiwi( String fileName, String? output, ) async { try { String inputFilePath = './test/inputs/$fileName.dart'; final library = await resolveCompilationUnit(inputFilePath); String? actual = _injectorGenerator.generate(library, null); expect(actual, output); } catch (genericError) { print('Its not possible to find inputs file.'); print('Error: $genericError'); rethrow; } } Future testKiwiException( String fileName, dynamic matcher, ) async { try { String inputFilePath = './test/inputs/$fileName.dart'; final library = await resolveCompilationUnit(inputFilePath); expect(() => _injectorGenerator.generate(library, null), throwsA(matcher)); } catch (genericError) { print('Its not possible to test kiwi exceptions.'); print('Error: $genericError'); rethrow; } } ================================================ FILE: tools/all.sh ================================================ #!/bin/bash ./packages_get.sh ./analyze.sh ./fix.sh ./format.sh ./test.sh ./build.sh ================================================ FILE: tools/analyze.sh ================================================ #!/bin/bash CURRENT=`pwd` DIR_NAME=`basename "$CURRENT"` if [ $DIR_NAME == 'tools' ] then cd .. fi echo "" echo "===========================" echo "dart_kiwi example package analyze" echo "---------------------------" cd examples/dart_kiwi flutter analyze echo "===========================" cd ../.. echo "" echo "===========================" echo "flutter_kiwi example package analyze" echo "---------------------------" cd examples/flutter_kiwi flutter analyze echo "===========================" cd ../.. echo "" echo "===========================" echo "kiwi final package analyze" echo "---------------------------" cd packages/kiwi dart analyze --fatal-infos --fatal-warnings . echo "===========================" cd ../.. echo "" echo "===========================" echo "kiwi_generator final package analyze" echo "---------------------------" cd packages/kiwi_generator dart analyze --fatal-infos --fatal-warnings . echo "===========================" ================================================ FILE: tools/build.sh ================================================ #!/bin/bash CURRENT=`pwd` DIR_NAME=`basename "$CURRENT"` if [ $DIR_NAME == 'tools' ] then cd .. fi echo "" echo "===========================" echo "dart_kiwi example package build_runner build" echo "---------------------------" cd examples/dart_kiwi dart run build_runner build --delete-conflicting-outputs echo "===========================" cd ../.. echo "" echo "===========================" echo "flutter_kiwi example package build_runner build" echo "---------------------------" cd examples/flutter_kiwi dart run build_runner build --delete-conflicting-outputs echo "===========================" cd ../.. echo "" echo "===========================" echo "kiwi final package build_runner build" echo "---------------------------" cd packages/kiwi echo "Nothing to generate here" echo "===========================" cd ../.. echo "" echo "===========================" echo "kiwi_generator final package build_runner build" echo "---------------------------" cd packages/kiwi_generator dart run build_runner build --delete-conflicting-outputs echo "===========================" ================================================ FILE: tools/fix.sh ================================================ #!/bin/bash CURRENT=`pwd` DIR_NAME=`basename "$CURRENT"` if [ $DIR_NAME == 'tools' ] then cd .. fi echo "" echo "dart_kiwi example package fix lib" cd examples/dart_kiwi dart fix --apply cd ../.. echo "" echo "flutter_kiwi example package fix lib" cd examples/flutter_kiwi dart fix --apply cd ../.. echo "" echo "kiwi final package fix lib" cd packages/kiwi dart fix --apply cd ../.. echo "" echo "kiwi_generator final package fix lib" cd packages/kiwi_generator dart fix --apply ================================================ FILE: tools/format.sh ================================================ #!/bin/bash CURRENT=`pwd` DIR_NAME=`basename "$CURRENT"` if [ $DIR_NAME == 'tools' ] then cd .. fi echo "" echo "dart_kiwi example package format lib" cd examples/dart_kiwi dart format . cd ../.. echo "" echo "flutter_kiwi example package format lib" cd examples/flutter_kiwi dart format . cd ../.. echo "" echo "kiwi final package format lib" cd packages/kiwi dart format . cd ../.. echo "" echo "kiwi_generator final package format lib" cd packages/kiwi_generator dart format . ================================================ FILE: tools/kiwi_cli_actions/bin/kiwi_cli_actions.dart ================================================ // ignore_for_file: unused_local_variable import 'package:kiwi_cli_actions/changelog_checker.dart'; void main() { const rootPath = '../..'; const examplesBasePath = '$rootPath/examples'; const packagesBasePath = '$rootPath/packages'; const toolsBasePath = '$rootPath/tools'; // Check the changelogs of all Kiwi packages. const changelogChecker = ChangelogChecker(); changelogChecker.checkIfChangelogHasBeenUpdated( absolutePath: '$packagesBasePath/kiwi', ); changelogChecker.checkIfChangelogHasBeenUpdated( absolutePath: '$packagesBasePath/kiwi_generator', ); } ================================================ FILE: tools/kiwi_cli_actions/lib/changelog_checker.dart ================================================ import 'dart:io'; import 'package:yaml/yaml.dart'; final class ChangelogChecker { const ChangelogChecker(); String getActualPubspecVersion(String path) { try { final pubspec = File('$path/pubspec.yaml'); final pubspecContent = pubspec.readAsStringSync(); final loadedYaml = loadYaml(pubspecContent); return loadedYaml['version']; } catch (genericError) { print('pubspec.yaml file not exists!'); print('error: $genericError'); rethrow; } } void checkIfChangelogHasBeenUpdated({required String absolutePath}) { try { final pubspecVersion = getActualPubspecVersion(absolutePath); final changelog = File('$absolutePath/CHANGELOG.md'); final changelogContent = changelog.readAsStringSync(); if (changelogContent.startsWith('# $pubspecVersion')) { print('Changelog for $absolutePath has been updated!'); } else { print('Changelog for $absolutePath has not been updated.'); exit(1); } } catch (genericError) { print('its not possible check if changelog has been updated.'); print('error: $genericError'); rethrow; } } } ================================================ FILE: tools/kiwi_cli_actions/pubspec.yaml ================================================ name: kiwi_cli_actions description: A CLI tool to check for problems in the kiwi and kiwi_generator changelog. version: 1.0.0+2 publish_to: none environment: sdk: '>=3.0.0 <4.0.0' dev_dependencies: test: ^1.25.1 yaml: ^3.1.1 ================================================ FILE: tools/packages_get.sh ================================================ #!/bin/bash CURRENT=`pwd` DIR_NAME=`basename "$CURRENT"` if [ $DIR_NAME == 'tools' ] then cd .. fi echo "dart_kiwi example package packages get" cd examples/dart_kiwi flutter packages get cd ../.. echo "flutter_kiwi example package packages get" cd examples/flutter_kiwi flutter packages get cd ../.. echo "kiwi final package packages get" cd packages/kiwi dart pub get cd ../.. echo "kiwi_generator final package packages get" cd packages/kiwi_generator dart pub get cd ../.. echo "actions packages get" cd tools/kiwi_cli_actions dart pub get ================================================ FILE: tools/test.sh ================================================ #!/bin/bash CURRENT=`pwd` DIR_NAME=`basename "$CURRENT"` if [ $DIR_NAME == 'tools' ] then cd .. fi echo "" echo "dart_kiwi example package test" cd examples/dart_kiwi echo "No tests for dart_kiwi" cd ../.. echo "" echo "flutter_kiwi example package test" cd examples/flutter_kiwi echo "No test for flutter_kiwi" cd ../.. echo "" echo "kiwi final package test" cd packages/kiwi dart test cd ../.. echo "" echo "kiwi_generator final package test" cd packages/kiwi_generator dart test