From 26cab774a84bf33b439cb5685b010bbc6acb43af Mon Sep 17 00:00:00 2001 From: Tobias Ottenweller Date: Mon, 2 Jun 2025 21:53:19 +0200 Subject: [PATCH 1/3] chore: add analyzer action --- .github/workflows/lint.yml | 27 ++++++++ packages/tonik/analysis_options.yaml | 4 ++ packages/tonik/bin/tonik.dart | 65 ++++++++++--------- packages/tonik/lib/src/openapi_loader.dart | 15 +++-- packages/tonik/pubspec.yaml | 6 +- .../tonik/test/src/openapi_loader_test.dart | 24 +++---- 6 files changed, 89 insertions(+), 52 deletions(-) create mode 100644 .github/workflows/lint.yml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..fcc0569 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,27 @@ +name: Tests + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Setup Dart + uses: dart-lang/setup-dart@v1 + with: + sdk: stable + - name: Install dependencies + run: | + dart pub global activate melos + melos bootstrap + + - name: Analyze code + run: melos exec dart analyze + \ No newline at end of file diff --git a/packages/tonik/analysis_options.yaml b/packages/tonik/analysis_options.yaml index b5cd897..f7f584e 100644 --- a/packages/tonik/analysis_options.yaml +++ b/packages/tonik/analysis_options.yaml @@ -3,3 +3,7 @@ include: package:very_good_analysis/analysis_options.yaml linter: rules: public_member_api_docs: false + +analyzer: + errors: + avoid_print: ignore \ No newline at end of file diff --git a/packages/tonik/bin/tonik.dart b/packages/tonik/bin/tonik.dart index dbbd4db..e2b171b 100644 --- a/packages/tonik/bin/tonik.dart +++ b/packages/tonik/bin/tonik.dart @@ -1,10 +1,11 @@ import 'dart:io'; + import 'package:args/args.dart'; import 'package:logging/logging.dart'; import 'package:tonik/src/openapi_loader.dart'; import 'package:tonik_core/tonik_core.dart'; -import 'package:tonik_parse/tonik_parse.dart'; import 'package:tonik_generate/tonik_generate.dart'; +import 'package:tonik_parse/tonik_parse.dart'; const issueUrl = 'https://github.com/t-unit/tonik/issues'; @@ -53,14 +54,14 @@ void printUsage(ArgParser argParser) { final Logger logger = Logger('tonik'); void main(List arguments) { - final ArgParser argParser = buildParser(); + final argParser = buildParser(); String logLevel; String packageName; String openApiPath; String outputDir; try { - final ArgResults results = argParser.parse(arguments); + final results = argParser.parse(arguments); if (results.flag('help')) { printUsage(argParser); @@ -75,7 +76,7 @@ void main(List arguments) { print(formatException.message); printUsage(argParser); exit(128); - } catch (_) { + } on Object catch (_) { printUsage(argParser); exit(128); } @@ -110,10 +111,11 @@ void main(List arguments) { } }); - logger.info('Starting Tonik'); - logger.fine('Package name: $packageName'); - logger.fine('OpenAPI document: $openApiPath'); - logger.fine('Output directory: $outputDir'); + logger + ..info('Starting Tonik') + ..fine('Package name: $packageName') + ..fine('OpenAPI document: $openApiPath') + ..fine('Output directory: $outputDir'); Map apiSpec; try { @@ -122,13 +124,14 @@ void main(List arguments) { } on OpenApiLoaderException catch (e) { logger.severe(e.message); exit(1); - } catch (e, s) { - logger.fine('Failed to load OpenAPI document', e, s); - logger.severe( - 'Unexpected error while loading OpenAPI document. ' - 'Make sure to run with verbose logging and report this issue at ' - '$issueUrl', - ); + } on Object catch (e, s) { + logger + ..fine('Failed to load OpenAPI document', e, s) + ..severe( + 'Unexpected error while loading OpenAPI document. ' + 'Make sure to run with verbose logging and report this issue at ' + '$issueUrl', + ); exit(1); } @@ -136,30 +139,32 @@ void main(List arguments) { try { apiDocument = Importer().import(apiSpec); logger.info('Successfully parsed OpenAPI document'); - } catch (e, s) { - logger.fine('Failed to parse OpenAPI document', e, s); - logger.severe( - 'Unexpected error while parsing OpenAPI document. ' - 'If you think your document is valid, please run ' - 'with verbose logging and report this issue at $issueUrl', - ); + } on Object catch (e, s) { + logger + ..fine('Failed to parse OpenAPI document', e, s) + ..severe('Unexpected error while parsing OpenAPI document. ' + 'Unexpected error while parsing OpenAPI document. ' + 'If you think your document is valid, please run ' + 'with verbose logging and report this issue at $issueUrl', + ); exit(1); } try { - Generator().generate( + const Generator().generate( apiDocument: apiDocument, outputDirectory: outputDir, package: packageName, ); logger.info('Successfully generated code'); - } catch (e, s) { - logger.fine('Failed to generate code', e, s); - logger.severe( - 'Unexpected error while generating code. ' - 'If you think your document is valid, please run with ' - 'verbose logging and report this issue at $issueUrl', - ); + } on Object catch (e, s) { + logger + ..fine('Failed to generate code', e, s) + ..severe( + 'Unexpected error while generating code. ' + 'If you think your document is valid, please run with ' + 'verbose logging and report this issue at $issueUrl', + ); exit(1); } } diff --git a/packages/tonik/lib/src/openapi_loader.dart b/packages/tonik/lib/src/openapi_loader.dart index 82b77d0..ef9a88c 100644 --- a/packages/tonik/lib/src/openapi_loader.dart +++ b/packages/tonik/lib/src/openapi_loader.dart @@ -1,5 +1,5 @@ -import 'dart:io'; import 'dart:convert'; +import 'dart:io'; import 'package:logging/logging.dart'; import 'package:yaml/yaml.dart'; @@ -11,13 +11,13 @@ Logger logger = Logger('openapi_loader'); /// /// Returns a Map representation of the OpenAPI document. Map loadOpenApiDocument(String path) { - final File file = File(path); + final file = File(path); if (!file.existsSync()) { throw OpenApiLoaderException('OpenAPI document not found'); } - final String content = file.readAsStringSync(); - final String extension = path.toLowerCase().split('.').last; + final content = file.readAsStringSync(); + final extension = path.toLowerCase().split('.').last; try { final apiSpec = switch (extension) { @@ -25,14 +25,15 @@ Map loadOpenApiDocument(String path) { 'yaml' || 'yml' => _convertYamlToMap(loadYaml(content)), _ => throw OpenApiLoaderException( - 'Unsupported file extension: .$extension. Must be .json, .yaml, or .yml', + 'Unsupported file extension: .$extension. ' + 'Must be .json, .yaml, or .yml', ), }; logger.fine('Parsed OpenAPI document as ${extension.toUpperCase()}'); return apiSpec; - } catch (e) { + } on Object catch (e) { logger.fine('Failed to parse OpenAPI document. $e'); throw OpenApiLoaderException('Failed to parse OpenAPI document.'); } @@ -54,7 +55,7 @@ dynamic _convertYamlNode(dynamic yaml) { ); } if (yaml is YamlList) { - return yaml.map((node) => _convertYamlNode(node)).toList(); + return yaml.map(_convertYamlNode).toList(); } return yaml; } diff --git a/packages/tonik/pubspec.yaml b/packages/tonik/pubspec.yaml index 9aab500..f702b2e 100644 --- a/packages/tonik/pubspec.yaml +++ b/packages/tonik/pubspec.yaml @@ -19,12 +19,12 @@ environment: dependencies: args: ^2.5.0 logging: ^1.3.0 - yaml: ^3.1.3 - tonik_parse: ^0.0.4 tonik_core: ^0.0.4 tonik_generate: ^0.0.4 + tonik_parse: ^0.0.4 + yaml: ^3.1.3 dev_dependencies: - very_good_analysis: ^7.0.0 path: ^1.9.1 test: ^1.24.0 + very_good_analysis: ^7.0.0 diff --git a/packages/tonik/test/src/openapi_loader_test.dart b/packages/tonik/test/src/openapi_loader_test.dart index f7b1789..e5d2bca 100644 --- a/packages/tonik/test/src/openapi_loader_test.dart +++ b/packages/tonik/test/src/openapi_loader_test.dart @@ -19,8 +19,8 @@ void main() { group('loadOpenApiDocument', () { test('loads valid JSON file', () { - final jsonFile = File(path.join(tempDir.path, 'test.json')); - jsonFile.writeAsStringSync(''' + final jsonFile = File(path.join(tempDir.path, 'test.json')) + ..writeAsStringSync(''' { "openapi": "3.0.0", "info": { @@ -38,8 +38,8 @@ void main() { }); test('loads valid YAML file', () { - final yamlFile = File(path.join(tempDir.path, 'test.yaml')); - yamlFile.writeAsStringSync(''' + final yamlFile = File(path.join(tempDir.path, 'test.yaml')) + ..writeAsStringSync(''' openapi: 3.0.0 info: title: Test API @@ -68,8 +68,8 @@ info: }); test('throws on unsupported file extension', () { - final txtFile = File(path.join(tempDir.path, 'test.txt')); - txtFile.writeAsStringSync('invalid'); + final txtFile = File(path.join(tempDir.path, 'test.txt')) + ..writeAsStringSync('invalid'); expect( () => loadOpenApiDocument(txtFile.path), @@ -78,8 +78,8 @@ info: }); test('throws on invalid JSON', () { - final jsonFile = File(path.join(tempDir.path, 'invalid.json')); - jsonFile.writeAsStringSync('invalid json'); + final jsonFile = File(path.join(tempDir.path, 'invalid.json')) + ..writeAsStringSync('invalid json'); expect( () => loadOpenApiDocument(jsonFile.path), @@ -94,8 +94,8 @@ info: }); test('throws on invalid YAML', () { - final yamlFile = File(path.join(tempDir.path, 'invalid.yaml')); - yamlFile.writeAsStringSync(''' + final yamlFile = File(path.join(tempDir.path, 'invalid.yaml')) + ..writeAsStringSync(''' invalid yaml: - misaligned: wrong indentation @@ -109,8 +109,8 @@ invalid yaml: }); test('handles complex YAML structures', () { - final yamlFile = File(path.join(tempDir.path, 'complex.yaml')); - yamlFile.writeAsStringSync(''' + final yamlFile = File(path.join(tempDir.path, 'complex.yaml')) + ..writeAsStringSync(''' openapi: 3.0.0 info: title: Complex API From c29dc62eabaf53bb4510614ac256967979805405 Mon Sep 17 00:00:00 2001 From: Tobias Ottenweller Date: Mon, 2 Jun 2025 21:56:08 +0200 Subject: [PATCH 2/3] chore: update readme --- packages/tonik/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/tonik/README.md b/packages/tonik/README.md index c835147..4328338 100644 --- a/packages/tonik/README.md +++ b/packages/tonik/README.md @@ -29,6 +29,8 @@ There are already numerous projects available to generate Dart code from OpenAPI This package aims to overcome these shortcomings. +Special thanks goes out to [felixwoestmann](https://github.com/felixwoestmann), as this project would not have been possible without him. + ## Features coming soon From c3b56ab25a9193dcdc5d259bc9b70aa5934fa033 Mon Sep 17 00:00:00 2001 From: Tobias Ottenweller Date: Mon, 2 Jun 2025 21:56:54 +0200 Subject: [PATCH 3/3] chore: fix action name --- .github/workflows/lint.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index fcc0569..a38e3e8 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,4 +1,4 @@ -name: Tests +name: Lint on: push: @@ -24,4 +24,3 @@ jobs: - name: Analyze code run: melos exec dart analyze - \ No newline at end of file