-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: adding new config for assets * feat: asset generators * comments * feat: download assets and adjust generators, adjust brick smaller fixes * cleanup * feat: added package info to the AssetImage getters * fix: line length * refactor: address PR feedback * fix: test * linterlove * linterlove? --------- Co-authored-by: Jesper <[email protected]>
- Loading branch information
1 parent
ece37d3
commit ea4a3dd
Showing
26 changed files
with
947 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import 'dart:io'; | ||
|
||
import 'package:figmage/src/command_runner.dart'; | ||
import 'package:riverpod/riverpod.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
void main() { | ||
group('Asset download integration test', () { | ||
test( | ||
'downloads and generates assets from figma with config', | ||
() async { | ||
final dir = Directory('./asset_test_package')..createSync(); | ||
addTearDown(() => dir.deleteSync(recursive: true)); | ||
|
||
// Create figmage.yaml with asset configuration | ||
File('${dir.path}/figmage.yaml').writeAsStringSync(''' | ||
fileId: AxYhq1VnMWeq09C4otvoQx | ||
assets: | ||
generate: true | ||
nodes: | ||
"1:5": | ||
name: icon_one | ||
scales: [0.5, 1, 2] | ||
"1:48": | ||
name: icon_two | ||
"2001:89": | ||
name: icon_three | ||
scales: [100, 2, 3] | ||
'''); | ||
|
||
// Create container and command runner | ||
final container = ProviderContainer(); | ||
addTearDown(container.dispose); | ||
|
||
// Using the command runner to enable break points | ||
final commandRunner = FigmageCommandRunner(container); | ||
|
||
// Run the forge command directly | ||
final exitCode = await commandRunner.run([ | ||
'forge', | ||
'-t', | ||
Platform.environment['FIGMA_FREE_TOKEN']!, | ||
'-p', | ||
dir.path, | ||
]); | ||
|
||
expect(exitCode, 0); | ||
|
||
// Verify assets directory was created | ||
final assetsDir = Directory('${dir.path}/assets/'); | ||
expect( | ||
assetsDir.existsSync(), | ||
true, | ||
reason: 'Assets directory was not created', | ||
); | ||
|
||
// Verify assets file was generated | ||
final assetsFile = File('${dir.path}/lib/src/assets.dart'); | ||
expect( | ||
assetsFile.existsSync(), | ||
true, | ||
reason: 'Assets file was not generated', | ||
); | ||
|
||
// Verify specific assets were downloaded with correct scales | ||
final expectedFiles = [ | ||
'icon_one.png', | ||
'[email protected]', | ||
'[email protected]', | ||
'icon_two.png', | ||
]; | ||
|
||
final assetFiles = | ||
assetsDir.listSync().map((f) => f.path.split('/').last); | ||
for (final expectedFile in expectedFiles) { | ||
expect( | ||
assetFiles.contains(expectedFile), | ||
true, | ||
reason: 'Expected asset $expectedFile was not downloaded', | ||
); | ||
} | ||
|
||
// Verify the generated assets.dart file has correct content | ||
final assetsContent = assetsFile.readAsStringSync(); | ||
expect( | ||
assetsContent, | ||
contains('static const String iconOne05xPng = '), | ||
reason: 'Assets class missing iconOne constant', | ||
); | ||
expect( | ||
assetsContent, | ||
contains('static const String iconTwoPng = '), | ||
reason: 'Assets class missing iconTwo constant', | ||
); | ||
}, | ||
timeout: const Timeout( | ||
Duration(minutes: 1), | ||
), | ||
); | ||
}); | ||
} |
112 changes: 112 additions & 0 deletions
112
lib/src/data/generators/assets/asset_class_generator.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import 'package:code_builder/code_builder.dart'; | ||
import 'package:figmage/src/data/generators/generator_util.dart'; | ||
import 'package:figmage/src/domain/generators/theme_class_generator.dart'; | ||
|
||
/// {@template asset_class_generator} | ||
/// Generates a class for accessing Figma assets. | ||
/// Creates constants for asset paths and convenience getters for AssetImage | ||
/// instances. Supports assets with different scale factors through filename | ||
/// suffixes. | ||
/// {@endtemplate} | ||
class AssetClassGenerator implements ThemeClassGenerator { | ||
/// {@macro asset_class_generator} | ||
const AssetClassGenerator({ | ||
required this.className, | ||
required this.assets, | ||
required this.packageName, | ||
}); | ||
|
||
@override | ||
final String className; | ||
|
||
/// The successfully downloaded assets to generate code for. | ||
/// where each entry: key: id, value: assetNames | ||
final Map<String, List<String>> assets; | ||
|
||
/// The name of the package these assets belong to. | ||
final String packageName; | ||
|
||
@override | ||
bool get buildContextExtensionNullable => false; | ||
|
||
@override | ||
Class generateClass() { | ||
return Class( | ||
(b) { | ||
b | ||
..name = className | ||
..constructors.add( | ||
Constructor( | ||
(b) => b..constant = true, | ||
), | ||
) | ||
..annotations.add( | ||
refer('immutable', 'package:meta/meta.dart'), | ||
) | ||
..modifier = ClassModifier.final$ | ||
..fields.add( | ||
Field( | ||
(b) => b | ||
..name = '_basePath' | ||
..static = true | ||
..modifier = FieldModifier.constant | ||
..type = refer('String') | ||
..assignment = const Code("'assets/'"), | ||
), | ||
) | ||
..fields.addAll([ | ||
for (final MapEntry(key: id, value: assetNames) in assets.entries) | ||
...assetNames.map((asset) { | ||
final assetName = convertToValidVariableName(asset); | ||
return Field( | ||
(b) => b | ||
..name = assetName | ||
..static = true | ||
..modifier = FieldModifier.constant | ||
..type = refer('String') | ||
..assignment = Code("'\${_basePath}$asset'") | ||
..docs.add('/// Rendered from frame $id'), | ||
); | ||
}), | ||
]) | ||
..methods.addAll( | ||
assets.values.expand((values) { | ||
return values.map((asset) { | ||
final assetName = convertToValidVariableName(asset); | ||
|
||
return Method( | ||
(b) => b | ||
..name = '${assetName}Image' | ||
..static = true | ||
..type = MethodType.getter | ||
..returns = refer('AssetImage') | ||
..lambda = true | ||
..body = | ||
Code("AssetImage($assetName, package: '$packageName')"), | ||
); | ||
}); | ||
}), | ||
); | ||
}, | ||
); | ||
} | ||
|
||
@override | ||
Extension generateExtension() { | ||
return Extension( | ||
(b) => b | ||
..name = '${className}BuildContextX' | ||
..on = refer('BuildContext', 'package:flutter/widgets.dart') | ||
..methods.add( | ||
Method( | ||
(b) => b | ||
..name = className.toLowerCase() | ||
..type = MethodType.getter | ||
..returns = refer(className) | ||
..lambda = true | ||
..body = Code('$className()'), | ||
), | ||
), | ||
); | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
lib/src/data/generators/file_generators/asset_file_generator.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import 'package:code_builder/code_builder.dart'; | ||
import 'package:figmage/src/data/generators/assets/asset_class_generator.dart'; | ||
import 'package:figmage/src/domain/generators/file_generator.dart'; | ||
import 'package:figmage/src/domain/generators/theme_class_generator.dart'; | ||
import 'package:figmage_package_generator/figmage_package_generator.dart'; | ||
|
||
/// {@template asset_file_generator} | ||
/// A [FileGenerator] that generates a file for accessing Figma assets. | ||
/// {@endtemplate} | ||
class AssetFileGenerator implements FileGenerator { | ||
/// {@macro asset_file_generator} | ||
AssetFileGenerator({ | ||
required this.assets, | ||
required this.packageName, | ||
}); | ||
|
||
/// Map of node IDs to their downloaded asset file names. | ||
final Map<String, List<String>> assets; | ||
|
||
/// The name of the package these assets belong to. | ||
final String packageName; | ||
|
||
@override | ||
final TokenFileType type = TokenFileType.assets; | ||
|
||
@override | ||
late final Iterable<ThemeClassGenerator> generators = [ | ||
AssetClassGenerator( | ||
className: 'Assets', | ||
assets: assets, | ||
packageName: packageName, | ||
), | ||
]; | ||
|
||
@override | ||
Library generate() { | ||
final lib = LibraryBuilder(); | ||
lib.comments.addAll(FileGenerator.generatedFilePrefix); | ||
lib.body.addAll( | ||
[ | ||
for (final g in generators) ...[ | ||
g.generateClass(), | ||
g.generateExtension(), | ||
], | ||
], | ||
); | ||
return lib.build(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.