[tool] refactor publish plugin command (#3779)

This commit is contained in:
Chris Yang
2021-04-05 13:54:05 -07:00
committed by GitHub
parent b8b7ef5cd5
commit 5ea4d5fdfc
2 changed files with 57 additions and 43 deletions

View File

@ -85,15 +85,24 @@ class PublishPluginCommand extends PluginCommand {
final Print _print;
final Stdin _stdin;
// The directory of the actual package that we are publishing.
Directory _packageDir;
StreamSubscription<String> _stdinSubscription;
@override
Future<Null> run() async {
checkSharding();
final String package = argResults[_packageOption];
if (package == null) {
_print(
'Must specify a package to publish. See `plugin_tools help publish-plugin`.');
throw ToolExit(1);
}
_print('Checking local repo...');
_packageDir = _checkPackageDir();
await _checkGitStatus();
if (!await GitDir.isGitDir(packagesDir.path)) {
_print('$packagesDir is not a valid Git repository.');
throw ToolExit(1);
}
final bool shouldPushTag = argResults[_pushTagsOption];
final String remote = argResults[_remoteOption];
String remoteUrl;
@ -102,23 +111,39 @@ class PublishPluginCommand extends PluginCommand {
}
_print('Local repo is ready!');
await _publish();
_print('Package published!');
if (!argResults[_tagReleaseOption]) {
return await _finishSuccesfully();
final Directory packageDir = _getPackageDir(package);
await _publishPlugin(packageDir: packageDir);
if (argResults[_tagReleaseOption] as bool) {
await _tagRelease(
packageDir: packageDir,
remote: remote,
remoteUrl: remoteUrl,
shouldPushTag: shouldPushTag);
}
await _finishSuccesfully();
}
_print('Tagging release...');
final String tag = _getTag();
Future<void> _publishPlugin({@required Directory packageDir}) async {
await _checkGitStatus(packageDir);
await _publish(packageDir);
_print('Package published!');
}
Future<void> _tagRelease(
{@required Directory packageDir,
@required String remote,
@required String remoteUrl,
@required bool shouldPushTag}) async {
final String tag = _getTag(packageDir);
_print('Tagging release $tag...');
await processRunner.runAndExitOnError('git', <String>['tag', tag],
workingDir: _packageDir);
workingDir: packageDir);
if (!shouldPushTag) {
return await _finishSuccesfully();
return;
}
_print('Pushing tag to $remote...');
await _pushTagToRemote(remote: remote, tag: tag, remoteUrl: remoteUrl);
await _finishSuccesfully();
}
Future<void> _finishSuccesfully() async {
@ -126,36 +151,28 @@ class PublishPluginCommand extends PluginCommand {
_print('Done!');
}
Directory _checkPackageDir() {
final String package = argResults[_packageOption];
if (package == null) {
_print(
'Must specify a package to publish. See `plugin_tools help publish-plugin`.');
// Returns the packageDirectory based on the package name.
// Throws ToolExit if the `package` doesn't exist.
Directory _getPackageDir(String package) {
final Directory packageDir = packagesDir.childDirectory(package);
if (!packageDir.existsSync()) {
_print('${packageDir.absolute.path} does not exist.');
throw ToolExit(1);
}
final Directory _packageDir = packagesDir.childDirectory(package);
if (!_packageDir.existsSync()) {
_print('${_packageDir.absolute.path} does not exist.');
throw ToolExit(1);
}
return _packageDir;
return packageDir;
}
Future<void> _checkGitStatus() async {
if (!await GitDir.isGitDir(packagesDir.path)) {
_print('$packagesDir is not a valid Git repository.');
throw ToolExit(1);
}
Future<void> _checkGitStatus(Directory packageDir) async {
final ProcessResult statusResult = await processRunner.runAndExitOnError(
'git',
<String>[
'status',
'--porcelain',
'--ignored',
_packageDir.absolute.path
packageDir.absolute.path
],
workingDir: _packageDir);
workingDir: packageDir);
final String statusOutput = statusResult.stdout;
if (statusOutput.isNotEmpty) {
_print(
@ -169,17 +186,17 @@ class PublishPluginCommand extends PluginCommand {
Future<String> _verifyRemote(String remote) async {
final ProcessResult remoteInfo = await processRunner.runAndExitOnError(
'git', <String>['remote', 'get-url', remote],
workingDir: _packageDir);
workingDir: packagesDir);
return remoteInfo.stdout;
}
Future<void> _publish() async {
Future<void> _publish(Directory packageDir) async {
final List<String> publishFlags = argResults[_pubFlagsOption];
_print(
'Running `pub publish ${publishFlags.join(' ')}` in ${_packageDir.absolute.path}...\n');
'Running `pub publish ${publishFlags.join(' ')}` in ${packageDir.absolute.path}...\n');
final Process publish = await processRunner.start(
'flutter', <String>['pub', 'publish'] + publishFlags,
workingDirectory: _packageDir);
workingDirectory: packageDir);
publish.stdout
.transform(utf8.decoder)
.listen((String data) => _print(data));
@ -196,9 +213,9 @@ class PublishPluginCommand extends PluginCommand {
}
}
String _getTag() {
String _getTag(Directory packageDir) {
final File pubspecFile =
fileSystem.file(p.join(_packageDir.path, 'pubspec.yaml'));
fileSystem.file(p.join(packageDir.path, 'pubspec.yaml'));
final YamlMap pubspecYaml = loadYaml(pubspecFile.readAsStringSync());
final String name = pubspecYaml['name'];
final String version = pubspecYaml['version'];
@ -220,7 +237,6 @@ class PublishPluginCommand extends PluginCommand {
_print('Tag push canceled.');
throw ToolExit(1);
}
await processRunner.runAndExitOnError('git', <String>['push', remote, tag],
workingDir: packagesDir);
}

View File

@ -50,7 +50,7 @@ void main() {
mockStdin = MockStdin();
commandRunner = CommandRunner<Null>('tester', '')
..addCommand(PublishPluginCommand(
mockPackagesDir, const LocalFileSystem(),
mockPackagesDir, mockPackagesDir.fileSystem,
processRunner: processRunner,
print: (Object message) => printedMessages.add(message.toString()),
stdinput: mockStdin));
@ -65,7 +65,6 @@ void main() {
test('requires a package flag', () async {
await expectLater(() => commandRunner.run(<String>['publish-plugin']),
throwsA(const TypeMatcher<ToolExit>()));
expect(
printedMessages.last, contains("Must specify a package to publish."));
});
@ -73,7 +72,7 @@ void main() {
test('requires an existing flag', () async {
await expectLater(
() => commandRunner
.run(<String>['publish-plugin', '--package', 'iamerror']),
.run(<String>['publish-plugin', '--package', 'iamerror', '--no-push-tags']),
throwsA(const TypeMatcher<ToolExit>()));
expect(printedMessages.last, contains('iamerror does not exist'));
@ -84,7 +83,7 @@ void main() {
await expectLater(
() => commandRunner
.run(<String>['publish-plugin', '--package', testPluginName]),
.run(<String>['publish-plugin', '--package', testPluginName, '--no-push-tags']),
throwsA(const TypeMatcher<ToolExit>()));
expect(
@ -98,7 +97,6 @@ void main() {
() => commandRunner
.run(<String>['publish-plugin', '--package', testPluginName]),
throwsA(const TypeMatcher<ToolExit>()));
expect(processRunner.results.last.stderr, contains("No such remote"));
});