Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"--lib=\"example/lib/\"",
"--arb=\"src/arbs/\"",
"--gen=\"src/generated/\"",
"--ignore=\"help, back.*\"",
"--comment=Generated from Google Sheets",
"--author=example@gmail.com",
"--context=From Google Sheets",
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.2.2

- **ADDED**: Optional support for ignoring specific sheets by title with RegExp patterns.

## 0.2.1

- **FIX**: Fix locales import to `dart:ui`
Expand Down
80 changes: 66 additions & 14 deletions bin/generate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,43 @@ void main(List<String>? $arguments) => runZonedGuarded<void>(
io.exit(0);
}

String? excludeQuotes(String? input) {
if (input == null || input.length < 2) return input;
final Runes(:first, :last) = input.runes;
if (first == 34 && last == 34) {
return input.substring(1, input.length - 1);
} else if (first == 39 && last == 39) {
return input.substring(1, input.length - 1);
} else {
return input;
}
}

$log('Reading command line arguments...');
final credentialsPath = args.option('credentials')?.replaceAll('"', '');
final sheetId = args.option('sheet')?.replaceAll('"', '');
final libDir = args.option('lib')?.replaceAll('"', '');
final arbDir = args.option('arb')?.replaceAll('"', '');
final genDir = args.option('gen')?.replaceAll('"', '');
final prefix = args.option('prefix')?.replaceAll('"', '') ?? 'app';
final header = args.option('header')?.replaceAll('"', '');
final credentialsPath = excludeQuotes(args.option('credentials'));
final sheetId = excludeQuotes(args.option('sheet'));
final libDir = excludeQuotes(args.option('lib'));
final arbDir = excludeQuotes(args.option('arb'));
final genDir = excludeQuotes(args.option('gen'));
final ignore = excludeQuotes(args.option('ignore'))
?.split(',')
.map((e) => e.trim())
.where((e) => e.isNotEmpty)
.map((e) => RegExp(e))
.toList(growable: false) ??
const [];
final prefix = excludeQuotes(args.option('prefix')) ?? 'app';
final header = excludeQuotes(args.option('header'));
final format = args.flag('format');
final meta = <String, String>{
if (args.option('author') case String author) '@@author': author,
if (args.option('modified') case String modified)
if (excludeQuotes(args.option('author')) case String author)
'@@author': author,
if (excludeQuotes(args.option('modified')) case String modified)
'@@last_modified': modified,
if (args.option('comment') case String comment) '@@comment': comment,
if (args.option('context') case String context) '@@context': context,
if (excludeQuotes(args.option('comment')) case String comment)
'@@comment': comment,
if (excludeQuotes(args.option('context')) case String context)
'@@context': context,
};

