mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:47:36 +00:00
[CFE] Add a few helper utils
These ease my life slightly. Examples: Compile to executable to get faster runs: ``` out/ReleaseX64/dart-sdk/bin/dart compile exe pkg/front_end/tool/gitformat_cl.dart -o ~/bin/format_cl out/ReleaseX64/dart-sdk/bin/dart compile exe pkg/front_end/tool/git_branch_helper.dart -o ~/bin/gitbranch ``` Now I can format my entire CL with ``` $ format_cl Using file:///path/to/dart-sdk/sdk/out/ReleaseX64/dart stdout> Formatted 3 files (0 changed) in 0.35 seconds. ``` and get info about my branching with ``` $ gitbranch ├── origin/main │ ├── add_a_few_cfe_util_tools [ahead 2] ``` Change-Id: I2e89196ab702660a1486894d22678e3cd0c07994 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/352641 Reviewed-by: Chloe Stefantsova <cstefantsova@google.com> Commit-Queue: Jens Johansen <jensj@google.com>
This commit is contained in:
parent
af1b5b8044
commit
29782f8750
|
@ -15,7 +15,7 @@ Future<void> main(List<String> args) async {
|
|||
// Expect something like /full/path/to/sdk/pkg/some_dir/whatever/else
|
||||
if (args.length != 1) throw "Need exactly one argument.";
|
||||
|
||||
final List<String> changedFiles = _getChangedFiles();
|
||||
final List<String> changedFiles = getChangedFiles();
|
||||
String callerPath = args[0].replaceAll("\\", "/");
|
||||
if (!_shouldRun(changedFiles, callerPath)) {
|
||||
return;
|
||||
|
@ -290,7 +290,7 @@ Future<void> _executePendingWorkItems(List<Work> workItems) async {
|
|||
/// Queries git about changes against upstream, or origin/main if no upstream is
|
||||
/// set. This is similar (but different), I believe, to what
|
||||
/// `git cl presubmit` does.
|
||||
List<String> _getChangedFiles() {
|
||||
List<String> getChangedFiles() {
|
||||
ProcessResult result = Process.runSync(
|
||||
"git",
|
||||
[
|
||||
|
|
|
@ -414,6 +414,7 @@ inconsistencies
|
|||
increasing
|
||||
incrementally
|
||||
increments
|
||||
indention
|
||||
indents
|
||||
ing
|
||||
inhibit
|
||||
|
@ -516,6 +517,7 @@ mxn
|
|||
mysdk
|
||||
naively
|
||||
naturally
|
||||
needle
|
||||
negatable
|
||||
newworld
|
||||
ninja
|
||||
|
@ -634,6 +636,7 @@ rediscover
|
|||
reducer
|
||||
reenable
|
||||
referential
|
||||
refname
|
||||
refusing
|
||||
regards
|
||||
regenerate
|
||||
|
|
106
pkg/front_end/tool/format_cl.dart
Normal file
106
pkg/front_end/tool/format_cl.dart
Normal file
|
@ -0,0 +1,106 @@
|
|||
// Copyright (c) 2024, 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:convert' show LineSplitter, utf8;
|
||||
import 'dart:developer' as dev show NativeRuntime;
|
||||
import 'dart:io';
|
||||
|
||||
import '../presubmit_helper.dart' show getChangedFiles;
|
||||
import '../test/utils/io_utils.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
Uri executable = getDartExecutable();
|
||||
final List<String> allChangedFiles = getChangedFiles();
|
||||
if (allChangedFiles.isEmpty) {
|
||||
print("No changes in CL.");
|
||||
return;
|
||||
}
|
||||
final List<String> changedDartFiles = [];
|
||||
for (String changedFile in allChangedFiles) {
|
||||
if (changedFile.toLowerCase().endsWith(".dart")) {
|
||||
changedDartFiles.add(changedFile);
|
||||
}
|
||||
}
|
||||
if (changedDartFiles.isEmpty) {
|
||||
print("No changed dart files in CL.");
|
||||
return;
|
||||
}
|
||||
Process p = await Process.start(
|
||||
executable.toFilePath(), ["format", ...changedDartFiles]);
|
||||
|
||||
p.stderr
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
.listen((String line) {
|
||||
stderr.writeln("stderr> $line");
|
||||
});
|
||||
p.stdout
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
.listen((String line) {
|
||||
stdout.writeln("stdout> $line");
|
||||
});
|
||||
|
||||
exitCode = await p.exitCode;
|
||||
}
|
||||
|
||||
Uri getDartExecutable() {
|
||||
Uri executable = Uri.base.resolve(Platform.resolvedExecutable);
|
||||
if (executable == Platform.script || dev.NativeRuntime.buildId != null) {
|
||||
// Probably aot compiled. We need to find "dart" another way.
|
||||
bool found = false;
|
||||
try {
|
||||
final Uri repoDir = computeRepoDirUri();
|
||||
for (String candidatePath in [
|
||||
"out/ReleaseX64/dart",
|
||||
"out/ReleaseX64/dart-sdk/bin/dart",
|
||||
"out/ReleaseX64/dart.exe",
|
||||
"out/ReleaseX64/dart-sdk/bin/dart.exe",
|
||||
"xcodebuild/ReleaseX64/dart",
|
||||
"xcodebuild/ReleaseX64/dart-sdk/bin/dart",
|
||||
]) {
|
||||
Uri candidate = repoDir.resolve(candidatePath);
|
||||
if (File.fromUri(candidate).existsSync()) {
|
||||
executable = candidate;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print("Warning: $e");
|
||||
}
|
||||
if (!found) {
|
||||
Uri? candidate = where("dart");
|
||||
if (candidate != null) {
|
||||
executable = candidate;
|
||||
} else {
|
||||
throw "Couldn't find a dart executable to use.";
|
||||
}
|
||||
}
|
||||
print("Using $executable");
|
||||
}
|
||||
return executable;
|
||||
}
|
||||
|
||||
Uri? where(String needle) {
|
||||
String pathEnvironment = Platform.environment["PATH"] ?? '';
|
||||
List<String> paths;
|
||||
if (Platform.isWindows) {
|
||||
paths = pathEnvironment.split(";");
|
||||
} else {
|
||||
paths = pathEnvironment.split(":");
|
||||
}
|
||||
// This isn't great but will probably work for our purposes.
|
||||
List<String> extensions = ["", ".exe", ".bat", ".com"];
|
||||
|
||||
for (String path in paths) {
|
||||
for (String extension in extensions) {
|
||||
File f = new File("$path${Platform.pathSeparator}$needle$extension");
|
||||
if (f.existsSync()) {
|
||||
return f.uri;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
144
pkg/front_end/tool/git_branch_helper.dart
Normal file
144
pkg/front_end/tool/git_branch_helper.dart
Normal file
|
@ -0,0 +1,144 @@
|
|||
// Copyright (c) 2024, 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:async';
|
||||
import 'dart:io';
|
||||
|
||||
void main(List<String> args) {
|
||||
// Use `runZonedGuarded` instead of try/catch, and do it here before anything
|
||||
// else has been printed --- both because of
|
||||
// https://github.com/dart-lang/sdk/issues/54911.
|
||||
runZonedGuarded(() {
|
||||
mainImpl(args);
|
||||
}, (e, _) {
|
||||
stderr.writeln("Error: $e");
|
||||
});
|
||||
}
|
||||
|
||||
const String CSI = "\x1b[";
|
||||
|
||||
Map<String, GitBranch> branches = {};
|
||||
|
||||
GitBranch getBranch(String name) {
|
||||
GitBranch? result = branches[name];
|
||||
if (result == null) {
|
||||
result = branches[name] = new GitBranch(name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void mainImpl(List<String> args) {
|
||||
ProcessResult result = Process.runSync("git",
|
||||
["branch", "--list", "--format=%(refname:short)%09%(upstream:short)"],
|
||||
runInShell: true);
|
||||
result.stdout.split("\n").forEach(processGitBranchLine);
|
||||
|
||||
result =
|
||||
Process.runSync("git", ["branch", "--show-current"], runInShell: true);
|
||||
String currentBranchName = result.stdout;
|
||||
currentBranchName = currentBranchName.trim();
|
||||
GitBranch currentBranch = branches[currentBranchName]!;
|
||||
Set<String> involvedBranchNames = {};
|
||||
currentBranch.collectSelfAndParentNames(involvedBranchNames);
|
||||
currentBranch.collectSelfAndChildrenNames(involvedBranchNames);
|
||||
|
||||
result = Process.runSync(
|
||||
"git",
|
||||
[
|
||||
"branch",
|
||||
"--list",
|
||||
"--format=%(refname:short)%09%(upstream:track)",
|
||||
...involvedBranchNames
|
||||
],
|
||||
runInShell: true);
|
||||
result.stdout.split("\n").forEach(processGitBranchTrackLine);
|
||||
|
||||
int indentation = currentBranch.parent?.printSelfAndParentChain() ?? 0;
|
||||
|
||||
currentBranch.printSelfAndChildren(indentation, color: true);
|
||||
}
|
||||
|
||||
void processGitBranchLine(String gitLine) {
|
||||
if (gitLine.isEmpty) return;
|
||||
int pos = gitLine.indexOf("\t");
|
||||
String thisName = gitLine.substring(0, pos);
|
||||
String parentName = gitLine.substring(pos + 1).trim();
|
||||
GitBranch thisBranch = getBranch(thisName);
|
||||
GitBranch parentBranch = getBranch(parentName);
|
||||
parentBranch.registerChild(thisBranch);
|
||||
}
|
||||
|
||||
void processGitBranchTrackLine(String gitLine) {
|
||||
if (gitLine.isEmpty) return;
|
||||
int pos = gitLine.indexOf("\t");
|
||||
String thisName = gitLine.substring(0, pos);
|
||||
String tracking = gitLine.substring(pos + 1).trim();
|
||||
GitBranch thisBranch = getBranch(thisName);
|
||||
thisBranch.tracking = tracking;
|
||||
}
|
||||
|
||||
class GitBranch {
|
||||
final String name;
|
||||
GitBranch? parent;
|
||||
final List<GitBranch> children = [];
|
||||
String? tracking;
|
||||
|
||||
GitBranch(this.name);
|
||||
|
||||
void collectSelfAndChildrenNames(Set<String> names) {
|
||||
names.add(name);
|
||||
for (GitBranch child in children) {
|
||||
child.collectSelfAndChildrenNames(names);
|
||||
}
|
||||
}
|
||||
|
||||
void collectSelfAndParentNames(Set<String> names) {
|
||||
parent?.collectSelfAndParentNames(names);
|
||||
names.add(name);
|
||||
}
|
||||
|
||||
void printSelfAndChildren(int indention, {bool color = false}) {
|
||||
_printLineWithIndention(indention, color: color);
|
||||
for (GitBranch child in children) {
|
||||
child.printSelfAndChildren(indention + 1);
|
||||
}
|
||||
}
|
||||
|
||||
int printSelfAndParentChain() {
|
||||
int indention = 0;
|
||||
GitBranch? parent = this.parent;
|
||||
if (parent != null) {
|
||||
indention = parent.printSelfAndParentChain();
|
||||
}
|
||||
_printLineWithIndention(indention);
|
||||
|
||||
return indention + 1;
|
||||
}
|
||||
|
||||
void registerChild(GitBranch child) {
|
||||
children.add(child);
|
||||
child.parent = this;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "GitBranch[$name, children = $children]";
|
||||
}
|
||||
|
||||
void _printLineWithIndention(int indention, {bool color = false}) {
|
||||
stdout.write("│ " * (indention));
|
||||
stdout.write("├── ");
|
||||
if (color) {
|
||||
stdout.write("${CSI}31m");
|
||||
}
|
||||
stdout.write("$name");
|
||||
if (color) {
|
||||
stdout.write("${CSI}0m");
|
||||
}
|
||||
if (tracking != null) {
|
||||
stdout.write(" $tracking");
|
||||
}
|
||||
stdout.write("\n");
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue