From 3e864005ec022f3ae430310744eda1dbd88ae3ec Mon Sep 17 00:00:00 2001 From: Stryder Date: Wed, 23 Mar 2022 19:51:01 -0400 Subject: [PATCH 01/25] Add `archive` package to dependencies. --- tool/plugin/pubspec.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tool/plugin/pubspec.yaml b/tool/plugin/pubspec.yaml index 2841fad205..014f5da86e 100644 --- a/tool/plugin/pubspec.yaml +++ b/tool/plugin/pubspec.yaml @@ -11,6 +11,7 @@ dependencies: git: ^2.0.0 markdown: ^4.0.0 path: ^1.7.0 + archive: ^3.2.2 dev_dependencies: lints: ^1.0.0 From d88ac748bd3735906e5947c3c8e0746798753f2b Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 09:42:02 -0400 Subject: [PATCH 02/25] Add `stripComponents` function to util.dart This function replicates the same behavior as the --strip-components=N flag used in the `tar` command. --- tool/plugin/lib/util.dart | 16 ++++++++++++++++ tool/plugin/test/artifact_test.dart | 28 ++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 tool/plugin/test/artifact_test.dart diff --git a/tool/plugin/lib/util.dart b/tool/plugin/lib/util.dart index 8a30bda03c..bfdf936e71 100644 --- a/tool/plugin/lib/util.dart +++ b/tool/plugin/lib/util.dart @@ -186,3 +186,19 @@ String _nextRelease() { var val = int.parse(current) + 1; return '$val.0'; } + +/// Replicates `tar` --strip-components=N behaviour +/// +/// Returns [filePath] with the first [i] components removed. +/// e.g. ('a/b/c/', 1) returns 'b/c' +String stripComponents(String filePath, int i) { + List components = p.split(filePath); + + if (i < components.length - 1) { + components.removeRange(0, i); + } else { + components.removeRange(0, components.length - 1); + } + + return p.joinAll(components); +} diff --git a/tool/plugin/test/artifact_test.dart b/tool/plugin/test/artifact_test.dart new file mode 100644 index 0000000000..4d56c892c3 --- /dev/null +++ b/tool/plugin/test/artifact_test.dart @@ -0,0 +1,28 @@ +/* + * Copyright 2022 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +// @dart = 2.10 +import 'package:path/path.dart' as p; +import 'package:plugin_tool/util.dart'; +import 'package:test/test.dart'; + +void main() { + group('Validate `stripComponents` function', () { + test('Correct components are removed', () { + var testPath = p.join('a', 'b', 'c', 'd'); + expect(stripComponents(testPath, 1), p.join('b', 'c', 'd')); + expect(stripComponents(testPath, 2), p.join('c', 'd')); + expect(stripComponents(testPath, 3), p.join('d')); + }); + + test('Last element is always returned', () { + var testPath = p.join('a', 'b', 'c', 'd'); + + expect(stripComponents(testPath, 4), p.join('d')); + expect(stripComponents(testPath, 5), p.join('d')); + }); + }); + +} From d12f5618643c38c6ff3aaf9231f603e8878155d3 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 10:02:17 -0400 Subject: [PATCH 03/25] Add a platform-agnostic function for extracting content from a tar'd Artifact object. --- tool/plugin/lib/util.dart | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tool/plugin/lib/util.dart b/tool/plugin/lib/util.dart index bfdf936e71..3ddaf4a0a1 100644 --- a/tool/plugin/lib/util.dart +++ b/tool/plugin/lib/util.dart @@ -7,6 +7,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'package:archive/archive.dart'; import 'package:cli_util/cli_logging.dart'; import 'package:git/git.dart'; import 'package:path/path.dart' as p; @@ -202,3 +203,51 @@ String stripComponents(String filePath, int i) { return p.joinAll(components); } + +/// Returns a File from [filePath], throw an error if it doesn't exist +File getFileOrThrow(String filePath) { + var file = File(filePath); + + if (!file.existsSync()) throw "Unable to locate file '${file.path}'"; + + return file; +} + +/// Extract files from a tar'd [artifact.file] to [artifact.output] +/// +/// The [artifact] file location can be specified using [cwd] and +/// [targetDirectory] can be used to set a directory for the extracted files. +/// +/// An int is returned to match existing patterns of checking for an error ala +/// the CLI +int extractTar(Artifact artifact, {targetDirectory = '', cwd = ''}) { + + var artifactPath = p.join(cwd, artifact.file); + var outputDir = p.join(cwd, targetDirectory, artifact.output); + + log('Extracting $artifactPath to $outputDir'); + + try { + + var file = getFileOrThrow(artifactPath); + var decodedGZipContent = GZipCodec().decode(file.readAsBytesSync()); + var iStream = InputStream(decodedGZipContent); + var decodedArchive = TarDecoder().decodeBuffer(iStream); + + for (var tarFile in decodedArchive.files) { + if (!tarFile.isFile) continue; // Don't need to create empty directories + + File(p.join(outputDir, stripComponents(tarFile.name, 1))) + ..createSync(recursive: true) + ..writeAsBytesSync(tarFile.content); + } + } on FileSystemException catch (e) { + log(e.osError.message); + return -1; + } catch (e) { + log('An unknown error occurred: $e'); + return -1; + } + + return 0; +} From 105b3b329b461bdad9a70778e11f3966bc9513d1 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 10:08:54 -0400 Subject: [PATCH 04/25] Throw explicit FileSystemException from `getFileOrThrow` --- tool/plugin/lib/util.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tool/plugin/lib/util.dart b/tool/plugin/lib/util.dart index 3ddaf4a0a1..c357a8d3d9 100644 --- a/tool/plugin/lib/util.dart +++ b/tool/plugin/lib/util.dart @@ -208,7 +208,9 @@ String stripComponents(String filePath, int i) { File getFileOrThrow(String filePath) { var file = File(filePath); - if (!file.existsSync()) throw "Unable to locate file '${file.path}'"; + if (!file.existsSync()) { + throw FileSystemException("Unable to locate file '${file.path}'"); + } return file; } From c4da661ee36128c6814b21ad0e16287edfb32478 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 10:13:59 -0400 Subject: [PATCH 05/25] Use the more specific osError.message and fall back to message if not available. --- tool/plugin/lib/util.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/plugin/lib/util.dart b/tool/plugin/lib/util.dart index c357a8d3d9..8f33480cc7 100644 --- a/tool/plugin/lib/util.dart +++ b/tool/plugin/lib/util.dart @@ -244,7 +244,7 @@ int extractTar(Artifact artifact, {targetDirectory = '', cwd = ''}) { ..writeAsBytesSync(tarFile.content); } } on FileSystemException catch (e) { - log(e.osError.message); + log(e.osError?.message ?? e.message); return -1; } catch (e) { log('An unknown error occurred: $e'); From 4cb06f95ea6b9bee187fa257d8f7db0d0f4cd07a Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 10:14:35 -0400 Subject: [PATCH 06/25] Implement platform-agnostic zip file extraction. --- tool/plugin/lib/util.dart | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tool/plugin/lib/util.dart b/tool/plugin/lib/util.dart index 8f33480cc7..9a9ff45529 100644 --- a/tool/plugin/lib/util.dart +++ b/tool/plugin/lib/util.dart @@ -253,3 +253,39 @@ int extractTar(Artifact artifact, {targetDirectory = '', cwd = ''}) { return 0; } + + +/// Extract files from a zipped [artifact.file] to [artifact.output] +/// +/// The [artifact] file location can be specified using [cwd] and +/// [targetDirectory] can be used to set a directory for the extracted files. +/// +/// An int is returned to match existing patterns of checking for an error ala +/// the CLI +int extractZip(Artifact artifact, {targetDirectory = '', cwd = ''}) { + var filePath = p.join(cwd, artifact.file); + var outputPath = p.join(cwd, targetDirectory); + + try { + File file = getFileOrThrow(filePath); + + Archive zipArchive = ZipDecoder().decodeBytes(file.readAsBytesSync()); + + for (ArchiveFile archiveItem in zipArchive.files) { + // Don't need to create empty directories + if (!archiveItem.isFile) continue; + + File(p.join(outputPath, archiveItem.name)) + ..createSync(recursive: true) + ..writeAsBytesSync(archiveItem.content); + } + } on FileSystemException catch (e) { + log(e.osError?.message ?? e.message); + return -1; + } catch (e) { + log('An unknown error occurred: $e'); + return -1; + } + + return 0; +} From e589ae4b8382ccc8e4302dff8e9a5822d8786a98 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 10:16:11 -0400 Subject: [PATCH 07/25] Indirection function to select the platform specific gradle wrapper. --- tool/plugin/lib/util.dart | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tool/plugin/lib/util.dart b/tool/plugin/lib/util.dart index 9a9ff45529..a7426a8dbc 100644 --- a/tool/plugin/lib/util.dart +++ b/tool/plugin/lib/util.dart @@ -289,3 +289,12 @@ int extractZip(Artifact artifact, {targetDirectory = '', cwd = ''}) { return 0; } + +/// Calls the platform specific gradle wrapper with the provided arguments +Future execGradleCommand(List args) async { + if (Platform.isWindows) { + return await exec('.\\gradlew.bat', args); + } else { + return await exec('./gradlew', args); + } +} \ No newline at end of file From ca09091ba97adb96f7a1c2fb5d383b2d2cf3d5bd Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 10:18:00 -0400 Subject: [PATCH 08/25] Refactor _stopDaemon to use gradle selector. --- tool/plugin/lib/plugin.dart | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tool/plugin/lib/plugin.dart b/tool/plugin/lib/plugin.dart index 1ba612f92d..bf014f38bf 100644 --- a/tool/plugin/lib/plugin.dart +++ b/tool/plugin/lib/plugin.dart @@ -410,11 +410,7 @@ class GradleBuildCommand extends BuildCommand { } Future _stopDaemon() async { - if (Platform.isWindows) { - return await exec('.\\gradlew.bat', ['--stop']); - } else { - return await exec('./gradlew', ['--stop']); - } + return execGradleCommand(['--stop']); } } From 840b83f9ebc87ddad791ee4adecad23c16e01a8c Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 10:21:10 -0400 Subject: [PATCH 09/25] Simplify `runGradleCommand` using a block for version 4.1 and gradle platform selector for all other versions. --- tool/plugin/lib/runner.dart | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tool/plugin/lib/runner.dart b/tool/plugin/lib/runner.dart index 72c74b0216..d280dc8626 100644 --- a/tool/plugin/lib/runner.dart +++ b/tool/plugin/lib/runner.dart @@ -100,19 +100,15 @@ baseVersion=${spec.baseVersion} // --daemon => Invalid byte 1 of 1-byte UTF-8 sequence, which is nonsense. // During instrumentation of FlutterProjectStep.form, which is a UTF-8 file. try { - if (Platform.isWindows) { - if (spec.version == '4.1') { + if (spec.version == '4.1') { + if (Platform.isWindows) { log('CANNOT BUILD ${spec.version} ON WINDOWS'); return 0; - } - result = await exec('.\\gradlew.bat', command); - } else { - if (spec.version == '4.1') { - return await runShellScript(command, spec); } else { - result = await exec('./gradlew', command); + return await runShellScript(command, spec); } } + result = await execGradleCommand(command); } finally { propertiesFile.writeAsStringSync(source); } From 0d20819a77837da194bfbd3c30f6fd7a12e86a53 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 10:26:04 -0400 Subject: [PATCH 10/25] extractZip just takes a file path, not an artifact. --- tool/plugin/lib/util.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tool/plugin/lib/util.dart b/tool/plugin/lib/util.dart index a7426a8dbc..8f3fe594ba 100644 --- a/tool/plugin/lib/util.dart +++ b/tool/plugin/lib/util.dart @@ -255,15 +255,15 @@ int extractTar(Artifact artifact, {targetDirectory = '', cwd = ''}) { } -/// Extract files from a zipped [artifact.file] to [artifact.output] +/// Extract files from a zipped [artifactPath] /// /// The [artifact] file location can be specified using [cwd] and /// [targetDirectory] can be used to set a directory for the extracted files. /// /// An int is returned to match existing patterns of checking for an error ala /// the CLI -int extractZip(Artifact artifact, {targetDirectory = '', cwd = ''}) { - var filePath = p.join(cwd, artifact.file); +int extractZip(String artifactPath, {targetDirectory = '', cwd = ''}) { + var filePath = p.join(cwd, artifactPath); var outputPath = p.join(cwd, targetDirectory); try { From 6f72f63a24598bd5ce87c2e3b17ed4ca56d46524 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 10:26:37 -0400 Subject: [PATCH 11/25] Replace calls to `unzip` on OS to a platform-agnostic call. --- tool/plugin/lib/artifact.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tool/plugin/lib/artifact.dart b/tool/plugin/lib/artifact.dart index 6eb091c581..713473f100 100644 --- a/tool/plugin/lib/artifact.dart +++ b/tool/plugin/lib/artifact.dart @@ -136,9 +136,10 @@ class ArtifactManager { if (artifact.isZip) { if (artifact.bareArchive) { - result = await exec( - 'unzip', ['-q', '-d', artifact.output, artifact.file], - cwd: 'artifacts'); + result = extractZip(artifact.file, + cwd: 'artifacts', + targetDirectory: artifact.output); + var files = Directory(artifact.outPath).listSync(); if (files.length < 3) /* Might have .DS_Store */ { // This is the Mac zip case. @@ -152,7 +153,7 @@ class ArtifactManager { Directory("${artifact.outPath}Temp").renameSync(artifact.outPath); } } else { - result = await exec('unzip', ['-q', artifact.file], cwd: 'artifacts'); + result = extractZip(artifact.file, cwd: 'artifacts'); } } else { result = await exec( From 10fb7fee72cd638fa7dda857ebba0cdb117fcc8d Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 10:27:49 -0400 Subject: [PATCH 12/25] Replace calls to `tar` on OS to a platform-agnostic call. --- tool/plugin/lib/artifact.dart | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/tool/plugin/lib/artifact.dart b/tool/plugin/lib/artifact.dart index 713473f100..bfaf785f61 100644 --- a/tool/plugin/lib/artifact.dart +++ b/tool/plugin/lib/artifact.dart @@ -156,17 +156,9 @@ class ArtifactManager { result = extractZip(artifact.file, cwd: 'artifacts'); } } else { - result = await exec( - 'tar', - [ - '--strip-components=1', - '-zxf', - artifact.file, - '-C', - artifact.output - ], - cwd: p.join(rootPath, 'artifacts'), - ); + result = extractTar(artifact, + cwd: 'artifacts', + targetDirectory: artifact.output); } if (result != 0) { log('unpacking failed'); From 17aa4c052c89c1138f1dae2877cd61eb12300e77 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 10:30:39 -0400 Subject: [PATCH 13/25] Remove redundant code. Code on line 124 performs the same action, just with a 'rebuildCache' check and directory creation should be handled by our file extraction to extra/empty dir's aren't created needlessly. --- tool/plugin/lib/artifact.dart | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tool/plugin/lib/artifact.dart b/tool/plugin/lib/artifact.dart index bfaf785f61..871dea54ba 100644 --- a/tool/plugin/lib/artifact.dart +++ b/tool/plugin/lib/artifact.dart @@ -128,12 +128,6 @@ class ArtifactManager { continue; } - // expand - if (Directory(artifact.outPath).existsSync()) { - await removeAll(artifact.outPath); - } - createDir(artifact.outPath); - if (artifact.isZip) { if (artifact.bareArchive) { result = extractZip(artifact.file, From b52e5f30daa063ad29494799d54bcaf1410ccc74 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 10:33:42 -0400 Subject: [PATCH 14/25] Replace `deleteBuildContents` shell call with platform-agnostic call. --- tool/plugin/lib/plugin.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tool/plugin/lib/plugin.dart b/tool/plugin/lib/plugin.dart index bf014f38bf..79b72cc2e4 100644 --- a/tool/plugin/lib/plugin.dart +++ b/tool/plugin/lib/plugin.dart @@ -60,10 +60,10 @@ List createBuildSpecs(ProductCommand command) { Future deleteBuildContents() async { final dir = Directory(p.join(rootPath, 'build')); if (!dir.existsSync()) throw 'No build directory found'; - var args = []; - args.add('-rf'); - args.add(p.join(rootPath, 'build', '*')); - return await exec('rm', args); + log('Deleting build contents from ${dir.path}'); + dir.deleteSync(recursive: true); + + return 0; } List findJars(String path) { From 57102bc6401f8278f4bf174796e1fcdba4898a49 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 10:37:15 -0400 Subject: [PATCH 15/25] Replace `moveToArtifacts` shell call with platform-agnostic call. --- tool/plugin/lib/plugin.dart | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tool/plugin/lib/plugin.dart b/tool/plugin/lib/plugin.dart index 79b72cc2e4..1726a4aaff 100644 --- a/tool/plugin/lib/plugin.dart +++ b/tool/plugin/lib/plugin.dart @@ -161,11 +161,15 @@ Future jar(String directory, String outFile) async { Future moveToArtifacts(ProductCommand cmd, BuildSpec spec) async { final dir = Directory(p.join(rootPath, 'artifacts')); if (!dir.existsSync()) throw 'No artifacts directory found'; - var file = pluginRegistryIds[spec.pluginId]; - var args = []; - args.add(p.join(rootPath, 'build', file)); - args.add(cmd.releasesFilePath(spec)); - return await exec('mv', args); + + var targetFile = + File(p.join(rootPath, 'build', pluginRegistryIds[spec.pluginId])); + var newPath = cmd.releasesFilePath(spec); + + log('Moving ${targetFile.path} to $newPath'); + targetFile.renameSync(newPath); + + return 0; } Future performReleaseChecks(ProductCommand cmd) async { From 3a63e480f75a6e39ba0d8f8af046387fcc182700 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 10:41:40 -0400 Subject: [PATCH 16/25] Replace `removeAll` shell call with a platform-agnostic version. Update calling methods. This and other like methods have the Future signature removed since they all executed using await in any case. Return values are still 'int' to support existing checks. --- tool/plugin/lib/artifact.dart | 4 ++-- tool/plugin/lib/plugin.dart | 2 +- tool/plugin/lib/util.dart | 23 ++++++++++++++++++++--- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/tool/plugin/lib/artifact.dart b/tool/plugin/lib/artifact.dart index 871dea54ba..742dbf3b84 100644 --- a/tool/plugin/lib/artifact.dart +++ b/tool/plugin/lib/artifact.dart @@ -122,7 +122,7 @@ class ArtifactManager { // clear unpacked cache if (rebuildCache || !FileSystemEntity.isDirectorySync(artifact.outPath)) { - await removeAll(artifact.outPath); + removeAll(artifact.outPath); } if (isCacheDirectoryValid(artifact)) { continue; @@ -156,7 +156,7 @@ class ArtifactManager { } if (result != 0) { log('unpacking failed'); - await removeAll(artifact.output); + removeAll(artifact.output); break; } diff --git a/tool/plugin/lib/plugin.dart b/tool/plugin/lib/plugin.dart index 1726a4aaff..2b7afeeff3 100644 --- a/tool/plugin/lib/plugin.dart +++ b/tool/plugin/lib/plugin.dart @@ -505,7 +505,7 @@ abstract class BuildCommand extends ProductCommand { } separator('Building flutter-intellij.jar'); - await removeAll('build'); + removeAll('build'); log('spec.version: ${spec.version}'); diff --git a/tool/plugin/lib/util.dart b/tool/plugin/lib/util.dart index 8f3fe594ba..a747aab743 100644 --- a/tool/plugin/lib/util.dart +++ b/tool/plugin/lib/util.dart @@ -109,9 +109,26 @@ Future curl(String url, {String to}) async { return await exec('curl', ['-o', to, url]); } -Future removeAll(String dir) async { - var args = ['-rf', dir]; - return await exec('rm', args); +int removeAll(String dir) { + var targetDirectory = Directory(dir); + + log('Removing Directory $dir'); + + if (targetDirectory.existsSync()) { + try { + targetDirectory.deleteSync(recursive: true); + } on FileSystemException catch (e) { + log(e.osError.message); + return -1; + } catch (e) { + log("An error occurred while deleteing $dir"); + log(e); + + return -1; + } + } + + return 0; } bool isCacheDirectoryValid(Artifact artifact) { From 408b398dc28c2580572b6b61e89d186116d75e5b Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 10:45:22 -0400 Subject: [PATCH 17/25] Add try/catch for `jar` command to notify the user if the shell command is not found. --- tool/plugin/lib/plugin.dart | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tool/plugin/lib/plugin.dart b/tool/plugin/lib/plugin.dart index 2b7afeeff3..5a16b2fb40 100644 --- a/tool/plugin/lib/plugin.dart +++ b/tool/plugin/lib/plugin.dart @@ -155,7 +155,18 @@ Future jar(String directory, String outFile) async { .listSync(followLinks: false) .map((f) => p.basename(f.path))); args.remove('.DS_Store'); - return await exec('jar', args, cwd: directory); + try { + return await exec('jar', args, cwd: directory); + } on ProcessException catch (e) { + if (e.message == 'No such file or directory'){ + log( + '\nThe build command requires `java` to be installed.' + '\nPlease ensure `jar` is on your \$PATH.', indent: false); + exit(e.errorCode); + } else { + rethrow; + } + } } Future moveToArtifacts(ProductCommand cmd, BuildSpec spec) async { From b78788b525812cb142f036d3da38326e4e6f6f97 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 13:47:58 -0400 Subject: [PATCH 18/25] Add dependency on `http` to support download operations. --- tool/plugin/pubspec.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/tool/plugin/pubspec.yaml b/tool/plugin/pubspec.yaml index 014f5da86e..6a8b5e08da 100644 --- a/tool/plugin/pubspec.yaml +++ b/tool/plugin/pubspec.yaml @@ -12,6 +12,7 @@ dependencies: markdown: ^4.0.0 path: ^1.7.0 archive: ^3.2.2 + http: ^0.13.4 dev_dependencies: lints: ^1.0.0 From b881c9df913c3dcec17292ef9f6853d6af25c913 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 13:59:08 -0400 Subject: [PATCH 19/25] Replace shell call to curl with platform-agnostic version. --- tool/plugin/lib/util.dart | 64 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/tool/plugin/lib/util.dart b/tool/plugin/lib/util.dart index a747aab743..d3fe582528 100644 --- a/tool/plugin/lib/util.dart +++ b/tool/plugin/lib/util.dart @@ -6,10 +6,12 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'dart:math' as math; import 'package:archive/archive.dart'; import 'package:cli_util/cli_logging.dart'; import 'package:git/git.dart'; +import 'package:http/http.dart'; import 'package:path/path.dart' as p; import 'artifact.dart'; @@ -106,7 +108,67 @@ void createDir(String name) { } Future curl(String url, {String to}) async { - return await exec('curl', ['-o', to, url]); + final File tmpFile = File('$to.tmp'); + final httpClient = Client(); + final request = Request('GET', Uri.parse(url)); + + List> blocks = []; + int blocksDownloaded = 0; + int totalDownloaded = 0; + + log('\n% Done\tReceived'); + + try { + StreamedResponse response = await httpClient.send(request); + + final flushSize = (response.contentLength / 100).floor(); //arbitrary value + final fmtDownloadSize = formatBytes(response.contentLength); + + // helper function to write blocks to tmpFile and log output + _flushToFile(int totalDownloaded, List> blocks) { + var pctComplete = + (totalDownloaded / response.contentLength * 100).floor(); + + log('$pctComplete\t${formatBytes(totalDownloaded)} of $fmtDownloadSize'); + + for (var block in blocks) { + tmpFile.writeAsBytesSync(block, mode: FileMode.append); + } + } + + await for (final List block in response.stream) { + blocks.add(block); + blocksDownloaded += block.length; + totalDownloaded += block.length; + + if (blocksDownloaded > flushSize) { + _flushToFile(totalDownloaded, blocks); + + blocks = []; + blocksDownloaded = 0; + } + } + + _flushToFile(totalDownloaded, blocks); + + tmpFile.renameSync(to); + } catch (e) { + log(e); + return -1; + } + + return 0; +} + +String formatBytes(int bytes) { + if (bytes <= 0) return '0'; + const suffixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; + + var i = (math.log(bytes) / math.log(1024)).floor(); + var size = ((bytes / math.pow(1024, i)).toStringAsFixed(0)); + var suffix = suffixes[i]; + + return '$size$suffix'; } int removeAll(String dir) { From 0c9b20181b623c337fc3f4ea8a3af8f1ba8a6a14 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 13:59:28 -0400 Subject: [PATCH 20/25] Rename `curl` to `download` --- tool/plugin/lib/artifact.dart | 4 ++-- tool/plugin/lib/util.dart | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tool/plugin/lib/artifact.dart b/tool/plugin/lib/artifact.dart index 742dbf3b84..fcb038ed35 100644 --- a/tool/plugin/lib/artifact.dart +++ b/tool/plugin/lib/artifact.dart @@ -85,7 +85,7 @@ class ArtifactManager { } if (doDownload) { log('downloading $path...'); - result = await curl('$base/${artifact.file}', to: path); + result = await download('$base/${artifact.file}', to: path); if (result != 0) { log('download failed'); } @@ -99,7 +99,7 @@ class ArtifactManager { if (artifact.isZip) { artifact.convertToTar(); path = 'artifacts/${artifact.file}'; - result = await curl('$base/${artifact.file}', to: path); + result = await download('$base/${artifact.file}', to: path); if (result != 0) { log('download failed'); artifacts.remove(artifact); diff --git a/tool/plugin/lib/util.dart b/tool/plugin/lib/util.dart index d3fe582528..e1ef77ff24 100644 --- a/tool/plugin/lib/util.dart +++ b/tool/plugin/lib/util.dart @@ -107,7 +107,7 @@ void createDir(String name) { } } -Future curl(String url, {String to}) async { +Future download(String url, {String to}) async { final File tmpFile = File('$to.tmp'); final httpClient = Client(); final request = Request('GET', Uri.parse(url)); From e85efd3b7a5fa10fd1d5f6df66d54950f05da841 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 17:57:53 -0400 Subject: [PATCH 21/25] Fix pathing updates to use platform separators. --- tool/plugin/lib/plugin.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tool/plugin/lib/plugin.dart b/tool/plugin/lib/plugin.dart index 5a16b2fb40..5a49f866a8 100644 --- a/tool/plugin/lib/plugin.dart +++ b/tool/plugin/lib/plugin.dart @@ -879,19 +879,19 @@ class RenamePackageCommand extends ProductCommand { } void moveFiles() { - final srcDir = Directory(p.join(baseDir, oldName.replaceAll('.', '/'))); - final destDir = Directory(p.join(baseDir, newName.replaceAll('.', '/'))); + final srcDir = Directory(p.joinAll([baseDir] + oldName.split('.'))); + final destDir = Directory(p.joinAll([baseDir] + newName.split('.'))); _editAndMoveAll(srcDir, destDir); } void editReferences() { - final srcDir = Directory(p.join(baseDir, oldName.replaceAll('.', '/'))); - final destDir = Directory(p.join(baseDir, newName.replaceAll('.', '/'))); + final srcDir = Directory(p.joinAll([baseDir] + oldName.split('.'))); + final destDir = Directory(p.joinAll([baseDir] + newName.split('.'))); _editAll(Directory(baseDir), skipOld: srcDir, skipNew: destDir); } Future deleteDir() async { - final dir = Directory(p.join(baseDir, oldName.replaceAll('.', '/'))); + final dir = Directory(p.joinAll([baseDir] + oldName.split('.'))); await dir.delete(recursive: true); return 0; } From 14117a8c49ba7333e1de366caf3652fbb91143f6 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 18:32:18 -0400 Subject: [PATCH 22/25] Normalize file paths to use OS separators. Update variable names to make intentions more apparent. --- tool/plugin/lib/artifact.dart | 33 ++++++++++++++------------ tool/plugin/lib/edit.dart | 17 +++++++++----- tool/plugin/lib/plugin.dart | 44 ++++++++++++++++++----------------- tool/plugin/lib/runner.dart | 5 ++-- tool/plugin/lib/util.dart | 4 ++-- 5 files changed, 57 insertions(+), 46 deletions(-) diff --git a/tool/plugin/lib/artifact.dart b/tool/plugin/lib/artifact.dart index fcb038ed35..a7b59fa830 100644 --- a/tool/plugin/lib/artifact.dart +++ b/tool/plugin/lib/artifact.dart @@ -23,9 +23,10 @@ class Artifact { bool get isZip => file.endsWith('.zip'); bool exists() { - if (FileSystemEntity.isFileSync('artifacts/$file')) return true; + var artifactFilePath = p.join('artifacts', file); + if (FileSystemEntity.isFileSync(artifactFilePath)) return true; convertToTar(); - return FileSystemEntity.isFileSync('artifacts/$file'); + return FileSystemEntity.isFileSync(artifactFilePath); } String get outPath => p.join(rootPath, 'artifacts', output); @@ -39,7 +40,7 @@ class Artifact { } class ArtifactManager { - final String base = + final String baseUri = 'https://storage.googleapis.com/flutter_infra_release/flutter/intellij'; final List artifacts = []; @@ -72,42 +73,44 @@ class ArtifactManager { doDownload = false; } - var path = 'artifacts/${artifact.file}'; - if (FileSystemEntity.isFileSync(path)) { - alreadyDownloaded(path); + var artifactFilePath = p.join('artifacts', artifact.file); + if (FileSystemEntity.isFileSync(artifactFilePath)) { + alreadyDownloaded(artifactFilePath); } else { if (artifact.isZip) { - var tarPath = _convertToTar(path); + var tarPath = _convertToTar(artifactFilePath); if (FileSystemEntity.isFileSync(tarPath)) { artifact.convertToTar(); alreadyDownloaded(tarPath); } } if (doDownload) { - log('downloading $path...'); - result = await download('$base/${artifact.file}', to: path); + log('downloading $artifactFilePath...'); + var artifactUri = p.join(baseUri, artifact.file); + + result = await download(artifactUri, to: artifactFilePath); if (result != 0) { log('download failed'); } - var archiveFile = File(path); + var archiveFile = File(artifactFilePath); if (!_isValidDownloadArtifact(archiveFile)) { // If the file is missing the server returns a small file containing // an error message. Delete it and try again. The smallest file we // store in the cloud is over 700K. - log('archive file not found: $base/${artifact.file}'); + log('archive file not found: $artifactUri'); archiveFile.deleteSync(); if (artifact.isZip) { artifact.convertToTar(); - path = 'artifacts/${artifact.file}'; - result = await download('$base/${artifact.file}', to: path); + + result = await download(artifactUri, to: artifactFilePath); if (result != 0) { log('download failed'); artifacts.remove(artifact); continue; } - var archiveFile = File(path); + var archiveFile = File(artifactFilePath); if (!_isValidDownloadArtifact(archiveFile)) { - log('archive file not found: $base/${artifact.file}'); + log('archive file not found: $artifactUri'); archiveFile.deleteSync(); artifacts.remove(artifact); continue; diff --git a/tool/plugin/lib/edit.dart b/tool/plugin/lib/edit.dart index 2a59b6d270..dc4e2fe3c2 100644 --- a/tool/plugin/lib/edit.dart +++ b/tool/plugin/lib/edit.dart @@ -10,6 +10,7 @@ import 'dart:async'; import 'dart:io'; import 'package:meta/meta.dart'; +import 'package:path/path.dart' as p; import 'build_spec.dart'; import 'util.dart'; @@ -96,17 +97,22 @@ class Unused extends EditCommand { } class EditAndroidModuleLibraryManager extends EditCommand { + + final _moduleManagerPath = p.join( + 'flutter-studio', 'src', 'io', 'flutter', 'android', 'AndroidModuleLibraryManager.java' + ); + @override - String get path => - 'flutter-studio/src/io/flutter/android/AndroidModuleLibraryManager.java'; + String get path => _moduleManagerPath; @override String convert(BuildSpec spec) { // Starting with 3.6 we need to call a simplified init(). // This is where the $PROJECT_FILE$ macro is defined, #registerComponents. + + var libMgrPath = _moduleManagerPath; if (spec.version.startsWith('4.2')) { - var processedFile = File( - 'flutter-studio/src/io/flutter/android/AndroidModuleLibraryManager.java'); + var processedFile = File(libMgrPath); var source = processedFile.readAsStringSync(); var original = source; source = source.replaceAll("ProjectExImpl", "ProjectImpl"); @@ -133,8 +139,7 @@ class EditAndroidModuleLibraryManager extends EditCommand { return original; } else { if (spec.version.startsWith('2021.2')) { - var processedFile = File( - 'flutter-studio/src/io/flutter/android/AndroidModuleLibraryManager.java'); + var processedFile = File(libMgrPath); var source = processedFile.readAsStringSync(); var original = source; source = source.replaceAll( diff --git a/tool/plugin/lib/plugin.dart b/tool/plugin/lib/plugin.dart index 5a49f866a8..f2a1947a9e 100644 --- a/tool/plugin/lib/plugin.dart +++ b/tool/plugin/lib/plugin.dart @@ -136,7 +136,7 @@ void genPresubmitYaml(List specs) { } bool isTravisFileValid() { - var travisPath = p.join(rootPath, '.github/workflows/presubmit.yaml'); + var travisPath = p.join(rootPath, '.github', 'workflows', 'presubmit.yaml'); var travisFile = File(travisPath); if (!travisFile.existsSync()) { return false; @@ -329,10 +329,11 @@ class AntBuildCommand extends BuildCommand { var r = await runner.javac2(spec); if (r == 0) { // copy resources - copyResources(from: 'src', to: 'build/classes'); - copyResources(from: 'resources', to: 'build/classes'); - copyResources(from: 'gen', to: 'build/classes'); - await genPluginFiles(spec, 'build/classes'); + var classPath = p.join('build', 'classes'); + copyResources(from: 'src', to: classPath); + copyResources(from: 'resources', to: classPath); + copyResources(from: 'gen', to: classPath); + await genPluginFiles(spec, classPath); } return r; } @@ -342,27 +343,26 @@ class AntBuildCommand extends BuildCommand { int result; // create the jars - createDir('build/flutter-intellij/lib'); - result = await jar( - 'build/classes', - 'build/flutter-intellij/lib/flutter-intellij.jar', - ); + var fijPath = p.join('build', 'flutter-intellij', 'lib'); + var fijarPath = p.join(fijPath, 'flutter-intellij.jar'); + var classPath = p.join('build', 'classes'); + + createDir(fijPath); + result = await jar(classPath, fijarPath); if (result != 0) { log('jar failed: ${result.toString()}'); return result; } if (spec.isTestTarget && !isReleaseMode && !isDevChannel) { _copyFile( - File('build/flutter-intellij/lib/flutter-intellij.jar'), + File(fijarPath), Directory(testTargetPath(spec)), filename: 'io.flutter.jar', ); } if (spec.isAndroidStudio) { - result = await jar( - 'build/studio', - 'build/flutter-intellij/lib/flutter-studio.jar', - ); + var studioPath = p.join('build', 'studio'); + result = await jar(studioPath, fijarPath); if (result != 0) { log('jar failed: ${result.toString()}'); return result; @@ -370,7 +370,7 @@ class AntBuildCommand extends BuildCommand { } // zip it up - result = await zip('build/flutter-intellij', releasesFilePath(spec)); + result = await zip(fijPath, releasesFilePath(spec)); if (result != 0) { log('zip failed: ${result.toString()}'); return result; @@ -391,8 +391,9 @@ class GradleBuildCommand extends BuildCommand { @override Future externalBuildCommand(BuildSpec spec) async { - var pluginFile = File('resources/META-INF/plugin.xml'); - var studioFile = File('resources/META-INF/studio-contribs.xml'); + var metaInfPath = p.join('resources', 'META-INF'); + var pluginFile = File(p.join(metaInfPath, 'plugin.xml')); + var studioFile = File(p.join(metaInfPath, 'studio-contribs.xml')); var pluginSrc = pluginFile.readAsStringSync(); var studioSrc = studioFile.readAsStringSync(); try { @@ -408,12 +409,13 @@ class GradleBuildCommand extends BuildCommand { Future savePluginArtifact(BuildSpec spec) async { final file = File(releasesFilePath(spec)); final version = buildVersionNumber(spec); - var source = File('build/distributions/flutter-intellij-$version.zip'); + var distPath = p.join('build', 'distributions'); + var source = File(p.join(distPath, 'flutter-intellij-$version.zip')); if (!source.existsSync()) { // Setting the plugin name in Gradle should eliminate the need for this, // but it does not. // TODO(messick) Find a way to make the Kokoro file name: flutter-intellij-DEV.zip - source = File('build/distributions/flutter-intellij-kokoro-$version.zip'); + source = File(p.join(distPath, 'flutter-intellij-kokoro-$version.zip')); } _copyFile( source, @@ -862,7 +864,7 @@ class RenamePackageCommand extends ProductCommand { @override Future doit() async { - if (argResults['studio']) baseDir = p.join(baseDir, 'flutter-studio/src'); + if (argResults['studio']) baseDir = p.join(baseDir, 'flutter-studio', 'src'); oldName = argResults['package']; newName = argResults.wasParsed('new-name') ? argResults['new-name'] diff --git a/tool/plugin/lib/runner.dart b/tool/plugin/lib/runner.dart index d280dc8626..dd598e7c7a 100644 --- a/tool/plugin/lib/runner.dart +++ b/tool/plugin/lib/runner.dart @@ -7,6 +7,7 @@ import 'dart:async'; import 'dart:io'; import 'package:args/command_runner.dart'; +import 'package:path/path.dart' as p; import 'build_spec.dart'; import 'globals.dart'; @@ -59,7 +60,7 @@ compile final jxBrowserKey = readTokenFromKeystore('FLUTTER_KEYSTORE_JXBROWSER_KEY_NAME'); final propertiesFile = - File("$rootPath/resources/jxbrowser/jxbrowser.properties"); + File(p.join(rootPath, 'resources', 'jxbrowser', 'jxbrowser.properties')); if (jxBrowserKey.isNotEmpty) { final contents = ''' jxbrowser.license.key=$jxBrowserKey @@ -92,7 +93,7 @@ testing=$testing buildSpec=${spec.version} baseVersion=${spec.baseVersion} '''; - final propertiesFile = File("$rootPath/gradle.properties"); + final propertiesFile = File(p.join(rootPath, 'gradle.properties')); final source = propertiesFile.readAsStringSync(); propertiesFile.writeAsStringSync(contents); int result; diff --git a/tool/plugin/lib/util.dart b/tool/plugin/lib/util.dart index e1ef77ff24..577495a90d 100644 --- a/tool/plugin/lib/util.dart +++ b/tool/plugin/lib/util.dart @@ -102,7 +102,7 @@ void log(String s, {bool indent = true}) { void createDir(String name) { final dir = Directory(name); if (!dir.existsSync()) { - log('creating $name/'); + log('creating $name'); dir.createSync(recursive: true); } } @@ -233,7 +233,7 @@ String readTokenFromKeystore(String keyName) { var id = env['FLUTTER_KEYSTORE_ID']; var name = env[keyName]; - var file = File('$base/${id}_$name'); + var file = File(p.join(base, '${id}_$name')); return file.existsSync() ? file.readAsStringSync() : ''; } From a1e2674f4a0eccc05d4a8db92fa41de42d721159 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 18:32:58 -0400 Subject: [PATCH 23/25] Cleanup and import optimization --- tool/grind.dart | 4 ++-- tool/plugin/lib/artifact.dart | 6 ++---- tool/plugin/lib/edit.dart | 6 ++---- tool/plugin/lib/plugin.dart | 10 ++++++---- tool/plugin/lib/runner.dart | 4 ++-- tool/plugin/lib/util.dart | 12 ++++-------- tool/plugin/test/artifact_test.dart | 1 - 7 files changed, 18 insertions(+), 25 deletions(-) diff --git a/tool/grind.dart b/tool/grind.dart index cb34c4cdf5..5319826c6e 100644 --- a/tool/grind.dart +++ b/tool/grind.dart @@ -12,8 +12,8 @@ void main(List args) => grind(args); @Task('Check plugin URLs for live-ness') void checkUrls() async { log('checking URLs in FlutterBundle.properties...'); - var lines = - await File('flutter-idea/src/io/flutter/FlutterBundle.properties').readAsLines(); + var lines = await File('flutter-idea/src/io/flutter/FlutterBundle.properties') + .readAsLines(); for (var line in lines) { var split = line.split('='); if (split.length == 2) { diff --git a/tool/plugin/lib/artifact.dart b/tool/plugin/lib/artifact.dart index a7b59fa830..eb9b36de85 100644 --- a/tool/plugin/lib/artifact.dart +++ b/tool/plugin/lib/artifact.dart @@ -134,8 +134,7 @@ class ArtifactManager { if (artifact.isZip) { if (artifact.bareArchive) { result = extractZip(artifact.file, - cwd: 'artifacts', - targetDirectory: artifact.output); + cwd: 'artifacts', targetDirectory: artifact.output); var files = Directory(artifact.outPath).listSync(); if (files.length < 3) /* Might have .DS_Store */ { @@ -154,8 +153,7 @@ class ArtifactManager { } } else { result = extractTar(artifact, - cwd: 'artifacts', - targetDirectory: artifact.output); + cwd: 'artifacts', targetDirectory: artifact.output); } if (result != 0) { log('unpacking failed'); diff --git a/tool/plugin/lib/edit.dart b/tool/plugin/lib/edit.dart index dc4e2fe3c2..8d7772a18d 100644 --- a/tool/plugin/lib/edit.dart +++ b/tool/plugin/lib/edit.dart @@ -97,10 +97,8 @@ class Unused extends EditCommand { } class EditAndroidModuleLibraryManager extends EditCommand { - - final _moduleManagerPath = p.join( - 'flutter-studio', 'src', 'io', 'flutter', 'android', 'AndroidModuleLibraryManager.java' - ); + final _moduleManagerPath = p.join('flutter-studio', 'src', 'io', 'flutter', + 'android', 'AndroidModuleLibraryManager.java'); @override String get path => _moduleManagerPath; diff --git a/tool/plugin/lib/plugin.dart b/tool/plugin/lib/plugin.dart index f2a1947a9e..3dcb58d61b 100644 --- a/tool/plugin/lib/plugin.dart +++ b/tool/plugin/lib/plugin.dart @@ -158,10 +158,11 @@ Future jar(String directory, String outFile) async { try { return await exec('jar', args, cwd: directory); } on ProcessException catch (e) { - if (e.message == 'No such file or directory'){ + if (e.message == 'No such file or directory') { log( - '\nThe build command requires `java` to be installed.' - '\nPlease ensure `jar` is on your \$PATH.', indent: false); + '\nThe build command requires `java` to be installed.' + '\nPlease ensure `jar` is on your \$PATH.', + indent: false); exit(e.errorCode); } else { rethrow; @@ -864,7 +865,8 @@ class RenamePackageCommand extends ProductCommand { @override Future doit() async { - if (argResults['studio']) baseDir = p.join(baseDir, 'flutter-studio', 'src'); + if (argResults['studio']) + baseDir = p.join(baseDir, 'flutter-studio', 'src'); oldName = argResults['package']; newName = argResults.wasParsed('new-name') ? argResults['new-name'] diff --git a/tool/plugin/lib/runner.dart b/tool/plugin/lib/runner.dart index dd598e7c7a..e3896afd1c 100644 --- a/tool/plugin/lib/runner.dart +++ b/tool/plugin/lib/runner.dart @@ -59,8 +59,8 @@ compile void writeJxBrowserKeyToFile() { final jxBrowserKey = readTokenFromKeystore('FLUTTER_KEYSTORE_JXBROWSER_KEY_NAME'); - final propertiesFile = - File(p.join(rootPath, 'resources', 'jxbrowser', 'jxbrowser.properties')); + final propertiesFile = File( + p.join(rootPath, 'resources', 'jxbrowser', 'jxbrowser.properties')); if (jxBrowserKey.isNotEmpty) { final contents = ''' jxbrowser.license.key=$jxBrowserKey diff --git a/tool/plugin/lib/util.dart b/tool/plugin/lib/util.dart index 577495a90d..45c1ee7ec1 100644 --- a/tool/plugin/lib/util.dart +++ b/tool/plugin/lib/util.dart @@ -25,7 +25,7 @@ Future exec(String cmd, List args, {String cwd}) async { log(_shorten('$cmd ${args.join(' ')}')); } - var codec = Platform.isWindows ? latin1: utf8; + var codec = Platform.isWindows ? latin1 : utf8; final process = await Process.start(cmd, args, workingDirectory: cwd); _toLineStream(process.stderr, codec).listen(log); _toLineStream(process.stdout, codec).listen(log); @@ -237,7 +237,6 @@ String readTokenFromKeystore(String keyName) { return file.existsSync() ? file.readAsStringSync() : ''; } - int get devBuildNumber { // The dev channel is automatically refreshed weekly, so the build number // is just the number of weeks since the last stable release. @@ -262,7 +261,7 @@ String buildVersionNumber(BuildSpec spec) { String _nextRelease() { var current = - RegExp(r'release_(\d+)').matchAsPrefix(lastReleaseName).group(1); + RegExp(r'release_(\d+)').matchAsPrefix(lastReleaseName).group(1); var val = int.parse(current) + 1; return '$val.0'; } @@ -302,21 +301,19 @@ File getFileOrThrow(String filePath) { /// An int is returned to match existing patterns of checking for an error ala /// the CLI int extractTar(Artifact artifact, {targetDirectory = '', cwd = ''}) { - var artifactPath = p.join(cwd, artifact.file); var outputDir = p.join(cwd, targetDirectory, artifact.output); log('Extracting $artifactPath to $outputDir'); try { - var file = getFileOrThrow(artifactPath); var decodedGZipContent = GZipCodec().decode(file.readAsBytesSync()); var iStream = InputStream(decodedGZipContent); var decodedArchive = TarDecoder().decodeBuffer(iStream); for (var tarFile in decodedArchive.files) { - if (!tarFile.isFile) continue; // Don't need to create empty directories + if (!tarFile.isFile) continue; // Don't need to create empty directories File(p.join(outputDir, stripComponents(tarFile.name, 1))) ..createSync(recursive: true) @@ -333,7 +330,6 @@ int extractTar(Artifact artifact, {targetDirectory = '', cwd = ''}) { return 0; } - /// Extract files from a zipped [artifactPath] /// /// The [artifact] file location can be specified using [cwd] and @@ -376,4 +372,4 @@ Future execGradleCommand(List args) async { } else { return await exec('./gradlew', args); } -} \ No newline at end of file +} diff --git a/tool/plugin/test/artifact_test.dart b/tool/plugin/test/artifact_test.dart index 4d56c892c3..fac42759c0 100644 --- a/tool/plugin/test/artifact_test.dart +++ b/tool/plugin/test/artifact_test.dart @@ -24,5 +24,4 @@ void main() { expect(stripComponents(testPath, 5), p.join('d')); }); }); - } From cb2296f7b5bb1916aae16f2be146e009bc4fe2c5 Mon Sep 17 00:00:00 2001 From: Stryder Crown Date: Wed, 23 Mar 2022 19:06:16 -0400 Subject: [PATCH 24/25] Use empty string as default instead of null. --- tool/plugin/lib/globals.dart | 2 +- tool/plugin/lib/util.dart | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tool/plugin/lib/globals.dart b/tool/plugin/lib/globals.dart index 690343c579..30bcca4948 100644 --- a/tool/plugin/lib/globals.dart +++ b/tool/plugin/lib/globals.dart @@ -14,7 +14,7 @@ const int cloudErrorFileMaxSize = 1000; // In bytes. // Globals are initialized early in ProductCommand. These are used in various // top-level functions. This is not ideal, but the "proper" solution would be // to move nearly all the top-level functions to methods in ProductCommand. -String rootPath; +String rootPath = ''; String lastReleaseName; DateTime lastReleaseDate; int pluginCount = 0; diff --git a/tool/plugin/lib/util.dart b/tool/plugin/lib/util.dart index 45c1ee7ec1..cd3a1d00f5 100644 --- a/tool/plugin/lib/util.dart +++ b/tool/plugin/lib/util.dart @@ -229,9 +229,9 @@ Stream _toLineStream(Stream> s, Encoding encoding) => String readTokenFromKeystore(String keyName) { var env = Platform.environment; - var base = env['KOKORO_KEYSTORE_DIR']; - var id = env['FLUTTER_KEYSTORE_ID']; - var name = env[keyName]; + var base = env['KOKORO_KEYSTORE_DIR'] ?? ''; + var id = env['FLUTTER_KEYSTORE_ID'] ?? ''; + var name = env[keyName] ?? ''; var file = File(p.join(base, '${id}_$name')); return file.existsSync() ? file.readAsStringSync() : ''; From ad3d092b9bc5fb9147b735bdda98c02fb45e1c96 Mon Sep 17 00:00:00 2001 From: Stryder Date: Thu, 24 Mar 2022 01:29:43 -0400 Subject: [PATCH 25/25] Remove param from _flushToFile The reference to the accumulator is already available and doesn't need to be passed in each time. Bit easier to read. --- tool/plugin/lib/util.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tool/plugin/lib/util.dart b/tool/plugin/lib/util.dart index cd3a1d00f5..e5c1b43ccb 100644 --- a/tool/plugin/lib/util.dart +++ b/tool/plugin/lib/util.dart @@ -125,7 +125,7 @@ Future download(String url, {String to}) async { final fmtDownloadSize = formatBytes(response.contentLength); // helper function to write blocks to tmpFile and log output - _flushToFile(int totalDownloaded, List> blocks) { + _flushToFile(List> blocks) { var pctComplete = (totalDownloaded / response.contentLength * 100).floor(); @@ -142,14 +142,14 @@ Future download(String url, {String to}) async { totalDownloaded += block.length; if (blocksDownloaded > flushSize) { - _flushToFile(totalDownloaded, blocks); + _flushToFile(blocks); blocks = []; blocksDownloaded = 0; } } - _flushToFile(totalDownloaded, blocks); + _flushToFile(blocks); tmpFile.renameSync(to); } catch (e) {