refactor(update-version-script): update the script to generate the markdown files from a json file that contains the data to allow automate the CHANGELOG.md for the packages easier in CI, add a comment that indicate those files are generated.

pull/1879/head
Ellet 11 months ago
parent 2d828830fc
commit 769e9f2882
  1. 122
      scripts/regenerate_versions.dart

@ -1,11 +1,12 @@
// ignore_for_file: avoid_print // ignore_for_file: avoid_print
import 'dart:convert' show jsonDecode, jsonEncode;
import 'dart:io' show File, exit; import 'dart:io' show File, exit;
import 'package:yaml_edit/yaml_edit.dart'; import 'package:yaml_edit/yaml_edit.dart' show YamlEditor;
/// The list of the packages that which will be used to update the `CHANGELOG.md` /// The list of the packages that which will be used to update the `CHANGELOG.md`
/// and `README.md` files for all the packages /// and the version in the `pubspec.yaml` for all the packages
final _packages = [ final _packages = [
'./', './',
'./dart_quill_delta', './dart_quill_delta',
@ -15,51 +16,120 @@ final _packages = [
'./quill_pdf_converter', './quill_pdf_converter',
]; ];
const _usage = 'Usage: ./script <version> <changelog-version-content>';
/// A script that should run in the root folder and not inside any other folder /// A script that should run in the root folder and not inside any other folder
/// it has one task, which update the version for `pubspec.yaml` and `CHANGELOG.md` for all the packages /// it has one task, which update the version for `pubspec.yaml` and
/// since we have only one CHANGELOG.md file and version, previously we had different `CHANGELOG.md` and `pubspec.yaml` package version /// `CHANGELOG.md` for all the packages, the `CHANGELOG.md` files will be
/// for each package /// generated from a json file which is the source of the data
///
/// the script can be used with the following args [_usage]
/// it will require a version and the changes for that version (as a [String])
/// if the version exist then it will modify it with the new changes
/// if not, then will be added at the start
/// ///
/// the new version should be passed in the [args], the script accept only one argument /// the source file (which used to generate the `CHANGELOG.md` files) will
/// also updated with the new change
///
/// this script designed to run in CI to automate the process of updating
/// the package
Future<void> main(List<String> args) async { Future<void> main(List<String> args) async {
if (args.isEmpty) { if (args.isEmpty || args.length < 2) {
print('Missing required version argument. Usage: ./script <new-version>'); print('Missing required arguments. $_usage');
exit(1); exit(1);
} }
if (args.length > 1) { if (args.length > 2) {
print('Too many arguments. Usage: ./script <new-version>'); print('Too many arguments. $_usage');
exit(1); exit(1);
} }
final newVersion = args[0]; final passedVersion = args[0];
if (newVersion.isEmpty) { if (passedVersion.isEmpty) {
print('The new version is empty. Usage: ./script <new-version>'); print('The version is empty. $_usage');
exit(1); exit(1);
} }
final passedVersionContent = args[1];
if (passedVersionContent.isEmpty) {
print('The version content is empty. $_usage');
exit(1);
}
// A file that will be used to build the `CHANGELOG.md` files
// the data format is in Json
final sourceChangeLogFile = File('./CHANGELOG.json');
await _replaceVersion(
sourceChangeLogFile: sourceChangeLogFile,
version: passedVersion,
versionContent: passedVersionContent,
);
final sourceChangeLog = jsonDecode(await sourceChangeLogFile.readAsString())
as Map<String, Object?>;
final generatedChangeLogBuffer = StringBuffer()
..write(
'<!-- This file is auto-generated from ${sourceChangeLogFile.uri.pathSegments.last} using a script - Manual changes will be overwritten -->\n\n',
)
..write('# Changelog\n\n')
..write(
'All notable changes to this project will be documented in this file.\n\n',
);
sourceChangeLog.forEach((version, versionContent) {
generatedChangeLogBuffer
..write('## $version\n\n')
..write('$versionContent\n\n');
});
for (final packagePath in _packages) { for (final packagePath in _packages) {
await updatePubspecYamlFile('$packagePath/pubspec.yaml', await _updatePubspecYamlFile(
newVersion: newVersion); pubspecYamlPath: '$packagePath/pubspec.yaml',
if (packagePath != _packages.first) { newVersion: passedVersion,
updateChangelogMD('$packagePath/CHANGELOG.md'); );
} _updateChangelog(
changeLogFilePath: '$packagePath/CHANGELOG.md',
changeLogContent: generatedChangeLogBuffer.toString(),
);
} }
} }
/// Replace the version content by the version if it exist
/// or add the version at the start of the map if it doesn't exist
///
/// then save the changes to the [sourceChangeLogFile]
Future<void> _replaceVersion({
required File sourceChangeLogFile,
required String version,
required String versionContent,
}) async {
final sourceChangeLog = jsonDecode(await sourceChangeLogFile.readAsString())
as Map<String, Object?>;
if (sourceChangeLog[version] != null) {
sourceChangeLog[version] = versionContent;
} else {
// A workaround to add the new item at the start, the order matter
// becase later it will generate the markdown files
final newMap = <String, Object?>{version: versionContent};
sourceChangeLog
..forEach((key, value) => newMap[key] = value)
..clear()
..addAll(newMap);
}
await sourceChangeLogFile.writeAsString(jsonEncode(sourceChangeLog));
}
/// Update the [pubspecYamlPath] file to update the `version` property from [newVersion] /// Update the [pubspecYamlPath] file to update the `version` property from [newVersion]
Future<void> updatePubspecYamlFile( Future<void> _updatePubspecYamlFile({
String pubspecYamlPath, { required String pubspecYamlPath,
required String newVersion, required String newVersion,
}) async { }) async {
final file = File(pubspecYamlPath); final file = File(pubspecYamlPath);
final yaml = await file.readAsString(); final yaml = await file.readAsString();
final yamlEditor = YamlEditor(yaml)..update(['version'], newVersion); final yamlEditor = YamlEditor(yaml)..update(['version'], newVersion);
await file.writeAsString(yamlEditor.toString()); await file.writeAsString(yamlEditor.toString());
print(yamlEditor.toString());
} }
/// Read the contents of the root `CHANGELOG.md` file and copy it /// Copy [changeLogContent] and overwrite it to the [changeLogFilePath]
/// to the [changeLogFilePath] Future<void> _updateChangelog({
Future<void> updateChangelogMD(String changeLogFilePath) async { required String changeLogFilePath,
final rootChangeLogFileContent = await File('./CHANGELOG.md').readAsString(); required String changeLogContent,
}) async {
final changeLogFile = File(changeLogFilePath); final changeLogFile = File(changeLogFilePath);
await changeLogFile.writeAsString(rootChangeLogFileContent); await changeLogFile.writeAsString(changeLogContent);
} }

Loading…
Cancel
Save