diff --git a/swagger_parser/CHANGELOG.md b/swagger_parser/CHANGELOG.md
index 2d7c13ac..0954ecd2 100644
--- a/swagger_parser/CHANGELOG.md
+++ b/swagger_parser/CHANGELOG.md
@@ -1,9 +1,15 @@
+## 1.10.0
+- Support for generating schemas by url (see [example](https://github.com/Carapacik/swagger_parser/blob/main/swagger_parser/example/swagger_parser.yaml))
+- Add new config parameter `schema_url`
+- Add new config parameter `schema_from_url_to_file`
+- Add new config parameter `prefer_schema_source`
+
## 1.9.2
- Fix error with `required` in clients ([#101](https://github.com/Carapacik/swagger_parser/issues/103))
## 1.9.1
- Handling incorrect names for classes, enums and methods.
-- Additional name for unnamed models [#98](https://github.com/Carapacik/swagger_parser/issues/98)
+- Additional name for unnamed models ([#98](https://github.com/Carapacik/swagger_parser/issues/98))
- Support for `deprecated` annotations for methods
## 1.9.0
@@ -13,7 +19,7 @@
- Fix error with missing File import ([#101](https://github.com/Carapacik/swagger_parser/issues/101))
## 1.8.0
-- Multiple schemas support(see ([example](https://github.com/Carapacik/swagger_parser/blob/main/swagger_parser/example/swagger_parser.yaml)))
+- Multiple schemas support (see [example](https://github.com/Carapacik/swagger_parser/blob/main/swagger_parser/example/swagger_parser.yaml))
- Support for specifying nullable types via anyOf
- Edit root client template
- Add new config parameter `root_client_name`
diff --git a/swagger_parser/README.md b/swagger_parser/README.md
index 4cf3bcbd..2e0a4d16 100644
--- a/swagger_parser/README.md
+++ b/swagger_parser/README.md
@@ -7,12 +7,14 @@
[![Tests](https://github.com/Carapacik/swagger_parser/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/Carapacik/swagger_parser/actions/workflows/tests.yml)
-## Dart package that generates REST clients and data classes from OpenApi definition file
+## Dart package that generates REST clients and data classes from OpenApi definition files or links
## Features
- Supports OpenApi v2, v3.0 and v3.1
- Support JSON and YAML format
+- Support for generation by link
+- Support for multiple schemes
- Generate REST client files based on Retrofit
- Generate data classes (also on [freezed](https://pub.dev/packages/freezed))
- Support for multiple languages (Dart, Kotlin)
@@ -46,8 +48,12 @@ An example of YAML is shown below. A default value is specified for each of the
```yaml
swagger_parser:
- # Required. Sets the OpenApi schema path directory for api definition.
+ # You must provide the file path and/or url to the OpenApi schema.
+
+ # Sets the OpenApi schema path directory for api definition.
schema_path: schemas/openapi.json
+ # Sets the url of the OpenApi schema
+ schema_url: https://petstore.swagger.io/v2/swagger.json
# Required. Sets output directory for generated files (Clients and DTOs).
output_directory: lib/api
@@ -56,6 +62,10 @@ swagger_parser:
# Current available languages are: dart, kotlin
language: dart
+ # Optional. If 'schema_path' and 'schema_url' are specified, what will be used.
+ # Current available options are: path, url.
+ prefer_schema_source: url
+
# Optional (dart only). Set 'true' to generate data classes using freezed package.
freezed: false
@@ -79,6 +89,9 @@ swagger_parser:
# Optional. Set to 'true' to squash all clients in one client.
squash_clients: false
+ # Optional. Set to 'false' to not write the schema from the url to the schema file.
+ schema_from_url_to_file: true
+
# Optional. Set postfix for Client class and file.
client_postfix: Client
@@ -123,14 +136,14 @@ swagger_parser:
put_in_folder: true
replacement_rules: []
- - schema_path: schemas/openapi.json
+ - schema_url: https://petstore.swagger.io/v2/swagger.json
name: pet_service
- client_postfix: DataSource
+ client_postfix: Service
put_clients_in_folder: true
- enums_to_json: true
put_in_folder: true
- - schema_path: schemas/openapi.json
+ - schema_path: schemas/pet_store.json
+ schema_url: https://petstore.swagger.io/v2/swagger.json
output_directory: lib/api/kotlin
language: kotlin
```
diff --git a/swagger_parser/example/swagger_parser.yaml b/swagger_parser/example/swagger_parser.yaml
index 759d476d..dba9b598 100644
--- a/swagger_parser/example/swagger_parser.yaml
+++ b/swagger_parser/example/swagger_parser.yaml
@@ -1,14 +1,22 @@
swagger_parser:
- # Required. Sets the OpenApi schema path directory for api definition.
+ # You must provide the file path and/or url to the OpenApi schema.
+
+ # Sets the OpenApi schema path directory for api definition.
# schema_path: schemas/openapi.json
+ # Sets the url of the OpenApi schema
+ # schema_url: https://petstore.swagger.io/v2/swagger.json
# Required. Sets output directory for generated files (Clients and DTOs).
output_directory: lib/api
# Optional. Sets the programming language.
- # Current available languages are: dart, kotlin
+ # Current available languages are: dart, kotlin.
language: dart
+ # Optional. If 'schema_path' and 'schema_url' are specified, what will be used.
+ # Current available options are: path, url.
+ prefer_schema_source: url
+
# Optional (dart only). Set 'true' to generate data classes using freezed package.
freezed: false
@@ -32,6 +40,9 @@ swagger_parser:
# Optional. Set to 'true' to squash all clients in one client.
squash_clients: false
+ # Optional. Set to 'false' to not write the schema from the url to the schema file.
+ schema_from_url_to_file: true
+
# Optional. Set postfix for Client class and file.
client_postfix: Client
@@ -67,13 +78,13 @@ swagger_parser:
put_in_folder: true
replacement_rules: []
- - schema_path: schemas/openapi.json
+ - schema_url: https://petstore.swagger.io/v2/swagger.json
name: pet_service
- client_postfix: DataSource
+ client_postfix: Service
put_clients_in_folder: true
- enums_to_json: true
put_in_folder: true
- - schema_path: schemas/openapi.json
+ - schema_path: schemas/pet_store.json
+ schema_url: https://petstore.swagger.io/v2/swagger.json
output_directory: lib/api/kotlin
language: kotlin
diff --git a/swagger_parser/lib/src/config/yaml_config.dart b/swagger_parser/lib/src/config/yaml_config.dart
index ceb189a2..94274c44 100644
--- a/swagger_parser/lib/src/config/yaml_config.dart
+++ b/swagger_parser/lib/src/config/yaml_config.dart
@@ -1,6 +1,8 @@
import 'package:args/args.dart';
+import 'package:collection/collection.dart';
import 'package:yaml/yaml.dart';
+import '../generator/models/prefer_schema_source.dart';
import '../generator/models/programming_language.dart';
import '../generator/models/replacement_rule.dart';
import '../utils/file_utils.dart';
@@ -17,9 +19,12 @@ import 'config_exception.dart';
final class YamlConfig {
/// Applies parameters directly from constructor
const YamlConfig({
- required this.schemaPath,
- required this.outputDirectory,
required this.name,
+ required this.outputDirectory,
+ this.schemaPath,
+ this.schemaUrl,
+ this.schemaFromUrlToFile,
+ this.preferSchemaSource,
this.language,
this.freezed,
this.rootClient,
@@ -48,9 +53,19 @@ final class YamlConfig {
schemaPath = '';
}
- if (schemaPath == null) {
+ final schemaUrl = yamlConfig['schema_url']?.toString();
+ if (schemaUrl != null) {
+ final uri = Uri.tryParse(schemaUrl);
+ if (uri == null) {
+ throw const ConfigException(
+ "Config parameter 'schema_url' must be valid URL.",
+ );
+ }
+ }
+
+ if (schemaPath == null && schemaUrl == null) {
throw const ConfigException(
- "Config parameter 'schema_path' is required.",
+ "Config parameters 'schema_path' or 'schema_url' are required.",
);
}
@@ -73,13 +88,48 @@ final class YamlConfig {
outputDirectory = rootConfig.outputDirectory;
}
+ final rawName = yamlConfig['name'];
+ if (rawName is! String?) {
+ throw const ConfigException(
+ "Config parameter 'name' must be String.",
+ );
+ }
+
+ final name = rawName == null || rawName.isEmpty
+ ? (schemaPath ?? schemaUrl)!
+ .split('/')
+ .lastOrNull
+ ?.split('.')
+ .firstOrNull ??
+ 'unknown'
+ : rawName;
+
+ final schemaFromUrlToFile = yamlConfig['schema_from_url_to_file'];
+ if (schemaFromUrlToFile is! bool?) {
+ throw const ConfigException(
+ "Config parameter 'schema_from_url_to_file' must be bool.",
+ );
+ }
+
+ PreferSchemaSource? preferSchemaSource;
+ final rawPreferSchemeSource =
+ yamlConfig['prefer_schema_source']?.toString();
+ if (rawPreferSchemeSource != null) {
+ preferSchemaSource = PreferSchemaSource.fromString(rawPreferSchemeSource);
+ if (preferSchemaSource == null) {
+ throw ConfigException(
+ "'prefer_schema_source' field must be contained in ${PreferSchemaSource.values.map((e) => e.name)}.",
+ );
+ }
+ }
+
ProgrammingLanguage? language;
final rawLanguage = yamlConfig['language']?.toString();
if (rawLanguage != null) {
language = ProgrammingLanguage.fromString(rawLanguage);
if (language == null) {
throw ConfigException(
- "'language' field must be contained in ${ProgrammingLanguage.values}.",
+ "'language' field must be contained in ${ProgrammingLanguage.values.map((e) => e.name)}.",
);
}
}
@@ -117,6 +167,13 @@ final class YamlConfig {
);
}
+ final putInFolder = yamlConfig['put_in_folder'];
+ if (putInFolder is! bool?) {
+ throw const ConfigException(
+ "Config parameter 'put_in_folder' must be bool.",
+ );
+ }
+
final squashClients = yamlConfig['squash_clients'];
if (squashClients is! bool?) {
throw const ConfigException(
@@ -180,37 +237,23 @@ final class YamlConfig {
}
}
- final putInFolder = yamlConfig['put_in_folder'];
- if (putInFolder is! bool?) {
- throw const ConfigException(
- "Config parameter 'put_in_folder' must be bool.",
- );
- }
-
- final rawName = yamlConfig['name'];
- if (rawName is! String?) {
- throw const ConfigException(
- "Config parameter 'name' must be String.",
- );
- }
-
- final name = rawName == null || rawName.isEmpty
- ? schemaPath.split('/').last.split('.').first
- : rawName;
-
return YamlConfig(
+ name: name,
schemaPath: schemaPath,
outputDirectory: outputDirectory,
- name: name,
+ schemaUrl: schemaUrl,
+ schemaFromUrlToFile:
+ schemaFromUrlToFile ?? rootConfig?.schemaFromUrlToFile,
+ preferSchemaSource: preferSchemaSource ?? rootConfig?.preferSchemaSource,
language: language ?? rootConfig?.language,
freezed: freezed ?? rootConfig?.freezed,
rootClient: rootClient ?? rootConfig?.rootClient,
rootClientName: rootClientName ?? rootConfig?.rootClientName,
clientPostfix: clientPostfix ?? rootConfig?.clientPostfix,
+ putInFolder: putInFolder ?? rootConfig?.putInFolder,
putClientsInFolder: putClientsInFolder ?? rootConfig?.putClientsInFolder,
squashClients: squashClients ?? rootConfig?.squashClients,
pathMethodName: pathMethodName ?? rootConfig?.pathMethodName,
- putInFolder: putInFolder ?? rootConfig?.putInFolder,
enumsToJson: enumsToJson ?? rootConfig?.enumsToJson,
enumsPrefix: enumsPrefix ?? rootConfig?.enumsPrefix,
markFilesAsGenerated:
@@ -249,17 +292,19 @@ final class YamlConfig {
final configs = [];
final schemaPath = yamlMap['schema_path'] as String?;
+ final schemaUrl = yamlMap['schema_url'] as String?;
final schemas = yamlMap['schemas'] as YamlList?;
- if (schemas == null && schemaPath == null) {
+ if (schemas == null && schemaUrl == null && schemaPath == null) {
throw const ConfigException(
- "Config parameter 'schema_path' or 'schemas' is required.",
+ "Config parameter 'schema_path', 'schema_url' or 'schemas' is required.",
);
}
- if (schemas != null && schemaPath != null) {
+ if (schemas != null && schemaPath != null ||
+ schemas != null && schemaUrl != null) {
throw const ConfigException(
- "Config parameter 'schema_path' and 'schemas' can't be used together.",
+ "Config parameter 'schema_path' or 'schema_url' can't be used with 'schemas'.",
);
}
@@ -290,16 +335,19 @@ final class YamlConfig {
}
final String name;
- final String schemaPath;
final String outputDirectory;
+ final String? schemaPath;
+ final String? schemaUrl;
+ final bool? schemaFromUrlToFile;
+ final PreferSchemaSource? preferSchemaSource;
final ProgrammingLanguage? language;
final bool? freezed;
final String? clientPostfix;
final bool? rootClient;
final String? rootClientName;
- final bool? putClientsInFolder;
final bool? squashClients;
final bool? pathMethodName;
+ final bool? putClientsInFolder;
final bool? putInFolder;
final bool? enumsToJson;
final bool? enumsPrefix;
diff --git a/swagger_parser/lib/src/generator/generator.dart b/swagger_parser/lib/src/generator/generator.dart
index cc9ac8dd..ab13ef9d 100644
--- a/swagger_parser/lib/src/generator/generator.dart
+++ b/swagger_parser/lib/src/generator/generator.dart
@@ -1,14 +1,18 @@
+import 'dart:convert';
+
import 'package:path/path.dart' as p;
import '../config/yaml_config.dart';
import '../parser/parser.dart';
import '../utils/case_utils.dart';
import '../utils/file_utils.dart';
+import '../utils/utils.dart';
import 'fill_controller.dart';
import 'generator_exception.dart';
import 'models/generated_file.dart';
import 'models/generation_statistics.dart';
import 'models/open_api_info.dart';
+import 'models/prefer_schema_source.dart';
import 'models/programming_language.dart';
import 'models/replacement_rule.dart';
import 'models/universal_data_class.dart';
@@ -21,11 +25,15 @@ final class Generator {
/// Applies parameters directly from constructor
/// and sets them to default if not found
Generator({
- required String schemaContent,
required String outputDirectory,
+ String? schemaPath,
+ String? schemaUrl,
+ String? schemaContent,
+ bool? isYaml,
+ bool? schemaFromUrlToFile,
+ PreferSchemaSource? preferSchemeSource,
ProgrammingLanguage? language,
String? name,
- bool? isYaml,
bool? freezed,
bool? rootClient,
String? clientPostfix,
@@ -38,11 +46,15 @@ final class Generator {
bool? enumsPrefix,
bool? markFilesAsGenerated,
List? replacementRules,
- }) : _schemaContent = schemaContent,
+ }) : _schemaPath = schemaPath,
+ _schemaUrl = schemaUrl,
+ _schemaContent = schemaContent,
+ _isYaml = isYaml ?? false,
+ _schemaFromUrlToFile = schemaFromUrlToFile ?? true,
+ _preferSchemeSource = preferSchemeSource ?? PreferSchemaSource.url,
_outputDirectory = outputDirectory,
_name = name,
_programmingLanguage = language ?? ProgrammingLanguage.dart,
- _isYaml = isYaml ?? false,
_freezed = freezed ?? false,
_rootClient = rootClient ?? true,
_rootClientName = rootClientName ?? 'RestClient',
@@ -58,21 +70,14 @@ final class Generator {
/// Applies parameters set from yaml config file
factory Generator.fromYamlConfig(YamlConfig yamlConfig) {
- final schemaPath = yamlConfig.schemaPath;
- final configFile = schemaFile(schemaPath);
- if (configFile == null) {
- throw GeneratorException("Can't find schema file at $schemaPath.");
- }
-
- final isYaml = p.extension(schemaPath).toLowerCase() == '.yaml';
- final schemaContent = configFile.readAsStringSync();
-
return Generator(
- schemaContent: schemaContent,
outputDirectory: yamlConfig.outputDirectory,
+ schemaPath: yamlConfig.schemaPath,
+ schemaUrl: yamlConfig.schemaUrl,
+ schemaFromUrlToFile: yamlConfig.schemaFromUrlToFile,
+ preferSchemeSource: yamlConfig.preferSchemaSource,
language: yamlConfig.language,
name: yamlConfig.name,
- isYaml: isYaml,
freezed: yamlConfig.freezed,
rootClient: yamlConfig.rootClient,
rootClientName: yamlConfig.rootClientName,
@@ -89,10 +94,22 @@ final class Generator {
}
/// The contents of your schema file
- final String _schemaContent;
+ String? _schemaContent;
/// Is the schema format YAML
- final bool _isYaml;
+ bool _isYaml;
+
+ /// The path to your schema file
+ final String? _schemaPath;
+
+ /// The url to your schema file
+ final String? _schemaUrl;
+
+ /// If true, schema will be extracted from url and saved to file
+ final bool _schemaFromUrlToFile;
+
+ /// Prefer schema from url or file
+ final PreferSchemaSource _preferSchemeSource;
/// Output directory
final String _outputDirectory;
@@ -155,6 +172,7 @@ final class Generator {
Future<(OpenApiInfo, GenerationStatistics)> generateFiles() async {
final stopwatch = Stopwatch()..start();
+ await _fetchSchemaContent();
_parseOpenApiDefinitionFile();
await _generateFiles();
@@ -177,15 +195,62 @@ final class Generator {
/// Generates content of files based on OpenApi definition file
/// and return list of [GeneratedFile]
Future> generateContent() async {
+ await _fetchSchemaContent();
_parseOpenApiDefinitionFile();
return _fillContent();
}
+ Future _fetchSchemaContent() async {
+ final url = _schemaUrl;
+ final path = _schemaPath;
+
+ if ((_preferSchemeSource == PreferSchemaSource.url || path == null) &&
+ url != null) {
+ final extension = p.extension(url).toLowerCase();
+ _isYaml = switch (extension) {
+ '.yaml' => true,
+ '.json' => false,
+ _ => throw GeneratorException(
+ 'Unsupported $url extension: $extension',
+ ),
+ };
+ extractingSchemaFromUrlMessage(url);
+ _schemaContent = await schemaFromUrl(url);
+ if (_schemaFromUrlToFile && path != null) {
+ if (!_isYaml) {
+ final formattedJson = const JsonEncoder.withIndent(' ')
+ .convert(jsonDecode(_schemaContent!));
+ writeSchemaToFile(formattedJson, path);
+ } else {
+ writeSchemaToFile(_schemaContent!, path);
+ }
+ }
+ } else if (path != null) {
+ final configFile = schemaFile(path);
+ if (configFile == null) {
+ throw GeneratorException("Can't find schema file at $path.");
+ }
+ final extension = p.extension(path).toLowerCase();
+ _isYaml = switch (extension) {
+ '.yaml' => true,
+ '.json' => false,
+ _ => throw GeneratorException(
+ 'Unsupported $path extension: $extension',
+ ),
+ };
+ _schemaContent = configFile.readAsStringSync();
+ } else if (_schemaContent == null) {
+ throw GeneratorException(
+ "Parameters 'schemaPath' or 'schemaUrl' or 'schemaContent' are required",
+ );
+ }
+ }
+
/// Parse definition file content and fill list of [UniversalRestClient]
/// and list of [UniversalDataClass]
void _parseOpenApiDefinitionFile() {
final parser = OpenApiParser(
- _schemaContent,
+ _schemaContent!,
isYaml: _isYaml,
pathMethodName: _pathMethodName,
enumsPrefix: _enumsPrefix,
diff --git a/swagger_parser/lib/src/generator/models/prefer_schema_source.dart b/swagger_parser/lib/src/generator/models/prefer_schema_source.dart
new file mode 100644
index 00000000..9a0b7801
--- /dev/null
+++ b/swagger_parser/lib/src/generator/models/prefer_schema_source.dart
@@ -0,0 +1,16 @@
+import 'package:collection/collection.dart';
+
+/// Enum for choosing schema source
+enum PreferSchemaSource {
+ /// Prefer remote schema from url
+ url,
+
+ /// Prefer local schema from file
+ path;
+
+ /// Returns [PreferSchemaSource] from string
+ static PreferSchemaSource? fromString(String string) =>
+ values.firstWhereOrNull(
+ (e) => e.name == string,
+ );
+}
diff --git a/swagger_parser/lib/src/parser/parser.dart b/swagger_parser/lib/src/parser/parser.dart
index baefc1fa..10100205 100644
--- a/swagger_parser/lib/src/parser/parser.dart
+++ b/swagger_parser/lib/src/parser/parser.dart
@@ -24,15 +24,15 @@ class OpenApiParser {
/// and [isYaml] schema format or not
OpenApiParser(
String fileContent, {
+ String? name,
bool isYaml = false,
bool enumsPrefix = false,
bool pathMethodName = false,
- String? name,
bool squashClients = false,
List replacementRules = const [],
- }) : _pathMethodName = pathMethodName,
+ }) : _name = name,
+ _pathMethodName = pathMethodName,
_enumsPrefix = enumsPrefix,
- _name = name,
_squashClients = squashClients,
_replacementRules = replacementRules {
_definitionFileContent = isYaml
diff --git a/swagger_parser/lib/src/utils/file_utils.dart b/swagger_parser/lib/src/utils/file_utils.dart
index 8819aa68..1b40b65c 100644
--- a/swagger_parser/lib/src/utils/file_utils.dart
+++ b/swagger_parser/lib/src/utils/file_utils.dart
@@ -1,3 +1,4 @@
+import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as p;
@@ -30,6 +31,18 @@ File? schemaFile(String filePath) {
return file.existsSync() ? file : null;
}
+void writeSchemaToFile(String schemaContent, String filePath) {
+ File(p.join(_rootDirectoryPath, filePath)).writeAsStringSync(schemaContent);
+}
+
+Future schemaFromUrl(String url) async {
+ final client = HttpClient();
+ final request = await client.getUrl(Uri.parse(url));
+ final response = await request.close();
+ final data = await response.transform(utf8.decoder).join();
+ return data;
+}
+
/// Creates DTO file
Future generateFile(
String outputDirectory,
diff --git a/swagger_parser/lib/src/utils/utils.dart b/swagger_parser/lib/src/utils/utils.dart
index 8da46b6f..46935fe8 100644
--- a/swagger_parser/lib/src/utils/utils.dart
+++ b/swagger_parser/lib/src/utils/utils.dart
@@ -10,6 +10,9 @@ import '../utils/case_utils.dart';
const _green = '\x1B[32m';
// ignore: unused_element
const _yellow = '\x1B[33m';
+// ignore: unused_element
+const _blue = '\x1B[34m';
+const _lightBlue = '\x1B[36m';
const _red = '\x1B[31m';
const _reset = '\x1B[0m';
@@ -78,12 +81,12 @@ const _ignoreLintsComment = '''
void introMessage() {
stdout.writeln(
- '''
- ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
- ┃ ┃
- ┃ Welcome to swagger_parser ┃
- ┃ ┃
- ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
+ r'''
+
+┃ ____ _ _ _ ____ ____ ____ ____ ____ ___ ____ ____ ____ ____ ____
+┃ [__ | | | |__| | __ | __ |___ |__/ |__] |__| |__/ [__ |___ |__/
+┃ ___] |_|_| | | |__] |__] |___ | \ ___ | | | | \ ___] |___ | \
+┃
''',
);
}
@@ -92,6 +95,10 @@ void generateMessage() {
stdout.writeln('Generate...');
}
+void extractingSchemaFromUrlMessage(String url) {
+ stdout.writeln('Extracting schema from $_lightBlue$url...$_reset');
+}
+
final _numbersRegExp = RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))');
String formatNumber(int number) => '$number'.replaceAllMapped(
@@ -112,12 +119,12 @@ void schemaStatisticsMessage({
}
stdout.writeln(
- '\n> $title $version: \n'
+ '> $title $version: \n'
' ${formatNumber(statistics.totalRestClients)} rest clients, '
'${formatNumber(statistics.totalRequests)} requests, '
'${formatNumber(statistics.totalDataClasses)} data classes.\n'
' ${formatNumber(statistics.totalFiles)} files with ${formatNumber(statistics.totalLines)} lines of code.\n'
- ' ${_green}Success (${statistics.timeElapsed.inMilliseconds / 1000} seconds)$_reset',
+ ' ${_green}Success (${statistics.timeElapsed.inMilliseconds / 1000} seconds)$_reset\n',
);
}
@@ -132,10 +139,10 @@ void schemaFailedMessage({
}
stdout.writeln(
- '\n> $title: \n'
+ '> $title: \n'
' ${_red}Failed to generate files.$_reset\n'
' $error\n'
- ' ${stack.toString().replaceAll('\n', '\n ')}',
+ ' ${stack.toString().replaceAll('\n', '\n ')}\n',
);
}
@@ -145,7 +152,7 @@ void summaryStatisticsMessage({
required GenerationStatistics statistics,
}) {
stdout.writeln(
- '\nSummary (${statistics.timeElapsed.inMilliseconds / 1000} seconds):\n'
+ 'Summary (${statistics.timeElapsed.inMilliseconds / 1000} seconds):\n'
'${successCount != schemasCount ? '$successCount/$schemasCount' : '$schemasCount'} schemas, '
'${formatNumber(statistics.totalRestClients)} clients, '
'${formatNumber(statistics.totalRequests)} requests, '
@@ -160,19 +167,16 @@ void doneMessage({
}) {
if (successSchemasCount == 0) {
stdout.writeln(
- '\n'
'${_red}The generation was completed with errors.\n'
'No schemas were generated.$_reset',
);
} else if (successSchemasCount != schemasCount) {
stdout.writeln(
- '\n'
'${_red}The generation was completed with errors.\n'
'${schemasCount - successSchemasCount} schemas were not generated.$_reset',
);
} else {
stdout.writeln(
- '\n'
'${schemasCount > 1 ? _green : ''}The generation was completed successfully. '
'You can run the generation using build_runner.${schemasCount > 1 ? _reset : ''}',
);