Skip to content

Commit 29782f8

Browse files
jensjohaCommit Queue
authored and
Commit Queue
committed
[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 <[email protected]> Commit-Queue: Jens Johansen <[email protected]>
1 parent af1b5b8 commit 29782f8

File tree

4 files changed

+255
-2
lines changed

4 files changed

+255
-2
lines changed

pkg/front_end/presubmit_helper.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Future<void> main(List<String> args) async {
1515
// Expect something like /full/path/to/sdk/pkg/some_dir/whatever/else
1616
if (args.length != 1) throw "Need exactly one argument.";
1717

18-
final List<String> changedFiles = _getChangedFiles();
18+
final List<String> changedFiles = getChangedFiles();
1919
String callerPath = args[0].replaceAll("\\", "/");
2020
if (!_shouldRun(changedFiles, callerPath)) {
2121
return;
@@ -290,7 +290,7 @@ Future<void> _executePendingWorkItems(List<Work> workItems) async {
290290
/// Queries git about changes against upstream, or origin/main if no upstream is
291291
/// set. This is similar (but different), I believe, to what
292292
/// `git cl presubmit` does.
293-
List<String> _getChangedFiles() {
293+
List<String> getChangedFiles() {
294294
ProcessResult result = Process.runSync(
295295
"git",
296296
[

pkg/front_end/test/spell_checking_list_tests.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ inconsistencies
414414
increasing
415415
incrementally
416416
increments
417+
indention
417418
indents
418419
ing
419420
inhibit
@@ -516,6 +517,7 @@ mxn
516517
mysdk
517518
naively
518519
naturally
520+
needle
519521
negatable
520522
newworld
521523
ninja
@@ -634,6 +636,7 @@ rediscover
634636
reducer
635637
reenable
636638
referential
639+
refname
637640
refusing
638641
regards
639642
regenerate

pkg/front_end/tool/format_cl.dart

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:convert' show LineSplitter, utf8;
6+
import 'dart:developer' as dev show NativeRuntime;
7+
import 'dart:io';
8+
9+
import '../presubmit_helper.dart' show getChangedFiles;
10+
import '../test/utils/io_utils.dart';
11+
12+
Future<void> main() async {
13+
Uri executable = getDartExecutable();
14+
final List<String> allChangedFiles = getChangedFiles();
15+
if (allChangedFiles.isEmpty) {
16+
print("No changes in CL.");
17+
return;
18+
}
19+
final List<String> changedDartFiles = [];
20+
for (String changedFile in allChangedFiles) {
21+
if (changedFile.toLowerCase().endsWith(".dart")) {
22+
changedDartFiles.add(changedFile);
23+
}
24+
}
25+
if (changedDartFiles.isEmpty) {
26+
print("No changed dart files in CL.");
27+
return;
28+
}
29+
Process p = await Process.start(
30+
executable.toFilePath(), ["format", ...changedDartFiles]);
31+
32+
p.stderr
33+
.transform(utf8.decoder)
34+
.transform(const LineSplitter())
35+
.listen((String line) {
36+
stderr.writeln("stderr> $line");
37+
});
38+
p.stdout
39+
.transform(utf8.decoder)
40+
.transform(const LineSplitter())
41+
.listen((String line) {
42+
stdout.writeln("stdout> $line");
43+
});
44+
45+
exitCode = await p.exitCode;
46+
}
47+
48+
Uri getDartExecutable() {
49+
Uri executable = Uri.base.resolve(Platform.resolvedExecutable);
50+
if (executable == Platform.script || dev.NativeRuntime.buildId != null) {
51+
// Probably aot compiled. We need to find "dart" another way.
52+
bool found = false;
53+
try {
54+
final Uri repoDir = computeRepoDirUri();
55+
for (String candidatePath in [
56+
"out/ReleaseX64/dart",
57+
"out/ReleaseX64/dart-sdk/bin/dart",
58+
"out/ReleaseX64/dart.exe",
59+
"out/ReleaseX64/dart-sdk/bin/dart.exe",
60+
"xcodebuild/ReleaseX64/dart",
61+
"xcodebuild/ReleaseX64/dart-sdk/bin/dart",
62+
]) {
63+
Uri candidate = repoDir.resolve(candidatePath);
64+
if (File.fromUri(candidate).existsSync()) {
65+
executable = candidate;
66+
found = true;
67+
break;
68+
}
69+
}
70+
} catch (e) {
71+
print("Warning: $e");
72+
}
73+
if (!found) {
74+
Uri? candidate = where("dart");
75+
if (candidate != null) {
76+
executable = candidate;
77+
} else {
78+
throw "Couldn't find a dart executable to use.";
79+
}
80+
}
81+
print("Using $executable");
82+
}
83+
return executable;
84+
}
85+
86+
Uri? where(String needle) {
87+
String pathEnvironment = Platform.environment["PATH"] ?? '';
88+
List<String> paths;
89+
if (Platform.isWindows) {
90+
paths = pathEnvironment.split(";");
91+
} else {
92+
paths = pathEnvironment.split(":");
93+
}
94+
// This isn't great but will probably work for our purposes.
95+
List<String> extensions = ["", ".exe", ".bat", ".com"];
96+
97+
for (String path in paths) {
98+
for (String extension in extensions) {
99+
File f = new File("$path${Platform.pathSeparator}$needle$extension");
100+
if (f.existsSync()) {
101+
return f.uri;
102+
}
103+
}
104+
}
105+
return null;
106+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:async';
6+
import 'dart:io';
7+
8+
void main(List<String> args) {
9+
// Use `runZonedGuarded` instead of try/catch, and do it here before anything
10+
// else has been printed --- both because of
11+
// https://github.com/dart-lang/sdk/issues/54911.
12+
runZonedGuarded(() {
13+
mainImpl(args);
14+
}, (e, _) {
15+
stderr.writeln("Error: $e");
16+
});
17+
}
18+
19+
const String CSI = "\x1b[";
20+
21+
Map<String, GitBranch> branches = {};
22+
23+
GitBranch getBranch(String name) {
24+
GitBranch? result = branches[name];
25+
if (result == null) {
26+
result = branches[name] = new GitBranch(name);
27+
}
28+
return result;
29+
}
30+
31+
void mainImpl(List<String> args) {
32+
ProcessResult result = Process.runSync("git",
33+
["branch", "--list", "--format=%(refname:short)%09%(upstream:short)"],
34+
runInShell: true);
35+
result.stdout.split("\n").forEach(processGitBranchLine);
36+
37+
result =
38+
Process.runSync("git", ["branch", "--show-current"], runInShell: true);
39+
String currentBranchName = result.stdout;
40+
currentBranchName = currentBranchName.trim();
41+
GitBranch currentBranch = branches[currentBranchName]!;
42+
Set<String> involvedBranchNames = {};
43+
currentBranch.collectSelfAndParentNames(involvedBranchNames);
44+
currentBranch.collectSelfAndChildrenNames(involvedBranchNames);
45+
46+
result = Process.runSync(
47+
"git",
48+
[
49+
"branch",
50+
"--list",
51+
"--format=%(refname:short)%09%(upstream:track)",
52+
...involvedBranchNames
53+
],
54+
runInShell: true);
55+
result.stdout.split("\n").forEach(processGitBranchTrackLine);
56+
57+
int indentation = currentBranch.parent?.printSelfAndParentChain() ?? 0;
58+
59+
currentBranch.printSelfAndChildren(indentation, color: true);
60+
}
61+
62+
void processGitBranchLine(String gitLine) {
63+
if (gitLine.isEmpty) return;
64+
int pos = gitLine.indexOf("\t");
65+
String thisName = gitLine.substring(0, pos);
66+
String parentName = gitLine.substring(pos + 1).trim();
67+
GitBranch thisBranch = getBranch(thisName);
68+
GitBranch parentBranch = getBranch(parentName);
69+
parentBranch.registerChild(thisBranch);
70+
}
71+
72+
void processGitBranchTrackLine(String gitLine) {
73+
if (gitLine.isEmpty) return;
74+
int pos = gitLine.indexOf("\t");
75+
String thisName = gitLine.substring(0, pos);
76+
String tracking = gitLine.substring(pos + 1).trim();
77+
GitBranch thisBranch = getBranch(thisName);
78+
thisBranch.tracking = tracking;
79+
}
80+
81+
class GitBranch {
82+
final String name;
83+
GitBranch? parent;
84+
final List<GitBranch> children = [];
85+
String? tracking;
86+
87+
GitBranch(this.name);
88+
89+
void collectSelfAndChildrenNames(Set<String> names) {
90+
names.add(name);
91+
for (GitBranch child in children) {
92+
child.collectSelfAndChildrenNames(names);
93+
}
94+
}
95+
96+
void collectSelfAndParentNames(Set<String> names) {
97+
parent?.collectSelfAndParentNames(names);
98+
names.add(name);
99+
}
100+
101+
void printSelfAndChildren(int indention, {bool color = false}) {
102+
_printLineWithIndention(indention, color: color);
103+
for (GitBranch child in children) {
104+
child.printSelfAndChildren(indention + 1);
105+
}
106+
}
107+
108+
int printSelfAndParentChain() {
109+
int indention = 0;
110+
GitBranch? parent = this.parent;
111+
if (parent != null) {
112+
indention = parent.printSelfAndParentChain();
113+
}
114+
_printLineWithIndention(indention);
115+
116+
return indention + 1;
117+
}
118+
119+
void registerChild(GitBranch child) {
120+
children.add(child);
121+
child.parent = this;
122+
}
123+
124+
@override
125+
String toString() {
126+
return "GitBranch[$name, children = $children]";
127+
}
128+
129+
void _printLineWithIndention(int indention, {bool color = false}) {
130+
stdout.write("│ " * (indention));
131+
stdout.write("├── ");
132+
if (color) {
133+
stdout.write("${CSI}31m");
134+
}
135+
stdout.write("$name");
136+
if (color) {
137+
stdout.write("${CSI}0m");
138+
}
139+
if (tracking != null) {
140+
stdout.write(" $tracking");
141+
}
142+
stdout.write("\n");
143+
}
144+
}

0 commit comments

Comments
 (0)