From 050c6b2084c31c991030204bf3bd97b8e520ab6b Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Thu, 1 Apr 2021 16:53:29 -0700 Subject: [PATCH 1/7] refactor --- script/tool/lib/src/common.dart | 4 +- .../tool/lib/src/publish_plugin_command.dart | 99 ++++++++++--------- .../test/publish_plugin_command_test.dart | 14 ++- 3 files changed, 64 insertions(+), 53 deletions(-) diff --git a/script/tool/lib/src/common.dart b/script/tool/lib/src/common.dart index 7d3063a20f53..febd1568c81c 100644 --- a/script/tool/lib/src/common.dart +++ b/script/tool/lib/src/common.dart @@ -526,7 +526,9 @@ class ProcessRunner { Directory workingDir, }) async { final io.ProcessResult result = await io.Process.run(executable, args, - workingDirectory: workingDir?.path); + workingDirectory: workingDir?.path, runInShell: true); + print(result.stderr); + print(result.stdout); if (result.exitCode != 0) { final String error = _getErrorString(executable, args, workingDir: workingDir); diff --git a/script/tool/lib/src/publish_plugin_command.dart b/script/tool/lib/src/publish_plugin_command.dart index eb59091db34a..60e8f81e6d37 100644 --- a/script/tool/lib/src/publish_plugin_command.dart +++ b/script/tool/lib/src/publish_plugin_command.dart @@ -63,6 +63,12 @@ class PublishPluginCommand extends PluginCommand { // Flutter convention is to use "upstream" for the single source of truth, and "origin" for personal forks. defaultsTo: 'upstream', ); + argParser.addOption( + _allOption, + help: + 'Based the diff between $_kBaseShaOption and HEAD, publish all the plugins that has pubspec change in this diff.\n' + 'The --package option is ignored if this flag is on. (This is currently under construction)' , + ); } static const String _packageOption = 'package'; @@ -70,6 +76,8 @@ class PublishPluginCommand extends PluginCommand { static const String _pushTagsOption = 'push-tags'; static const String _pubFlagsOption = 'pub-publish-flags'; static const String _remoteOption = 'remote'; + static const String _allOption = 'all'; + static const String _kBaseShaOption = 'base-sha'; // Version tags should follow -v. For example, // `flutter_plugin_tools-v0.0.24`. @@ -85,40 +93,58 @@ class PublishPluginCommand extends PluginCommand { final Print _print; final Stdin _stdin; // The directory of the actual package that we are publishing. - Directory _packageDir; StreamSubscription _stdinSubscription; @override Future run() async { checkSharding(); - _print('Checking local repo...'); - _packageDir = _checkPackageDir(); - await _checkGitStatus(); + final String package = argResults[_packageOption]; + if (package == null) { + _print( + 'Must specify a package to publish. See `plugin_tools help publish-plugin`.'); + throw ToolExit(1); + } + + 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; if (shouldPushTag) { remoteUrl = await _verifyRemote(remote); } - _print('Local repo is ready!'); - await _publish(); + final Directory packageDir = _checkPackageDir(package); + await _publishPlugin(packageDir: packagesDir); + + await _tagRelease(packageDir: packageDir, remote: remote, remoteUrl: remoteUrl, shouldPushTag: shouldPushTag); + await _finishSuccesfully(); + } + + Future _publishPlugin({@required Directory packageDir}) async { + _print('Checking local repo...'); + await _checkGitStatus(packageDir); + _print('Local repo is ready!'); + await _publish(packageDir); _print('Package published!'); + } + + Future _tagRelease({@required Directory packageDir, @required String remote, @required String remoteUrl, @required bool shouldPushTag}) async { if (!argResults[_tagReleaseOption]) { - return await _finishSuccesfully(); + return; } - _print('Tagging release...'); - final String tag = _getTag(); - await processRunner.runAndExitOnError('git', ['tag', tag], - workingDir: _packageDir); + final String tag = _getTag(packageDir); + await processRunner.runAndExitOnError('git', ['tag', tag], workingDir: packageDir); if (!shouldPushTag) { - return await _finishSuccesfully(); + return; } _print('Pushing tag to $remote...'); await _pushTagToRemote(remote: remote, tag: tag, remoteUrl: remoteUrl); - await _finishSuccesfully(); } Future _finishSuccesfully() async { @@ -126,36 +152,23 @@ 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`.'); - throw ToolExit(1); - } - final Directory _packageDir = packagesDir.childDirectory(package); - if (!_packageDir.existsSync()) { - _print('${_packageDir.absolute.path} does not exist.'); + Directory _checkPackageDir(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 _checkGitStatus() async { - if (!await GitDir.isGitDir(packagesDir.path)) { - _print('$packagesDir is not a valid Git repository.'); - throw ToolExit(1); - } - - final ProcessResult statusResult = await processRunner.runAndExitOnError( - 'git', - [ + Future _checkGitStatus(Directory packageDir) async { + final ProcessResult statusResult = await processRunner.runAndExitOnError('git', [ 'status', '--porcelain', '--ignored', - _packageDir.absolute.path - ], - workingDir: _packageDir); + packageDir.absolute.path + ], workingDir: packageDir); + final String statusOutput = statusResult.stdout; if (statusOutput.isNotEmpty) { _print( @@ -168,18 +181,17 @@ class PublishPluginCommand extends PluginCommand { Future _verifyRemote(String remote) async { final ProcessResult remoteInfo = await processRunner.runAndExitOnError( - 'git', ['remote', 'get-url', remote], - workingDir: _packageDir); + 'git', ['remote', 'get-url', remote], workingDir: packagesDir); return remoteInfo.stdout; } - Future _publish() async { + Future _publish(Directory packageDir) async { final List 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', ['pub', 'publish'] + publishFlags, - workingDirectory: _packageDir); + workingDirectory: packageDir); publish.stdout .transform(utf8.decoder) .listen((String data) => _print(data)); @@ -196,9 +208,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 +232,6 @@ class PublishPluginCommand extends PluginCommand { _print('Tag push canceled.'); throw ToolExit(1); } - await processRunner.runAndExitOnError('git', ['push', remote, tag], workingDir: packagesDir); } diff --git a/script/tool/test/publish_plugin_command_test.dart b/script/tool/test/publish_plugin_command_test.dart index 9a0f1d6b6e63..82d31c8f41cd 100644 --- a/script/tool/test/publish_plugin_command_test.dart +++ b/script/tool/test/publish_plugin_command_test.dart @@ -42,15 +42,15 @@ void main() { assert(pluginDir != null && pluginDir.existsSync()); createFakePubspec(pluginDir, includeVersion: true); io.Process.runSync('git', ['init'], - workingDirectory: mockPackagesDir.path); - gitDir = await GitDir.fromExisting(mockPackagesDir.path); + workingDirectory: parentDir.path); + gitDir = await GitDir.fromExisting(parentDir.path); await gitDir.runCommand(['add', '-A']); await gitDir.runCommand(['commit', '-m', 'Initial commit']); processRunner = TestProcessRunner(); mockStdin = MockStdin(); commandRunner = CommandRunner('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(['publish-plugin']), throwsA(const TypeMatcher())); - 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(['publish-plugin', '--package', 'iamerror']), + .run(['publish-plugin', '--package', 'iamerror', '--no-push-tags']), throwsA(const TypeMatcher())); expect(printedMessages.last, contains('iamerror does not exist')); @@ -84,7 +83,7 @@ void main() { await expectLater( () => commandRunner - .run(['publish-plugin', '--package', testPluginName]), + .run(['publish-plugin', '--package', testPluginName, '--no-push-tags']), throwsA(const TypeMatcher())); expect( @@ -98,8 +97,7 @@ void main() { () => commandRunner .run(['publish-plugin', '--package', testPluginName]), throwsA(const TypeMatcher())); - - expect(processRunner.results.last.stderr, contains("No such remote")); + expect(processRunner.results.last.stdout, contains("No such remote")); }); test("doesn't validate the remote if it's not pushing tags", () async { From cff39aa5a6c21f32666ebbc3463ed4128863479f Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Thu, 1 Apr 2021 16:54:58 -0700 Subject: [PATCH 2/7] fix tests --- script/tool/test/publish_plugin_command_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/tool/test/publish_plugin_command_test.dart b/script/tool/test/publish_plugin_command_test.dart index 82d31c8f41cd..1bccc2748d36 100644 --- a/script/tool/test/publish_plugin_command_test.dart +++ b/script/tool/test/publish_plugin_command_test.dart @@ -97,7 +97,7 @@ void main() { () => commandRunner .run(['publish-plugin', '--package', testPluginName]), throwsA(const TypeMatcher())); - expect(processRunner.results.last.stdout, contains("No such remote")); + expect(processRunner.results.last.stderr, contains("No such remote")); }); test("doesn't validate the remote if it's not pushing tags", () async { From c91253f51a5d4539f8b1857f21b6d3a88c8ef5b7 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Thu, 1 Apr 2021 16:55:41 -0700 Subject: [PATCH 3/7] cleanup --- script/tool/lib/src/publish_plugin_command.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/script/tool/lib/src/publish_plugin_command.dart b/script/tool/lib/src/publish_plugin_command.dart index 60e8f81e6d37..eb887eb0bf52 100644 --- a/script/tool/lib/src/publish_plugin_command.dart +++ b/script/tool/lib/src/publish_plugin_command.dart @@ -119,7 +119,6 @@ class PublishPluginCommand extends PluginCommand { final Directory packageDir = _checkPackageDir(package); await _publishPlugin(packageDir: packagesDir); - await _tagRelease(packageDir: packageDir, remote: remote, remoteUrl: remoteUrl, shouldPushTag: shouldPushTag); await _finishSuccesfully(); } From de62ed332a9166ef740bde1fcf4c6b58c10c7b2f Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Thu, 1 Apr 2021 17:05:51 -0700 Subject: [PATCH 4/7] cleanup --- script/tool/lib/src/common.dart | 2 -- script/tool/lib/src/publish_plugin_command.dart | 4 ++-- script/tool/test/publish_plugin_command_test.dart | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/script/tool/lib/src/common.dart b/script/tool/lib/src/common.dart index febd1568c81c..5c7bc58a3983 100644 --- a/script/tool/lib/src/common.dart +++ b/script/tool/lib/src/common.dart @@ -527,8 +527,6 @@ class ProcessRunner { }) async { final io.ProcessResult result = await io.Process.run(executable, args, workingDirectory: workingDir?.path, runInShell: true); - print(result.stderr); - print(result.stdout); if (result.exitCode != 0) { final String error = _getErrorString(executable, args, workingDir: workingDir); diff --git a/script/tool/lib/src/publish_plugin_command.dart b/script/tool/lib/src/publish_plugin_command.dart index eb887eb0bf52..202e0315538b 100644 --- a/script/tool/lib/src/publish_plugin_command.dart +++ b/script/tool/lib/src/publish_plugin_command.dart @@ -105,6 +105,7 @@ class PublishPluginCommand extends PluginCommand { throw ToolExit(1); } + _print('Checking local repo...'); if (!await GitDir.isGitDir(packagesDir.path)) { _print('$packagesDir is not a valid Git repository.'); throw ToolExit(1); @@ -116,6 +117,7 @@ class PublishPluginCommand extends PluginCommand { if (shouldPushTag) { remoteUrl = await _verifyRemote(remote); } + _print('Local repo is ready!'); final Directory packageDir = _checkPackageDir(package); await _publishPlugin(packageDir: packagesDir); @@ -124,9 +126,7 @@ class PublishPluginCommand extends PluginCommand { } Future _publishPlugin({@required Directory packageDir}) async { - _print('Checking local repo...'); await _checkGitStatus(packageDir); - _print('Local repo is ready!'); await _publish(packageDir); _print('Package published!'); } diff --git a/script/tool/test/publish_plugin_command_test.dart b/script/tool/test/publish_plugin_command_test.dart index 1bccc2748d36..cfa40b9dc0a5 100644 --- a/script/tool/test/publish_plugin_command_test.dart +++ b/script/tool/test/publish_plugin_command_test.dart @@ -42,8 +42,8 @@ void main() { assert(pluginDir != null && pluginDir.existsSync()); createFakePubspec(pluginDir, includeVersion: true); io.Process.runSync('git', ['init'], - workingDirectory: parentDir.path); - gitDir = await GitDir.fromExisting(parentDir.path); + workingDirectory: mockPackagesDir.path); + gitDir = await GitDir.fromExisting(mockPackagesDir.path); await gitDir.runCommand(['add', '-A']); await gitDir.runCommand(['commit', '-m', 'Initial commit']); processRunner = TestProcessRunner(); From ea7e9f2c55f62517c88fd73f5aab7bbf9f36da38 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Thu, 1 Apr 2021 17:08:09 -0700 Subject: [PATCH 5/7] fix typo --- script/tool/lib/src/publish_plugin_command.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/tool/lib/src/publish_plugin_command.dart b/script/tool/lib/src/publish_plugin_command.dart index 202e0315538b..f465aa34d297 100644 --- a/script/tool/lib/src/publish_plugin_command.dart +++ b/script/tool/lib/src/publish_plugin_command.dart @@ -120,7 +120,7 @@ class PublishPluginCommand extends PluginCommand { _print('Local repo is ready!'); final Directory packageDir = _checkPackageDir(package); - await _publishPlugin(packageDir: packagesDir); + await _publishPlugin(packageDir: packageDir); await _tagRelease(packageDir: packageDir, remote: remote, remoteUrl: remoteUrl, shouldPushTag: shouldPushTag); await _finishSuccesfully(); } From 538ed18f1a0f7d8a6703b5073a21bd819ddf97ed Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Thu, 1 Apr 2021 17:08:47 -0700 Subject: [PATCH 6/7] clean --- script/tool/lib/src/common.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/tool/lib/src/common.dart b/script/tool/lib/src/common.dart index 5c7bc58a3983..7d3063a20f53 100644 --- a/script/tool/lib/src/common.dart +++ b/script/tool/lib/src/common.dart @@ -526,7 +526,7 @@ class ProcessRunner { Directory workingDir, }) async { final io.ProcessResult result = await io.Process.run(executable, args, - workingDirectory: workingDir?.path, runInShell: true); + workingDirectory: workingDir?.path); if (result.exitCode != 0) { final String error = _getErrorString(executable, args, workingDir: workingDir); From d0e470707b2ed8ad5026bd8b43864a6c792c8b3b Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Fri, 2 Apr 2021 10:31:53 -0700 Subject: [PATCH 7/7] review --- .../tool/lib/src/publish_plugin_command.dart | 46 +++++++++++-------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/script/tool/lib/src/publish_plugin_command.dart b/script/tool/lib/src/publish_plugin_command.dart index f465aa34d297..d00400294ab3 100644 --- a/script/tool/lib/src/publish_plugin_command.dart +++ b/script/tool/lib/src/publish_plugin_command.dart @@ -63,12 +63,6 @@ class PublishPluginCommand extends PluginCommand { // Flutter convention is to use "upstream" for the single source of truth, and "origin" for personal forks. defaultsTo: 'upstream', ); - argParser.addOption( - _allOption, - help: - 'Based the diff between $_kBaseShaOption and HEAD, publish all the plugins that has pubspec change in this diff.\n' - 'The --package option is ignored if this flag is on. (This is currently under construction)' , - ); } static const String _packageOption = 'package'; @@ -76,8 +70,6 @@ class PublishPluginCommand extends PluginCommand { static const String _pushTagsOption = 'push-tags'; static const String _pubFlagsOption = 'pub-publish-flags'; static const String _remoteOption = 'remote'; - static const String _allOption = 'all'; - static const String _kBaseShaOption = 'base-sha'; // Version tags should follow -v. For example, // `flutter_plugin_tools-v0.0.24`. @@ -119,9 +111,15 @@ class PublishPluginCommand extends PluginCommand { } _print('Local repo is ready!'); - final Directory packageDir = _checkPackageDir(package); + final Directory packageDir = _getPackageDir(package); await _publishPlugin(packageDir: packageDir); - await _tagRelease(packageDir: packageDir, remote: remote, remoteUrl: remoteUrl, shouldPushTag: shouldPushTag); + if (argResults[_tagReleaseOption] as bool) { + await _tagRelease( + packageDir: packageDir, + remote: remote, + remoteUrl: remoteUrl, + shouldPushTag: shouldPushTag); + } await _finishSuccesfully(); } @@ -131,13 +129,15 @@ class PublishPluginCommand extends PluginCommand { _print('Package published!'); } - Future _tagRelease({@required Directory packageDir, @required String remote, @required String remoteUrl, @required bool shouldPushTag}) async { - if (!argResults[_tagReleaseOption]) { - return; - } - _print('Tagging release...'); + Future _tagRelease( + {@required Directory packageDir, + @required String remote, + @required String remoteUrl, + @required bool shouldPushTag}) async { final String tag = _getTag(packageDir); - await processRunner.runAndExitOnError('git', ['tag', tag], workingDir: packageDir); + _print('Tagging release $tag...'); + await processRunner.runAndExitOnError('git', ['tag', tag], + workingDir: packageDir); if (!shouldPushTag) { return; } @@ -151,7 +151,9 @@ class PublishPluginCommand extends PluginCommand { _print('Done!'); } - Directory _checkPackageDir(String package) { + // 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.'); @@ -161,12 +163,15 @@ class PublishPluginCommand extends PluginCommand { } Future _checkGitStatus(Directory packageDir) async { - final ProcessResult statusResult = await processRunner.runAndExitOnError('git', [ + final ProcessResult statusResult = await processRunner.runAndExitOnError( + 'git', + [ 'status', '--porcelain', '--ignored', packageDir.absolute.path - ], workingDir: packageDir); + ], + workingDir: packageDir); final String statusOutput = statusResult.stdout; if (statusOutput.isNotEmpty) { @@ -180,7 +185,8 @@ class PublishPluginCommand extends PluginCommand { Future _verifyRemote(String remote) async { final ProcessResult remoteInfo = await processRunner.runAndExitOnError( - 'git', ['remote', 'get-url', remote], workingDir: packagesDir); + 'git', ['remote', 'get-url', remote], + workingDir: packagesDir); return remoteInfo.stdout; }