// Validate arguments
Expand All @@ -64,6 +86,7 @@ void main(List<String>? $arguments) => runZonedGuarded<void>(
final sheets = fetchSpreadsheets(
credentialsPath: credentialsPath,
sheetId: sheetId,
ignore: ignore,
);

// Generate localization table from the fetched sheets
Expand Down Expand Up @@ -210,6 +233,26 @@ ArgParser buildArgumentsParser() => ArgParser()
help: 'Output directory for generated localization classes, '
'relative to the library directory',
)
..addOption(
'ignore',
abbr: 'i',
aliases: const <String>[
'ignore-table',
'exclude',
'skip',
'ignore-patterns',
'ignore-sheets',
'exclude-sheets',
'skip-sheets',
'exclude-patterns',
'skip-patterns',
],
mandatory: false,
defaultsTo: '',
valueHelp: 'help, backend-.*, temp-.*',
help: 'Comma-separated list of RegExp patterns to ignore sheets '
'whose titles match any of the patterns',
)
..addOption(
'author',
aliases: const <String>['meta-author'],
Expand Down Expand Up @@ -284,6 +327,7 @@ ArgParser buildArgumentsParser() => ArgParser()
Stream<({Sheet sheet, List<List<Object?>> values})> fetchSpreadsheets({
required String credentialsPath,
required String sheetId,
List<RegExp> ignore = const [],
}) async* {
$log('Credentials path: $credentialsPath');
final credentialsFile = io.File(credentialsPath);
Expand Down Expand Up @@ -340,17 +384,25 @@ Stream<({Sheet sheet, List<List<Object?>> values})> fetchSpreadsheets({
continue;
}
final SheetProperties(sheetId: id, title: title) = properties;

// Check if the sheet title matches any of the ignore patterns
if (id == null) {
$err('Sheet ID is null, skipping sheet...');
continue;
} else if (title == null || title.isEmpty) {
$err('Sheet title is null or empty, skipping sheet...');
continue;
} else if (ignore.any((pattern) => pattern.hasMatch(title))) {
$log('Ignoring sheet "$title" as it matches ignore patterns');
continue;
}

final ValueRange(:values) = await sheetsApi.spreadsheets.values.get(
sheetId,
title,
);

// Validate sheet values
if (values == null) {
$err('Sheet "$title" has no values, skipping sheet...');
continue;
Expand All @@ -363,9 +415,9 @@ Stream<({Sheet sheet, List<List<Object?>> values})> fetchSpreadsheets({
} else if (values.first.length < 4) {
$err('Sheet "$title" has no localizations, skipping sheet...');
continue;
} else {
yield (sheet: sheet, values: values);
}

yield (sheet: sheet, values: values);
}
}

Expand Down Expand Up @@ -706,7 +758,7 @@ Future<Set<String>> generateFlutterLocalization({
'gen-l10n',
'--no-nullable-getter',
// flutter config --explicit-package-dependencies
'--no-synthetic-package',
//'--no-synthetic-package',
'--template-arb-file=${prefix ?? 'app'}_en.arb',
'--arb-dir=$dir',
'--output-dir=${genDir.path}',
Expand Down
8 changes: 5 additions & 3 deletions example/lib/localization.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// This file is generated, do not edit it manually!
// ignore_for_file: directives_ordering
library;

export 'package:flutter_localizations/flutter_localizations.dart';

export 'src/generated/app/app_localization.dart';
export 'src/generated/chat/chat_localization.dart';
export 'src/generated/errors/errors_localization.dart';
export 'src/generated/pay/pay_localization.dart';
export 'src/generated/settings/settings_localization.dart';
export 'src/generated/sign_up/sign_up_localization.dart';
export 'src/generated/chat/chat_localization.dart';
export 'src/generated/settings/settings_localization.dart';
export 'src/generated/pay/pay_localization.dart';
export 'src/generated/locales.dart';
45 changes: 45 additions & 0 deletions example/lib/src/arbs/app/example_ar.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"@@locale": "ar",
"@@author": "example@gmail.com",
"@@last_modified": "2025-08-26T14:28:36.220548Z",
"@@comment": "Generated from Google Sheets",
"@@context": "From Google Sheets",
"title": "دكتورينا",
"@title": {},
"checkVersionUpdateNowButton": "التحديث الآن",
"@checkVersionUpdateNowButton": {
"description": "Кнопка обновиться"
},
"checkVersionMaybeLaterButton": "ربما في وقت لاحق",
"@checkVersionMaybeLaterButton": {
"description": "Кнопка отложить обновление"
},
"checkVersionUpdateOptionalTitle": "تحديث جديد متاح",
"@checkVersionUpdateOptionalTitle": {
"description": "Заголовок можешь обновиться"
},
"checkVersionUpdateRequiredTitle": "التحديث مطلوب",
"@checkVersionUpdateRequiredTitle": {
"description": "Заголовок обязан обновиться"
},
"checkVersionUpdateOptionalText": "يتوفر إصدار جديد (v{version}) من التطبيق. يُرجى التحديث للاستمرار في الاستخدام للحصول على أفضل تجربة.",
"@checkVersionUpdateOptionalText": {
"description": "Сообщение о доступности новой версии \nприложения с приглашением обновиться",
"placeholders": {
"version": {
"type": "String",
"example": "2.3.1"
}
}
},
"checkVersionUpdateRequiredText": "للمتابعة، يُرجى تحديث التطبيق. يتضمن هذا التحديث إصلاحات وتحسينات مهمة.",
"@checkVersionUpdateRequiredText": {
"description": "Сообщение с требованием обновиться",
"placeholders": {
"version": {
"type": "String",
"example": "2.3.1"
}
}
}
}
45 changes: 45 additions & 0 deletions example/lib/src/arbs/app/example_bn.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"@@locale": "bn",
"@@author": "example@gmail.com",
"@@last_modified": "2025-08-26T14:28:36.220548Z",
"@@comment": "Generated from Google Sheets",
"@@context": "From Google Sheets",
"title": "ডক্টরিনা",
"@title": {},
"checkVersionUpdateNowButton": "এখনই আপডেট করুন",
"@checkVersionUpdateNowButton": {
"description": "Кнопка обновиться"
},
"checkVersionMaybeLaterButton": "হয়তো পরে",
"@checkVersionMaybeLaterButton": {
"description": "Кнопка отложить обновление"
},
"checkVersionUpdateOptionalTitle": "নতুন আপডেট উপলব্ধ",
"@checkVersionUpdateOptionalTitle": {
"description": "Заголовок можешь обновиться"
},
"checkVersionUpdateRequiredTitle": "আপডেট প্রয়োজন",
"@checkVersionUpdateRequiredTitle": {
"description": "Заголовок обязан обновиться"
},
"checkVersionUpdateOptionalText": "অ্যাপটির একটি নতুন সংস্করণ (v{version}) উপলব্ধ৷ সেরা অভিজ্ঞতার জন্য চালিয়ে যেতে অনুগ্রহ করে আপডেট করুন।",
"@checkVersionUpdateOptionalText": {
"description": "Сообщение о доступности новой версии \nприложения с приглашением обновиться",
"placeholders": {
"version": {
"type": "String",
"example": "2.3.1"
}
}
},
"checkVersionUpdateRequiredText": "চালিয়ে যেতে, অনুগ্রহ করে অ্যাপটি আপডেট করুন। এই আপডেটে গুরুত্বপূর্ণ সংশোধন এবং উন্নতি অন্তর্ভুক্ত রয়েছে।",
"@checkVersionUpdateRequiredText": {
"description": "Сообщение с требованием обновиться",
"placeholders": {
"version": {
"type": "String",
"example": "2.3.1"
}
}
}
}
2 changes: 1 addition & 1 deletion example/lib/src/arbs/app/example_de.arb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"@@locale": "de",
"@@author": "example@gmail.com",
"@@last_modified": "2025-06-04T15:18:15.787321Z",
"@@last_modified": "2025-08-26T14:28:36.220548Z",
"@@comment": "Generated from Google Sheets",
"@@context": "From Google Sheets",
"title": "Doctorina",
Expand Down
2 changes: 1 addition & 1 deletion example/lib/src/arbs/app/example_en.arb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"@@locale": "en",
"@@author": "example@gmail.com",
"@@last_modified": "2025-06-04T15:18:15.787321Z",
"@@last_modified": "2025-08-26T14:28:36.220548Z",
"@@comment": "Generated from Google Sheets",
"@@context": "From Google Sheets",
"title": "Doctorina",
Expand Down
2 changes: 1 addition & 1 deletion example/lib/src/arbs/app/example_es.arb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"@@locale": "es",
"@@author": "example@gmail.com",
"@@last_modified": "2025-06-04T15:18:15.787321Z",
"@@last_modified": "2025-08-26T14:28:36.220548Z",
"@@comment": "Generated from Google Sheets",
"@@context": "From Google Sheets",
"title": "Doctorina",
Expand Down
45 changes: 45 additions & 0 deletions example/lib/src/arbs/app/example_fr.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"@@locale": "fr",
"@@author": "example@gmail.com",
"@@last_modified": "2025-08-26T14:28:36.220548Z",
"@@comment": "Generated from Google Sheets",
"@@context": "From Google Sheets",
"title": "Docteure",
"@title": {},
"checkVersionUpdateNowButton": "Mettre à jour maintenant",
"@checkVersionUpdateNowButton": {
"description": "Кнопка обновиться"
},
"checkVersionMaybeLaterButton": "Peut-être plus tard",
"@checkVersionMaybeLaterButton": {
"description": "Кнопка отложить обновление"
},
"checkVersionUpdateOptionalTitle": "Nouvelle mise à jour disponible",
"@checkVersionUpdateOptionalTitle": {
"description": "Заголовок можешь обновиться"
},
"checkVersionUpdateRequiredTitle": "Mise à jour requise",
"@checkVersionUpdateRequiredTitle": {
"description": "Заголовок обязан обновиться"
},
"checkVersionUpdateOptionalText": "Une nouvelle version (v{version}) de l'application est disponible. Veuillez la mettre à jour pour profiter d'une expérience optimale.",
"@checkVersionUpdateOptionalText": {
"description": "Сообщение о доступности новой версии \nприложения с приглашением обновиться",
"placeholders": {
"version": {
"type": "String",
"example": "2.3.1"
}
}
},
"checkVersionUpdateRequiredText": "Pour continuer, veuillez mettre à jour l'application. Cette mise à jour inclut des correctifs et améliorations importants.",
"@checkVersionUpdateRequiredText": {
"description": "Сообщение с требованием обновиться",
"placeholders": {
"version": {
"type": "String",
"example": "2.3.1"
}
}
}
}
45 changes: 45 additions & 0 deletions example/lib/src/arbs/app/example_hi.arb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"@@locale": "hi",
"@@author": "example@gmail.com",
"@@last_modified": "2025-08-26T14:28:36.220548Z",
"@@comment": "Generated from Google Sheets",
"@@context": "From Google Sheets",
"title": "डॉक्टरिना",
"@title": {},
"checkVersionUpdateNowButton": "अभी अद्यतन करें",
"@checkVersionUpdateNowButton": {
"description": "Кнопка обновиться"
},
"checkVersionMaybeLaterButton": "शायद बाद में",
"@checkVersionMaybeLaterButton": {
"description": "Кнопка отложить обновление"
},
"checkVersionUpdateOptionalTitle": "नया अपडेट उपलब्ध है",
"@checkVersionUpdateOptionalTitle": {
"description": "Заголовок можешь обновиться"
},
"checkVersionUpdateRequiredTitle": "अद्यतन आवश्यक है",
"@checkVersionUpdateRequiredTitle": {
"description": "Заголовок обязан обновиться"
},
"checkVersionUpdateOptionalText": "ऐप का नया संस्करण (v{version}) उपलब्ध है। कृपया बेहतर अनुभव के लिए इसे अपडेट करते रहें।",
"@checkVersionUpdateOptionalText": {
"description": "Сообщение о доступности новой версии \nприложения с приглашением обновиться",
"placeholders": {
"version": {
"type": "String",
"example": "2.3.1"
}
}
},
"checkVersionUpdateRequiredText": "जारी रखने के लिए, कृपया ऐप अपडेट करें। इस अपडेट में महत्वपूर्ण सुधार और सुधार शामिल हैं।",
"@checkVersionUpdateRequiredText": {
"description": "Сообщение с требованием обновиться",
"placeholders": {
"version": {
"type": "String",
"example": "2.3.1"
}
}
}
}
Loading