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

Support different set of assets depending on platform and flavor parameters #25487

Closed
wants to merge 14 commits into from
Closed
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
6 changes: 6 additions & 0 deletions packages/flutter_tools/bin/xcode_backend.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ BuildApp() {
project_path="${FLUTTER_APPLICATION_PATH}"
fi

local flavor=""
if [[ -n "$FLUTTER_FLAVOR" ]]; then
flavor="${FLUTTER_FLAVOR}"
fi

local target_path="lib/main.dart"
if [[ -n "$FLUTTER_TARGET" ]]; then
target_path="${FLUTTER_TARGET}"
Expand Down Expand Up @@ -239,6 +244,7 @@ BuildApp() {
${verbose_flag} \
build bundle \
--target-platform=ios \
--flavor="${flavor}" \
--target="${target_path}" \
--${build_mode} \
--depfile="${build_dir}/snapshot_blob.bin.d" \
Expand Down
10 changes: 10 additions & 0 deletions packages/flutter_tools/gradle/flutter.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,10 @@ class FlutterPlugin implements Plugin<Project> {
if (project.hasProperty('target-platform')) {
targetPlatformValue = project.property('target-platform')
}
String flavorValue = null
if (project.hasProperty('flavor')) {
flavorValue = project.property('flavor')
}

def addFlutterDeps = { variant ->
String flutterBuildMode = buildModeFor(variant.buildType)
Expand Down Expand Up @@ -380,6 +384,7 @@ class FlutterPlugin implements Plugin<Project> {
baselineDir baselineDirValue
buildSharedLibrary buildSharedLibraryValue
targetPlatform targetPlatformValue
flavor flavorValue
sourceDir project.file(project.flutter.source)
intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}")
extraFrontEndOptions extraFrontEndOptionsValue
Expand Down Expand Up @@ -447,6 +452,8 @@ abstract class BaseFlutterTask extends DefaultTask {
Boolean buildSharedLibrary
@Optional @Input
String targetPlatform
@Optional @Input
String flavor
File sourceDir
File intermediateDir
@Optional @Input
Expand Down Expand Up @@ -556,6 +563,9 @@ abstract class BaseFlutterTask extends DefaultTask {
if (targetPlatform != null) {
args "--target-platform", "${targetPlatform}"
}
if (flavor != null) {
args "--flavor", "${flavor}"
}
if (buildMode == "release" || buildMode == "profile") {
args "--precompiled"
} else {
Expand Down
2 changes: 2 additions & 0 deletions packages/flutter_tools/lib/src/android/gradle.dart
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,8 @@ Future<void> _buildGradleProjectV2(
}
if (buildInfo.targetPlatform != null)
command.add('-Ptarget-platform=${getNameForTargetPlatform(buildInfo.targetPlatform)}');
if (buildInfo.flavor != null)
command.add('-Pflavor=${buildInfo.flavor}');

command.add(assembleTask);
final int exitCode = await runCommandAndStreamOutput(
Expand Down
10 changes: 8 additions & 2 deletions packages/flutter_tools/lib/src/asset.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ abstract class AssetBundle {

/// Returns 0 for success; non-zero for failure.
Future<int> build({
TargetPlatform platform,
String flavor,
String manifestPath = _ManifestAssetBundle.defaultManifestPath,
String assetDirPath,
String packagesPath,
Expand Down Expand Up @@ -88,17 +90,21 @@ class _ManifestAssetBundle implements AssetBundle {

@override
Future<int> build({
TargetPlatform platform,
String flavor,
String manifestPath = defaultManifestPath,
String assetDirPath,
String packagesPath,
bool includeDefaultFonts = true,
bool reportLicensedPackages = false
}) async {
final String platformName = platform != null ? getNameForTargetPlatform(platform) : null;
assetDirPath ??= getAssetBuildDirectory();
packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath);
FlutterManifest flutterManifest;
try {
flutterManifest = await FlutterManifest.createFromPath(manifestPath);
flutterManifest = await FlutterManifest.createFromPath(manifestPath,
platform: platformName, flavor: flavor);
} catch (e) {
printStatus('Error detected in pubspec.yaml:', emphasis: true);
printError('$e');
Expand Down Expand Up @@ -145,7 +151,7 @@ class _ManifestAssetBundle implements AssetBundle {
final Uri package = packageMap.map[packageName];
if (package != null && package.scheme == 'file') {
final String packageManifestPath = fs.path.fromUri(package.resolve('../pubspec.yaml'));
final FlutterManifest packageFlutterManifest = await FlutterManifest.createFromPath(packageManifestPath);
final FlutterManifest packageFlutterManifest = await FlutterManifest.createFromPath(packageManifestPath, platform: platformName);
if (packageFlutterManifest == null)
continue;
// Skip the app itself
Expand Down
7 changes: 7 additions & 0 deletions packages/flutter_tools/lib/src/bundle.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const String _kIsolateSnapshotInstr = 'isolate_snapshot_instr';
Future<void> build({
TargetPlatform platform,
BuildMode buildMode,
String flavor,
String mainPath = defaultMainPath,
String manifestPath = defaultManifestPath,
String applicationKernelFilePath,
Expand Down Expand Up @@ -143,6 +144,8 @@ Future<void> build({
}

final AssetBundle assets = await buildAssets(
platform: platform,
flavor: flavor,
manifestPath: manifestPath,
assetDirPath: assetDirPath,
packagesPath: packagesPath,
Expand All @@ -162,6 +165,8 @@ Future<void> build({
}

Future<AssetBundle> buildAssets({
TargetPlatform platform,
String flavor,
String manifestPath,
String assetDirPath,
String packagesPath,
Expand All @@ -174,6 +179,8 @@ Future<AssetBundle> buildAssets({
// Build the asset bundle.
final AssetBundle assetBundle = AssetBundleFactory.instance.createBundle();
final int result = await assetBundle.build(
platform: platform,
flavor: flavor,
manifestPath: manifestPath,
assetDirPath: assetDirPath,
packagesPath: packagesPath,
Expand Down
3 changes: 3 additions & 0 deletions packages/flutter_tools/lib/src/commands/build_bundle.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class BuildBundleCommand extends BuildSubCommand {
usesFilesystemOptions(hide: !verboseHelp);
usesBuildNumberOption();
addBuildModeFlags(verboseHelp: verboseHelp);
usesFlavorOption();
addDynamicModeFlags(verboseHelp: verboseHelp);
addDynamicBaselineFlags(verboseHelp: verboseHelp);
argParser
Expand Down Expand Up @@ -73,6 +74,7 @@ class BuildBundleCommand extends BuildSubCommand {
throwToolExit('Unknown platform: $targetPlatform');

final BuildMode buildMode = getBuildMode();
final String flavor = getFlavor();

int buildNumber;
try {
Expand All @@ -86,6 +88,7 @@ class BuildBundleCommand extends BuildSubCommand {
await build(
platform: platform,
buildMode: buildMode,
flavor: flavor,
mainPath: targetFile,
manifestPath: argResults['manifest'],
depfilePath: argResults['depfile'],
Expand Down
72 changes: 68 additions & 4 deletions packages/flutter_tools/lib/src/flutter_manifest.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ class FlutterManifest {
}

/// Returns null on invalid manifest. Returns empty manifest on missing file.
static Future<FlutterManifest> createFromPath(String path) async {
static Future<FlutterManifest> createFromPath(String path,
{String platform, String flavor}) async {
if (path == null || !fs.isFileSync(path))
return _createFromYaml(null);
final String manifest = await fs.file(path).readAsString();
return createFromString(manifest);
return _createFromPathWithAssets(path, platform, flavor);
}

/// Returns null on missing or invalid manifest
Expand All @@ -56,14 +56,53 @@ class FlutterManifest {

final Map<dynamic, dynamic> flutterMap = pubspec._descriptor['flutter'];
if (flutterMap != null) {
pubspec._flutterDescriptor = flutterMap.cast<String, dynamic>();
pubspec._flutterDescriptor = Map<String, dynamic>.from(flutterMap);
} else {
pubspec._flutterDescriptor = <String, dynamic>{};
}

return pubspec;
}

static Future<FlutterManifest> _createFromPath(String path) async {
final String manifest = await fs.file(path).readAsString();
return createFromString(manifest);
}

static Future<FlutterManifest> _createFromPathWithAssets(
String path, String platform, String flavor) async {
final FlutterManifest flutterManifest = await _createFromPath(path);
if (flutterManifest == null)
return null;

for (String assetPath in buildAssetFilePaths(path, platform, flavor)) {
if (!fs.isFileSync(assetPath))
continue;

final FlutterManifest manifest = await _createFromPath(assetPath);
if (manifest == null)
return null;

if (manifest._flutterDescriptor['uses-material-design'] != null) {
flutterManifest._flutterDescriptor['uses-material-design'] =
manifest._flutterDescriptor['uses-material-design'];
}

if (manifest._flutterDescriptor['assets'] != null) {
flutterManifest._flutterDescriptor['assets'] =
manifest._flutterDescriptor['assets'];
}

if (manifest._flutterDescriptor['fonts'] != null) {
flutterManifest._fonts = null;
flutterManifest._flutterDescriptor['fonts'] =
manifest._flutterDescriptor['fonts'];
}
}

return flutterManifest;
}

/// A map representation of the entire `pubspec.yaml` file.
Map<String, dynamic> _descriptor;

Expand Down Expand Up @@ -290,3 +329,28 @@ Future<bool> _validate(dynamic manifest) async {
return false;
}
}

const String _assetsFilesPrefix = 'assets';
const String _assetsFilesDelimiter = '-';

String _buildAssetFilePath(String dirname, {String platform, String flavor}) {
final List<String> segments = <String>[_assetsFilesPrefix];
if (platform != null) {
segments.add(platform.split('-').first);
}
if (flavor != null) {
segments.add(flavor);
}
return fs.path.join(dirname, '${segments.join(_assetsFilesDelimiter)}.yaml');
}

@visibleForTesting
List<String> buildAssetFilePaths(String path, String platform, String flavor) {
final String dirname = fs.path.dirname(path);
final Set<String> paths = Set<String>()
..add(_buildAssetFilePath(dirname))
..add(_buildAssetFilePath(dirname, platform: platform))
..add(_buildAssetFilePath(dirname, flavor: flavor))
..add(_buildAssetFilePath(dirname, platform: platform, flavor: flavor));
return paths.toList(growable: false);
}
3 changes: 3 additions & 0 deletions packages/flutter_tools/lib/src/ios/xcodeproj.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ Future<void> updateGeneratedXcodeProperties({
if (targetOverride != null)
localsBuffer.writeln('FLUTTER_TARGET=$targetOverride');

if (buildInfo.flavor != null)
localsBuffer.writeln('FLUTTER_FLAVOR=${buildInfo.flavor}');

// The build outputs directory, relative to FLUTTER_APPLICATION_PATH.
localsBuffer.writeln('FLUTTER_BUILD_DIR=${getBuildDirectory()}');

Expand Down
9 changes: 5 additions & 4 deletions packages/flutter_tools/lib/src/runner/flutter_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,10 @@ abstract class FlutterCommand extends Command<void> {
return _defaultBuildMode;
}

String getFlavor() => argParser.options.containsKey('flavor') && argResults['flavor'] != ''
? argResults['flavor']
: null;

void usesFlavorOption() {
argParser.addOption(
'flavor',
Expand Down Expand Up @@ -377,10 +381,7 @@ abstract class FlutterCommand extends Command<void> {
'--patch-number (${argResults['patch-number']}) must be an int.', null);
}

return BuildInfo(getBuildMode(),
argParser.options.containsKey('flavor')
? argResults['flavor']
: null,
return BuildInfo(getBuildMode(), getFlavor(),
trackWidgetCreation: trackWidgetCreation,
compilationTraceFilePath: argParser.options.containsKey('compilation-trace-file')
? argResults['compilation-trace-file']
Expand Down