commit 3bfd3820eb56272158aab13b206ccb163bbb7853 Author: Gabriel Rohden Date: Wed Jun 3 09:28:01 2020 -0300 chore(sources): Initial commit files diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bb431f0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,75 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..616b046 --- /dev/null +++ b/.metadata @@ -0,0 +1,10 @@ +# 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: e6b34c2b5c96bb95325269a29a84e83ed8909b5f + channel: stable + +project_type: package diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..78d7dc9 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +## [0.0.1] - 03/06/2020 + +Initial release (not on pub.dev) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ba75c69 --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +TODO: Add your license here. diff --git a/README.md b/README.md new file mode 100644 index 0000000..0d9c0e8 --- /dev/null +++ b/README.md @@ -0,0 +1,89 @@ +# icomoon_selection_gen + +A simple source generator for icomoon selection.json file, +you can use it to generate a similar class as the `Icons` material class. + +## Not published + +I'm just making this open source so people can look at the code. + +### Why write it then? + +I was just trying to write a code generator and got this idea after +some "manual codegen", so I'm not planning to publish it on pub.dev, and +I'm kinda lazy to make the desired build flags work (see TODOs) + +### How to install then? + +Just ref this git repo on `pubspec.yaml` +```yaml +dev_dependencies: + ... + icomoon_selection_gen: + git: + url: git://github.com/Grohden/icomoon-selection-gen + ref: v0.0.1 +``` + +To keep it working and not get a surprising error, use the git tags/versions on url. + +## Usage + +I'm assuming you already know how to use icomoon. + +After you choose the place for your files (`selection.json` and `icomoon.ttf`) + +```yaml +# your pubspec probably has something like this: + fonts: + - family: Icomoon # this is the font_name prop for build.yaml + fonts: + - asset: lib/assets/icons/icomoon.ttf +``` + +Configure your `build.yaml` + +```yaml +targets: + $default: + builders: + icomoon_selection_gen: + generate_for: + - lib/assets/icons/selection.json + options: + font_name: Icomoon # same as the `family` prop in pubspec.yaml +``` + +If it's correctly configured, you can run the `flutter packages pub run build_runner build` +and you will get a file named `selection.dart` with a `Icomoon` class with static `IconData` like +this: + +```dart +class Icomoon { + Icomoon._(); + + static const _kFontFam = 'Icomoon'; + + // Names are the snake_case version of the original ones (the ones you've set on icomoon) + static const IconData my_icon = IconData(0xe941, fontFamily: _kFontFam); +} +``` + +so you can use it like: + +```dart +const myIcon = Icon(Icomoon.my_icon); +``` + +### TODO + +I may (and wish to) do these: + +* [x] support custom name for the .json file (you can only use selection.json as the name) + * [See `generate_for`](https://github.com/dart-lang/build/blob/master/build_config/README.md#configuring-builders-applied-to-your-package) +* [ ] support custom name for the generated file - (builder is confusing in this part) +* [ ] support for custom location for the generated file +* [ ] Try again `source_gen` to be able to support `ignore_for_file` - had problems + because `source_gen` is basically only for dart (not json) files +* [ ] Add test cases + \ No newline at end of file diff --git a/build.yaml b/build.yaml new file mode 100644 index 0000000..bcb5224 --- /dev/null +++ b/build.yaml @@ -0,0 +1,8 @@ +builders: + icomoon_selection_gen: + import: 'package:icomoon_selection_gen/builder.dart' + builder_factories: ['genFromJson'] + build_extensions: {".json": [".dart"]} + auto_apply: root_package + build_to: source + applies_builders: ["source_gen|combining_builder"] diff --git a/lib/builder.dart b/lib/builder.dart new file mode 100644 index 0000000..1046a4b --- /dev/null +++ b/lib/builder.dart @@ -0,0 +1,101 @@ +import 'dart:convert'; + +import 'package:build/build.dart'; +import 'package:code_builder/code_builder.dart'; +import 'package:dart_style/dart_style.dart'; +import 'package:meta/meta.dart'; +import 'package:recase/recase.dart'; + +import 'models.dart'; + +final _dartfmt = DartFormatter(); + +Builder genFromJson(BuilderOptions options) { + final parsedOptions = GeneratorOptions.fromOptions(options); + + return IcomoonBuilder(parsedOptions); +} + +class GeneratorOptions { + GeneratorOptions({ + @required this.fontName, + @required this.selectionJsonPath, + }); + + factory GeneratorOptions.fromOptions(BuilderOptions options) { + final config = options.config; + + assert( + config['font_name'] != null, + 'fontName must not be null', + ); + + return GeneratorOptions( + fontName: config['font_name'] as String, + selectionJsonPath: config['selection_json_path'] as String, + ); + } + + final String fontName; + final String selectionJsonPath; +} + +class IcomoonBuilder implements Builder { + IcomoonBuilder(this.options); + + final GeneratorOptions options; + + @override + Future build(BuildStep buildStep) async { + final inputId = buildStep.inputId; + + final contents = await buildStep.readAsString(inputId); + final selection = SelectionModel.fromJson( + jsonDecode(contents) as Map, + ); + + final fields = selection.icons.map((icon) { + final props = icon.properties; + final code = props.code.toRadixString(16); + final name = ReCase(props.name).snakeCase; + + return Field((b) => b + ..name = name + ..static = true + ..modifier = FieldModifier.constant + ..type = refer('IconData', 'package:flutter/widgets.dart') + ..assignment = Code('IconData(0x$code, fontFamily: _kFontFam)')); + }); + + final icomoonClass = Class((b) => b + ..name = 'Icomoon' + ..constructors.add(Constructor((b) => b..name = '_')) + ..fields.add(Field( + (b) => b + ..name = '_kFontFam' + ..static = true + ..modifier = FieldModifier.constant + ..assignment = Code("'${options.fontName}'"), + )) + ..fields.addAll(fields)); + final content = Library( + (b) => b.body..add(icomoonClass), + ).accept(DartEmitter(Allocator())); + + await buildStep.writeAsString( + buildStep.inputId.changeExtension('.dart'), + _dartfmt.format(''' + // Generated by icomoon_selection_gen, do not modify by hand + + // ignore_for_file: constant_identifier_names + + $content + '''), + ); + } + + @override + Map> get buildExtensions => { + '.json': ['.dart'] + }; +} diff --git a/lib/models.dart b/lib/models.dart new file mode 100644 index 0000000..68ccc0f --- /dev/null +++ b/lib/models.dart @@ -0,0 +1,44 @@ +import 'package:meta/meta.dart'; + +class SelectionModel { + SelectionModel({ + @required this.icons, + }); + + factory SelectionModel.fromJson(Map json) { + final icons = json['icons'] as List; + + return SelectionModel( + icons: icons + .map((icon) => IcomoonIcon.fromJson(icon as Map)) + .toList()); + } + + final List icons; +} + +class IcomoonIcon { + IcomoonIcon({@required this.properties}); + + factory IcomoonIcon.fromJson(Map json) { + final properties = json['properties'] as Map; + + return IcomoonIcon(properties: IconProperties.fromJson(properties)); + } + + final IconProperties properties; +} + +class IconProperties { + IconProperties({@required this.name, @required this.code}); + + factory IconProperties.fromJson(Map json) { + return IconProperties( + name: json['name'] as String, + code: json['code'] as int, + ); + } + + final String name; + final int code; +} diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..2675a9e --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,509 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "0.39.8" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.0" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.1" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + build: + dependency: "direct main" + description: + name: build + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + build_config: + dependency: "direct main" + description: + name: build_config + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.2" + build_daemon: + dependency: transitive + description: + name: build_daemon + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.4" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.9" + build_runner: + dependency: "direct dev" + description: + name: build_runner + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + url: "https://pub.dartlang.org" + source: hosted + version: "5.2.0" + build_test: + dependency: "direct dev" + description: + name: build_test + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.12+1" + built_collection: + dependency: transitive + description: + name: built_collection + url: "https://pub.dartlang.org" + source: hosted + version: "4.3.2" + built_value: + dependency: transitive + description: + name: built_value + url: "https://pub.dartlang.org" + source: hosted + version: "7.1.0" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.3" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + code_builder: + dependency: "direct main" + description: + name: code_builder + url: "https://pub.dartlang.org" + source: hosted + version: "3.3.0" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.14.12" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + coverage: + dependency: transitive + description: + name: coverage + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.9" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.4" + csslib: + dependency: transitive + description: + name: csslib + url: "https://pub.dartlang.org" + source: hosted + version: "0.16.1" + dart_style: + dependency: "direct main" + description: + name: dart_style + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.6" + fixnum: + dependency: transitive + description: + name: fixnum + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.11" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + graphs: + dependency: transitive + description: + name: graphs + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0" + html: + dependency: transitive + description: + name: html + url: "https://pub.dartlang.org" + source: hosted + version: "0.14.0+3" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.1" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.4" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.4" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.1+1" + json_annotation: + dependency: transitive + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "0.11.4" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.6" + meta: + dependency: "direct main" + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.8" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.6+3" + multi_server_socket: + dependency: transitive + description: + name: multi_server_socket + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + node_interop: + dependency: transitive + description: + name: node_interop + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + node_io: + dependency: transitive + description: + name: node_io + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + node_preamble: + dependency: transitive + description: + name: node_preamble + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.9" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" + package_resolver: + dependency: transitive + description: + name: package_resolver + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.10" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.4" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.0" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.0" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.4" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.5" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.3" + recase: + dependency: "direct main" + description: + name: recase + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "0.7.5" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + shelf_static: + dependency: transitive + description: + name: shelf_static + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.8" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.3" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + source_maps: + dependency: transitive + description: + name: source_maps + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.9" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + stream_transform: + dependency: transitive + description: + name: stream_transform + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + test: + dependency: transitive + description: + name: test + url: "https://pub.dartlang.org" + source: hosted + version: "1.14.6" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.16" + test_core: + dependency: transitive + description: + name: test_core + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.6" + timing: + dependency: transitive + description: + name: timing + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.1+2" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + vm_service: + dependency: transitive + description: + name: vm_service + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.4" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.7+15" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + url: "https://pub.dartlang.org" + source: hosted + version: "0.7.3" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.1" +sdks: + dart: ">=2.7.0 <3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..45fa048 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,21 @@ +name: icomoon_selection_gen +description: A code generator for flutter that reads icomoon selection.json and generate the icon classes +version: 0.0.1 +author: Gabriel Rohden +homepage: + +environment: + sdk: ">=2.7.0 <3.0.0" + +dependencies: + meta: ^1.1.7 + build: ^1.1.4 + build_config: ^0.4.0 + recase: ^2.0.1 + code_builder: ^3.3.0 + dart_style: ^1.0.0 + +dev_dependencies: + build_runner: ^1.5.0 + build_test: ^0.10.7+3 +