Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,22 @@ jobs:
files: ./packages/core/coverage.lcov

- name: Generate example then check formats and changes
run: |
run: | # Run format and diff for each gen step.
melos run gen:examples:command --no-select
dart format --set-exit-if-changed examples
git --no-pager diff --exit-code examples

melos run gen:examples:build_runner --no-select
dart format --set-exit-if-changed examples
git --no-pager diff --exit-code examples

melos run gen:examples:workspace:command --no-select
dart format --set-exit-if-changed examples
git --no-pager diff --exit-code examples

melos run gen:examples:workspace:build_runner --no-select
dart format --set-exit-if-changed examples
git --no-pager diff --exit-code examples

- name: Statically analyze the code
run: melos analyze
1 change: 1 addition & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
pnpm-lock.yaml
**/pubspec.lock

.dart_tool/
build/
packages/**/android/
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
## Next

**Feature**

- Add `build_runner --workspace` support for `flutter_gen_runner` using a manifest + post-process materialization pipeline.
- Add `fluttergen --workspace` support to the command package, including package-local `build.yaml` overrides for each workspace member.

**Development**

- Document and align the minimum supported versions for the new build pipeline: Dart `>=3.7.0` and `build_runner >=2.12.0`.
- Document the current `build_runner --workspace` rebuild limitation for manually deleted generated files and recommend `build_runner clean` before rebuilding.

## 5.13.0+1

