Skip to content

Commit

Permalink
Make locations of output files configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
Pante committed Jun 17, 2024
1 parent a9cf1c7 commit 192fff4
Show file tree
Hide file tree
Showing 21 changed files with 349 additions and 235 deletions.
5 changes: 5 additions & 0 deletions nitrogen/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.3.0
* Add configuration for output locations.
* Move configuration from `pubspec.yaml` to `build.yaml`.
* Remove generation of `flutter_extension`.

## 0.2.0
* Add `flutter-extension` option.
* Change `file` asset key option to `file-name`.
Expand Down
51 changes: 34 additions & 17 deletions nitrogen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ Widget build(BuildContext context) => Assets.images.foo();

## Getting started

3rd party packages are supported via 'extension' packages. `extension` packages generate `extension`s in separate files.
These `extension`s provide a `call(...)` function that transforms an `Asset` into a 3rd party type.
3rd party packages are supported via 'extension' packages. `extension` packages contain an `extension` that provide a
`call(...)` function that transforms an `Asset` into a 3rd party type.

| Type | Package | Extension Package | Version | Default generated file |
|-------------------|---------------|------------------------|----------------------------------------------------------------------------------------------------------------|----------------------------------|
| SVG images | `flutter_svg` | `nitrogen_flutter_svg` | [![Pub Dev](https://img.shields.io/pub/v/nitrogen_flutter_svg)](https://pub.dev/packages/nitrogen_flutter_svg) | `svg_extension.nitrogen.dart` |
| Lottie animations | `lottie` | `nitrogen_lottie` | [![Pub Dev](https://img.shields.io/pub/v/nitrogen_lottie)](https://pub.dev/packages/nitrogen_lottie) | `lottie_extension.nitrogen.dart` |
| Type | Package | Extension Package | Version |
|-------------------|---------------|------------------------|----------------------------------------------------------------------------------------------------------------|
| SVG images | `flutter_svg` | `nitrogen_flutter_svg` | [![Pub Dev](https://img.shields.io/pub/v/nitrogen_flutter_svg)](https://pub.dev/packages/nitrogen_flutter_svg) |
| Lottie animations | `lottie` | `nitrogen_lottie` | [![Pub Dev](https://img.shields.io/pub/v/nitrogen_lottie)](https://pub.dev/packages/nitrogen_lottie) |


Install the following:
Expand Down Expand Up @@ -72,19 +72,26 @@ dart run build_runner build

## Configuration

Nitrogen's configuration can be set in the `nitrogen` section of your pubspec.yaml. In most cases, the default
Nitrogen's configuration can be set in the `nitrogen` section of your build.yaml. In most cases, the default
configuration works out of the box.

### Example

A simple configuration looks like:
```yaml
nitrogen:
package: true
prefix: 'MyPrefix'
key: file
themes:
fallback: assets/themes/light
targets:
$default:
builders:
nitrogen:
options:
package: true
prefix: 'MyPrefix'
key: file-name
assets:
output: 'lib/src/assets.nitrogen.dart'
themes:
output: 'lib/src/asset_themes.nitrogen.dart'
fallback: assets/themes/light
```
### `package`
Expand Down Expand Up @@ -115,15 +122,25 @@ Optional. Defaults to `file`. Controls the generated assets' key parameters. The
| file-name | file name, without the extension | `assets/images/foo.png` | `foo` |
| grpc-enum | parent directory and file name, without the extension | `assets/images/foo.png` | `IMAGES_FOO` |

### `assets`

Optional. Controls the location of the generated assets file.

```yaml
assets:
# Path to the generated assets file. Relative to the project root. Defaults to `lib/src/assets.nitrogen.dart`.
output: lib/src/my/path/assets.nitrogen.dart
```
### `themes`

Optional. Defaults to `null`. Controls whether to generate an additional `asset_themes.nitrogen.dart` file. Useful for
working with theme-specific assets.

```yaml
nitrogen:
themes:
# Path to fallback theme, relative to package root. Assumes that all themes are under 'assets/themes'.
fallback: assets/themes/light
themes:
# Path to the generated themes file. Relative to the project root. Defaults to `lib/src/asset_themes.nitrogen.dart`.
output: lib/src/my/path/assets_themes.nitrogen.dart
# Path to fallback theme, relative to package root. Assumes that all themes are under 'assets/themes'.
fallback: assets/themes/light
```
11 changes: 10 additions & 1 deletion nitrogen/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ builders:
nitrogen:
import: "package:nitrogen/nitrogen.dart"
builder_factories: [ "nitrogenBuilder" ]
build_extensions: { "$package$": [ "lib/src/assets.nitrogen.dart", "lib/src/asset_themes.nitrogen.dart", "lib/src/flutter_extension.nitrogen.dart"] }
build_extensions: { "$package$": [ "lib/src/assets.nitrogen.dart", "lib/src/asset_themes.nitrogen.dart" ] }
defaults:
options:
package: false
prefix: ""
key: "file-name"
assets:
output: "lib/src/assets.nitrogen.dart"
themes:
output: "lib/src/asset_themes.nitrogen.dart"
auto_apply: dependents
build_to: source
45 changes: 34 additions & 11 deletions nitrogen/lib/nitrogen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,45 @@ import 'dart:async';

import 'package:build/build.dart';
import 'package:glob/glob.dart';
import 'package:path/path.dart';
import 'package:yaml/yaml.dart';

import 'package:nitrogen/src/configuration/build_configuration.dart';
import 'package:nitrogen/src/configuration/configuration.dart';
import 'package:nitrogen/src/file_system.dart';
import 'package:nitrogen/src/generators/asset_generator.dart';
import 'package:nitrogen/src/generators/theme_generator.dart';
import 'package:nitrogen/src/lints/reserved_keyword_lint.dart';
import 'package:nitrogen/src/nitrogen_exception.dart';
import 'package:nitrogen/src/walker.dart';
import 'package:path/path.dart';
import 'package:yaml/yaml.dart';

/// Creates a [NitrogenBuilder].
Builder nitrogenBuilder(BuilderOptions options) => NitrogenBuilder();
Builder nitrogenBuilder(BuilderOptions options) {
try {
BuildConfiguration.lint(options.config);
return NitrogenBuilder(BuildConfiguration.parse(options.config));

} on NitrogenException {
return EmptyBuilder();
}
}

/// A Nitrogen builder.
class NitrogenBuilder extends Builder {

static final _pubspec = Glob('pubspec.yaml');
static final _assets = Glob('assets/**');

final BuildConfiguration _configuration;

/// Creates a [NitrogenBuilder].
NitrogenBuilder(this._configuration);

@override
FutureOr<void> build(BuildStep buildStep) async {
try {
final pubspec = loadYaml(await buildStep.readAsString(await buildStep.findAssets(_pubspec).first));

Configuration.lint(pubspec);
final configuration = Configuration.parse(pubspec);
final configuration = Configuration.merge(_configuration, pubspec);

final walker = Walker(configuration.package, configuration.flutterAssets, configuration.key.call);

Expand All @@ -38,8 +51,8 @@ class NitrogenBuilder extends Builder {

lintReservedKeyword(assets);

final assetsOutput = AssetId(buildStep.inputId.package, join('lib', 'src', 'assets.nitrogen.dart'));
if (configuration.fallbackTheme case final fallback?) {
final assetsOutput = AssetId(buildStep.inputId.package, configuration.assets.output);
if (configuration.themes case (:final fallback, :final output)) {
var themes = assets;
var fallbackTheme = assets;
for (final segment in split(fallback).skip(1)) {
Expand All @@ -53,7 +66,7 @@ class NitrogenBuilder extends Builder {
);

await buildStep.writeAsString(
AssetId(buildStep.inputId.package, join('lib', 'src', 'asset_themes.nitrogen.dart')),
AssetId(buildStep.inputId.package, output),
ThemeGenerator(configuration.prefix, themes, fallbackTheme).generate(),
);

Expand All @@ -72,9 +85,19 @@ class NitrogenBuilder extends Builder {
@override
Map<String, List<String>> get buildExtensions => {
r'$package$': [
'lib/src/assets.nitrogen.dart',
'lib/src/asset_themes.nitrogen.dart',
_configuration.assets.output,
if (_configuration.themes != null)
_configuration.themes!.output,
],
};

}

/// A stub builder for when Nitrogen fails to build.
class EmptyBuilder extends Builder {
@override
void build(BuildStep buildStep) {}

@override
Map<String, List<String>> get buildExtensions => {};
}
92 changes: 92 additions & 0 deletions nitrogen/lib/src/configuration/build_configuration.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import 'package:build/build.dart';
import 'package:meta/meta.dart';

import 'package:nitrogen/src/configuration/key.dart';
import 'package:nitrogen/src/nitrogen_exception.dart';

/// Nitrogen's build.yaml configuration.
final class BuildConfiguration {

/// The Nitrogen configuration's valid keys.
static const keys = { 'package', 'prefix', 'key', 'assets', 'themes' };

/// Lints the pubspec.
static void lint(Map<dynamic, dynamic> configuration) {
for (final key in {...configuration.keys }..removeAll(keys)) {
log.warning('Unknown key, "$key", in build.yaml\'s nitrogen configuration. See https://github.com/forus-labs/cauldron/tree/master/nitrogen#configuration for valid configuration options.');
}

final assets = configuration['assets'] as Map;
for (final key in {...assets.keys }..removeAll({ 'output' })) {
log.warning('Unknown key, "$key", in build.yaml\'s nitrogen assets configuration. See https://github.com/forus-labs/cauldron/tree/master/nitrogen#assets for valid configuration options.');
}

final themes = configuration['themes'] as Map;
for (final key in {...themes.keys }..removeAll({ 'fallback', 'output' })) {
log.warning('Unknown key, "$key", in build.yaml\'s nitrogen themes configuration. See https://github.com/forus-labs/cauldron/tree/master/nitrogen#themes for valid configuration options.');
}
}

/// Parses the assets configuration.
@visibleForTesting
static ({String output,}) parseAssets(Map<dynamic, dynamic> configuration) {
switch (configuration) {
case { 'output': final String output }:
return (output: output);

default:
log.severe("Unable to read assets configuration in build.yaml's nitrogen configuration. See https://github.com/forus-labs/cauldron/tree/master/nitrogen#assets.");
throw NitrogenException();
}
}

/// Parses the themes configuration.
@visibleForTesting
static ({String fallback, String output})? parseThemes(Map<dynamic, dynamic> configuration) {
switch (configuration) {
case { 'fallback': final String fallback, 'output': final String output }:
return (fallback: fallback, output: output);

case { 'output': String _ }:
return null;

default:
log.severe("Unable to read themes configuration in build.yaml's nitrogen configuration. See https://github.com/forus-labs/cauldron/tree/master/nitrogen#themes.");
throw NitrogenException();
}
}

/// Whether to generate assets for a package.
final bool package;

/// The prefix for generated classes.
final String prefix;

/// The function for generating asset keys.
final String Function(List<String>) key;

/// The output location of the generated assets.
final ({String output,}) assets;

/// The fallback theme and output location of the generated themes.
final ({String fallback, String output})? themes;

/// Parses the build configuration.
factory BuildConfiguration.parse(Map<dynamic, dynamic> configuration) => BuildConfiguration(
package: configuration['package'],
prefix: configuration['prefix'],
key: Key.parse(configuration['key']),
assets: parseAssets(configuration['assets']),
themes: parseThemes(configuration['themes']),
);

/// Creates a [BuildConfiguration].
BuildConfiguration({
required this.package,
required this.prefix,
required this.key,
required this.assets,
required this.themes,
});

}
Loading

0 comments on commit 192fff4

Please sign in to comment.