Skip to content

Commit 3820422

Browse files
authored
Adapt package:messages to be loading mechanism independent (#843)
* Squashed commit * Add newline * Add g.dart files to generated * Upgrade to dart:asset * Add changelogs * Add wip * Run tests only on dev * Add logger * Update examples * Do not use dart:asset * Use a dart run script instead of hooks * Also output code in dart run * Adapt workflow * Fixes * Add licenses * typo * Fix issues * Sort on key * Refactor to list * Sort * Clean ups * sort deps * Changelog * Remove build_runner remaisn * Delete old examples * Add new examples * Fix flutter specific package loading * Fix zero word case * Switch to flutter in wf * Fix CI * Setup flutter * use dart not flutter * do not check flutter examples * Changes as per review * Update CI sha * Use main channel * use beta channel * Use new CI tool * Rename * Add licenses * Use dart run messages again
1 parent c878218 commit 3820422

File tree

95 files changed

+1724
-653
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+1724
-653
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
pkgs/intl4x/lib/src/bindings/* linguist-generated=true
2+
pkgs/intl4x/**/*.g.dart linguist-generated=true

.github/workflows/messages.yml

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,28 +21,34 @@ jobs:
2121
defaults:
2222
run:
2323
working-directory: pkgs/messages
24-
strategy:
25-
matrix:
26-
sdk: [stable, dev] # {pkgs.versions}
27-
dependencies: [path, published]
28-
include:
29-
- sdk: stable
30-
run-tests: true
3124

3225
steps:
3326
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
34-
- uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672
27+
28+
- uses: flutter-actions/setup-flutter@61f93c6f11e0234fa9ec4df59362c9699b979660
3529
with:
36-
sdk: ${{matrix.sdk}}
30+
channel: beta
31+
32+
- run: dart pub get
3733

3834
- run: dart pub get
35+
working-directory: pkgs/messages/example
3936

40-
- run: (cd example_json; dart pub get)
37+
- run: flutter pub get
38+
working-directory: pkgs/messages/examples_flutter/my_application
39+
40+
- run: flutter pub get
41+
working-directory: pkgs/messages/examples_flutter/my_shopping_cart
4142

4243
- run: dart analyze --fatal-infos
4344

4445
- run: dart format --output=none --set-exit-if-changed .
45-
if: ${{matrix.run-tests}}
4646

4747
- run: dart test
48-
if: ${{matrix.run-tests}}
48+
49+
- name: Regenerate and run example
50+
working-directory: pkgs/messages/example
51+
run: |
52+
dart run messages
53+
git diff --exit-code
54+
dart run

.github/workflows/messages_builder.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ jobs:
2323
working-directory: pkgs/messages_builder
2424
strategy:
2525
matrix:
26-
sdk: [stable, dev] # {pkgs.versions}
26+
sdk: [dev]
2727
include:
28-
- sdk: stable
28+
- sdk: dev
2929
run-tests: true
3030
steps:
3131
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9

.github/workflows/messages_serializer.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ jobs:
2323
working-directory: pkgs/messages_serializer
2424
strategy:
2525
matrix:
26-
sdk: [stable, dev] # {pkgs.versions}
26+
sdk: [dev]
2727
include:
28-
- sdk: stable
28+
- sdk: dev
2929
run-tests: true
3030
steps:
3131
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9

.github/workflows/messages_shrinker.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ jobs:
2323
working-directory: pkgs/messages_shrinker
2424
strategy:
2525
matrix:
26-
sdk: [stable, dev] # {pkgs.versions}
26+
sdk: [dev]
2727
include:
28-
- sdk: stable
28+
- sdk: dev
2929
run-tests: true
3030
steps:
3131
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9

pkgs/messages/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.3.0-wip
2+
3+
- Adapt to output data files to assets.
4+
15
## 0.2.0
26

37
- Remove `IntlObject` interface.

pkgs/messages/README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,9 @@ The `builder` to generate the named methods and data files from the input `arb`
3434
The logic for serializing `arb` message files into data files.
3535

3636
## Example
37-
Add `package:messages` and `package:messages_builder` to your dependencies:
37+
Add `package:messages` to your dependencies:
3838
```bash
3939
dart pub add messages
40-
dart pub add dev:messages_builder
4140
```
4241

4342
Given translation message files in two languages:
@@ -68,7 +67,7 @@ This translated file was created by a translator given the reference `en.arb`.
6867
```
6968
you can then run
7069

71-
`dart run build_runner build -d`
70+
`dart run messages`
7271

7372
This will generate both code to call your messages, as well as data files which will be shipped with your application. You can then use these generated files by importing the generated files:
7473

@@ -105,4 +104,4 @@ package_options:
105104
// multi
106105
// line
107106
// header
108-
```
107+
```

pkgs/messages/bin/messages.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:io';
6+
7+
Future<void> main(List<String> args) async {
8+
final runBuilder = await Process.run('dart', ['run', 'messages_builder']);
9+
stdout.write(runBuilder.stdout as String);
10+
11+
final runBuilderStdErr = runBuilder.stderr as String;
12+
final messagesBuilderNotInDeps =
13+
runBuilderStdErr.contains('Could not find package `messages_builder`');
14+
if (messagesBuilderNotInDeps) {
15+
print('Adding `package:messages_builder` to dev dependencies...');
16+
final addBuilder = await runDart(['pub', 'add', 'dev:messages_builder']);
17+
if (addBuilder.exitCode == 0) {
18+
print('Re-running message generation');
19+
await runDart(['run', 'messages_builder']);
20+
}
21+
} else {
22+
stderr.write(runBuilderStdErr);
23+
}
24+
}
25+
26+
Future<ProcessResult> runDart(List<String> arguments) async {
27+
final processResult = await Process.run('dart', arguments);
28+
stdout.write(processResult.stdout as String);
29+
stderr.write(processResult.stderr as String);
30+
return processResult;
31+
}

pkgs/messages/example_json/.gitignore renamed to pkgs/messages/example/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44

55
# Conventional directory for build output.
66
build/
7+
bin/example/

pkgs/messages/example_json/lib/testarb.arb renamed to pkgs/messages/example/assets/l10n/testarb.arb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,4 @@
3636
}
3737
},
3838
"helloAndWelcome2": "Welcome {firstName} von {lastName}!"
39-
}
39+
}

pkgs/messages/example_json/lib/testarb_de.arb renamed to pkgs/messages/example/assets/l10n/testarb_de.arb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
"helloAndWelcome2": "Willkommen {firstName} von {lastName} 2",
66
"newMessages": "testde {newMessages, plural, =0 {No new messages} =1 {One new message} two{Two new Messages} other {test {newMessages} new messages}}",
77
"newMessages2": "testdse is just a simple message"
8-
}
8+
}

pkgs/messages/example_json/lib/testarbctx2.arb renamed to pkgs/messages/example/assets/l10n/testarbctx2.arb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,4 @@
4343
}
4444
}
4545
}
46-
}
46+
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
{
22
"@@context": "AboutPage",
3+
"@@locale": "fr",
34
"helloAndWelcome": "Welcome {firstName} von {lastName} <",
45
"otherMsg": "other",
56
"aboutMessage": "Sur {websitename}",
67
"newMessages": "test {newMessages, plural, =0 {No new messages} =1 {One new message} two{Two new Messages} other {test {newMessages} new messages}}",
78
"newMessages2": "test {gender, select,male {No new messages} female {One new message} other{Two new Messages} other {test {gender} new messages of type {newVar}}}"
8-
}
9+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[0,"en","dr9Md951",1,null,["helloAndWelcome","Welcome von !",[8,0],[13,1]],["helloAndWelcome2","Welcome von !",[8,0],[13,1]],[6,"newMessages","test ",[3,0,["test new messages",[5,0]],[0,"No new messages",1,"One new message","w2","Two new Messages"]]],[6,"newMessages2","test ",[4,0,"Two new Messages",{"male":"No new messages","female":"One new message"}]]]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[0,"de","hbDN1MhX",1,null,["helloAndWelcome","Willkommen von ",[11,0],[16,1]],["helloAndWelcome2","Willkommen von 2",[11,0],[16,1]],[6,"newMessages","testde ",[3,0,["test new messages",[5,0]],[0,"No new messages",1,"One new message","w2","Two new Messages"]]],["newMessages2","testdse is just a simple message"]]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[0,"en","QrwRSsOy",1,null,["aboutMessage","About ",[6,0]],["helloAndWelcome","Welcome von <",[8,0],[13,1]],[6,"newMessages","test ",[3,0,["test new messages",[5,0]],[0,"No new messages",1,"One new message","w2","Two new Messages"]]],[6,"newMessages2","test ",[4,0,"Two new Messages",{"male":"No new messages","female":"One new message"}]],["otherMsg","other"]]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[0,"fr","390XWry3",1,null,["aboutMessage","Sur ",[4,0]],["helloAndWelcome","Welcome von <",[8,0],[13,1]],[6,"newMessages","test ",[3,0,["test new messages",[5,0]],[0,"No new messages",1,"One new message","w2","Two new Messages"]]],[6,"newMessages2","test ",[4,0,"Two new Messages",{"male":"No new messages","female":"One new message"}]],["otherMsg","other"]]

pkgs/messages/example_json/bin/example.dart renamed to pkgs/messages/example/bin/example.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66

77
import 'dart:io';
88

9-
import 'package:example_json/testarbctx2.g.dart';
9+
import 'package:example/messages.g.dart';
1010

1111
Future<void> main(List<String> arguments) async {
12-
final messages =
13-
AboutPageMessages((String id) async => File(id).readAsString());
12+
final messages = AboutPageMessages(
13+
(id) => File(id.split('/').skip(2).join('/')).readAsString(),
14+
);
1415
// final index = AboutPageMessagesEnum.aboutMessage;
1516

1617
await messages.loadLocale('en');
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
// Generated by package:messages_builder.
2+
3+
// ignore_for_file: non_constant_identifier_names
4+
5+
import 'package:intl/intl.dart';
6+
import 'package:messages/messages_json.dart';
7+
8+
Message _pluralSelector(
9+
num howMany,
10+
String locale, {
11+
required Message other,
12+
Message? few,
13+
Message? many,
14+
Map<int, Message>? numberCases,
15+
Map<int, Message>? wordCases,
16+
}) {
17+
return Intl.pluralLogic(
18+
howMany,
19+
few: few,
20+
many: many,
21+
zero: numberCases?[0] ?? wordCases?[0],
22+
one: numberCases?[1] ?? wordCases?[1],
23+
two: numberCases?[2] ?? wordCases?[2],
24+
other: other,
25+
locale: locale,
26+
);
27+
}
28+
29+
class AboutPageMessages {
30+
AboutPageMessages(this._assetLoader);
31+
32+
final Future<String> Function(String id) _assetLoader;
33+
34+
String _currentLocale = 'en';
35+
36+
final Map<String, MessageList> _messages = {};
37+
38+
static const _dataFiles = {
39+
'en': ('packages/example/assets/testarbctx2.arb.json', 'QrwRSsOy'),
40+
'fr': ('packages/example/assets/testarbctx2_fr.arb.json', '390XWry3')
41+
};
42+
43+
String get currentLocale => _currentLocale;
44+
45+
MessageList get _currentMessages => _messages[currentLocale]!;
46+
47+
String getById(
48+
String id, [
49+
List<dynamic> args = const [],
50+
]) {
51+
return _currentMessages.generateStringAtId(id, args);
52+
}
53+
54+
static Iterable<String> get knownLocales => _dataFiles.keys;
55+
56+
Future<void> loadLocale(String locale) async {
57+
if (!_messages.containsKey(locale)) {
58+
final info = _dataFiles[locale];
59+
final dataFile = info?.$1;
60+
if (dataFile == null) {
61+
throw ArgumentError('Locale $locale is not in $knownLocales');
62+
}
63+
final data = await _assetLoader(dataFile);
64+
final messageList = MessageListJson.fromString(data, _pluralSelector);
65+
if (messageList.preamble.hash != info?.$2) {
66+
throw ArgumentError('''
67+
Messages file for locale $locale has different hash "${messageList.preamble.hash}" than generated code "${info?.$2}".''');
68+
}
69+
_messages[locale] = messageList;
70+
}
71+
_currentLocale = locale;
72+
}
73+
74+
Future<void> loadAllLocales() async {
75+
for (final locale in knownLocales) {
76+
await loadLocale(locale);
77+
}
78+
}
79+
80+
String aboutMessage(String websitename) =>
81+
_currentMessages.generateStringAtIndex(0, [websitename]);
82+
83+
String helloAndWelcome(
84+
String firstName,
85+
int lastName,
86+
) =>
87+
_currentMessages.generateStringAtIndex(1, [firstName, lastName]);
88+
89+
String newMessages(int newMessages) =>
90+
_currentMessages.generateStringAtIndex(2, [newMessages]);
91+
92+
String newMessages2(
93+
String gender,
94+
int newVar,
95+
) =>
96+
_currentMessages.generateStringAtIndex(3, [gender, newVar]);
97+
98+
String get otherMsg => _currentMessages.generateStringAtIndex(4, []);
99+
}
100+
101+
class HomePageMessages {
102+
HomePageMessages(this._assetLoader);
103+
104+
final Future<String> Function(String id) _assetLoader;
105+
106+
String _currentLocale = 'en';
107+
108+
final Map<String, MessageList> _messages = {};
109+
110+
static const _dataFiles = {
111+
'de': ('packages/example/assets/testarb_de.arb.json', 'hbDN1MhX'),
112+
'en': ('packages/example/assets/testarb.arb.json', 'dr9Md951')
113+
};
114+
115+
String get currentLocale => _currentLocale;
116+
117+
MessageList get _currentMessages => _messages[currentLocale]!;
118+
119+
String getById(
120+
String id, [
121+
List<dynamic> args = const [],
122+
]) {
123+
return _currentMessages.generateStringAtId(id, args);
124+
}
125+
126+
static Iterable<String> get knownLocales => _dataFiles.keys;
127+
128+
Future<void> loadLocale(String locale) async {
129+
if (!_messages.containsKey(locale)) {
130+
final info = _dataFiles[locale];
131+
final dataFile = info?.$1;
132+
if (dataFile == null) {
133+
throw ArgumentError('Locale $locale is not in $knownLocales');
134+
}
135+
final data = await _assetLoader(dataFile);
136+
final messageList = MessageListJson.fromString(data, _pluralSelector);
137+
if (messageList.preamble.hash != info?.$2) {
138+
throw ArgumentError('''
139+
Messages file for locale $locale has different hash "${messageList.preamble.hash}" than generated code "${info?.$2}".''');
140+
}
141+
_messages[locale] = messageList;
142+
}
143+
_currentLocale = locale;
144+
}
145+
146+
Future<void> loadAllLocales() async {
147+
for (final locale in knownLocales) {
148+
await loadLocale(locale);
149+
}
150+
}
151+
152+
String helloAndWelcome(
153+
String firstName,
154+
String lastName,
155+
) =>
156+
_currentMessages.generateStringAtIndex(0, [firstName, lastName]);
157+
158+
String helloAndWelcome2(
159+
String firstName,
160+
String lastName,
161+
) =>
162+
_currentMessages.generateStringAtIndex(1, [firstName, lastName]);
163+
164+
String newMessages(int newMessages) =>
165+
_currentMessages.generateStringAtIndex(2, [newMessages]);
166+
167+
String newMessages2(
168+
String gender,
169+
int newVar,
170+
) =>
171+
_currentMessages.generateStringAtIndex(3, [gender, newVar]);
172+
}

0 commit comments

Comments
 (0)