Skip to content

Commit

Permalink
Clean-up and tweaks of the firehose project. (#117)
Browse files Browse the repository at this point in the history
Cleaned up and reduced RegExp use.
Simplified some functions.
Upped SDK constraint to 3.0.0, to use `firstOrNull` from SDK.
Use a named parameter for optional boolean parameer.
Added documentation to remaining `RegExp`s.
(Always document what a RegExp matches in prose. They are *not* readable or self-explanatory.)
  • Loading branch information
lrhn committed Jun 29, 2023
1 parent 9ef5948 commit 19fa443
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 58 deletions.
5 changes: 5 additions & 0 deletions pkgs/firehose/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
## 0.3.19
- Clean-up and optimizations.
- Stop depending on `package:collection` now that SDK 3.0.0 has `firstOrNull`.

## 0.3.18
- Add Github workflow for PR health.
- Refactorings to health workflow.
- Require Dart `3.0.0`.

## 0.3.17

Expand Down
17 changes: 10 additions & 7 deletions pkgs/firehose/lib/firehose.dart
Original file line number Diff line number Diff line change
Expand Up @@ -288,18 +288,21 @@ class VerificationResults {

bool get hasError => results.any((r) => r.severity == Severity.error);

String describeAsMarkdown([bool withTag = true]) {
String describeAsMarkdown({bool withTag = true}) {
results.sort((a, b) => Enum.compareByIndex(a.severity, b.severity));

return results.map((r) {
var sev = r.severity == Severity.error ? '(error) ' : '';
var tag = r.gitTag == null ? '' : '`${r.gitTag}`';
var publishReleaseUri = r.publishReleaseUri;
if (publishReleaseUri != null) {
tag = '[$tag]($publishReleaseUri)';
}
var tagColumn = '';
if (withTag) {
var tag = r.gitTag == null ? '' : '`${r.gitTag}`';
var publishReleaseUri = r.publishReleaseUri;
if (publishReleaseUri != null) {
tag = '[$tag]($publishReleaseUri)';
}

var tagColumn = withTag ? ' | $tag' : '';
tagColumn = ' | $tag';
}
return '| package:${r.package.name} | ${r.package.version} | '
'$sev${r.message}$tagColumn |';
}).join('\n');
Expand Down
2 changes: 1 addition & 1 deletion pkgs/firehose/lib/health.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class Health {
var markdownTable = '''
| Package | Version | Status |
| :--- | ---: | :--- |
${results.describeAsMarkdown(false)}
${results.describeAsMarkdown(withTag: false)}
Documentation at https://github.com/dart-lang/ecosystem/wiki/Publishing-automation.
''';
Expand Down
68 changes: 39 additions & 29 deletions pkgs/firehose/lib/src/changelog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,69 +4,79 @@

import 'dart:io';

import 'package:collection/collection.dart';

class Changelog {
static const _headerLinePrefix = '## ';

final File file;

Changelog(this.file);

bool get exists => file.existsSync();

/// Pattern recognizing some SemVer formats.
///
/// Accepts:
/// > digits '.' digits '.' digits
///
/// optionally followed by `-` or `+` character
/// and one or more "word characters", which are
/// ASCII letters (`a`-`z`, `A`-`Z`), digits (`0`-`9`),
/// underscore (`_`) and dollar-sign (`$`).
///
/// This is not all complete SemVer version strings,
/// since it doesn't allow `.` in the continuation,
/// or a `+...` sequence after a `-` sequence.
/// It should be enough for the user-cases we need it for
/// in this package.
static final _versionRegex = RegExp(r'\d+\.\d+\.\d+(?:[\-+]\w+)?');

String? get latestVersion {
var input = latestHeading;

if (input == null) {
return null;
if (input != null) {
var match = _versionRegex.firstMatch(input);
if (match != null) {
var version = match[0];
return version;
}
}

final versionRegex = RegExp(r'[0-9]+\.[0-9]+\.[0-9]+([-\+]\w+)?');

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();
var section = sections.firstOrNull;
if (section == null) return null;
// Remove the leading `_headerLinePrefix`, then trim left-over whitespace.
var title = section.title;
assert(title.startsWith(_headerLinePrefix));
return title.substring(_headerLinePrefix.length).trim();
}

List<String> get latestChangeEntries {
var sections = _parseSections();
return sections.isEmpty ? [] : sections.first.entries;
}
List<String> get latestChangeEntries =>
_parseSections().firstOrNull?.entries ?? [];

Iterable<_Section> _parseSections() sync* {
if (!exists) return;

_Section? section;

for (var line in file.readAsLinesSync().where((line) => line.isNotEmpty)) {
if (line.startsWith('## ')) {
for (var line in file.readAsLinesSync()) {
if (line.isEmpty) continue;
if (line.startsWith(_headerLinePrefix)) {
if (section != null) yield section;

section = _Section(line);
} else if (section != null) {
section.entries.add(line);
} else {
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();
}
String get describeLatestChanges => latestChangeEntries.join();
}

class _Section {
Expand Down
59 changes: 40 additions & 19 deletions pkgs/firehose/lib/src/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,41 +25,62 @@ Future<int> runCommand(

process.stdout
.transform(utf8.decoder)
.transform(LineSplitter())
.listen((line) => stdout.writeln(' $line'));
.transform(const LineSplitter())
.listen((line) => stdout
..write(' ')
..writeln(line));
process.stderr
.transform(utf8.decoder)
.transform(LineSplitter())
.listen((line) => stderr.writeln(' $line'));
.transform(const LineSplitter())
.listen((line) => stderr
..write(' ')
..writeln(line));

return process.exitCode;
}

class Tag {
/// RegExp matching a version tag at the start of a line.
///
/// A version tag is an optional starting seqeuence
/// of non-whitespace, which is the package name,
/// followed by a `v` and a simplified SemVer version
/// number.
/// The version number accepted is
/// > digits '.' digits '.' digits
///
/// and if followed by a `+`, then it includes the
/// rest of the line.
static final RegExp packageVersionTag =
RegExp(r'^(\S+)-v(\d+\.\d+\.\d+(\+.*)?)');

static final RegExp versionTag = RegExp(r'^v(\d+\.\d+\.\d+(\+.*)?)');
RegExp(r'^(?:(\S+)-)?v(\d+\.\d+\.\d+(?:\+.*)?)');

/// A package version tag.
///
/// Is expected to have the format:
/// > (package-name)? 'v' SemVer-version
///
/// If not, the tag is not [valid], and the [package] and [version]
/// will both be `null`.
final String tag;

Tag(this.tag);

bool get valid => version != null;

String? get package {
var match = packageVersionTag.firstMatch(tag);
return match?.group(1);
}
/// The package name before the `v` in the version [tag], if any.
///
/// Is `null` if there is no package name before the `v`,
/// or if the tag is not [valid].
String? get package => packageVersionTag.firstMatch(tag)?[1];

String? get version {
var match = packageVersionTag.firstMatch(tag);
if (match != null) {
return match.group(2);
}
match = versionTag.firstMatch(tag);
return match?.group(1);
}
/// The SemVer version string of the version [tag], if any.
///
/// This is the part after the `v` of the [tag] string,
/// of the form, which is a major/minor/patch version string
/// optionally followed by a `+` and more characters.
///
/// Is `null` if the tag is not [valid].
String? get version => packageVersionTag.firstMatch(tag)?[2];

@override
String toString() => tag;
Expand Down
3 changes: 1 addition & 2 deletions pkgs/firehose/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: firehose
description: A tool to automate publishing of Pub packages from GitHub actions.
version: 0.3.18
version: 0.3.19
repository: https://github.com/dart-lang/ecosystem/tree/main/pkgs/firehose

environment:
Expand All @@ -11,7 +11,6 @@ executables:

dependencies:
args: ^2.3.0
collection: ^1.17.0
http: ^0.13.0
path: ^1.8.0
pub_semver: ^2.1.0
Expand Down

0 comments on commit 19fa443

Please sign in to comment.