Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(shorebird_cli): upgrade to latest shorebird (3.7.10) #247

Merged
merged 11 commits into from
Apr 7, 2023
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
2 changes: 1 addition & 1 deletion bin/internal/shared.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ unset CDPATH
# Either clones or pulls the Shorebird Flutter repository, depending on whether FLUTTER_PATH exists.
function update_flutter {
if [[ -d "$FLUTTER_PATH" ]]; then
git --git-dir="$FLUTTER_PATH/.git" pull
git --git-dir="$FLUTTER_PATH/.git" --work-tree="$FLUTTER_PATH" pull
else
git clone --filter=tree:0 https://github.com/shorebirdtech/flutter.git -b stable "$FLUTTER_PATH"
fi
Expand Down
131 changes: 131 additions & 0 deletions packages/shorebird_cli/lib/src/cache.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import 'dart:io' hide Platform;
import 'dart:isolate';

import 'package:archive/archive_io.dart';
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as p;
import 'package:platform/platform.dart';
import 'package:shorebird_cli/src/engine_revision.dart';
import 'package:shorebird_cli/src/shorebird_environment.dart';

typedef ArchiveExtracter = Future<void> Function(
String archivePath,
String outputPath,
);

Future<void> _defaultArchiveExtractor(String archivePath, String outputPath) {
return Isolate.run(() {
final inputStream = InputFileStream(archivePath);
final archive = ZipDecoder().decodeBuffer(inputStream);
extractArchiveToDisk(archive, outputPath);
});
}

class Cache {
Cache({
http.Client? httpClient,
this.extractArchive = _defaultArchiveExtractor,
Platform platform = const LocalPlatform(),
}) : httpClient = httpClient ?? http.Client() {
registerArtifact(PatchArtifact(cache: this, platform: platform));
}

final http.Client httpClient;
final ArchiveExtracter extractArchive;

void registerArtifact(CachedArtifact artifact) => _artifacts.add(artifact);

Future<void> updateAll() async {
for (final artifact in _artifacts) {
if (await artifact.isUpToDate()) {
continue;
}

await artifact.update();
}
}

/// Get a named directory from with the cache's artifact directory;
/// for example, `foo` would return `bin/cache/artifacts/foo`.
Directory getArtifactDirectory(String name) {
return Directory(p.join(shorebirdArtifactsDirectory.path, name));
}

/// The Shorebird cache directory.
static Directory get shorebirdCacheDirectory => Directory(
p.join(ShorebirdEnvironment.shorebirdRoot.path, 'bin', 'cache'),
);

/// The Shorebird cached artifacts directory.
static Directory get shorebirdArtifactsDirectory => Directory(
p.join(shorebirdCacheDirectory.path, 'artifacts'),
);

final List<CachedArtifact> _artifacts = [];

String get storageBaseUrl => 'https://storage.googleapis.com';

String get storageBucket => 'download.shorebird.dev';
}

abstract class CachedArtifact {
CachedArtifact({required this.cache, required this.platform});

final Cache cache;
final Platform platform;

String get name;

String get storagePath;

List<String> get executables => [];

Directory get location => cache.getArtifactDirectory(name);

Future<bool> isUpToDate() async => location.existsSync();

Future<void> update() async {
final url = '${cache.storageBaseUrl}/${cache.storageBucket}/$storagePath';
final request = http.Request('GET', Uri.parse(url));
final response = await cache.httpClient.send(request);
final tempDir = Directory.systemTemp.createTempSync();
final archivePath = p.join(tempDir.path, '$name.zip');
final outputPath = location.path;
await response.stream.pipe(File(archivePath).openWrite());
await cache.extractArchive(archivePath, outputPath);

if (platform.isWindows) return;

for (final executable in executables) {
final process = await Process.start(
felangel marked this conversation as resolved.
Show resolved Hide resolved
'chmod',
['+x', p.join(location.path, executable)],
);
await process.exitCode;
}
}
}

class PatchArtifact extends CachedArtifact {
PatchArtifact({required super.cache, required super.platform});

@override
String get name => 'patch';

@override
List<String> get executables => ['patch'];

@override
String get storagePath {
felangel marked this conversation as resolved.
Show resolved Hide resolved
var artifactName = 'patch-';
if (platform.isMacOS) {
artifactName += 'darwin-x64.zip';
} else if (platform.isLinux) {
artifactName += 'linux-x64.zip';
} else if (platform.isWindows) {
artifactName += 'windows-x64.zip';
}

return 'shorebird/$shorebirdEngineRevision/$artifactName';
}
}
4 changes: 4 additions & 0 deletions packages/shorebird_cli/lib/src/command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:http/http.dart' as http;
import 'package:mason_logger/mason_logger.dart';
import 'package:meta/meta.dart';
import 'package:shorebird_cli/src/auth/auth.dart';
import 'package:shorebird_cli/src/cache.dart';
import 'package:shorebird_cli/src/shorebird_process.dart';
import 'package:shorebird_cli/src/validators/validators.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
Expand All @@ -28,11 +29,13 @@ abstract class ShorebirdCommand extends Command<int> {
ShorebirdCommand({
required this.logger,
Auth? auth,
Cache? cache,
CodePushClientBuilder? buildCodePushClient,
RunProcess? runProcess,
StartProcess? startProcess,
ShorebirdFlutterValidator? flutterValidator,
}) : auth = auth ?? Auth(),
cache = cache ?? Cache(),
buildCodePushClient = buildCodePushClient ?? CodePushClient.new,
runProcess = runProcess ?? ShorebirdProcess.run,
startProcess = startProcess ?? ShorebirdProcess.start {
Expand All @@ -41,6 +44,7 @@ abstract class ShorebirdCommand extends Command<int> {
}

final Auth auth;
final Cache cache;
final CodePushClientBuilder buildCodePushClient;
final Logger logger;
final RunProcess runProcess;
Expand Down
1 change: 0 additions & 1 deletion packages/shorebird_cli/lib/src/command_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ class ShorebirdCliCommandRunner extends CompletionCommandRunner<int> {
_logger.info(
'''
Shorebird $packageVersion
Flutter Engine • revision $requiredFlutterEngineRevision
Shorebird Engine • revision $shorebirdEngineRevision''',
);
exitCode = ExitCode.success.code;
Expand Down
14 changes: 1 addition & 13 deletions packages/shorebird_cli/lib/src/commands/build_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,14 @@ import 'package:shorebird_cli/src/command.dart';
import 'package:shorebird_cli/src/flutter_validation_mixin.dart';
import 'package:shorebird_cli/src/shorebird_build_mixin.dart';
import 'package:shorebird_cli/src/shorebird_config_mixin.dart';
import 'package:shorebird_cli/src/shorebird_engine_mixin.dart';

/// {@template build_command}
///
/// `shorebird build`
/// Build a new release of your application.
/// {@endtemplate}
class BuildCommand extends ShorebirdCommand
with
FlutterValidationMixin,
ShorebirdConfigMixin,
ShorebirdEngineMixin,
ShorebirdBuildMixin {
with FlutterValidationMixin, ShorebirdConfigMixin, ShorebirdBuildMixin {
/// {@macro build_command}
BuildCommand({
required super.logger,
Expand All @@ -42,13 +37,6 @@ class BuildCommand extends ShorebirdCommand
return ExitCode.noUser.code;
}

try {
await ensureEngineExists();
} catch (error) {
logger.err(error.toString());
return ExitCode.software.code;
}

await logFlutterValidationIssues();

final buildProgress = logger.progress('Building release ');
Expand Down
22 changes: 9 additions & 13 deletions packages/shorebird_cli/lib/src/commands/patch_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import 'package:shorebird_cli/src/flutter_validation_mixin.dart';
import 'package:shorebird_cli/src/shorebird_build_mixin.dart';
import 'package:shorebird_cli/src/shorebird_config_mixin.dart';
import 'package:shorebird_cli/src/shorebird_create_app_mixin.dart';
import 'package:shorebird_cli/src/shorebird_engine_mixin.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';

/// {@template patch_command}
Expand All @@ -21,14 +20,14 @@ class PatchCommand extends ShorebirdCommand
with
FlutterValidationMixin,
ShorebirdConfigMixin,
ShorebirdEngineMixin,
ShorebirdBuildMixin,
ShorebirdCreateAppMixin {
/// {@macro patch_command}
PatchCommand({
required super.logger,
super.auth,
super.buildCodePushClient,
super.cache,
super.runProcess,
super.flutterValidator,
HashFunction? hashFn,
Expand Down Expand Up @@ -101,15 +100,6 @@ class PatchCommand extends ShorebirdCommand
return ExitCode.noUser.code;
}

try {
await ensureEngineExists();
} catch (error) {
logger.err(error.toString());
return ExitCode.software.code;
}

await logFlutterValidationIssues();

final force = results['force'] == true;
final dryRun = results['dry-run'] == true;

Expand All @@ -118,6 +108,10 @@ class PatchCommand extends ShorebirdCommand
return ExitCode.usage.code;
}

await logFlutterValidationIssues();

await cache.updateAll();

final buildProgress = logger.progress('Building patch');
try {
await buildRelease();
Expand Down Expand Up @@ -388,8 +382,10 @@ Please create a release using "shorebird release" and try again.
}) async {
final tempDir = await Directory.systemTemp.createTemp();
final diffPath = p.join(tempDir.path, 'diff.patch');

final diffExecutable = p.join(shorebirdEnginePath, 'patch');
final diffExecutable = p.join(
cache.getArtifactDirectory('patch').path,
'patch',
);
final diffArguments = [
releaseArtifactPath,
patchArtifactPath,
Expand Down
9 changes: 0 additions & 9 deletions packages/shorebird_cli/lib/src/commands/release_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import 'package:shorebird_cli/src/flutter_validation_mixin.dart';
import 'package:shorebird_cli/src/shorebird_build_mixin.dart';
import 'package:shorebird_cli/src/shorebird_config_mixin.dart';
import 'package:shorebird_cli/src/shorebird_create_app_mixin.dart';
import 'package:shorebird_cli/src/shorebird_engine_mixin.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';

/// {@template release_command}
Expand All @@ -20,7 +19,6 @@ class ReleaseCommand extends ShorebirdCommand
with
FlutterValidationMixin,
ShorebirdConfigMixin,
ShorebirdEngineMixin,
ShorebirdBuildMixin,
ShorebirdCreateAppMixin {
/// {@macro release_command}
Expand Down Expand Up @@ -79,13 +77,6 @@ make smaller updates to your app.
return ExitCode.noUser.code;
}

try {
await ensureEngineExists();
} catch (error) {
logger.err(error.toString());
return ExitCode.software.code;
}

await logFlutterValidationIssues();

final buildProgress = logger.progress('Building release');
Expand Down
16 changes: 1 addition & 15 deletions packages/shorebird_cli/lib/src/commands/run_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ import 'package:mason_logger/mason_logger.dart';
import 'package:shorebird_cli/src/command.dart';
import 'package:shorebird_cli/src/flutter_validation_mixin.dart';
import 'package:shorebird_cli/src/shorebird_config_mixin.dart';
import 'package:shorebird_cli/src/shorebird_engine_mixin.dart';

/// {@template run_command}
/// `shorebird run`
/// Run the Flutter application.
/// {@endtemplate}
class RunCommand extends ShorebirdCommand
with FlutterValidationMixin, ShorebirdConfigMixin, ShorebirdEngineMixin {
with FlutterValidationMixin, ShorebirdConfigMixin {
/// {@macro run_command}
RunCommand({
required super.logger,
Expand All @@ -36,13 +35,6 @@ class RunCommand extends ShorebirdCommand
return ExitCode.noUser.code;
}

try {
await ensureEngineExists();
} catch (error) {
logger.err(error.toString());
return ExitCode.software.code;
}

await logFlutterValidationIssues();

logger.info('Running app...');
Expand All @@ -52,12 +44,6 @@ class RunCommand extends ShorebirdCommand
'run',
// Eventually we should support running in both debug and release mode.
'--release',
'--local-engine-src-path',
shorebirdEnginePath,
'--local-engine',
// This is temporary because the Shorebird engine currently
// only supports Android arm64.
'android_release_arm64',
...results.rest
],
runInShell: true,
Expand Down
6 changes: 1 addition & 5 deletions packages/shorebird_cli/lib/src/engine_revision.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
/// The hash of the Flutter engine required by Shorebird.
/// Currently, Shorebird only supports the latest stable Flutter channel.
const requiredFlutterEngineRevision = '9aa7816315';

/// The hash of the Shorebird engine used by this version of Shorebird CLI.
const shorebirdEngineRevision = 'ff32625d5b';
const shorebirdEngineRevision = '978a56f2d97f9ce24a2b6bc22c9bbceaaba0343c';
10 changes: 2 additions & 8 deletions packages/shorebird_cli/lib/src/shorebird_build_mixin.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import 'dart:io';

import 'package:mason_logger/mason_logger.dart';
import 'package:shorebird_cli/src/shorebird_engine_mixin.dart';
import 'package:shorebird_cli/src/command.dart';

mixin ShorebirdBuildMixin on ShorebirdEngineMixin {
mixin ShorebirdBuildMixin on ShorebirdCommand {
Future<void> buildRelease() async {
const executable = 'flutter';
final arguments = [
Expand All @@ -12,12 +12,6 @@ mixin ShorebirdBuildMixin on ShorebirdEngineMixin {
// only supports Android.
'appbundle',
'--release',
'--local-engine-src-path',
shorebirdEnginePath,
'--local-engine',
// This is temporary because the Shorebird engine currently
// only supports Android arm64.
'android_release_arm64',
...results.rest,
];

Expand Down
Loading