blob: 76b65ef980124a8d6b38575af72d2dfab39c3750 [file] [log] [blame]
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:io';
import 'package:collection/collection.dart';
class Changelog {
final File file;
Changelog(this.file);
bool get exists => file.existsSync();
String? get latestVersion {
var input = latestHeading;
if (input == null) {
return null;
}
final versionRegex = RegExp(r'[0-9]+\.[0-9]+\.[0-9]+(\+[0-9]+)?');
var match = versionRegex.firstMatch(input);
if (match != null) {
var version = match.group(0);
return version;
}
return null;
}
String? get latestHeading {
var sections = _parseSections();
// Remove all leading "#"
return sections.firstOrNull?.title.replaceAll(RegExp(r'^#*'), '').trim();
}
List<String> get latestChangeEntries {
var sections = _parseSections();
return sections.isEmpty ? [] : sections.first.entries;
}
Iterable<_Section> _parseSections() sync* {
if (!exists) return;
_Section? section;
for (var line in file.readAsLinesSync().where((line) => line.isNotEmpty)) {
if (line.startsWith('## ')) {
if (section != null) yield section;
section = _Section(line);
} else if (section != null) {
section.entries.add(line);
}
}
if (section != null) yield section;
}
String get describeLatestChanges {
var buf = StringBuffer();
for (var entry in latestChangeEntries) {
buf.writeln(entry);
}
return buf.toString();
}
}
class _Section {
final String title;
final List<String> entries = [];
_Section(this.title);
}