refactor(artifact_proxy): use dart config (#241)

This commit is contained in:
Felix Angelov
2023-04-06 09:55:38 -05:00
committed by GitHub
parent e5890d6057
commit 79c5685cfd
11 changed files with 175 additions and 129 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ Storage (either Shorebird's bucket or the official Flutter buckets).
## Usage
Uses `config.yaml` to configure the engine revisions and artifact overrides.
Uses `config.dart` to configure the engine revisions and artifact overrides.
```bash
# Run locally with hot-reload enabled.
+1 -3
View File
@@ -3,15 +3,13 @@
import 'dart:io';
import 'package:artifact_proxy/artifact_proxy.dart';
import 'package:artifact_proxy/config.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_hotreload/shelf_hotreload.dart';
import 'package:yaml/yaml.dart';
Future<void> main() async {
const configPath = 'config.yaml';
final isDev = Platform.environment['DEV'] == 'true';
final config = loadYaml(File(configPath).readAsStringSync()) as Map;
final handler = artifactProxyHandler(config: config);
final ip = InternetAddress.anyIPv6;
final port = int.parse(Platform.environment['PORT'] ?? '8080');
-25
View File
@@ -1,25 +0,0 @@
engine_mappings:
79f4c5321a581f580a9bda01ec372cbf4a53aa53:
flutter_engine_revision: 9aa7816315095c86410527932918c718cb35e7d6
shorebird_storage_bucket: download.shorebird.dev
shorebird_artifact_overrides:
# artifacts.zip
- flutter_infra_release/flutter/$engine/android-arm-64-release/artifacts.zip
- flutter_infra_release/flutter/$engine/android-arm-release/artifacts.zip
- flutter_infra_release/flutter/$engine/android-x64-release/artifacts.zip
# embedding release
- download.flutter.io/io/flutter/flutter_embedding_release/1.0.0-$engine/flutter_embedding_release-1.0.0-$engine.pom
- download.flutter.io/io/flutter/flutter_embedding_release/1.0.0-$engine/flutter_embedding_release-1.0.0-$engine.jar
# arm64_v8a release
- download.flutter.io/io/flutter/arm64_v8a_release/1.0.0-$engine/arm64_v8a_release-1.0.0-$engine.pom
- download.flutter.io/io/flutter/arm64_v8a_release/1.0.0-$engine/arm64_v8a_release-1.0.0-$engine.jar
# armeabi_v7a release
- download.flutter.io/io/flutter/armeabi_v7a_release/1.0.0-$engine/armeabi_v7a_release-1.0.0-$engine.pom
- download.flutter.io/io/flutter/armeabi_v7a_release/1.0.0-$engine/armeabi_v7a_release-1.0.0-$engine.jar
# x86_64 release
- download.flutter.io/io/flutter/x86_64_release/1.0.0-$engine/x86_64_release-1.0.0-$engine.pom
- download.flutter.io/io/flutter/x86_64_release/1.0.0-$engine/x86_64_release-1.0.0-$engine.jar
@@ -1,88 +1,2 @@
// ignore_for_file: avoid_print
import 'package:collection/collection.dart';
import 'package:shelf/shelf.dart';
/// A [Handler] that proxies artifact requests to the correct location.
/// This is determined based on the [config].
Handler artifactProxyHandler({required Map<dynamic, dynamic> config}) {
final engineMappings = config['engine_mappings'] as Map;
final shorebirdEngineRevisions = engineMappings.keys.cast<String>();
return (Request request) {
final path = request.url.path;
final shorebirdEngineRevision = shorebirdEngineRevisions.firstWhereOrNull(
path.contains,
);
final normalizedPath = shorebirdEngineRevision != null
? path.replaceAll(shorebirdEngineRevision, r'$engine')
: path;
if (shorebirdEngineRevision == null) {
final location = getFlutterArtifactLocation(artifactPath: normalizedPath);
print('No engine revision detected, forwarding to: $location');
return Response.found(location);
}
final engineMapping = engineMappings[shorebirdEngineRevision] as Map;
final shorebirdOverrides =
engineMapping['shorebird_artifact_overrides'] as List;
final flutterEngineRevision =
engineMapping['flutter_engine_revision'] as String;
final shorebirdStorageBucket =
engineMapping['shorebird_storage_bucket'] as String;
final shouldOverride = shorebirdOverrides.contains(normalizedPath);
if (shouldOverride) {
final location = getShorebirdArtifactLocation(
artifactPath: normalizedPath,
engine: shorebirdEngineRevision,
bucket: shorebirdStorageBucket,
);
print('Shorebird artifact detected, forwarding to: $location');
return Response.found(location);
}
final location = getFlutterArtifactLocation(
artifactPath: normalizedPath,
engine: flutterEngineRevision,
);
print('Flutter artifact detected, forwarding to: $location');
return Response.found(location);
};
}
/// Returns the location of the artifact at [artifactPath] using the
/// specified [engine] revision for original Flutter artifacts.
String getFlutterArtifactLocation({
required String artifactPath,
String? engine,
}) {
final adjustedPath = engine != null
? artifactPath.replaceAll(r'$engine', engine)
: artifactPath;
final isChromeInfra = adjustedPath.contains('flutter_infra_release/cipd');
/// TODO(felangel): remove this after 3.8 is released.
if (isChromeInfra) {
return adjustedPath.replaceAll(
'flutter_infra_release/cipd',
'https://chrome-infra-packages.appspot.com/dl',
);
}
return 'https://storage.googleapis.com/$adjustedPath';
}
/// Returns the location of the artifact at [artifactPath] using the
/// specified [engine] revision for Shorebird artifacts.
String getShorebirdArtifactLocation({
required String artifactPath,
required String engine,
required String bucket,
}) {
final adjustedPath = artifactPath.replaceAll(r'$engine', engine);
return 'https://storage.googleapis.com/$bucket/$adjustedPath';
}
export 'src/artifact_proxy.dart';
export 'src/models/models.dart';
+38
View File
@@ -0,0 +1,38 @@
import 'package:artifact_proxy/artifact_proxy.dart';
/// The proxy configuration used by the server.
const config = ProxyConfig(
engineMappings: {
...flutter_3_7_8,
},
);
/// Flutter 3.7.8
const flutter_3_7_8 = {
'79f4c5321a581f580a9bda01ec372cbf4a53aa53': EngineMapping(
flutterEngineRevision: '9aa7816315095c86410527932918c718cb35e7d6',
shorebirdStorageBucket: 'download.shorebird.dev',
shorebirdArtifactOverrides: {
// artifacts.zip
r'flutter_infra_release/flutter/$engine/android-arm-64-release/artifacts.zip',
r'flutter_infra_release/flutter/$engine/android-arm-release/artifacts.zip',
r'flutter_infra_release/flutter/$engine/android-x64-release/artifacts.zip',
// embedding release
r'download.flutter.io/io/flutter/flutter_embedding_release/1.0.0-$engine/flutter_embedding_release-1.0.0-$engine.pom',
r'download.flutter.io/io/flutter/flutter_embedding_release/1.0.0-$engine/flutter_embedding_release-1.0.0-$engine.jar',
// arm64_v8a release
r'download.flutter.io/io/flutter/arm64_v8a_release/1.0.0-$engine/arm64_v8a_release-1.0.0-$engine.pom',
r'download.flutter.io/io/flutter/arm64_v8a_release/1.0.0-$engine/arm64_v8a_release-1.0.0-$engine.jar',
// armeabi_v7a release
r'download.flutter.io/io/flutter/armeabi_v7a_release/1.0.0-$engine/armeabi_v7a_release-1.0.0-$engine.pom',
r'download.flutter.io/io/flutter/armeabi_v7a_release/1.0.0-$engine/armeabi_v7a_release-1.0.0-$engine.jar',
// x86_64 release
r'download.flutter.io/io/flutter/x86_64_release/1.0.0-$engine/x86_64_release-1.0.0-$engine.pom',
r'download.flutter.io/io/flutter/x86_64_release/1.0.0-$engine/x86_64_release-1.0.0-$engine.jar',
},
),
};
@@ -0,0 +1,86 @@
// ignore_for_file: avoid_print
import 'package:artifact_proxy/artifact_proxy.dart';
import 'package:collection/collection.dart';
import 'package:shelf/shelf.dart';
/// A [Handler] that proxies artifact requests to the correct location.
/// This is determined based on the [config].
Handler artifactProxyHandler({required ProxyConfig config}) {
final engineMappings = config.engineMappings;
final shorebirdEngineRevisions = engineMappings.keys.cast<String>();
return (Request request) {
final path = request.url.path;
final shorebirdEngineRevision = shorebirdEngineRevisions.firstWhereOrNull(
path.contains,
);
final normalizedPath = shorebirdEngineRevision != null
? path.replaceAll(shorebirdEngineRevision, r'$engine')
: path;
if (shorebirdEngineRevision == null) {
final location = getFlutterArtifactLocation(artifactPath: normalizedPath);
print('No engine revision detected, forwarding to: $location');
return Response.found(location);
}
final engineMapping = engineMappings[shorebirdEngineRevision]!;
final shorebirdOverrides = engineMapping.shorebirdArtifactOverrides;
final flutterEngineRevision = engineMapping.flutterEngineRevision;
final shorebirdStorageBucket = engineMapping.shorebirdStorageBucket;
final shouldOverride = shorebirdOverrides.contains(normalizedPath);
if (shouldOverride) {
final location = getShorebirdArtifactLocation(
artifactPath: normalizedPath,
engine: shorebirdEngineRevision,
bucket: shorebirdStorageBucket,
);
print('Shorebird artifact detected, forwarding to: $location');
return Response.found(location);
}
final location = getFlutterArtifactLocation(
artifactPath: normalizedPath,
engine: flutterEngineRevision,
);
print('Flutter artifact detected, forwarding to: $location');
return Response.found(location);
};
}
/// Returns the location of the artifact at [artifactPath] using the
/// specified [engine] revision for original Flutter artifacts.
String getFlutterArtifactLocation({
required String artifactPath,
String? engine,
}) {
final adjustedPath = engine != null
? artifactPath.replaceAll(r'$engine', engine)
: artifactPath;
final isChromeInfra = adjustedPath.contains('flutter_infra_release/cipd');
// TODO(felangel): remove this after 3.8 is released.
if (isChromeInfra) {
return adjustedPath.replaceAll(
'flutter_infra_release/cipd',
'https://chrome-infra-packages.appspot.com/dl',
);
}
return 'https://storage.googleapis.com/$adjustedPath';
}
/// Returns the location of the artifact at [artifactPath] using the
/// specified [engine] revision for Shorebird artifacts.
String getShorebirdArtifactLocation({
required String artifactPath,
required String engine,
required String bucket,
}) {
final adjustedPath = artifactPath.replaceAll(r'$engine', engine);
return 'https://storage.googleapis.com/$bucket/$adjustedPath';
}
@@ -0,0 +1 @@
export 'proxy_config.dart';
@@ -0,0 +1,35 @@
/// A map of shorebird engine revision to the corresponding [EngineMapping].
typedef EngineMappings = Map<String, EngineMapping>;
/// {@template proxy_config}
/// Contains all the information needed to proxy requests.
/// {@endtemplate}
class ProxyConfig {
/// {@macro proxy_config}
const ProxyConfig({required this.engineMappings});
/// The registered engine mappings.
final EngineMappings engineMappings;
}
/// {@template engine_mapping}
/// Contains all the information needed to proxy requests for a specific
/// shorebird engine revision.
/// {@endtemplate}
class EngineMapping {
/// {@macro engine_mapping}
const EngineMapping({
required this.flutterEngineRevision,
required this.shorebirdStorageBucket,
required this.shorebirdArtifactOverrides,
});
/// The flutter engine revision that this engine mapping is based on.
final String flutterEngineRevision;
/// The storage bucket that contains the shorebird artifacts.
final String shorebirdStorageBucket;
/// The list of shorebird artifacts that should be overridden.
final Set<String> shorebirdArtifactOverrides;
}
+1 -1
View File
@@ -394,7 +394,7 @@ packages:
source: hosted
version: "1.2.0"
yaml:
dependency: "direct main"
dependency: transitive
description:
name: yaml
sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370"
-1
View File
@@ -11,7 +11,6 @@ dependencies:
collection: ^1.17.1
shelf: ^1.4.0
shelf_hotreload: ^1.4.0
yaml: ^3.1.1
dev_dependencies:
mocktail: ^0.3.0
@@ -8,17 +8,17 @@ void main() {
const shorebirdEngineRevision = 'ff32625d5bda6d3eb2eb131e30a4c26ed4960002';
const flutterEngineRevision = 'ec975089acb540fc60752606a3d3ba809dd1528b';
const shorebirdStorageBucket = 'download.shorebird.dev';
const config = {
'engine_mappings': {
shorebirdEngineRevision: {
'flutter_engine_revision': flutterEngineRevision,
'shorebird_storage_bucket': shorebirdStorageBucket,
'shorebird_artifact_overrides': [
const config = ProxyConfig(
engineMappings: {
shorebirdEngineRevision: EngineMapping(
flutterEngineRevision: flutterEngineRevision,
shorebirdStorageBucket: shorebirdStorageBucket,
shorebirdArtifactOverrides: {
r'flutter_infra_release/flutter/$engine/android-x64-release/artifacts.zip'
]
}
}
};
},
),
},
);
Request buildRequest(String path) {
return Request('GET', Uri.parse('http://localhost').replace(path: path));