Skip to content

Commit a30012b

Browse files
Add update packages roller (flutter#100982)
1 parent 0dd0c2e commit a30012b

12 files changed

+760
-24
lines changed

dev/bots/analyze.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,6 +1778,7 @@ const Set<String> kExecutableAllowlist = <String>{
17781778
'dev/bots/docs.sh',
17791779

17801780
'dev/conductor/bin/conductor',
1781+
'dev/conductor/bin/roll-packages',
17811782
'dev/conductor/core/lib/src/proto/compile_proto.sh',
17821783

17831784
'dev/customer_testing/ci.sh',

dev/conductor/bin/conductor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ DART_BIN="$REPO_DIR/bin/dart"
4040
# Ensure pub get has been run in the repo before running the conductor
4141
(cd "$REPO_DIR/dev/conductor/core"; "$DART_BIN" pub get 1>&2)
4242

43-
"$DART_BIN" --enable-asserts "$REPO_DIR/dev/conductor/core/bin/cli.dart" "$@"
43+
exec "$DART_BIN" --enable-asserts "$REPO_DIR/dev/conductor/core/bin/cli.dart" "$@"

dev/conductor/bin/roll-packages

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2014 The Flutter Authors. All rights reserved.
3+
# Use of this source code is governed by a BSD-style license that can be
4+
# found in the LICENSE file.
5+
6+
set -euo pipefail
7+
8+
# Needed because if it is set, cd may print the path it changed to.
9+
unset CDPATH
10+
11+
# On Mac OS, readlink -f doesn't work, so follow_links traverses the path one
12+
# link at a time, and then cds into the link destination and find out where it
13+
# ends up.
14+
#
15+
# The returned filesystem path must be a format usable by Dart's URI parser,
16+
# since the Dart command line tool treats its argument as a file URI, not a
17+
# filename. For instance, multiple consecutive slashes should be reduced to a
18+
# single slash, since double-slashes indicate a URI "authority", and these are
19+
# supposed to be filenames. There is an edge case where this will return
20+
# multiple slashes: when the input resolves to the root directory. However, if
21+
# that were the case, we wouldn't be running this shell, so we don't do anything
22+
# about it.
23+
#
24+
# The function is enclosed in a subshell to avoid changing the working directory
25+
# of the caller.
26+
function follow_links() (
27+
cd -P "$(dirname -- "$1")"
28+
file="$PWD/$(basename -- "$1")"
29+
while [[ -h "$file" ]]; do
30+
cd -P "$(dirname -- "$file")"
31+
file="$(readlink -- "$file")"
32+
cd -P "$(dirname -- "$file")"
33+
file="$PWD/$(basename -- "$file")"
34+
done
35+
echo "$file"
36+
)
37+
38+
PROG_NAME="$(follow_links "${BASH_SOURCE[0]}")"
39+
BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
40+
REPO_DIR="$BIN_DIR/../../.."
41+
DART_BIN="$REPO_DIR/bin/dart"
42+
43+
# Ensure pub get has been run in the repo before running the conductor
44+
(cd "$REPO_DIR/dev/conductor/core"; "$DART_BIN" pub get 1>&2)
45+
46+
exec "$DART_BIN" --enable-asserts "$REPO_DIR/dev/conductor/core/bin/roll_packages.dart" "$@"
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:io' as io;
6+
7+
import 'package:args/args.dart';
8+
import 'package:conductor_core/conductor_core.dart';
9+
import 'package:conductor_core/packages_autoroller.dart';
10+
import 'package:file/file.dart';
11+
import 'package:file/local.dart';
12+
import 'package:platform/platform.dart';
13+
import 'package:process/process.dart';
14+
15+
const String kTokenOption = 'token';
16+
const String kGithubClient = 'github-client';
17+
const String kMirrorRemote = 'mirror-remote';
18+
const String kUpstreamRemote = 'upstream-remote';
19+
20+
Future<void> main(List<String> args) async {
21+
final ArgParser parser = ArgParser();
22+
parser.addOption(
23+
kTokenOption,
24+
help: 'GitHub access token env variable name.',
25+
defaultsTo: 'GITHUB_TOKEN',
26+
);
27+
parser.addOption(
28+
kGithubClient,
29+
help: 'Path to GitHub CLI client. If not provided, it is assumed `gh` is '
30+
'present on the PATH.',
31+
);
32+
parser.addOption(
33+
kMirrorRemote,
34+
help: 'The mirror git remote that the feature branch will be pushed to. '
35+
'Required',
36+
mandatory: true,
37+
);
38+
parser.addOption(
39+
kUpstreamRemote,
40+
help: 'The upstream git remote that the feature branch will be merged to.',
41+
hide: true,
42+
defaultsTo: 'https://github.com/flutter/flutter.git',
43+
);
44+
45+
final ArgResults results;
46+
try {
47+
results = parser.parse(args);
48+
} on FormatException {
49+
io.stdout.writeln('''
50+
Usage:
51+
52+
${parser.usage}
53+
''');
54+
rethrow;
55+
}
56+
57+
final String mirrorUrl = results[kMirrorRemote]! as String;
58+
final String upstreamUrl = results[kUpstreamRemote]! as String;
59+
const Platform platform = LocalPlatform();
60+
final String tokenName = results[kTokenOption]! as String;
61+
final String? token = platform.environment[tokenName];
62+
if (token == null || token.isEmpty) {
63+
throw FormatException(
64+
'Tried to read a GitHub access token from env variable \$$tokenName but it was undefined or empty',
65+
);
66+
}
67+
68+
final FrameworkRepository framework = FrameworkRepository(
69+
_localCheckouts,
70+
mirrorRemote: Remote.mirror(mirrorUrl),
71+
upstreamRemote: Remote.upstream(upstreamUrl),
72+
);
73+
74+
await PackageAutoroller(
75+
framework: framework,
76+
githubClient: results[kGithubClient] as String? ?? 'gh',
77+
orgName: _parseOrgName(mirrorUrl),
78+
token: token,
79+
processManager: const LocalProcessManager(),
80+
).roll();
81+
}
82+
83+
String _parseOrgName(String remoteUrl) {
84+
final RegExp pattern = RegExp(r'^https:\/\/github\.com\/(.*)\/');
85+
final RegExpMatch? match = pattern.firstMatch(remoteUrl);
86+
if (match == null) {
87+
throw FormatException(
88+
'Malformed upstream URL "$remoteUrl", should start with "https://github.com/"',
89+
);
90+
}
91+
return match.group(1)!;
92+
}
93+
94+
Checkouts get _localCheckouts {
95+
const FileSystem fileSystem = LocalFileSystem();
96+
const ProcessManager processManager = LocalProcessManager();
97+
const Platform platform = LocalPlatform();
98+
final Stdio stdio = VerboseStdio(
99+
stdout: io.stdout,
100+
stderr: io.stderr,
101+
stdin: io.stdin,
102+
);
103+
return Checkouts(
104+
fileSystem: fileSystem,
105+
parentDirectory: _localFlutterRoot.parent,
106+
platform: platform,
107+
processManager: processManager,
108+
stdio: stdio,
109+
);
110+
}
111+
112+
Directory get _localFlutterRoot {
113+
String filePath;
114+
const FileSystem fileSystem = LocalFileSystem();
115+
const Platform platform = LocalPlatform();
116+
117+
filePath = platform.script.toFilePath();
118+
final String checkoutsDirname = fileSystem.path.normalize(
119+
fileSystem.path.join(
120+
fileSystem.path.dirname(filePath), // flutter/dev/conductor/core/bin
121+
'..', // flutter/dev/conductor/core
122+
'..', // flutter/dev/conductor
123+
'..', // flutter/dev
124+
'..', // flutter
125+
),
126+
);
127+
return fileSystem.directory(checkoutsDirname);
128+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
export 'src/packages_autoroller.dart';

0 commit comments

Comments
 (0)