Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

[tool] refactor publish plugin command #3779

Merged
merged 7 commits into from
Apr 5, 2021
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
92 changes: 54 additions & 38 deletions script/tool/lib/src/publish_plugin_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
stuartmorgan marked this conversation as resolved.
Show resolved Hide resolved
_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;
Expand All @@ -102,60 +111,68 @@ 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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's flip this and the line above, so the print can include the tag for ease of debugging issues.

_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 {
await _stdinSubscription.cancel();
_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`.');
throw ToolExit(1);
}
final Directory _packageDir = packagesDir.childDirectory(package);
if (!_packageDir.existsSync()) {
_print('${_packageDir.absolute.path} does not exist.');
// 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);
}
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(
Expand All @@ -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));
Expand All @@ -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'];
Expand All @@ -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);
}
Expand Down
8 changes: 3 additions & 5 deletions script/tool/test/publish_plugin_command_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -65,15 +65,14 @@ 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."));
});

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'));
Expand All @@ -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(
Expand All @@ -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"));
});

Expand Down