**Development**
Expand Down
73 changes: 71 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,17 @@ Widget build(BuildContext context) {
1. Add [build_runner] and [FlutterGen] to your package's pubspec.yaml file:

```yaml
environment:
sdk: ^3.7.0

dev_dependencies:
build_runner:
build_runner: ^2.12.0
flutter_gen_runner:
```

`flutter_gen_runner` now relies on post-process builders with
`build_to: source`, so `build_runner >=2.12.0` is required.

2. Install [FlutterGen]

```sh
Expand All @@ -75,6 +81,47 @@ Widget build(BuildContext context) {
dart run build_runner build
```

#### Pub workspaces

FlutterGen also supports [`dart pub` workspaces](https://dart.dev/tools/pub/workspaces).
Run `build_runner` from the workspace root, and make sure each workspace member
that should be built has `resolution: workspace` in its `pubspec.yaml`.

```yaml
# workspace root pubspec.yaml
environment:
sdk: ^3.7.0

workspace:
- packages/app
```

```yaml
# packages/app/pubspec.yaml
name: app
resolution: workspace

dev_dependencies:
flutter_gen_runner:
build_runner: ^2.12.0
```

```sh
dart run build_runner build --workspace
```

FlutterGen will resolve each package from the active build target instead of the
process working directory, so package-local `pubspec.yaml` configuration and
output paths continue to work in workspace builds.

If generated source files were removed manually while `.dart_tool/build` is
still present, run `dart run build_runner clean` from the workspace root before
running `build --workspace` again. The current post-process builder flow can
re-materialize files reliably after a clean build, but a warm incremental build
may skip unchanged manifests.

For workspace builds, use Dart `>=3.7.0` together with `build_runner >=2.12.0`.

### Pub Global

Works with macOS, Linux and Windows.
Expand Down Expand Up @@ -130,8 +177,28 @@ Run `fluttergen` after the configuration [`pubspec.yaml`](https://dart.dev/tools
fluttergen -h

fluttergen -c example/pubspec.yaml

fluttergen --workspace -c pubspec.yaml
```

Use `--workspace` to treat the config file as a workspace root pubspec and run
generation for each listed workspace member. Without `--workspace`, the command
generates for exactly one package.

When `--workspace` is enabled, the root `pubspec.yaml` is used only to discover
workspace members from its `workspace:` section. FlutterGen then switches to
each member package and loads that package's own `pubspec.yaml` and, if
present, its local `build.yaml`.

That means workspace-wide command execution behaves like this:

- Root `pubspec.yaml`: selects which packages to visit.
- Member `pubspec.yaml`: provides `flutter` and `flutter_gen` configuration.
- Member `build.yaml`: overrides generator options for that member only.

The `--build` option is only available in single-package mode. In workspace
mode, put any overrides in each package's local `build.yaml` instead.

## Configuration file

[FlutterGen] generates dart files based on the key **`flutter`** and **`flutter_gen`** of [`pubspec.yaml`](https://dart.dev/tools/pub/pubspec).
Expand Down Expand Up @@ -171,7 +238,9 @@ flutter:

### build.yaml

You can also configure generate options in the `build.yaml`, it will be read before the `pubspec.yaml` if it exists.
When using `build_runner`, you can also configure generator options in the
target `build.yaml`. These builder options are applied on top of the
`pubspec.yaml` configuration for the current target.

```yaml
# build.yaml
Expand Down
42 changes: 42 additions & 0 deletions examples/example_workspace/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# example_workspace

A minimal pub workspace example for FlutterGen.

## Workspace layout

- `packages/gallery_one`: generates asset accessors for `flutter3.jpg`
- `packages/gallery_two`: generates asset accessors for `dart.svg`

Both packages use `flutter_gen_runner` through `build_runner --workspace`.

## Version requirements

- Dart SDK: `>=3.7.0`
- `build_runner`: `>=2.12.0`

FlutterGen's current `build_runner` integration relies on post-process builders
with `build_to: source`, which is only supported in `build_runner 2.12+`.

## Getting started

```sh
cd examples/example_workspace
flutter pub get
```

Generate all workspace members from the workspace root:

```sh
dart run build_runner clean
dart run build_runner build --workspace
```

The explicit `clean` step is recommended if generated files were deleted
manually. With the current `build_runner` post-process builder model, a warm
incremental build may skip unchanged manifests and therefore not recreate
missing generated source files on its own.

Generated files will be written to:

- `packages/gallery_one/lib/gen/assets.gen.dart`
- `packages/gallery_two/lib/gen/assets.gen.dart`
16 changes: 16 additions & 0 deletions examples/example_workspace/example_workspace_root.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
library;

export 'gen/assets.gen.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// dart format width=80

/// GENERATED CODE - DO NOT MODIFY BY HAND
/// *****************************************************
/// FlutterGen
/// *****************************************************

// coverage:ignore-file
// ignore_for_file: type=lint
// ignore_for_file: deprecated_member_use,directives_ordering,implicit_dynamic_list_literal,unnecessary_import

import 'package:flutter/widgets.dart';

class $AssetsImagesGen {
const $AssetsImagesGen();

/// File path: assets/images/flutter3.jpg
AssetGenImage get flutter3 =>
const AssetGenImage('assets/images/flutter3.jpg');

/// List of all assets
List<AssetGenImage> get values => [flutter3];
}

class GalleryOneAssets {
const GalleryOneAssets._();

static const $AssetsImagesGen images = $AssetsImagesGen();
}

class AssetGenImage {
const AssetGenImage(
this._assetName, {
this.size,
this.flavors = const {},
this.animation,
});

final String _assetName;

final Size? size;
final Set<String> flavors;
final AssetGenImageAnimation? animation;

Image image({
Key? key,
AssetBundle? bundle,
ImageFrameBuilder? frameBuilder,
ImageErrorWidgetBuilder? errorBuilder,
String? semanticLabel,
bool excludeFromSemantics = false,
double? scale,
double? width,
double? height,
Color? color,
Animation<double>? opacity,
BlendMode? colorBlendMode,
BoxFit? fit,
AlignmentGeometry alignment = Alignment.center,
ImageRepeat repeat = ImageRepeat.noRepeat,
Rect? centerSlice,
bool matchTextDirection = false,
bool gaplessPlayback = true,
bool isAntiAlias = false,
String? package,
FilterQuality filterQuality = FilterQuality.medium,
int? cacheWidth,
int? cacheHeight,
}) {
return Image.asset(
_assetName,
key: key,
bundle: bundle,
frameBuilder: frameBuilder,
errorBuilder: errorBuilder,
semanticLabel: semanticLabel,
excludeFromSemantics: excludeFromSemantics,
scale: scale,
width: width,
height: height,
color: color,
opacity: opacity,
colorBlendMode: colorBlendMode,
fit: fit,
alignment: alignment,
repeat: repeat,
centerSlice: centerSlice,
matchTextDirection: matchTextDirection,
gaplessPlayback: gaplessPlayback,
isAntiAlias: isAntiAlias,
package: package,
filterQuality: filterQuality,
cacheWidth: cacheWidth,
cacheHeight: cacheHeight,
);
}

ImageProvider provider({AssetBundle? bundle, String? package}) {
return AssetImage(_assetName, bundle: bundle, package: package);
}

String get path => _assetName;

String get keyName => _assetName;
}

class AssetGenImageAnimation {
const AssetGenImageAnimation({
required this.isAnimation,
required this.duration,
required this.frames,
});

final bool isAnimation;
final Duration duration;
final int frames;
}
27 changes: 27 additions & 0 deletions examples/example_workspace/packages/gallery_one/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: gallery_one
publish_to: 'none'
resolution: workspace

environment:
sdk: ^3.7.0

dependencies:
flutter:
sdk: flutter

dev_dependencies:
lints: any

build_runner: ^2.12.2
flutter_gen_runner: # overrode

flutter_gen:
output: lib/gen/
assets:
enabled: true
outputs:
class_name: GalleryOneAssets

flutter:
assets:
- assets/images/
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading