Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 10 additions & 16 deletions .github/workflows/groundskeeper.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Groundskeeper
description: Reusable workflow to run dart format and dart fix across packages using groundskeeper, and create a PR if there are changes.
description: Reusable workflow to run dart format and dart fix on a single package, and create a PR if there are changes.

on:
workflow_call:
Expand Down Expand Up @@ -34,11 +34,6 @@ on:
required: false
type: boolean
default: true
exclude:
description: 'Comma-separated list of package directories to exclude'
required: false
type: string
default: ''
branch:
description: 'PR branch name'
required: false
Expand Down Expand Up @@ -90,22 +85,21 @@ jobs:
run: dart pub get

- name: Run Tidy Script
working-directory: ${{ inputs.directory }}
run: |
dart .github/ecosystem-helper/pkgs/firehose/bin/groundskeeper.dart \
--directory=${{ inputs.directory }} \
dart $GITHUB_WORKSPACE/.github/ecosystem-helper/pkgs/firehose/bin/groundskeeper.dart \
--format=${{ inputs.run-format }} \
--fix=${{ inputs.run-fix }} \
--exclude="${{ inputs.exclude }}"

- name: Clean up helper
run: rm -rf .github/ecosystem-helper
--fix=${{ inputs.run-fix }}

- name: Update changelog
if: ${{ inputs.update-changelog }}
working-directory: ${{ inputs.directory }}
working-directory: .github/ecosystem-helper/pkgs/repo_manage
run: |
dart install --git-path pkgs/repo_manage --git-ref addChangelogUpdater https://github.com/dart-lang/ecosystem.git
report changelog "${{ inputs.changelog-message }}"
dart pub get
dart run bin/report.dart changelog --changelog "../../../../${{ inputs.directory }}/CHANGELOG.md" "${{ inputs.changelog-message }}"

- name: Clean up helper
run: rm -rf .github/ecosystem-helper

- name: Create Pull Request
uses: peter-evans/create-pull-request@6fff569d741c6b8131d2a49663b16573ef90be31
Expand Down
15 changes: 15 additions & 0 deletions .github/workflows/groundskeeper_internal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,20 @@ jobs:
permissions:
contents: write
pull-requests: write
strategy:
matrix:
package:
- blast_repo
- canary
- corpus
- dart_flutter_team_lints
- firehose
- repo_manage
- sdk_triage_bot
- trebuchet
uses: ./.github/workflows/groundskeeper.yml
with:
directory: pkgs/${{ matrix.package }}
branch: auto-tidy-${{ matrix.package }}
title: 'Tidy: package:${{ matrix.package }}'
secrets: inherit
1 change: 1 addition & 0 deletions pkgs/firehose/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- Fix web coverage reporting and coverage aggregation.
- Improve and clarify readme documentation.
- Add description for the table 'Package publishing'.
- Simplify `groundskeeper` workflow

## 0.13.1

Expand Down
95 changes: 41 additions & 54 deletions pkgs/firehose/bin/groundskeeper.dart
Original file line number Diff line number Diff line change
@@ -1,51 +1,41 @@
// 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:args/args.dart';
import 'package:firehose/firehose.dart';
import 'package:glob/glob.dart';
import 'package:path/path.dart' as path;
Comment thread
mosuem marked this conversation as resolved.

void main(List<String> args) async {
final parser = ArgParser()
..addOption('directory', defaultsTo: '.')
..addOption('format', defaultsTo: 'true', allowed: ['true', 'false'])
..addOption('fix', defaultsTo: 'true', allowed: ['true', 'false'])
..addOption('exclude', defaultsTo: '');
..addOption('fix', defaultsTo: 'true', allowed: ['true', 'false']);

final argResults = parser.parse(args);

final targetDirectoryPath = argResults['directory'] as String;
final targetDirectory = Directory(targetDirectoryPath);

final targetDirectory = Directory.current;
final runFormat = argResults['format'] != 'false';
final runFix = argResults['fix'] != 'false';
final excludeStr = argResults['exclude'] as String;

final excludes = excludeStr.isEmpty
? <String>[]
: excludeStr.split(',').map((e) => e.trim()).toList();

print('Target Directory: ${targetDirectory.absolute.path}');
print('Excludes: $excludes');
print('Run format: $runFormat');
print('Run fix: $runFix');

// Locate packages early to use for both format and fix
final repo = Repository(targetDirectory);
final packages = repo.locatePackages(
ignore: excludes.map(Glob.new).toList(),
includeUnpublished: true,
);
final pubspecFile = File(path.join(targetDirectory.path, 'pubspec.yaml'));
final isPackage = pubspecFile.existsSync();

if (runFix && !isPackage) {
print('''
Error: Run fix is enabled, but no pubspec.yaml found in ${targetDirectory.path}''');
exit(1);
}

if (runFormat) {
print('Running dart format...');
// Respect excludes by only formatting located packages.
// If no packages are found, default to the target directory.
final pathsToFormat = packages.isEmpty
? [targetDirectory.path]
: packages.map((p) => p.directory.path).toList();

final result = await Process.run(
'dart',
['format', ...pathsToFormat],
['format', targetDirectory.path],
);
stdout.write(result.stdout);
stderr.write(result.stderr);
Expand All @@ -55,38 +45,35 @@ void main(List<String> args) async {
}

if (runFix) {
print('Found packages: ${packages.map((e) => e.directory.path).toList()}');
final repo = Repository(targetDirectory);
final pkg = Package(targetDirectory, repo);
final pkgPath = targetDirectory.path;

for (final pkg in packages) {
final pkgPath = pkg.directory.path;
// Detect if it is a Flutter package
final isFlutter = pkg.pubspec.dependencies.containsKey('flutter') ||
pkg.pubspec.devDependencies.containsKey('flutter');
final tool = isFlutter ? 'flutter' : 'dart';
Comment thread
mosuem marked this conversation as resolved.

// Detect if it is a Flutter package
final isFlutter = pkg.pubspec.dependencies.containsKey('flutter') ||
pkg.pubspec.devDependencies.containsKey('flutter');
final tool = isFlutter ? 'flutter' : 'dart';
print('Tidying package in $pkgPath (${isFlutter ? 'Flutter' : 'Dart'})...');

print(
'Tidying package in $pkgPath (${isFlutter ? 'Flutter' : 'Dart'})...');

print(' Running $tool pub get...');
final pubGetResult =
await Process.run(tool, ['pub', 'get'], workingDirectory: pkgPath);
stdout.write(pubGetResult.stdout);
stderr.write(pubGetResult.stderr);
if (pubGetResult.exitCode != 0) {
print('Error: $tool pub get failed in $pkgPath');
exit(pubGetResult.exitCode);
}
print(' Running $tool pub get...');
final pubGetResult =
await Process.run(tool, ['pub', 'get'], workingDirectory: pkgPath);
stdout.write(pubGetResult.stdout);
stderr.write(pubGetResult.stderr);
if (pubGetResult.exitCode != 0) {
print('Error: $tool pub get failed in $pkgPath');
exit(pubGetResult.exitCode);
}

print(' Running dart fix --apply...');
final fixResult = await Process.run('dart', ['fix', '--apply'],
workingDirectory: pkgPath);
stdout.write(fixResult.stdout);
stderr.write(fixResult.stderr);
if (fixResult.exitCode != 0) {
print('Error: dart fix failed in $pkgPath');
exit(fixResult.exitCode);
}
print(' Running dart fix --apply...');
final fixResult = await Process.run('dart', ['fix', '--apply'],
workingDirectory: pkgPath);
stdout.write(fixResult.stdout);
stderr.write(fixResult.stderr);
if (fixResult.exitCode != 0) {
print('Error: dart fix failed in $pkgPath');
exit(fixResult.exitCode);
}
}
}
9 changes: 3 additions & 6 deletions pkgs/firehose/test/changelog_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,10 @@ void main() {

void withChangelog(String contents, void Function(File file) closure) {
final dir = Directory.systemTemp.createTempSync();
addTearDown(() => dir.deleteSync(recursive: true));
final file = File('${dir.path}/CHANGELOG.md');
try {
file.writeAsStringSync(contents);
closure(file);
} finally {
dir.deleteSync(recursive: true);
}
file.writeAsStringSync(contents);
closure(file);
}

const _defaultContents = '''
Expand Down
5 changes: 3 additions & 2 deletions pkgs/firehose/test/health_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,9 @@ Future<void> checkGolden(
List<String> ignoredPackage = const [],
List<String> flutterPackages = const [],
}) async {
final commentPath = p.join(Directory.systemTemp.createTempSync().path,
'comment_${check.displayName}.md');
final tempDir = Directory.systemTemp.createTempSync();
addTearDown(() => tempDir.deleteSync(recursive: true));
final commentPath = p.join(tempDir.path, 'comment_${check.displayName}.md');
await FakeHealth(
directory,
check,
Expand Down
45 changes: 37 additions & 8 deletions pkgs/repo_manage/lib/changelog_updater.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,33 @@
import 'dart:convert';
import 'dart:io';

import 'package:path/path.dart' as path;

import 'src/common.dart';

String updateChangelogContent(String changelog, String message) {
final lines = LineSplitter.split(changelog).toList();
void updatePubspecVersion(File pubspecFile, String newVersion) {
final content = pubspecFile.readAsStringSync();
final lines = LineSplitter.split(content).toList();
var updated = false;
for (var i = 0; i < lines.length; i++) {
final line = lines[i];
if (line.startsWith('version:')) {
lines[i] = 'version: $newVersion';
updated = true;
break;
}
}
if (updated) {
pubspecFile.writeAsStringSync('${lines.join('\n')}\n');
}
}

void updateChangelog({
required File changelogFile,
required String message,
}) {
final changelogContent = changelogFile.readAsStringSync();
final lines = LineSplitter.split(changelogContent).toList();
var currentVersion = '0.0.1';
var currentVersionLine = 0;

Expand Down Expand Up @@ -49,7 +72,16 @@ String updateChangelogContent(String changelog, String message) {
]);
}

return '${output.join('\n')}\n';
changelogFile.writeAsStringSync('${output.join('\n')}\n');

if (!isWip) {
final newVersion = '$currentVersion-wip';
final changelogDir = path.dirname(changelogFile.path);
final pubspecFile = File(path.join(changelogDir, 'pubspec.yaml'));
if (pubspecFile.existsSync()) {
updatePubspecVersion(pubspecFile, newVersion);
}
}
}

class ChangelogUpdaterCommand extends ReportCommand {
Expand All @@ -74,6 +106,7 @@ Usage: dart run report.dart changelog [--changelog <path>] "Your changelog messa
}

final message = args.join(' ');

final changelogFile =
File(argResults?['changelog'] as String? ?? 'CHANGELOG.md');

Expand All @@ -82,11 +115,7 @@ Usage: dart run report.dart changelog [--changelog <path>] "Your changelog messa
return 1;
}

final newChangelog = updateChangelogContent(
changelogFile.readAsStringSync(),
message,
);
changelogFile.writeAsStringSync(newChangelog);
updateChangelog(changelogFile: changelogFile, message: message);
stdout.writeln('Changelog updated successfully.');
return 0;
}
Expand Down
Loading
Loading