Skip to content

Commit 21f3523

Browse files
committed
feat: add support for use in packages
1 parent 3cb3214 commit 21f3523

File tree

6 files changed

+160
-44
lines changed

6 files changed

+160
-44
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.3.0
2+
3+
- Add support for use in packages.
4+
15
## 0.2.1
26

37
- Update README.md file to reflect previous changes and be more concise.

README.md

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# Fontsource for Flutter
22

3-
Add Fontsource fonts to your flutter app. Direct access to Fontsource API.
3+
Easily add Fontsource fonts to your flutter app. Also includes a dart interface for the Fontsource API.
44

55
## Getting started
66

77
To start, create a config in either your `pubspec.yaml` file under the `fontsource` key or in the `fontsource.yaml` file.
88

99
```yaml
10+
include: [my-package] # Defaults to all
1011
fonts:
1112
alex-brush: # This can be any font id
1213
version: 4.5.3 # Defaults to latest
@@ -23,7 +24,7 @@ You can then import the `fontsource` package:
2324
import 'package:fontsource/fontsource.dart';
2425
```
2526

26-
Use [`FontsourceTextStyle`](https://pub.dev/documentation/fontsource/latest/fontsource/FontsourceTextStyle-class.html) to use a Fontsource font:
27+
Use the [`FontsourceTextStyle`](https://pub.dev/documentation/fontsource/latest/fontsource/FontsourceTextStyle-class.html) class to use a Fontsource font:
2728

2829
```dart
2930
const Text(
@@ -32,7 +33,13 @@ const Text(
3233
),
3334
```
3435

35-
[`FontsourceTextStyle`](https://pub.dev/documentation/fontsource/latest/fontsource/FontsourceTextStyle-class.html) extends the `TextStyle` class, so any styling properties can be used to change the way the text looks.
36+
[`FontsourceTextStyle`](https://pub.dev/documentation/fontsource/latest/fontsource/FontsourceTextStyle-class.html) extends the [`TextStyle`](https://api.flutter.dev/flutter/painting/TextStyle-class.html) class, so any styling properties can be used to change the way the text looks.
37+
38+
## Use With Packages
39+
40+
To use this in a package, add a configuration like normal, but don't run the fontsource cli.
41+
42+
Packages with a fontsource configuration will automatically be included. To manually specify what packages should be scanned, provide an `include` key with a list of package names to scan.
3643

3744
## Fontsource API
3845

example/pubspec.lock

+8-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ packages:
8080
path: ".."
8181
relative: true
8282
source: path
83-
version: "0.2.1"
83+
version: "0.3.0"
8484
fontsource_gen:
8585
dependency: "direct main"
8686
description:
@@ -205,6 +205,13 @@ packages:
205205
url: "https://pub.dartlang.org"
206206
source: hosted
207207
version: "2.1.1"
208+
version:
209+
dependency: transitive
210+
description:
211+
name: version
212+
url: "https://pub.dartlang.org"
213+
source: hosted
214+
version: "2.0.0"
208215
yaml:
209216
dependency: transitive
210217
description:

lib/src/cli/config.dart

+135-38
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1+
import 'dart:convert';
12
import 'dart:io';
3+
24
import 'package:fontsource/api.dart';
5+
import 'package:path/path.dart' as path;
6+
import 'package:version/version.dart';
37
import 'package:yaml/yaml.dart';
48

5-
import '../utils.dart';
6-
79
class FontConfig {
8-
List<String> subsets;
9-
List<int> weights;
10-
List<String> styles;
10+
Set<String> subsets;
11+
Set<int> weights;
12+
Set<String> styles;
1113
FontMetadata metadata;
1214
String? version;
1315
FontConfig(this.subsets, this.weights, this.styles, this.metadata,
1416
[this.version]);
1517
@override
1618
String toString() {
17-
return '{subsets: $subsets, weights: $weights, styles: $styles}';
19+
return '{subsets: $subsets, weights: $weights, styles: $styles, version: $version}';
1820
}
1921
}
2022

@@ -27,90 +29,185 @@ class FontsourceConfig {
2729
}
2830
}
2931

30-
Future<FontsourceConfig> getConfig() async {
31-
dynamic configYaml;
32+
late FontsourceConfig _config;
33+
late Set<String> _scannedPackages;
34+
Map<String, String>? _packageSources;
35+
36+
Future<void> _resolve(String dir, [bool isRoot = false]) async {
37+
Map configMap;
38+
Set<String> dependencies = {};
39+
3240
try {
33-
File fontsourceFile = File(cwdJoin('fontsource.yaml'));
34-
if (fontsourceFile.existsSync()) {
35-
String fontsourceFileString = fontsourceFile.readAsStringSync();
41+
late YamlMap configYaml;
42+
bool configFound = false;
43+
44+
File pubspecFile = File(path.join(dir, 'pubspec.yaml'));
45+
if (pubspecFile.existsSync()) {
46+
YamlMap pubspecYaml = loadYaml(pubspecFile.readAsStringSync());
3647

37-
if (fontsourceFileString.isNotEmpty) {
38-
configYaml = loadYaml(fontsourceFileString);
48+
if (pubspecYaml.containsKey('fontsource')) {
49+
configYaml = pubspecYaml['fontsource'] ?? YamlMap();
50+
configFound = true;
51+
}
52+
53+
if (pubspecYaml['dependencies'] != null) {
54+
dependencies = (pubspecYaml['dependencies'] as YamlMap)
55+
.keys
56+
.toSet()
57+
.cast<String>();
3958
}
4059
}
41-
if (configYaml == null) {
42-
File pubspecFile = File(cwdJoin('pubspec.yaml'));
4360

44-
if (pubspecFile.existsSync()) {
45-
dynamic pubspecYaml = loadYaml(pubspecFile.readAsStringSync());
61+
if (!configFound) {
62+
File fontsourceFile = File(path.join(dir, 'fontsource.yaml'));
63+
if (fontsourceFile.existsSync()) {
64+
String fontsourceFileString = fontsourceFile.readAsStringSync();
4665

47-
if (pubspecYaml['fontsource'] != null) {
48-
configYaml = pubspecYaml['fontsource'];
49-
}
66+
configYaml = loadYaml(fontsourceFileString) ?? {};
67+
configFound = true;
5068
}
5169
}
52-
if (configYaml == null) throw Exception();
70+
71+
if (!configFound) throw Exception();
72+
73+
configMap = configYaml;
5374
} catch (e) {
54-
throw Exception('Fontsource config not found.');
75+
if (isRoot) {
76+
throw Exception('Fontsource config not found.');
77+
} else {
78+
return;
79+
}
80+
}
81+
82+
for (var key in configMap.keys) {
83+
if (key != 'include' && key != 'fonts') {
84+
throw Exception('Unknown key in configuration: $key');
85+
}
86+
}
87+
Set<String> include =
88+
(configMap['include'] == null || configMap['include'] == 'all'
89+
? dependencies
90+
: (configMap['include'] as YamlList).toSet().cast<String>());
91+
92+
if (include.isNotEmpty) {
93+
if (_packageSources == null) {
94+
final packageConfig =
95+
jsonDecode(File('.dart_tool/package_config.json').readAsStringSync());
96+
97+
if (packageConfig['configVersion'] != 2) {
98+
throw Exception(
99+
'Unknown package_config.json version: ${packageConfig['configVersion']}');
100+
}
101+
102+
_packageSources = {};
103+
104+
for (var package in (packageConfig['packages'] as List)) {
105+
var packagePath = path.fromUri(package['rootUri']);
106+
_packageSources![package['name']] = path.isRelative(packagePath)
107+
? (path.normalize(path.join('.dart_tool', packagePath)))
108+
: (package['rootUri']);
109+
}
110+
}
111+
112+
for (var package in include) {
113+
if (!_scannedPackages.contains(package)) {
114+
await _resolve(_packageSources![package] as String);
115+
}
116+
}
55117
}
56118

57-
Map configMap = configYaml;
58119
Map fontsMap = configMap['fonts'] ?? {};
59-
final config = FontsourceConfig({});
60120
await Future.wait(fontsMap.keys.map((id) async {
61121
FontMetadata metadata;
62122
try {
63-
metadata = (await listFontMetadata(id: id))[0];
123+
metadata = (_config.fonts[id]?.metadata == null)
124+
? (await listFontMetadata(id: id)).first
125+
: _config.fonts[id]!.metadata;
64126
} catch (e) {
65127
throw Exception('Font $id not found.');
66128
}
67129

68-
List<String> subsets;
69-
List<int> weights;
70-
List<String> styles;
130+
Set<String> subsets;
131+
Set<int> weights;
132+
Set<String> styles;
133+
71134
if (fontsMap[id]?['subsets'] == null || fontsMap[id]['subsets'] == 'all') {
72-
subsets = metadata.subsets;
135+
subsets = metadata.subsets.toSet();
73136
} else {
74137
subsets = (fontsMap[id]['subsets'] as YamlList)
75138
.map((subset) => subset as String)
76-
.toList();
139+
.toSet();
77140
for (var subset in subsets) {
78141
if (!metadata.subsets.contains(subset)) {
79142
throw Exception(
80143
'Subset $subset not found in font ${metadata.family}');
81144
}
82145
}
83146
}
147+
84148
if (fontsMap[id]?['weights'] == null || fontsMap[id]['weights'] == 'all') {
85-
weights = metadata.weights;
149+
weights = metadata.weights.toSet();
86150
} else {
87151
weights = (fontsMap[id]['weights'] as YamlList)
88152
.map((weight) => weight as int)
89-
.toList();
153+
.toSet();
90154
for (var weight in weights) {
91155
if (!metadata.weights.contains(weight)) {
92156
throw Exception(
93157
'Weight $weight not found in font ${metadata.family}');
94158
}
95159
}
96160
}
97-
if (fontsMap[id]?['weights'] == null || fontsMap[id]['styles'] == 'all') {
98-
styles = metadata.styles;
161+
162+
if (fontsMap[id]?['styles'] == null || fontsMap[id]['styles'] == 'all') {
163+
styles = metadata.styles.toSet();
99164
} else {
100165
styles = (fontsMap[id]['styles'] as YamlList)
101166
.map((style) => style as String)
102-
.toList();
167+
.toSet();
103168
for (var style in styles) {
104169
if (!metadata.styles.contains(style)) {
105170
throw Exception('Style $style not found in font ${metadata.family}');
106171
}
107172
}
108173
}
174+
109175
String? version = fontsMap[id]?['version'];
110176
if (version == 'latest') version = null;
111-
config.fonts[id] = FontConfig(
112-
subsets, weights, styles, metadata, fontsMap[id]?['version']);
177+
178+
if (_config.fonts[id] == null) {
179+
_config.fonts[id] = FontConfig(
180+
subsets, weights, styles, metadata, fontsMap[id]?['version']);
181+
} else {
182+
_config.fonts[id]?.subsets.addAll(subsets);
183+
_config.fonts[id]?.weights.addAll(weights);
184+
_config.fonts[id]?.styles.addAll(styles);
185+
186+
// Give latest specified version from all packages unless root specifies.
187+
if (isRoot) {
188+
_config.fonts[id]?.version = fontsMap[id]?['version'];
189+
} else {
190+
if (_config.fonts[id]?.version != null) {
191+
if (fontsMap[id]?['version'] == null) {
192+
_config.fonts[id]?.version = null;
193+
} else {
194+
if (Version.parse(fontsMap[id]?['version']) >
195+
Version.parse(_config.fonts[id]?.version)) {
196+
_config.fonts[id]?.version = fontsMap[id]?['version'];
197+
}
198+
}
199+
}
200+
}
201+
}
113202
}));
203+
}
204+
205+
Future<FontsourceConfig> getConfig() async {
206+
_config = FontsourceConfig({});
207+
208+
_scannedPackages = {};
209+
210+
await _resolve(Directory.current.path, true);
114211

115-
return config;
212+
return _config;
116213
}

lib/src/cli/gen_fonts.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import 'dart:io';
22

3-
import 'package:fontsource/src/utils.dart';
43
import 'package:json2yaml/json2yaml.dart';
54
import 'package:progress_bar/progress_bar.dart';
65

76
import '../../api.dart';
7+
import '../utils.dart';
88
import 'config.dart';
99

1010
final _genPackagePath = cwdJoin('.fontsource');

pubspec.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: fontsource
22
description: Add Fontsource fonts to your flutter app. Direct access to Fontsource API.
3-
version: 0.2.1
3+
version: 0.3.0
44
repository: https://github.com/fontsource/fontsource-flutter
55

66
environment:
@@ -14,6 +14,7 @@ dependencies:
1414
json2yaml: ^3.0.0
1515
path: ^1.8.0
1616
progress_bar: ^1.0.0
17+
version: ^2.0.0
1718
yaml: ^3.1.0
1819

1920
dev_dependencies:

0 commit comments

Comments
 (0)