Skip to content

Commit

Permalink
feat: add format config
Browse files Browse the repository at this point in the history
  • Loading branch information
Tienisto committed Oct 23, 2024
1 parent 13d64ff commit 663f711
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 7 deletions.
3 changes: 2 additions & 1 deletion slang/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## 4.0.1
## 4.1.0

- feat: add `format` config to automatically format generated files (#184)
- fix: correctly generate with `enum_name` and `class_name` different from `AppLocale` / `Translations` (#254)

## 4.0.0
Expand Down
22 changes: 22 additions & 0 deletions slang/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ dart run slang migrate arb src.arb dest.json # migrate arb to json
- [Comments](#-comments)
- [Recasing](#-recasing)
- [Obfuscation](#-obfuscation)
- [Formatting](#-formatting)
- [Dart Only](#-dart-only)
- [Tools](#tools)
- [Main Command](#-main-command)
Expand Down Expand Up @@ -332,6 +333,9 @@ interfaces:
obfuscation:
enabled: false
secret: somekey
format:
enabled: true
width: 150
imports:
- 'package:my_package/path_to_enum.dart'
```
Expand Down Expand Up @@ -398,6 +402,9 @@ targets:
obfuscation:
enabled: false
secret: somekey
format:
enabled: true
width: 150
imports:
- 'package:my_package/path_to_enum.dart'
```
Expand Down Expand Up @@ -438,6 +445,8 @@ targets:
| `children of interfaces` | `Pairs of Alias:Path` | alias interfaces [(i)](#-interfaces) | `null` |
| `obfuscation`/`enabled` | `Boolean` | enable obfuscation [(i)](#-obfuscation) | `false` |
| `obfuscation`/`secret` | `String` | obfuscation secret (random if null) [(i)](#-obfuscation) | `null` |
| `format`/`enabled` | `Boolean` | enable auto format [(i)](#-formatting) | `false` |
| `format`/`width` | `String` | set line length / characters per line [(i)](#-formatting) | `null` |
| `imports` | `List<String>` | generate import statements | `[]` |

## Main Features
Expand Down Expand Up @@ -1445,6 +1454,19 @@ Keep in mind that this only prevents simple string searches of the binary.

An experienced reverse engineer can still find the strings given enough time.

### ➤ Formatting

The generated code is not formatted by default to keep the algorithm fast and efficient.

You can enable it:

```yaml
# Config
format:
enabled: true
width: 150 # optional
```

### ➤ Dart Only

You can use this library without flutter.
Expand Down
28 changes: 24 additions & 4 deletions slang/bin/slang.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import 'package:slang/src/runner/edit.dart';
import 'package:slang/src/runner/migrate.dart';
import 'package:slang/src/runner/normalize.dart';
import 'package:slang/src/runner/stats.dart';
import 'package:slang/src/runner/utils/format.dart';
import 'package:watcher/watcher.dart';

/// Determines what the runner will do
Expand Down Expand Up @@ -348,12 +349,31 @@ Future<void> generateTranslations({
locale: locale,
)}');
}
print('');
}

if (stopwatch != null) {
print(
'${_GREEN}Translations generated successfully. ${stopwatch.elapsedSeconds}$_RESET');
if (fileCollection.config.format.enabled) {
final formatDir = PathUtils.getParentPath(outputFilePath)!;
Stopwatch? formatStopwatch;
if (verbose) {
print('');
print('Formatting "$formatDir" ...');
if (stopwatch != null) {
formatStopwatch = Stopwatch()..start();
}
}
await runDartFormat(
dir: formatDir,
width: fileCollection.config.format.width,
);
if (verbose && formatStopwatch != null) {
print('Format done. ${formatStopwatch.elapsedSeconds}');
}
}

if (verbose && stopwatch != null) {
print('');
print(
'${_GREEN}Translations generated successfully. ${stopwatch.elapsedSeconds}$_RESET');
}
}

Expand Down
11 changes: 11 additions & 0 deletions slang/lib/src/builder/builder/raw_config_builder.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:slang/src/builder/model/context_type.dart';
import 'package:slang/src/builder/model/enums.dart';
import 'package:slang/src/builder/model/format_config.dart';
import 'package:slang/src/builder/model/i18n_locale.dart';
import 'package:slang/src/builder/model/interface.dart';
import 'package:slang/src/builder/model/obfuscation_config.dart';
Expand Down Expand Up @@ -113,6 +114,8 @@ class RawConfigBuilder {
obfuscation: (map['obfuscation'] as Map<String, dynamic>?)
?.toObfuscationConfig() ??
RawConfig.defaultObfuscationConfig,
format: (map['format'] as Map<String, dynamic>?)?.toFormatConfig() ??
RawConfig.defaultFormatConfig,
imports: map['imports']?.cast<String>() ?? RawConfig.defaultImports,
rawMap: map,
);
Expand Down Expand Up @@ -218,6 +221,14 @@ extension on Map<String, dynamic> {
secret: this['secret'],
);
}

/// Parses the 'format' config
FormatConfig toFormatConfig() {
return FormatConfig(
enabled: this['enabled'],
width: this['width'],
);
}
}

extension on String {
Expand Down
13 changes: 13 additions & 0 deletions slang/lib/src/builder/model/format_config.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/// Configuration model for the "format" entry.
class FormatConfig {
static const bool defaultEnabled = false;
static const int? defaultWidth = null;

final bool enabled;
final int? width;

const FormatConfig({
required this.enabled,
required this.width,
});
}
12 changes: 12 additions & 0 deletions slang/lib/src/builder/model/raw_config.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:slang/src/builder/model/context_type.dart';
import 'package:slang/src/builder/model/enums.dart';
import 'package:slang/src/builder/model/format_config.dart';
import 'package:slang/src/builder/model/i18n_locale.dart';
import 'package:slang/src/builder/model/interface.dart';
import 'package:slang/src/builder/model/obfuscation_config.dart';
Expand Down Expand Up @@ -39,6 +40,10 @@ class RawConfig {
static const List<InterfaceConfig> defaultInterfaces = <InterfaceConfig>[];
static final ObfuscationConfig defaultObfuscationConfig =
ObfuscationConfig.disabled();
static const FormatConfig defaultFormatConfig = FormatConfig(
enabled: FormatConfig.defaultEnabled,
width: FormatConfig.defaultWidth,
);
static const List<String> defaultImports = <String>[];

final FileType fileType;
Expand Down Expand Up @@ -72,6 +77,7 @@ class RawConfig {
final List<ContextType> contexts;
final List<InterfaceConfig> interfaces;
final ObfuscationConfig obfuscation;
final FormatConfig format;
final List<String> imports;

/// Used by external tools to access the raw config. (e.g. slang_gpt)
Expand Down Expand Up @@ -108,6 +114,7 @@ class RawConfig {
required this.contexts,
required this.interfaces,
required this.obfuscation,
required this.format,
required this.imports,
required this.rawMap,
}) : fileType = _determineFileType(inputFilePattern),
Expand Down Expand Up @@ -139,6 +146,7 @@ class RawConfig {
List<ContextType>? contexts,
List<InterfaceConfig>? interfaces,
ObfuscationConfig? obfuscation,
FormatConfig? format,
}) {
return RawConfig(
baseLocale: baseLocale ?? this.baseLocale,
Expand Down Expand Up @@ -172,6 +180,7 @@ class RawConfig {
contexts: contexts ?? this.contexts,
interfaces: interfaces ?? this.interfaces,
obfuscation: obfuscation ?? this.obfuscation,
format: format ?? this.format,
imports: imports,
rawMap: rawMap,
);
Expand Down Expand Up @@ -249,6 +258,8 @@ class RawConfig {
}
}
print(' -> obfuscation: ${obfuscation.enabled ? 'enabled' : 'disabled'}');
print(
' -> format: ${format.enabled ? 'enabled (width=${format.width})' : 'disabled'}');
print(' -> imports: $imports');
}

Expand Down Expand Up @@ -285,6 +296,7 @@ class RawConfig {
contexts: RawConfig.defaultContexts,
interfaces: RawConfig.defaultInterfaces,
obfuscation: RawConfig.defaultObfuscationConfig,
format: RawConfig.defaultFormatConfig,
imports: RawConfig.defaultImports,
className: RawConfig.defaultClassName,
rawMap: {},
Expand Down
9 changes: 9 additions & 0 deletions slang/lib/src/builder/utils/path_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ class PathUtils {
return segments[segments.length - 2];
}

/// Converts /a/b/file.json to /a/b
static String? getParentPath(String path) {
final segments = getPathSegments(path);
if (segments.length == 1) {
return null;
}
return segments.sublist(0, segments.length - 1).join('/');
}

/// finds locale in directory path
/// eg. /en-US/b/file.json will result in en-US
static I18nLocale? findDirectoryLocale(
Expand Down
25 changes: 25 additions & 0 deletions slang/lib/src/runner/utils/format.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import 'dart:io';

/// Formats a given directory by running a separate dart format process.
Future<void> runDartFormat({
required String dir,
required int? width,
}) async {
final executable = Platform.resolvedExecutable;

final status = Process.runSync(
executable,
[
'format',
dir,
if (width != null) ...[
'--line-length',
width.toString(),
],
],
);

if (status.exitCode != 0) {
print('Dart format failed with exit code ${status.exitCode}');
}
}
5 changes: 5 additions & 0 deletions slang_build_runner/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 4.1.0

- feat: add `dart_style` dependency to auto format generated files
- bump `slang` to `4.1.0`

## 4.0.0

- Bump `slang` to `4.0.0`
Expand Down
18 changes: 16 additions & 2 deletions slang_build_runner/lib/slang_build_runner.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';

import 'package:build/build.dart';
import 'package:dart_style/dart_style.dart';
import 'package:glob/glob.dart';
// ignore: implementation_imports
import 'package:slang/src/builder/builder/raw_config_builder.dart';
Expand Down Expand Up @@ -81,10 +82,15 @@ class I18nBuilder implements Builder {
// STEP 4: write output to hard drive
FileUtils.createMissingFolders(filePath: outputFilePath);

final formatter = DartFormatter(
pageWidth: config.format.width,
);

FileUtils.writeFile(
path: BuildResultPaths.mainPath(outputFilePath),
content: result.main,
content: result.main.formatted(config, formatter),
);

for (final entry in result.translations.entries) {
final locale = entry.key;
final localeTranslations = entry.value;
Expand All @@ -93,7 +99,7 @@ class I18nBuilder implements Builder {
outputPath: outputFilePath,
locale: locale,
),
content: localeTranslations,
content: localeTranslations.formatted(config, formatter),
);
}
}
Expand All @@ -109,4 +115,12 @@ extension on String {
String getFileExtension() {
return PathUtils.getFileExtension(this);
}

/// Conditionally formats the string using the provided [formatter].
String formatted(RawConfig config, DartFormatter formatter) {
return switch (config.format.enabled) {
true => formatter.format(this),
false => this,
};
}
}
1 change: 1 addition & 0 deletions slang_build_runner/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ environment:

dependencies:
build: ^2.2.1
dart_style: ^2.3.0
glob: ^2.0.2

# Use a tight version to ensure that all features are available
Expand Down
4 changes: 4 additions & 0 deletions slang_flutter/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 4.1.0

- bump `slang` to `4.1.0`

## 4.0.0

- Bump `slang` to `4.0.0`
Expand Down

0 comments on commit 663f711

Please sign in to comment.