run method
Runs this command.
The return value is wrapped in a Future if necessary and returned by
CommandRunner.runCommand.
Implementation
@override
Future<void> run() async {
final currentDir = Directory.current;
print('Current project directory: ${currentDir.path}');
final changelogFile = File('${currentDir.path}/CHANGELOG.md');
final readmeFile = File('${currentDir.path}/README.md');
// Get the latest git tag (version)
final latestTagResult = await Process.run('git', [
'describe',
'--tags',
'--abbrev=0',
]);
String latestVersion = 'Unreleased';
if (latestTagResult.exitCode == 0) {
latestVersion = (latestTagResult.stdout as String).trim();
} else {
print('No git tags found, using "Unreleased" as version.');
}
// Get commits since the latest tag or all commits if no tag
List<String> commits = [];
if (latestVersion != 'Unreleased') {
final commitsResult = await Process.run('git', [
'log',
'$latestVersion..HEAD',
'--pretty=format:%s',
]);
if (commitsResult.exitCode == 0) {
commits = (commitsResult.stdout as String)
.split('\n')
.where((c) => c.trim().isNotEmpty)
.toList();
}
} else {
final commitsResult = await Process.run('git', [
'log',
'--pretty=format:%s',
]);
if (commitsResult.exitCode == 0) {
commits = (commitsResult.stdout as String)
.split('\n')
.where((c) => c.trim().isNotEmpty)
.toList();
}
}
if (commits.isEmpty) {
print('No new commits found to update CHANGELOG.md');
return;
}
final newVersion = latestVersion == 'Unreleased'
? 'v0.1.0'
: _incrementVersion(latestVersion);
final changelogEntry = StringBuffer();
changelogEntry.writeln('## $newVersion\n');
for (final commit in commits) {
changelogEntry.writeln('- $commit');
}
changelogEntry.writeln();
String existingChangelog = '';
if (await changelogFile.exists()) {
existingChangelog = await changelogFile.readAsString();
}
final updatedChangelog = StringBuffer();
updatedChangelog.writeln(changelogEntry.toString());
updatedChangelog.writeln(existingChangelog);
// Write or update CHANGELOG.md
if (await changelogFile.exists()) {
// Prepend new entry to existing changelog
final existingChangelog = await changelogFile.readAsString();
final updatedChangelogExisting = StringBuffer();
updatedChangelogExisting.writeln(changelogEntry.toString());
updatedChangelogExisting.writeln(existingChangelog);
await changelogFile.writeAsString(updatedChangelogExisting.toString());
print('CHANGELOG.md updated with version $newVersion');
} else {
// Create a new changelog file
final newChangelog = StringBuffer();
newChangelog.writeln('# Changelog\n');
newChangelog.writeln(
'All notable changes to this project will be documented in this file.',
);
newChangelog.writeln();
newChangelog.writeln(changelogEntry.toString());
await changelogFile.writeAsString(newChangelog.toString());
print('CHANGELOG.md created with version $newVersion');
}
// Only generate README if it does not already exist. If it exists, skip modifications.
if (await readmeFile.exists()) {
print('README.md exists; skipping README generation or updates.');
} else {
// Create a minimal README with version and changelog summary
final changelogSummary = commits.map((c) => '- $c').join('\n');
final newReadmeContent =
'''# Project
Latest Version: $newVersion
## Changelog Summary
$changelogSummary
''';
await readmeFile.writeAsString(newReadmeContent);
print('README.md created with latest version and changelog summary');
}
}