Use new Maven artifacts from Gradle (#39157)
This commit is contained in:
parent
d30e4228af
commit
b63cb44105
@ -52,7 +52,6 @@ Future<void> main() async {
|
||||
'assets/flutter_assets/isolate_snapshot_data',
|
||||
'assets/flutter_assets/kernel_blob.bin',
|
||||
'assets/flutter_assets/vm_snapshot_data',
|
||||
'lib/armeabi-v7a/libflutter.so',
|
||||
// Debug mode intentionally includes `x86` and `x86_64`.
|
||||
'lib/x86/libflutter.so',
|
||||
'lib/x86_64/libflutter.so',
|
||||
@ -79,7 +78,6 @@ Future<void> main() async {
|
||||
'assets/flutter_assets/isolate_snapshot_data',
|
||||
'assets/flutter_assets/kernel_blob.bin',
|
||||
'assets/flutter_assets/vm_snapshot_data',
|
||||
'lib/armeabi-v7a/libflutter.so',
|
||||
// Debug mode intentionally includes `x86` and `x86_64`.
|
||||
'lib/x86/libflutter.so',
|
||||
'lib/x86_64/libflutter.so',
|
||||
|
@ -57,6 +57,6 @@ dependencies {
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||
implementation 'com.android.support:appcompat-v7:26.1.0'
|
||||
implementation 'com.android.support:design:26.1.0'
|
||||
implementation 'com.android.support:appcompat-v7:28.0.0'
|
||||
implementation 'com.android.support:design:28.0.0'
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath "com.android.tools.build:gradle:3.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,6 +42,8 @@ android {
|
||||
apply plugin: FlutterPlugin
|
||||
|
||||
class FlutterPlugin implements Plugin<Project> {
|
||||
private static final String MAVEN_REPO = "http://download.flutter.io";
|
||||
|
||||
// The platforms that can be passed to the `--Ptarget-platform` flag.
|
||||
private static final String PLATFORM_ARM32 = "android-arm";
|
||||
private static final String PLATFORM_ARM64 = "android-arm64";
|
||||
@ -85,6 +87,7 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
// to match.
|
||||
static final String FLUTTER_BUILD_PREFIX = "flutterBuild"
|
||||
|
||||
private Project project
|
||||
private Map baseJar = [:]
|
||||
private File flutterRoot
|
||||
private File flutterExecutable
|
||||
@ -92,16 +95,18 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
private String localEngineSrcPath
|
||||
private Properties localProperties
|
||||
private File flutterJar
|
||||
private String engineVersion
|
||||
|
||||
@Override
|
||||
void apply(Project project) {
|
||||
this.project = project
|
||||
|
||||
project.extensions.create("flutter", FlutterExtension)
|
||||
project.afterEvaluate this.&addFlutterTasks
|
||||
|
||||
// By default, assembling APKs generates fat APKs if multiple platforms are passed.
|
||||
// Configuring split per ABI allows to generate separate APKs for each abi.
|
||||
// This is a noop when building a bundle.
|
||||
if (splitPerAbi(project)) {
|
||||
if (shouldSplitPerAbi()) {
|
||||
project.android {
|
||||
splits {
|
||||
abi {
|
||||
@ -115,14 +120,10 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
}
|
||||
}
|
||||
}
|
||||
getTargetPlatforms(project).each { targetArch ->
|
||||
getTargetPlatforms().each { targetArch ->
|
||||
String abiValue = PLATFORM_ARCH_MAP[targetArch]
|
||||
project.android {
|
||||
packagingOptions {
|
||||
// Prevent the ELF library from getting corrupted.
|
||||
doNotStrip "*/${abiValue}/libapp.so"
|
||||
}
|
||||
if (splitPerAbi(project)) {
|
||||
if (shouldSplitPerAbi()) {
|
||||
splits {
|
||||
abi {
|
||||
include abiValue
|
||||
@ -131,7 +132,6 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add custom build types
|
||||
project.android.buildTypes {
|
||||
profile {
|
||||
@ -141,8 +141,7 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String flutterRootPath = resolveProperty(project, "flutter.sdk", System.env.FLUTTER_ROOT)
|
||||
String flutterRootPath = resolveProperty("flutter.sdk", System.env.FLUTTER_ROOT)
|
||||
if (flutterRootPath == null) {
|
||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file or with a FLUTTER_ROOT environment variable.")
|
||||
}
|
||||
@ -151,12 +150,14 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
throw new GradleException("flutter.sdk must point to the Flutter SDK directory")
|
||||
}
|
||||
|
||||
engineVersion = Paths.get(flutterRoot.absolutePath, "bin", "internal", "engine.version")
|
||||
.toFile().text.trim()
|
||||
|
||||
String flutterExecutableName = Os.isFamily(Os.FAMILY_WINDOWS) ? "flutter.bat" : "flutter"
|
||||
flutterExecutable = Paths.get(flutterRoot.absolutePath, "bin", flutterExecutableName).toFile();
|
||||
|
||||
if (useLocalEngine(project)) {
|
||||
String engineOutPath = project.property('localEngineOut')
|
||||
File engineOut = project.file(engineOutPath)
|
||||
if (useLocalEngine()) {
|
||||
File engineOut = project.file(project.property('localEngineOut'))
|
||||
if (!engineOut.isDirectory()) {
|
||||
throw new GradleException('localEngineOut must point to a local engine build')
|
||||
}
|
||||
@ -175,45 +176,48 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
})
|
||||
}
|
||||
} else {
|
||||
String basePlatformArch = getBasePlatform(project)
|
||||
// This is meant to include the compiled classes only, however it will include `libflutter.so` as well.
|
||||
Path baseEnginePath = Paths.get(flutterRoot.absolutePath, "bin", "cache", "artifacts", "engine")
|
||||
File debugJar = baseEnginePath.resolve("${basePlatformArch}").resolve("flutter.jar").toFile()
|
||||
baseJar["debug"] = debugJar
|
||||
if (!debugJar.isFile()) {
|
||||
project.exec {
|
||||
executable flutterExecutable.absolutePath
|
||||
args "--suppress-analytics"
|
||||
args "precache"
|
||||
}
|
||||
if (!debugJar.isFile()) {
|
||||
throw new GradleException("Unable to find flutter.jar in SDK: ${debugJar}")
|
||||
}
|
||||
}
|
||||
baseJar["profile"] = baseEnginePath.resolve("${basePlatformArch}-profile").resolve("flutter.jar").toFile()
|
||||
baseJar["release"] = baseEnginePath.resolve("${basePlatformArch}-release").resolve("flutter.jar").toFile()
|
||||
project.android.buildTypes.each this.&addFlutterDependencies
|
||||
project.android.buildTypes.whenObjectAdded this.&addFlutterDependencies
|
||||
}
|
||||
}
|
||||
|
||||
// Add flutter.jar dependencies to all <buildType>Api configurations, including custom ones
|
||||
// added after applying the Flutter plugin.
|
||||
project.android.buildTypes.each {
|
||||
def buildMode = buildModeFor(it)
|
||||
addApiDependencies(project, it.name, project.files {
|
||||
baseJar[buildMode]
|
||||
})
|
||||
}
|
||||
project.android.buildTypes.whenObjectAdded {
|
||||
def buildMode = buildModeFor(it)
|
||||
addApiDependencies(project, it.name, project.files {
|
||||
baseJar[buildMode]
|
||||
})
|
||||
/**
|
||||
* Adds the dependencies required by the Flutter project.
|
||||
* This includes:
|
||||
* 1. The embedding
|
||||
* 2. libflutter.so
|
||||
*/
|
||||
void addFlutterDependencies(buildType) {
|
||||
project.rootProject.allprojects {
|
||||
repositories {
|
||||
maven {
|
||||
url MAVEN_REPO
|
||||
}
|
||||
}
|
||||
}
|
||||
String flutterBuildMode = buildModeFor(buildType)
|
||||
// Add the embedding dependency.
|
||||
addApiDependencies(project, buildType.name,
|
||||
"io.flutter:flutter_embedding_$flutterBuildMode:1.0.0-$engineVersion")
|
||||
|
||||
List<String> platforms = getTargetPlatforms().collect()
|
||||
// Debug mode includes x86 and x64, which are commonly used in emulators.
|
||||
if (flutterBuildMode == "debug") {
|
||||
platforms.add("android-x86")
|
||||
platforms.add("android-x64")
|
||||
}
|
||||
platforms.each { platform ->
|
||||
String arch = PLATFORM_ARCH_MAP[platform].replace("-", "_")
|
||||
// Add the `libflutter.so` dependency.
|
||||
addApiDependencies(project, buildType.name,
|
||||
"io.flutter:${arch}_$flutterBuildMode:1.0.0-$engineVersion")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory where the plugins are built.
|
||||
*/
|
||||
private File getPluginBuildDir(Project project) {
|
||||
private File getPluginBuildDir() {
|
||||
// Module projects specify this flag to include plugins in the same repo as the module project.
|
||||
if (project.ext.has("pluginBuildDir")) {
|
||||
return project.ext.get("pluginBuildDir")
|
||||
@ -221,13 +225,75 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
return project.buildDir
|
||||
}
|
||||
|
||||
private Properties getPluginList(Project project) {
|
||||
/**
|
||||
* Configures the Flutter plugin dependencies.
|
||||
*
|
||||
* The plugins are added to pubspec.yaml. Then, upon running `flutter pub get`,
|
||||
* the tool generates a `.flutter-plugins` file, which contains a 1:1 map to each plugin location.
|
||||
* Finally, the project's `settings.gradle` loads each plugin's android directory as a subproject.
|
||||
*/
|
||||
private void configurePlugins() {
|
||||
if (!buildPluginAsAar()) {
|
||||
getPluginList().each this.&configurePlugin
|
||||
return
|
||||
}
|
||||
addPluginTasks()
|
||||
List<String> tasksToExecute = project.gradle.startParameter.taskNames
|
||||
Set buildTypes = getBuildTypesForTasks(tasksToExecute)
|
||||
if (tasksToExecute.contains("clean")) {
|
||||
// Because the plugins are built during configuration, the task "clean"
|
||||
// cannot run in conjunction with an assembly task.
|
||||
if (!buildTypes.empty) {
|
||||
throw new GradleException("Can't run the clean task along with other assemble tasks")
|
||||
}
|
||||
}
|
||||
// Build plugins when a task "assembly*" will be called later.
|
||||
if (!buildTypes.empty) {
|
||||
// Build the plugin during configuration.
|
||||
// This is required when Jetifier is enabled, otherwise the implementation dependency
|
||||
// cannot be added.
|
||||
buildAarPlugins(buildTypes)
|
||||
}
|
||||
}
|
||||
|
||||
private void configurePlugin(String name, String _) {
|
||||
Project pluginProject = project.rootProject.findProject(":$name")
|
||||
if (pluginProject == null) {
|
||||
project.logger.error("Plugin project :$name not found. Please update settings.gradle.")
|
||||
return
|
||||
}
|
||||
// Add plugin dependency to the app project.
|
||||
project.dependencies {
|
||||
if (project.getConfigurations().findByName("implementation")) {
|
||||
implementation pluginProject
|
||||
} else {
|
||||
compile pluginProject
|
||||
}
|
||||
}
|
||||
Closure addEmbeddingCompileOnlyDependency = { buildType ->
|
||||
String flutterBuildMode = buildModeFor(buildType)
|
||||
// Add the embedding as a compile only dependency to the plugin.
|
||||
addFlutterJarCompileOnlyDependency(pluginProject, buildType.name,
|
||||
flutterJar ?: "io.flutter:flutter_embedding_$flutterBuildMode:1.0.0-$engineVersion")
|
||||
}
|
||||
pluginProject.afterEvaluate {
|
||||
pluginProject.android.buildTypes {
|
||||
profile {
|
||||
initWith debug
|
||||
}
|
||||
}
|
||||
pluginProject.android.buildTypes.each addEmbeddingCompileOnlyDependency
|
||||
pluginProject.android.buildTypes.whenObjectAdded addEmbeddingCompileOnlyDependency
|
||||
}
|
||||
}
|
||||
|
||||
private Properties getPluginList() {
|
||||
File pluginsFile = new File(project.projectDir.parentFile.parentFile, '.flutter-plugins')
|
||||
return readPropertiesIfExist(pluginsFile)
|
||||
}
|
||||
|
||||
private void addPluginTasks(Project project) {
|
||||
Properties plugins = getPluginList(project)
|
||||
private void addPluginTasks() {
|
||||
Properties plugins = getPluginList()
|
||||
project.android.buildTypes.each { buildType ->
|
||||
plugins.each { name, path ->
|
||||
String buildModeValue = buildType.debuggable ? "debug" : "release"
|
||||
@ -240,17 +306,17 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
project.tasks.create(name: taskName, type: FlutterPluginTask) {
|
||||
flutterExecutable this.flutterExecutable
|
||||
buildMode buildModeValue
|
||||
verbose isVerbose(project)
|
||||
verbose isVerbose()
|
||||
pluginDir project.file(path)
|
||||
sourceDir project.file(project.flutter.source)
|
||||
intermediateDir getPluginBuildDir(project)
|
||||
intermediateDir getPluginBuildDir()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void buildPlugins(Project project, Set buildTypes) {
|
||||
private void buildAarPlugins(Set buildTypes) {
|
||||
List<Project> projects = [project]
|
||||
// Module projects set the `hostProjects` extra property in `include_flutter.groovy`.
|
||||
// This is required to set the local repository in each host app project.
|
||||
@ -260,7 +326,7 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
projects.each { hostProject ->
|
||||
hostProject.repositories {
|
||||
maven {
|
||||
url "${getPluginBuildDir(project)}/outputs/repo"
|
||||
url "${getPluginBuildDir()}/outputs/repo"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -295,7 +361,7 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
* Returns a set with the build type names that apply to the given list of tasks
|
||||
* required to configure the plugin dependencies.
|
||||
*/
|
||||
private Set getBuildTypesForTasks(Project project, List<String> tasksToExecute) {
|
||||
private Set getBuildTypesForTasks(List<String> tasksToExecute) {
|
||||
Set buildTypes = []
|
||||
tasksToExecute.each { task ->
|
||||
project.android.buildTypes.each { buildType ->
|
||||
@ -320,7 +386,7 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
return "${parts[0]}${parts[1..-1].collect { it.capitalize() }.join('')}"
|
||||
}
|
||||
|
||||
private String resolveProperty(Project project, String name, String defaultValue) {
|
||||
private String resolveProperty(String name, String defaultValue) {
|
||||
if (localProperties == null) {
|
||||
localProperties = readPropertiesIfExist(new File(project.projectDir.parentFile, "local.properties"))
|
||||
}
|
||||
@ -345,7 +411,7 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
return result
|
||||
}
|
||||
|
||||
private static List<String> getTargetPlatforms(Project project) {
|
||||
private List<String> getTargetPlatforms() {
|
||||
if (!project.hasProperty('target-platform')) {
|
||||
return DEFAULT_PLATFORMS
|
||||
}
|
||||
@ -357,18 +423,18 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
}
|
||||
}
|
||||
|
||||
private static Boolean splitPerAbi(Project project) {
|
||||
private Boolean shouldSplitPerAbi() {
|
||||
if (project.hasProperty('split-per-abi')) {
|
||||
return project.property('split-per-abi').toBoolean()
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Boolean useLocalEngine(Project project) {
|
||||
private Boolean useLocalEngine() {
|
||||
return project.hasProperty('localEngineOut')
|
||||
}
|
||||
|
||||
private static Boolean isVerbose(Project project) {
|
||||
private Boolean isVerbose() {
|
||||
if (project.hasProperty('verbose')) {
|
||||
return project.property('verbose').toBoolean()
|
||||
}
|
||||
@ -379,20 +445,7 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
return System.getProperty('build-plugins-as-aars') == 'true'
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the platform that is used to extract the `libflutter.so` and the .class files.
|
||||
*
|
||||
* Note: This is only needed to add the .class files.
|
||||
* Unfortunately, the engine artifacts include the .class and libflutter.so files.
|
||||
*/
|
||||
private static String getBasePlatform(Project project) {
|
||||
if (PLATFORM_ARM64 in getTargetPlatforms(project)) {
|
||||
return PLATFORM_ARM64;
|
||||
}
|
||||
return PLATFORM_ARM32;
|
||||
}
|
||||
|
||||
private void addFlutterJarCompileOnlyDependency(Project project, String variantName, FileCollection files) {
|
||||
private void addFlutterJarCompileOnlyDependency(Project project, String variantName, Object dependency) {
|
||||
if (project.state.failure) {
|
||||
return
|
||||
}
|
||||
@ -402,7 +455,7 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
} else {
|
||||
configuration = "${variantName}Provided";
|
||||
}
|
||||
project.dependencies.add(configuration, files)
|
||||
project.dependencies.add(configuration, dependency)
|
||||
}
|
||||
|
||||
private static void addApiDependencies(Project project, String variantName, Object dependency, Closure config = null) {
|
||||
@ -455,7 +508,6 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
if (project.hasProperty('target')) {
|
||||
target = project.property('target')
|
||||
}
|
||||
|
||||
String[] fileSystemRootsValue = null
|
||||
if (project.hasProperty('filesystem-roots')) {
|
||||
fileSystemRootsValue = project.property('filesystem-roots').split('\\|')
|
||||
@ -492,10 +544,9 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
if (project.hasProperty('extra-gen-snapshot-options')) {
|
||||
extraGenSnapshotOptionsValue = project.property('extra-gen-snapshot-options')
|
||||
}
|
||||
|
||||
def targetPlatforms = getTargetPlatforms(project)
|
||||
def targetPlatforms = getTargetPlatforms()
|
||||
def addFlutterDeps = { variant ->
|
||||
if (splitPerAbi(project)) {
|
||||
if (shouldSplitPerAbi()) {
|
||||
variant.outputs.each { output ->
|
||||
// Assigns the new version code to versionCodeOverride, which changes the version code
|
||||
// for only the output APK, not for the variant itself. Skipping this step simply
|
||||
@ -508,31 +559,17 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String flutterBuildMode = buildModeFor(variant.buildType)
|
||||
if (flutterBuildMode == 'debug' && project.tasks.findByName("${FLUTTER_BUILD_PREFIX}X86Jar")) {
|
||||
Task task = project.tasks.findByName("compile${variant.name.capitalize()}JavaWithJavac")
|
||||
if (task) {
|
||||
task.dependsOn project.flutterBuildX86Jar
|
||||
}
|
||||
task = project.tasks.findByName("compile${variant.name.capitalize()}Kotlin")
|
||||
if (task) {
|
||||
task.dependsOn project.flutterBuildX86Jar
|
||||
}
|
||||
}
|
||||
|
||||
def compileTasks = targetPlatforms.collect { targetArch ->
|
||||
String abiValue = PLATFORM_ARCH_MAP[targetArch]
|
||||
String taskName = toCammelCase(["compile", FLUTTER_BUILD_PREFIX, variant.name, targetArch.replace('android-', '')])
|
||||
FlutterTask compileTask = project.tasks.create(name: taskName, type: FlutterTask) {
|
||||
project.tasks.create(name: taskName, type: FlutterTask) {
|
||||
flutterRoot this.flutterRoot
|
||||
flutterExecutable this.flutterExecutable
|
||||
buildMode flutterBuildMode
|
||||
buildMode buildModeFor(variant.buildType)
|
||||
localEngine this.localEngine
|
||||
localEngineSrcPath this.localEngineSrcPath
|
||||
abi abiValue
|
||||
abi PLATFORM_ARCH_MAP[targetArch]
|
||||
targetPath target
|
||||
verbose isVerbose(project)
|
||||
verbose isVerbose()
|
||||
fileSystemRoots fileSystemRootsValue
|
||||
fileSystemScheme fileSystemSchemeValue
|
||||
trackWidgetCreation trackWidgetCreationValue
|
||||
@ -547,51 +584,24 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
extraGenSnapshotOptions extraGenSnapshotOptionsValue
|
||||
}
|
||||
}
|
||||
|
||||
def libJar = project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/libs.jar")
|
||||
def libFlutterPlatforms = targetPlatforms.collect()
|
||||
// x86/x86_64 native library used for debugging only, for now.
|
||||
if (flutterBuildMode == 'debug') {
|
||||
libFlutterPlatforms.add('android-x86')
|
||||
libFlutterPlatforms.add('android-x64')
|
||||
}
|
||||
Task packFlutterSnapshotsAndLibsTask = project.tasks.create(name: "packLibs${FLUTTER_BUILD_PREFIX}${variant.name.capitalize()}", type: Jar) {
|
||||
Task packFlutterAppAotTask = project.tasks.create(name: "packLibs${FLUTTER_BUILD_PREFIX}${variant.name.capitalize()}", type: Jar) {
|
||||
destinationDir libJar.parentFile
|
||||
archiveName libJar.name
|
||||
libFlutterPlatforms.each { targetArch ->
|
||||
// This check prevents including `libflutter.so` twice, since it's included in the base platform jar.
|
||||
// Unfortunately, the `pickFirst` setting in `packagingOptions` does not work when the project `:flutter`
|
||||
// is included as an implementation dependency, which causes duplicated `libflutter.so`.
|
||||
if (getBasePlatform(project) == targetArch) {
|
||||
return
|
||||
}
|
||||
// Don't include `libflutter.so` for other architectures when a local engine is specified.
|
||||
if (useLocalEngine(project)) {
|
||||
return
|
||||
}
|
||||
def engineArtifactSubdir = getEngineArtifactDirName(variant.buildType, targetArch);
|
||||
// Include `libflutter.so`.
|
||||
// TODO(blasten): The libs should be outside `flutter.jar` when the artifacts are downloaded.
|
||||
from(project.zipTree("${flutterRoot}/bin/cache/artifacts/engine/${engineArtifactSubdir}/flutter.jar")) {
|
||||
include 'lib/**'
|
||||
}
|
||||
}
|
||||
dependsOn compileTasks
|
||||
// Add the ELF library.
|
||||
compileTasks.each { compileTask ->
|
||||
from(compileTask.intermediateDir) {
|
||||
include '*.so'
|
||||
// Move `app.so` to `lib/<abi>/libapp.so`
|
||||
rename { String filename ->
|
||||
return "lib/${compileTask.abi}/lib${filename}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Include the snapshots and libflutter.so in `lib/`.
|
||||
addApiDependencies(project, variant.name, project.files {
|
||||
packFlutterSnapshotsAndLibsTask
|
||||
packFlutterAppAotTask
|
||||
})
|
||||
|
||||
// We know that the flutter app is a subproject in another Android app when these tasks exist.
|
||||
Task packageAssets = project.tasks.findByPath(":flutter:package${variant.name.capitalize()}Assets")
|
||||
Task cleanPackageAssets = project.tasks.findByPath(":flutter:cleanPackage${variant.name.capitalize()}Assets")
|
||||
@ -618,57 +628,7 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
} else {
|
||||
project.android.libraryVariants.all addFlutterDeps
|
||||
}
|
||||
|
||||
if (buildPluginAsAar()) {
|
||||
addPluginTasks(project)
|
||||
|
||||
List<String> tasksToExecute = project.gradle.startParameter.taskNames
|
||||
Set buildTypes = getBuildTypesForTasks(project, tasksToExecute)
|
||||
if (tasksToExecute.contains("clean")) {
|
||||
// Because the plugins are built during configuration, the task "clean"
|
||||
// cannot run in conjunction with an assembly task.
|
||||
if (!buildTypes.empty) {
|
||||
throw new GradleException("Can't run the clean task along with other assemble tasks")
|
||||
}
|
||||
}
|
||||
// Build plugins when a task "assembly*" will be called later.
|
||||
if (!buildTypes.empty) {
|
||||
// Build the plugin during configuration.
|
||||
// This is required when Jetifier is enabled, otherwise the implementation dependency
|
||||
// cannot be added.
|
||||
buildPlugins(project, buildTypes)
|
||||
}
|
||||
} else {
|
||||
getPluginList(project).each { name, _ ->
|
||||
def pluginProject = project.rootProject.findProject(":$name")
|
||||
if (pluginProject != null) {
|
||||
project.dependencies {
|
||||
if (project.getConfigurations().findByName("implementation")) {
|
||||
implementation pluginProject
|
||||
} else {
|
||||
compile pluginProject
|
||||
}
|
||||
}
|
||||
pluginProject.afterEvaluate {
|
||||
pluginProject.android.buildTypes {
|
||||
profile {
|
||||
initWith debug
|
||||
}
|
||||
}
|
||||
pluginProject.android.buildTypes.each {
|
||||
def buildMode = buildModeFor(it)
|
||||
addFlutterJarCompileOnlyDependency(pluginProject, it.name, project.files( flutterJar ?: baseJar[buildMode] ))
|
||||
}
|
||||
pluginProject.android.buildTypes.whenObjectAdded {
|
||||
def buildMode = buildModeFor(it)
|
||||
addFlutterJarCompileOnlyDependency(pluginProject, it.name, project.files( flutterJar ?: baseJar[buildMode] ))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
project.logger.error("Plugin project :$name not found. Please update settings.gradle.")
|
||||
}
|
||||
}
|
||||
}
|
||||
configurePlugins()
|
||||
}
|
||||
}
|
||||
|
||||
|
64
packages/flutter_tools/gradle/resolve_dependencies.gradle
Normal file
64
packages/flutter_tools/gradle/resolve_dependencies.gradle
Normal file
@ -0,0 +1,64 @@
|
||||
// Copyright 2019 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.
|
||||
//
|
||||
//
|
||||
// This script is used to warm the Gradle cache by downloading the Flutter dependencies
|
||||
// used during the build. This script is invoked when `flutter precache` is run.
|
||||
//
|
||||
// Command:
|
||||
// gradle -b <flutter-sdk>packages/flutter_tools/gradle/resolve_dependencies.gradle
|
||||
// resolveDependencies
|
||||
//
|
||||
// This way, Gradle can run with the `--offline` flag later on to eliminate any
|
||||
// network request during the build process.
|
||||
//
|
||||
// This includes:
|
||||
// 1. The embedding
|
||||
// 2. libflutter.so
|
||||
|
||||
import java.nio.file.Paths
|
||||
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
maven {
|
||||
url "http://download.flutter.io"
|
||||
}
|
||||
}
|
||||
|
||||
File flutterRoot = projectDir.parentFile.parentFile.parentFile
|
||||
|
||||
assert flutterRoot.isDirectory()
|
||||
String engineVersion = Paths.get(flutterRoot.absolutePath, "bin", "internal", "engine.version")
|
||||
.toFile().text.trim()
|
||||
|
||||
configurations {
|
||||
flutterRelease.extendsFrom releaseImplementation
|
||||
flutterDebug.extendsFrom debugImplementation
|
||||
flutterProfile.extendsFrom debugImplementation
|
||||
}
|
||||
|
||||
dependencies {
|
||||
flutterRelease "io.flutter:flutter_embedding_release:1.0.0-$engineVersion"
|
||||
flutterRelease "io.flutter:armeabi_v7a_release:1.0.0-$engineVersion"
|
||||
flutterRelease "io.flutter:arm64_v8a_release:1.0.0-$engineVersion"
|
||||
|
||||
flutterProfile "io.flutter:flutter_embedding_profile:1.0.0-$engineVersion"
|
||||
flutterProfile "io.flutter:armeabi_v7a_profile:1.0.0-$engineVersion"
|
||||
flutterProfile "io.flutter:arm64_v8a_profile:1.0.0-$engineVersion"
|
||||
|
||||
flutterDebug "io.flutter:flutter_embedding_debug:1.0.0-$engineVersion"
|
||||
flutterDebug "io.flutter:armeabi_v7a_debug:1.0.0-$engineVersion"
|
||||
flutterDebug "io.flutter:arm64_v8a_debug:1.0.0-$engineVersion"
|
||||
flutterDebug "io.flutter:x86_debug:1.0.0-$engineVersion"
|
||||
flutterDebug "io.flutter:x86_64_debug:1.0.0-$engineVersion"
|
||||
}
|
||||
|
||||
task resolveDependencies {
|
||||
configurations.each { configuration ->
|
||||
if (configuration.name.startsWith("flutter")) {
|
||||
configuration.resolve()
|
||||
}
|
||||
}
|
||||
}
|
@ -84,7 +84,7 @@ Future<void> main(List<String> args) async {
|
||||
LogsCommand(),
|
||||
MakeHostAppEditableCommand(),
|
||||
PackagesCommand(),
|
||||
PrecacheCommand(),
|
||||
PrecacheCommand(verboseHelp: verboseHelp),
|
||||
RunCommand(verboseHelp: verboseHelp),
|
||||
ScreenshotCommand(),
|
||||
ShellCompletionCommand(),
|
||||
|
@ -6,14 +6,16 @@ import 'dart:async';
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import 'android/gradle.dart';
|
||||
import 'base/common.dart';
|
||||
import 'base/context.dart';
|
||||
import 'base/file_system.dart';
|
||||
import 'base/io.dart' show SocketException;
|
||||
import 'base/io.dart' show Process, SocketException;
|
||||
import 'base/logger.dart';
|
||||
import 'base/net.dart';
|
||||
import 'base/os.dart';
|
||||
import 'base/platform.dart';
|
||||
import 'base/process.dart';
|
||||
import 'globals.dart';
|
||||
|
||||
/// A tag for a set of development artifacts that need to be cached.
|
||||
@ -30,7 +32,10 @@ class DevelopmentArtifact {
|
||||
final bool unstable;
|
||||
|
||||
/// Artifacts required for Android development.
|
||||
static const DevelopmentArtifact android = DevelopmentArtifact._('android');
|
||||
static const DevelopmentArtifact androidGenSnapshot = DevelopmentArtifact._('android_gen_snapshot');
|
||||
static const DevelopmentArtifact androidMaven = DevelopmentArtifact._('android_maven');
|
||||
// Artifacts used for internal builds.
|
||||
static const DevelopmentArtifact androidInternalBuild = DevelopmentArtifact._('android_internal_build');
|
||||
|
||||
/// Artifacts required for iOS development.
|
||||
static const DevelopmentArtifact iOS = DevelopmentArtifact._('ios');
|
||||
@ -58,7 +63,9 @@ class DevelopmentArtifact {
|
||||
|
||||
/// The values of DevelopmentArtifacts.
|
||||
static final List<DevelopmentArtifact> values = <DevelopmentArtifact>[
|
||||
android,
|
||||
androidGenSnapshot,
|
||||
androidMaven,
|
||||
androidInternalBuild,
|
||||
iOS,
|
||||
web,
|
||||
macOS,
|
||||
@ -74,12 +81,16 @@ class DevelopmentArtifact {
|
||||
class Cache {
|
||||
/// [rootOverride] is configurable for testing.
|
||||
/// [artifacts] is configurable for testing.
|
||||
Cache({ Directory rootOverride, List<CachedArtifact> artifacts }) : _rootOverride = rootOverride {
|
||||
Cache({ Directory rootOverride, List<ArtifactSet> artifacts }) : _rootOverride = rootOverride {
|
||||
if (artifacts == null) {
|
||||
_artifacts.add(MaterialFonts(this));
|
||||
_artifacts.add(AndroidEngineArtifacts(this));
|
||||
_artifacts.add(IOSEngineArtifacts(this));
|
||||
|
||||
_artifacts.add(GradleWrapper(this));
|
||||
_artifacts.add(AndroidMavenArtifacts());
|
||||
_artifacts.add(AndroidGenSnapshotArtifacts(this));
|
||||
_artifacts.add(AndroidInternalBuildArtifacts(this));
|
||||
|
||||
_artifacts.add(IOSEngineArtifacts(this));
|
||||
_artifacts.add(FlutterWebSdk(this));
|
||||
_artifacts.add(FlutterSdk(this));
|
||||
_artifacts.add(WindowsEngineArtifacts(this));
|
||||
@ -101,7 +112,7 @@ class Cache {
|
||||
];
|
||||
|
||||
final Directory _rootOverride;
|
||||
final List<CachedArtifact> _artifacts = <CachedArtifact>[];
|
||||
final List<ArtifactSet> _artifacts = <ArtifactSet>[];
|
||||
|
||||
// Initialized by FlutterCommandRunner on startup.
|
||||
static String flutterRoot;
|
||||
@ -245,11 +256,16 @@ class Cache {
|
||||
return _dyLdLibEntry;
|
||||
}
|
||||
final List<String> paths = <String>[];
|
||||
for (CachedArtifact artifact in _artifacts) {
|
||||
final String currentPath = artifact.dyLdLibPath;
|
||||
if (currentPath.isNotEmpty) {
|
||||
paths.add(currentPath);
|
||||
for (ArtifactSet artifact in _artifacts) {
|
||||
final Map<String, String> env = artifact.environment;
|
||||
if (env == null || !env.containsKey('DYLD_LIBRARY_PATH')) {
|
||||
continue;
|
||||
}
|
||||
final String path = env['DYLD_LIBRARY_PATH'];
|
||||
if (path.isEmpty) {
|
||||
continue;
|
||||
}
|
||||
paths.add(path);
|
||||
}
|
||||
_dyLdLibEntry = MapEntry<String, String>('DYLD_LIBRARY_PATH', paths.join(':'));
|
||||
return _dyLdLibEntry;
|
||||
@ -289,7 +305,7 @@ class Cache {
|
||||
return isOlderThanReference(entity: entity, referenceFile: flutterToolsStamp);
|
||||
}
|
||||
|
||||
bool isUpToDate() => _artifacts.every((CachedArtifact artifact) => artifact.isUpToDate());
|
||||
bool isUpToDate() => _artifacts.every((ArtifactSet artifact) => artifact.isUpToDate());
|
||||
|
||||
Future<String> getThirdPartyFile(String urlStr, String serviceName) async {
|
||||
final Uri url = Uri.parse(urlStr);
|
||||
@ -318,22 +334,27 @@ class Cache {
|
||||
if (!_lockEnabled) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
for (CachedArtifact artifact in _artifacts) {
|
||||
if (!artifact.isUpToDate()) {
|
||||
await artifact.update(requiredArtifacts);
|
||||
for (ArtifactSet artifact in _artifacts) {
|
||||
if (!requiredArtifacts.contains(artifact.developmentArtifact)) {
|
||||
printTrace('Artifact $artifact is not required, skipping update.');
|
||||
continue;
|
||||
}
|
||||
if (artifact.isUpToDate()) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
await artifact.update();
|
||||
} on SocketException catch (e) {
|
||||
if (_hostsBlockedInChina.contains(e.address?.host)) {
|
||||
printError(
|
||||
'Failed to retrieve Flutter tool dependencies: ${e.message}.\n'
|
||||
'If you\'re in China, please see this page: '
|
||||
'https://flutter.dev/community/china',
|
||||
emphasis: true,
|
||||
);
|
||||
}
|
||||
rethrow;
|
||||
}
|
||||
} on SocketException catch (e) {
|
||||
if (_hostsBlockedInChina.contains(e.address?.host)) {
|
||||
printError(
|
||||
'Failed to retrieve Flutter tool dependencies: ${e.message}.\n'
|
||||
'If you\'re in China, please see this page: '
|
||||
'https://flutter.dev/community/china',
|
||||
emphasis: true,
|
||||
);
|
||||
}
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@ -354,23 +375,42 @@ class Cache {
|
||||
}
|
||||
}
|
||||
|
||||
/// An artifact managed by the cache.
|
||||
abstract class CachedArtifact {
|
||||
CachedArtifact(this.name, this.cache, this.developmentArtifacts);
|
||||
/// Representation of a set of artifacts used by the tool.
|
||||
abstract class ArtifactSet {
|
||||
ArtifactSet(this.developmentArtifact) : assert(developmentArtifact != null);
|
||||
|
||||
/// The development artifact.
|
||||
final DevelopmentArtifact developmentArtifact;
|
||||
|
||||
/// [true] if the artifact is up to date.
|
||||
bool isUpToDate();
|
||||
|
||||
/// The environment variables (if any) required to consume the artifacts.
|
||||
Map<String, String> get environment {
|
||||
return const <String, String>{};
|
||||
}
|
||||
|
||||
/// Updates the artifact.
|
||||
Future<void> update();
|
||||
}
|
||||
|
||||
/// An artifact set managed by the cache.
|
||||
abstract class CachedArtifact extends ArtifactSet {
|
||||
CachedArtifact(
|
||||
this.name,
|
||||
this.cache,
|
||||
DevelopmentArtifact developmentArtifact,
|
||||
) : super(developmentArtifact);
|
||||
|
||||
final String name;
|
||||
final Cache cache;
|
||||
|
||||
/// The canonical name of the artifact.
|
||||
final String name;
|
||||
|
||||
// The name of the stamp file. Defaults to the same as the
|
||||
// artifact name.
|
||||
String get stampName => name;
|
||||
|
||||
/// Returns a string to be set as environment DYLD_LIBARY_PATH variable
|
||||
String get dyLdLibPath => '';
|
||||
|
||||
/// All development artifacts this cache provides.
|
||||
final Set<DevelopmentArtifact> developmentArtifacts;
|
||||
|
||||
Directory get location => cache.getArtifactDirectory(name);
|
||||
String get version => cache.getVersionFor(name);
|
||||
|
||||
@ -380,6 +420,7 @@ abstract class CachedArtifact {
|
||||
/// starting from scratch.
|
||||
final List<File> _downloadedFiles = <File>[];
|
||||
|
||||
@override
|
||||
bool isUpToDate() {
|
||||
if (!location.existsSync()) {
|
||||
return false;
|
||||
@ -390,13 +431,8 @@ abstract class CachedArtifact {
|
||||
return isUpToDateInner();
|
||||
}
|
||||
|
||||
Future<void> update(Set<DevelopmentArtifact> requiredArtifacts) async {
|
||||
// If the set of required artifacts does not include any from this cache,
|
||||
// then we can claim we are up to date to skip downloading.
|
||||
if (!requiredArtifacts.any(developmentArtifacts.contains)) {
|
||||
printTrace('Artifact $this is not required, skipping update.');
|
||||
return;
|
||||
}
|
||||
@override
|
||||
Future<void> update() async {
|
||||
if (!location.existsSync()) {
|
||||
try {
|
||||
location.createSync(recursive: true);
|
||||
@ -499,7 +535,7 @@ class MaterialFonts extends CachedArtifact {
|
||||
MaterialFonts(Cache cache) : super(
|
||||
'material_fonts',
|
||||
cache,
|
||||
const <DevelopmentArtifact>{ DevelopmentArtifact.universal },
|
||||
DevelopmentArtifact.universal,
|
||||
);
|
||||
|
||||
@override
|
||||
@ -517,7 +553,7 @@ class FlutterWebSdk extends CachedArtifact {
|
||||
FlutterWebSdk(Cache cache) : super(
|
||||
'flutter_web_sdk',
|
||||
cache,
|
||||
const <DevelopmentArtifact>{ DevelopmentArtifact.web },
|
||||
DevelopmentArtifact.web,
|
||||
);
|
||||
|
||||
@override
|
||||
@ -558,8 +594,8 @@ abstract class EngineCachedArtifact extends CachedArtifact {
|
||||
EngineCachedArtifact(
|
||||
this.stampName,
|
||||
Cache cache,
|
||||
Set<DevelopmentArtifact> requiredArtifacts,
|
||||
) : super('engine', cache, requiredArtifacts);
|
||||
DevelopmentArtifact developmentArtifact,
|
||||
) : super('engine', cache, developmentArtifact);
|
||||
|
||||
@override
|
||||
final String stampName;
|
||||
@ -680,7 +716,7 @@ class FlutterSdk extends EngineCachedArtifact {
|
||||
FlutterSdk(Cache cache) : super(
|
||||
'flutter_sdk',
|
||||
cache,
|
||||
const <DevelopmentArtifact>{ DevelopmentArtifact.universal },
|
||||
DevelopmentArtifact.universal,
|
||||
);
|
||||
|
||||
@override
|
||||
@ -714,7 +750,7 @@ class MacOSEngineArtifacts extends EngineCachedArtifact {
|
||||
MacOSEngineArtifacts(Cache cache) : super(
|
||||
'macos-sdk',
|
||||
cache,
|
||||
const <DevelopmentArtifact> { DevelopmentArtifact.macOS },
|
||||
DevelopmentArtifact.macOS,
|
||||
);
|
||||
|
||||
@override
|
||||
@ -736,7 +772,7 @@ class WindowsEngineArtifacts extends EngineCachedArtifact {
|
||||
WindowsEngineArtifacts(Cache cache) : super(
|
||||
'windows-sdk',
|
||||
cache,
|
||||
const <DevelopmentArtifact> { DevelopmentArtifact.windows },
|
||||
DevelopmentArtifact.windows,
|
||||
);
|
||||
|
||||
@override
|
||||
@ -758,7 +794,7 @@ class LinuxEngineArtifacts extends EngineCachedArtifact {
|
||||
LinuxEngineArtifacts(Cache cache) : super(
|
||||
'linux-sdk',
|
||||
cache,
|
||||
const <DevelopmentArtifact> { DevelopmentArtifact.linux },
|
||||
DevelopmentArtifact.linux,
|
||||
);
|
||||
|
||||
@override
|
||||
@ -776,11 +812,12 @@ class LinuxEngineArtifacts extends EngineCachedArtifact {
|
||||
List<String> getLicenseDirs() => const <String>[];
|
||||
}
|
||||
|
||||
class AndroidEngineArtifacts extends EngineCachedArtifact {
|
||||
AndroidEngineArtifacts(Cache cache) : super(
|
||||
/// The artifact used to generate snapshots for Android builds.
|
||||
class AndroidGenSnapshotArtifacts extends EngineCachedArtifact {
|
||||
AndroidGenSnapshotArtifacts(Cache cache) : super(
|
||||
'android-sdk',
|
||||
cache,
|
||||
const <DevelopmentArtifact>{ DevelopmentArtifact.android },
|
||||
DevelopmentArtifact.androidGenSnapshot,
|
||||
);
|
||||
|
||||
@override
|
||||
@ -794,23 +831,19 @@ class AndroidEngineArtifacts extends EngineCachedArtifact {
|
||||
..._osxBinaryDirs,
|
||||
..._linuxBinaryDirs,
|
||||
..._windowsBinaryDirs,
|
||||
..._androidBinaryDirs,
|
||||
..._dartSdks,
|
||||
]
|
||||
else if (platform.isWindows)
|
||||
...<List<String>>[
|
||||
..._windowsBinaryDirs,
|
||||
..._androidBinaryDirs,
|
||||
]
|
||||
else if (platform.isMacOS)
|
||||
...<List<String>>[
|
||||
..._osxBinaryDirs,
|
||||
..._androidBinaryDirs,
|
||||
]
|
||||
else if (platform.isLinux)
|
||||
...<List<String>>[
|
||||
..._linuxBinaryDirs,
|
||||
..._androidBinaryDirs,
|
||||
]
|
||||
];
|
||||
}
|
||||
@ -819,11 +852,79 @@ class AndroidEngineArtifacts extends EngineCachedArtifact {
|
||||
List<String> getLicenseDirs() { return <String>[]; }
|
||||
}
|
||||
|
||||
/// Artifacts used for internal builds. The flutter tool builds Android projects
|
||||
/// using the artifacts cached by [AndroidMavenArtifacts].
|
||||
class AndroidInternalBuildArtifacts extends EngineCachedArtifact {
|
||||
AndroidInternalBuildArtifacts(Cache cache) : super(
|
||||
'android-internal-build-artifacts',
|
||||
cache,
|
||||
DevelopmentArtifact.androidInternalBuild,
|
||||
);
|
||||
|
||||
@override
|
||||
List<String> getPackageDirs() => const <String>[];
|
||||
|
||||
@override
|
||||
List<List<String>> getBinaryDirs() {
|
||||
return _androidBinaryDirs;
|
||||
}
|
||||
|
||||
@override
|
||||
List<String> getLicenseDirs() { return <String>[]; }
|
||||
}
|
||||
|
||||
/// A cached artifact containing the Maven dependencies used to build Android projects.
|
||||
class AndroidMavenArtifacts extends ArtifactSet {
|
||||
AndroidMavenArtifacts() : super(DevelopmentArtifact.androidMaven);
|
||||
|
||||
@override
|
||||
Future<void> update() async {
|
||||
final Directory tempDir =
|
||||
fs.systemTempDirectory.createTempSync('gradle_wrapper.');
|
||||
injectGradleWrapperIfNeeded(tempDir);
|
||||
|
||||
final Status status = logger.startProgress('Downloading Android Maven dependencies...',
|
||||
timeout: timeoutConfiguration.slowOperation);
|
||||
final File gradle = tempDir.childFile(
|
||||
platform.isWindows ? 'gradlew.bat' : 'gradlew',
|
||||
);
|
||||
assert(gradle.existsSync());
|
||||
os.makeExecutable(gradle);
|
||||
|
||||
try {
|
||||
final String gradleExecutable = gradle.absolute.path;
|
||||
final String flutterSdk = escapePath(Cache.flutterRoot);
|
||||
final Process process = await runCommand(
|
||||
<String>[
|
||||
gradleExecutable,
|
||||
'-b', fs.path.join(flutterSdk, 'packages', 'flutter_tools', 'gradle', 'resolve_dependencies.gradle'),
|
||||
'--project-cache-dir', tempDir.path,
|
||||
'resolveDependencies',
|
||||
]);
|
||||
final int exitCode = await process.exitCode;
|
||||
if (exitCode != 0) {
|
||||
printError('Failed to download the Android dependencies');
|
||||
}
|
||||
} finally {
|
||||
status.stop();
|
||||
tempDir.deleteSync(recursive: true);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool isUpToDate() {
|
||||
// The dependencies are downloaded and cached by Gradle.
|
||||
// The tool doesn't know if the dependencies are already cached at this point.
|
||||
// Therefore, call Gradle to figure this out.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class IOSEngineArtifacts extends EngineCachedArtifact {
|
||||
IOSEngineArtifacts(Cache cache) : super(
|
||||
'ios-sdk',
|
||||
cache,
|
||||
<DevelopmentArtifact>{ DevelopmentArtifact.iOS },
|
||||
DevelopmentArtifact.iOS,
|
||||
);
|
||||
|
||||
@override
|
||||
@ -856,7 +957,7 @@ class GradleWrapper extends CachedArtifact {
|
||||
GradleWrapper(Cache cache) : super(
|
||||
'gradle_wrapper',
|
||||
cache,
|
||||
const <DevelopmentArtifact>{ DevelopmentArtifact.universal },
|
||||
DevelopmentArtifact.universal,
|
||||
);
|
||||
|
||||
List<String> get _gradleScripts => <String>['gradlew', 'gradlew.bat'];
|
||||
@ -897,11 +998,13 @@ class GradleWrapper extends CachedArtifact {
|
||||
|
||||
/// Common functionality for pulling Fuchsia SDKs.
|
||||
abstract class _FuchsiaSDKArtifacts extends CachedArtifact {
|
||||
_FuchsiaSDKArtifacts(Cache cache, String platform)
|
||||
:_path = 'fuchsia/sdk/core/$platform-amd64',
|
||||
super('fuchsia-$platform', cache, const <DevelopmentArtifact> {
|
||||
DevelopmentArtifact.fuchsia,
|
||||
});
|
||||
_FuchsiaSDKArtifacts(Cache cache, String platform) :
|
||||
_path = 'fuchsia/sdk/core/$platform-amd64',
|
||||
super(
|
||||
'fuchsia-$platform',
|
||||
cache,
|
||||
DevelopmentArtifact.fuchsia,
|
||||
);
|
||||
|
||||
final String _path;
|
||||
|
||||
@ -917,10 +1020,11 @@ abstract class _FuchsiaSDKArtifacts extends CachedArtifact {
|
||||
|
||||
/// The pre-built flutter runner for Fuchsia development.
|
||||
class FlutterRunnerSDKArtifacts extends CachedArtifact {
|
||||
FlutterRunnerSDKArtifacts(Cache cache)
|
||||
: super('flutter_runner', cache, const <DevelopmentArtifact>{
|
||||
FlutterRunnerSDKArtifacts(Cache cache) : super(
|
||||
'flutter_runner',
|
||||
cache,
|
||||
DevelopmentArtifact.flutterRunner,
|
||||
});
|
||||
);
|
||||
|
||||
@override
|
||||
Directory get location => cache.getArtifactDirectory('flutter_runner');
|
||||
@ -971,7 +1075,7 @@ class IosUsbArtifacts extends CachedArtifact {
|
||||
name,
|
||||
cache,
|
||||
// This is universal to ensure every command checks for them first
|
||||
const <DevelopmentArtifact>{ DevelopmentArtifact.universal },
|
||||
DevelopmentArtifact.universal,
|
||||
);
|
||||
|
||||
static const List<String> artifactNames = <String>[
|
||||
@ -984,8 +1088,10 @@ class IosUsbArtifacts extends CachedArtifact {
|
||||
];
|
||||
|
||||
@override
|
||||
String get dyLdLibPath {
|
||||
return cache.getArtifactDirectory(name).path;
|
||||
Map<String, String> get environment {
|
||||
return <String, String>{
|
||||
'DYLD_LIBRARY_PATH': cache.getArtifactDirectory(name).path,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
@ -1093,6 +1199,12 @@ const List<List<String>> _windowsBinaryDirs = <List<String>>[
|
||||
<String>['android-arm64-release/windows-x64', 'android-arm64-release/windows-x64.zip'],
|
||||
];
|
||||
|
||||
const List<List<String>> _iosBinaryDirs = <List<String>>[
|
||||
<String>['ios', 'ios/artifacts.zip'],
|
||||
<String>['ios-profile', 'ios-profile/artifacts.zip'],
|
||||
<String>['ios-release', 'ios-release/artifacts.zip'],
|
||||
];
|
||||
|
||||
const List<List<String>> _androidBinaryDirs = <List<String>>[
|
||||
<String>['android-x86', 'android-x86/artifacts.zip'],
|
||||
<String>['android-x64', 'android-x64/artifacts.zip'],
|
||||
@ -1104,12 +1216,6 @@ const List<List<String>> _androidBinaryDirs = <List<String>>[
|
||||
<String>['android-arm64-release', 'android-arm64-release/artifacts.zip'],
|
||||
];
|
||||
|
||||
const List<List<String>> _iosBinaryDirs = <List<String>>[
|
||||
<String>['ios', 'ios/artifacts.zip'],
|
||||
<String>['ios-profile', 'ios-profile/artifacts.zip'],
|
||||
<String>['ios-release', 'ios-release/artifacts.zip'],
|
||||
];
|
||||
|
||||
const List<List<String>> _dartSdks = <List<String>> [
|
||||
<String>['darwin-x64', 'dart-sdk-darwin-x64.zip'],
|
||||
<String>['linux-x64', 'dart-sdk-linux-x64.zip'],
|
||||
|
@ -9,7 +9,7 @@ import '../base/os.dart';
|
||||
import '../build_info.dart';
|
||||
import '../project.dart';
|
||||
import '../reporting/reporting.dart';
|
||||
import '../runner/flutter_command.dart' show DevelopmentArtifact, FlutterCommandResult;
|
||||
import '../runner/flutter_command.dart' show FlutterCommandResult;
|
||||
import 'build.dart';
|
||||
|
||||
class BuildAarCommand extends BuildSubCommand {
|
||||
@ -52,12 +52,6 @@ class BuildAarCommand extends BuildSubCommand {
|
||||
return usage;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Set<DevelopmentArtifact>> get requiredArtifacts async => const <DevelopmentArtifact>{
|
||||
DevelopmentArtifact.universal,
|
||||
DevelopmentArtifact.android,
|
||||
};
|
||||
|
||||
@override
|
||||
final String description = 'Build a repository containing an AAR and a POM file.\n\n'
|
||||
'The POM file is used to include the dependencies that the AAR was compiled against.\n\n'
|
||||
|
@ -10,7 +10,7 @@ import '../build_info.dart';
|
||||
import '../globals.dart';
|
||||
import '../project.dart';
|
||||
import '../reporting/reporting.dart';
|
||||
import '../runner/flutter_command.dart' show DevelopmentArtifact, FlutterCommandResult;
|
||||
import '../runner/flutter_command.dart' show FlutterCommandResult;
|
||||
import 'build.dart';
|
||||
|
||||
class BuildApkCommand extends BuildSubCommand {
|
||||
@ -68,12 +68,6 @@ class BuildApkCommand extends BuildSubCommand {
|
||||
return usage;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Set<DevelopmentArtifact>> get requiredArtifacts async => const <DevelopmentArtifact>{
|
||||
DevelopmentArtifact.universal,
|
||||
DevelopmentArtifact.android,
|
||||
};
|
||||
|
||||
@override
|
||||
Future<FlutterCommandResult> runCommand() async {
|
||||
final BuildInfo buildInfo = getBuildInfo();
|
||||
|
@ -37,7 +37,7 @@ class DoctorCommand extends FlutterCommand {
|
||||
// This is required because we use gen_snapshot to check if the host
|
||||
// machine can execute the provided artifacts. See `_genSnapshotRuns`
|
||||
// in `doctor.dart`.
|
||||
DevelopmentArtifact.android,
|
||||
DevelopmentArtifact.androidGenSnapshot,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -10,13 +10,23 @@ import '../runner/flutter_command.dart';
|
||||
import '../version.dart';
|
||||
|
||||
class PrecacheCommand extends FlutterCommand {
|
||||
PrecacheCommand() {
|
||||
PrecacheCommand({bool verboseHelp = false}) {
|
||||
argParser.addFlag('all-platforms', abbr: 'a', negatable: false,
|
||||
help: 'Precache artifacts for all host platforms.');
|
||||
argParser.addFlag('force', abbr: 'f', negatable: false,
|
||||
help: 'Force downloading of artifacts.');
|
||||
argParser.addFlag('android', negatable: true, defaultsTo: true,
|
||||
help: 'Precache artifacts for Android development.');
|
||||
help: 'Precache artifacts for Android development.',
|
||||
hide: verboseHelp);
|
||||
argParser.addFlag('android_gen_snapshot', negatable: true, defaultsTo: true,
|
||||
help: 'Precache gen_snapshot for Android development.',
|
||||
hide: !verboseHelp);
|
||||
argParser.addFlag('android_maven', negatable: true, defaultsTo: true,
|
||||
help: 'Precache Gradle dependencies for Android development.',
|
||||
hide: !verboseHelp);
|
||||
argParser.addFlag('android_internal_build', negatable: true, defaultsTo: false,
|
||||
help: 'Precache dependencies for internal Android development.',
|
||||
hide: !verboseHelp);
|
||||
argParser.addFlag('ios', negatable: true, defaultsTo: true,
|
||||
help: 'Precache artifacts for iOS development.');
|
||||
argParser.addFlag('web', negatable: true, defaultsTo: false,
|
||||
@ -58,6 +68,10 @@ class PrecacheCommand extends FlutterCommand {
|
||||
if (argResults[artifact.name]) {
|
||||
requiredArtifacts.add(artifact);
|
||||
}
|
||||
// The `android` flag expands to android_gen_snapshot, android_maven, android_internal_build.
|
||||
if (artifact.name.startsWith('android_') && argResults['android']) {
|
||||
requiredArtifacts.add(artifact);
|
||||
}
|
||||
}
|
||||
final bool forceUpdate = argResults['force'];
|
||||
if (forceUpdate || !cache.isUpToDate()) {
|
||||
|
@ -644,7 +644,7 @@ DevelopmentArtifact _artifactFromTargetPlatform(TargetPlatform targetPlatform) {
|
||||
case TargetPlatform.android_arm64:
|
||||
case TargetPlatform.android_x64:
|
||||
case TargetPlatform.android_x86:
|
||||
return DevelopmentArtifact.android;
|
||||
return DevelopmentArtifact.androidGenSnapshot;
|
||||
case TargetPlatform.web_javascript:
|
||||
return DevelopmentArtifact.web;
|
||||
case TargetPlatform.ios:
|
||||
|
@ -47,9 +47,9 @@ dependencies {
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
||||
{{/androidX}}
|
||||
{{^androidX}}
|
||||
implementation 'com.android.support:appcompat-v7:27.1.1'
|
||||
implementation 'com.android.support:appcompat-v7:28.0.0'
|
||||
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
|
||||
implementation 'com.android.support:design:27.1.1'
|
||||
implementation 'com.android.support:design:28.0.0'
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||
{{/androidX}}
|
||||
|
@ -8,8 +8,10 @@ import 'package:file_testing/file_testing.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:platform/platform.dart';
|
||||
import 'package:process/process.dart';
|
||||
|
||||
import 'package:flutter_tools/src/base/common.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart' show InternetAddress, SocketException;
|
||||
@ -136,18 +138,30 @@ void main() {
|
||||
when(artifact1.isUpToDate()).thenReturn(true);
|
||||
when(artifact2.isUpToDate()).thenReturn(false);
|
||||
final Cache cache = Cache(artifacts: <CachedArtifact>[artifact1, artifact2]);
|
||||
await cache.updateAll(<DevelopmentArtifact>{});
|
||||
verifyNever(artifact1.update(<DevelopmentArtifact>{}));
|
||||
verify(artifact2.update(<DevelopmentArtifact>{}));
|
||||
await cache.updateAll(<DevelopmentArtifact>{
|
||||
null,
|
||||
});
|
||||
verifyNever(artifact1.update());
|
||||
verify(artifact2.update());
|
||||
});
|
||||
testUsingContext('getter dyLdLibEntry concatenates the output of each artifact\'s dyLdLibEntry getter', () async {
|
||||
final CachedArtifact artifact1 = MockCachedArtifact();
|
||||
final CachedArtifact artifact2 = MockCachedArtifact();
|
||||
final CachedArtifact artifact3 = MockCachedArtifact();
|
||||
when(artifact1.dyLdLibPath).thenReturn('/path/to/alpha:/path/to/beta');
|
||||
when(artifact2.dyLdLibPath).thenReturn('/path/to/gamma:/path/to/delta:/path/to/epsilon');
|
||||
when(artifact3.dyLdLibPath).thenReturn(''); // Empty output
|
||||
final IosUsbArtifacts artifact1 = MockIosUsbArtifacts();
|
||||
final IosUsbArtifacts artifact2 = MockIosUsbArtifacts();
|
||||
final IosUsbArtifacts artifact3 = MockIosUsbArtifacts();
|
||||
when(artifact1.environment)
|
||||
.thenReturn(<String, String>{
|
||||
'DYLD_LIBRARY_PATH': '/path/to/alpha:/path/to/beta',
|
||||
});
|
||||
when(artifact2.environment)
|
||||
.thenReturn(<String, String>{
|
||||
'DYLD_LIBRARY_PATH': '/path/to/gamma:/path/to/delta:/path/to/epsilon',
|
||||
});
|
||||
when(artifact3.environment)
|
||||
.thenReturn(<String, String>{
|
||||
'DYLD_LIBRARY_PATH': '',
|
||||
});
|
||||
final Cache cache = Cache(artifacts: <CachedArtifact>[artifact1, artifact2, artifact3]);
|
||||
|
||||
expect(cache.dyLdLibEntry.key, 'DYLD_LIBRARY_PATH');
|
||||
expect(
|
||||
cache.dyLdLibEntry.value,
|
||||
@ -163,18 +177,20 @@ void main() {
|
||||
when(artifact2.isUpToDate()).thenReturn(false);
|
||||
final MockInternetAddress address = MockInternetAddress();
|
||||
when(address.host).thenReturn('storage.googleapis.com');
|
||||
when(artifact1.update(<DevelopmentArtifact>{})).thenThrow(SocketException(
|
||||
when(artifact1.update()).thenThrow(SocketException(
|
||||
'Connection reset by peer',
|
||||
address: address,
|
||||
));
|
||||
final Cache cache = Cache(artifacts: <CachedArtifact>[artifact1, artifact2]);
|
||||
try {
|
||||
await cache.updateAll(<DevelopmentArtifact>{});
|
||||
await cache.updateAll(<DevelopmentArtifact>{
|
||||
null,
|
||||
});
|
||||
fail('Mock thrown exception expected');
|
||||
} catch (e) {
|
||||
verify(artifact1.update(<DevelopmentArtifact>{}));
|
||||
verify(artifact1.update());
|
||||
// Don't continue when retrieval fails.
|
||||
verifyNever(artifact2.update(<DevelopmentArtifact>{}));
|
||||
verifyNever(artifact2.update());
|
||||
expect(
|
||||
testLogger.errorText,
|
||||
contains('https://flutter.dev/community/china'),
|
||||
@ -226,6 +242,7 @@ void main() {
|
||||
binaryDirs: <List<String>>[
|
||||
<String>['bin_dir', 'unused_url_path'],
|
||||
],
|
||||
requiredArtifacts: DevelopmentArtifact.universal,
|
||||
);
|
||||
await artifact.updateInner();
|
||||
final Directory dir = memoryFileSystem.systemTempDirectory
|
||||
@ -244,25 +261,56 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
testUsingContext('throws tool exit on fs exception', () async {
|
||||
final FakeCachedArtifact fakeCachedArtifact = FakeCachedArtifact(
|
||||
cache: MockCache(),
|
||||
requiredArtifacts: <DevelopmentArtifact>{
|
||||
DevelopmentArtifact.android,
|
||||
}
|
||||
);
|
||||
final Directory mockDirectory = MockDirectory();
|
||||
when(fakeCachedArtifact.cache.getArtifactDirectory(any))
|
||||
.thenReturn(mockDirectory);
|
||||
when(mockDirectory.existsSync()).thenReturn(false);
|
||||
when(mockDirectory.createSync(recursive: true))
|
||||
.thenThrow(const FileSystemException());
|
||||
group('AndroidMavenArtifacts', () {
|
||||
MemoryFileSystem memoryFileSystem;
|
||||
MockProcessManager processManager;
|
||||
MockCache mockCache;
|
||||
MockProcess mockProcess;
|
||||
|
||||
expect(() => fakeCachedArtifact.update(<DevelopmentArtifact>{
|
||||
DevelopmentArtifact.android,
|
||||
}), throwsA(isInstanceOf<ToolExit>()));
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => MemoryFileSystem(),
|
||||
setUp(() {
|
||||
memoryFileSystem = MemoryFileSystem();
|
||||
processManager = MockProcessManager();
|
||||
mockCache = MockCache();
|
||||
mockProcess = MockProcess();
|
||||
});
|
||||
|
||||
test('development artifact', () async {
|
||||
final AndroidMavenArtifacts mavenArtifacts = AndroidMavenArtifacts();
|
||||
expect(mavenArtifacts.developmentArtifact, DevelopmentArtifact.androidMaven);
|
||||
});
|
||||
|
||||
testUsingContext('update', () async {
|
||||
final AndroidMavenArtifacts mavenArtifacts = AndroidMavenArtifacts();
|
||||
expect(mavenArtifacts.isUpToDate(), isFalse);
|
||||
|
||||
final Directory gradleWrapperDir = fs.systemTempDirectory.createTempSync('gradle_wrapper.');
|
||||
when(mockCache.getArtifactDirectory('gradle_wrapper')).thenReturn(gradleWrapperDir);
|
||||
|
||||
fs.directory(gradleWrapperDir.childDirectory('gradle').childDirectory('wrapper'))
|
||||
.createSync(recursive: true);
|
||||
fs.file(fs.path.join(gradleWrapperDir.path, 'gradlew')).writeAsStringSync('irrelevant');
|
||||
fs.file(fs.path.join(gradleWrapperDir.path, 'gradlew.bat')).writeAsStringSync('irrelevant');
|
||||
|
||||
when(processManager.start(any))
|
||||
.thenAnswer((Invocation invocation){
|
||||
final List<String> args = invocation.positionalArguments[0];
|
||||
expect(args.length, 6);
|
||||
expect(args[1], '-b');
|
||||
expect(args[2].endsWith('resolve_dependencies.gradle'), isTrue);
|
||||
expect(args[5], 'resolveDependencies');
|
||||
|
||||
return Future<Process>.value(mockProcess);
|
||||
});
|
||||
when(mockProcess.exitCode).thenAnswer((_) async => 0);
|
||||
|
||||
await mavenArtifacts.update();
|
||||
|
||||
expect(mavenArtifacts.isUpToDate(), isFalse);
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: ()=> mockCache,
|
||||
FileSystem: () => memoryFileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -270,7 +318,7 @@ class FakeCachedArtifact extends EngineCachedArtifact {
|
||||
FakeCachedArtifact({
|
||||
String stampName = 'STAMP',
|
||||
@required Cache cache,
|
||||
Set<DevelopmentArtifact> requiredArtifacts = const <DevelopmentArtifact>{},
|
||||
DevelopmentArtifact requiredArtifacts,
|
||||
this.binaryDirs = const <List<String>>[],
|
||||
this.licenseDirs = const <String>[],
|
||||
this.packageDirs = const <String>[],
|
||||
@ -290,12 +338,15 @@ class FakeCachedArtifact extends EngineCachedArtifact {
|
||||
List<String> getPackageDirs() => packageDirs;
|
||||
}
|
||||
|
||||
class MockProcessManager extends Mock implements ProcessManager {}
|
||||
class MockProcess extends Mock implements Process {}
|
||||
class MockFileSystem extends Mock implements FileSystem {}
|
||||
class MockFile extends Mock implements File {}
|
||||
class MockDirectory extends Mock implements Directory {}
|
||||
|
||||
class MockRandomAccessFile extends Mock implements RandomAccessFile {}
|
||||
class MockCachedArtifact extends Mock implements CachedArtifact {}
|
||||
class MockIosUsbArtifacts extends Mock implements IosUsbArtifacts {}
|
||||
class MockInternetAddress extends Mock implements InternetAddress {}
|
||||
class MockCache extends Mock implements Cache {}
|
||||
class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils {}
|
||||
|
@ -27,12 +27,24 @@ void main() {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(
|
||||
const <String>['precache', '--ios', '--android', '--web', '--macos', '--linux', '--windows', '--fuchsia', '--flutter_runner']
|
||||
const <String>[
|
||||
'precache',
|
||||
'--ios',
|
||||
'--android',
|
||||
'--web',
|
||||
'--macos',
|
||||
'--linux',
|
||||
'--windows',
|
||||
'--fuchsia',
|
||||
'--flutter_runner',
|
||||
]
|
||||
);
|
||||
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
|
||||
DevelopmentArtifact.universal,
|
||||
DevelopmentArtifact.iOS,
|
||||
DevelopmentArtifact.android,
|
||||
DevelopmentArtifact.androidGenSnapshot,
|
||||
DevelopmentArtifact.androidMaven,
|
||||
DevelopmentArtifact.androidInternalBuild,
|
||||
DevelopmentArtifact.web,
|
||||
DevelopmentArtifact.macOS,
|
||||
DevelopmentArtifact.linux,
|
||||
@ -44,6 +56,54 @@ void main() {
|
||||
Cache: () => cache,
|
||||
});
|
||||
|
||||
testUsingContext('Expands android artifacts when the android flag is used', () async {
|
||||
// Release lock between test cases.
|
||||
Cache.releaseLockEarly();
|
||||
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(
|
||||
const <String>[
|
||||
'precache',
|
||||
'--no-ios',
|
||||
'--android',
|
||||
]
|
||||
);
|
||||
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
|
||||
DevelopmentArtifact.universal,
|
||||
DevelopmentArtifact.androidGenSnapshot,
|
||||
DevelopmentArtifact.androidMaven,
|
||||
DevelopmentArtifact.androidInternalBuild,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
});
|
||||
|
||||
testUsingContext('Adds artifact flags to requested android artifacts', () async {
|
||||
// Release lock between test cases.
|
||||
Cache.releaseLockEarly();
|
||||
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(
|
||||
const <String>[
|
||||
'precache',
|
||||
'--no-ios',
|
||||
'--android_gen_snapshot',
|
||||
'--android_maven',
|
||||
'--android_internal_build',
|
||||
]
|
||||
);
|
||||
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
|
||||
DevelopmentArtifact.universal,
|
||||
DevelopmentArtifact.androidGenSnapshot,
|
||||
DevelopmentArtifact.androidMaven,
|
||||
DevelopmentArtifact.androidInternalBuild,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
});
|
||||
|
||||
final MockFlutterVersion flutterVersion = MockFlutterVersion();
|
||||
when(flutterVersion.isMaster).thenReturn(false);
|
||||
|
||||
@ -53,18 +113,31 @@ void main() {
|
||||
final PrecacheCommand command = PrecacheCommand();
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(
|
||||
const <String>['precache', '--ios', '--android', '--web', '--macos', '--linux', '--windows', '--fuchsia', '--flutter_runner']
|
||||
const <String>[
|
||||
'precache',
|
||||
'--ios',
|
||||
'--android_gen_snapshot',
|
||||
'--android_maven',
|
||||
'--android_internal_build',
|
||||
'--web',
|
||||
'--macos',
|
||||
'--linux',
|
||||
'--windows',
|
||||
'--fuchsia',
|
||||
'--flutter_runner',
|
||||
]
|
||||
);
|
||||
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
|
||||
DevelopmentArtifact.universal,
|
||||
DevelopmentArtifact.iOS,
|
||||
DevelopmentArtifact.android,
|
||||
}));
|
||||
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
|
||||
DevelopmentArtifact.universal,
|
||||
DevelopmentArtifact.iOS,
|
||||
DevelopmentArtifact.androidGenSnapshot,
|
||||
DevelopmentArtifact.androidMaven,
|
||||
DevelopmentArtifact.androidInternalBuild,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FlutterVersion: () => flutterVersion,
|
||||
});
|
||||
|
||||
testUsingContext('Downloads artifacts when --force is provided', () async {
|
||||
when(cache.isUpToDate()).thenReturn(true);
|
||||
// Release lock between test cases.
|
||||
@ -73,10 +146,12 @@ void main() {
|
||||
applyMocksToCommand(command);
|
||||
await createTestCommandRunner(command).run(const <String>['precache', '--force']);
|
||||
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
|
||||
DevelopmentArtifact.universal,
|
||||
DevelopmentArtifact.iOS,
|
||||
DevelopmentArtifact.android,
|
||||
}));
|
||||
DevelopmentArtifact.universal,
|
||||
DevelopmentArtifact.iOS,
|
||||
DevelopmentArtifact.androidGenSnapshot,
|
||||
DevelopmentArtifact.androidMaven,
|
||||
DevelopmentArtifact.androidInternalBuild,
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Cache: () => cache,
|
||||
FlutterVersion: () => flutterVersion,
|
||||
|
@ -138,7 +138,7 @@ void main() {
|
||||
|
||||
expect(await RunCommand().requiredArtifacts, unorderedEquals(<DevelopmentArtifact>{
|
||||
DevelopmentArtifact.universal,
|
||||
DevelopmentArtifact.android,
|
||||
DevelopmentArtifact.androidGenSnapshot,
|
||||
}));
|
||||
|
||||
when(mockDeviceManager.getDevices()).thenAnswer((Invocation invocation) {
|
||||
@ -162,7 +162,7 @@ void main() {
|
||||
expect(await RunCommand().requiredArtifacts, unorderedEquals(<DevelopmentArtifact>{
|
||||
DevelopmentArtifact.universal,
|
||||
DevelopmentArtifact.iOS,
|
||||
DevelopmentArtifact.android,
|
||||
DevelopmentArtifact.androidGenSnapshot,
|
||||
}));
|
||||
|
||||
when(mockDeviceManager.getDevices()).thenAnswer((Invocation invocation) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user