Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
c9b466f9
Unverified
Commit
c9b466f9
authored
Jul 23, 2019
by
Emmanuel Garcia
Committed by
GitHub
Jul 23, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "Add flutter build aar (#35217)" (#36731)
This reverts commit
11460b83
.
parent
11460b83
Changes
30
Hide whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
147 additions
and
2162 deletions
+147
-2162
test.dart
dev/bots/test.dart
+0
-5
build_aar_module_test.dart
dev/devicelab/bin/tasks/build_aar_module_test.dart
+0
-219
build_aar_plugin_test.dart
dev/devicelab/bin/tasks/build_aar_plugin_test.dart
+0
-138
gradle_jetifier_test.dart
dev/devicelab/bin/tasks/gradle_jetifier_test.dart
+0
-138
gradle_migrate_settings_test.dart
dev/devicelab/bin/tasks/gradle_migrate_settings_test.dart
+0
-180
gradle_plugin_dependencies_test.dart
dev/devicelab/bin/tasks/gradle_plugin_dependencies_test.dart
+0
-147
module_test.dart
dev/devicelab/bin/tasks/module_test.dart
+1
-1
module_test_ios.dart
dev/devicelab/bin/tasks/module_test_ios.dart
+1
-1
apk_utils.dart
dev/devicelab/lib/framework/apk_utils.dart
+0
-87
utils.dart
dev/devicelab/lib/framework/utils.dart
+3
-16
aar_init_script.gradle
packages/flutter_tools/gradle/aar_init_script.gradle
+0
-128
deprecated_settings.gradle
packages/flutter_tools/gradle/deprecated_settings.gradle
+0
-31
flutter.gradle
packages/flutter_tools/gradle/flutter.gradle
+65
-248
manual_migration_settings.gradle.md
.../flutter_tools/gradle/manual_migration_settings.gradle.md
+0
-19
settings_aar.gradle.tmpl
packages/flutter_tools/gradle/settings_aar.gradle.tmpl
+0
-1
aar.dart
packages/flutter_tools/lib/src/android/aar.dart
+0
-62
gradle.dart
packages/flutter_tools/lib/src/android/gradle.dart
+49
-325
build.dart
packages/flutter_tools/lib/src/commands/build.dart
+0
-2
build_aar.dart
packages/flutter_tools/lib/src/commands/build_aar.dart
+0
-94
features.dart
packages/flutter_tools/lib/src/features.dart
+0
-18
project.dart
packages/flutter_tools/lib/src/project.dart
+4
-0
usage.dart
packages/flutter_tools/lib/src/reporting/usage.dart
+1
-4
build.gradle.tmpl
...tes/module/android/library/Flutter.tmpl/build.gradle.tmpl
+0
-3
include_flutter.groovy.copy.tmpl
...s/module/android/library/include_flutter.groovy.copy.tmpl
+10
-23
build.gradle.tmpl
...ools/templates/plugin/android-java.tmpl/build.gradle.tmpl
+1
-1
gradle-wrapper.properties
...gin/android.tmpl/gradle/wrapper/gradle-wrapper.properties
+0
-5
gradle_test.dart
...flutter_tools/test/general.shard/android/gradle_test.dart
+12
-160
build_aar_test.dart
...ter_tools/test/general.shard/commands/build_aar_test.dart
+0
-87
features_test.dart
packages/flutter_tools/test/general.shard/features_test.dart
+0
-15
testbed.dart
packages/flutter_tools/test/src/testbed.dart
+0
-4
No files found.
dev/bots/test.dart
View file @
c9b466f9
...
@@ -961,14 +961,9 @@ Future<void> _androidGradleTests(String subShard) async {
...
@@ -961,14 +961,9 @@ Future<void> _androidGradleTests(String subShard) async {
if
(
subShard
==
'gradle1'
)
{
if
(
subShard
==
'gradle1'
)
{
await
_runDevicelabTest
(
'gradle_plugin_light_apk_test'
,
env:
env
);
await
_runDevicelabTest
(
'gradle_plugin_light_apk_test'
,
env:
env
);
await
_runDevicelabTest
(
'gradle_plugin_fat_apk_test'
,
env:
env
);
await
_runDevicelabTest
(
'gradle_plugin_fat_apk_test'
,
env:
env
);
await
_runDevicelabTest
(
'gradle_jetifier_test'
,
env:
env
);
await
_runDevicelabTest
(
'gradle_plugin_dependencies_test'
,
env:
env
);
await
_runDevicelabTest
(
'gradle_migrate_settings_test'
,
env:
env
);
}
}
if
(
subShard
==
'gradle2'
)
{
if
(
subShard
==
'gradle2'
)
{
await
_runDevicelabTest
(
'gradle_plugin_bundle_test'
,
env:
env
);
await
_runDevicelabTest
(
'gradle_plugin_bundle_test'
,
env:
env
);
await
_runDevicelabTest
(
'module_test'
,
env:
env
);
await
_runDevicelabTest
(
'module_test'
,
env:
env
);
await
_runDevicelabTest
(
'build_aar_plugin_test'
,
env:
env
);
await
_runDevicelabTest
(
'build_aar_module_test'
,
env:
env
);
}
}
}
}
dev/devicelab/bin/tasks/build_aar_module_test.dart
deleted
100644 → 0
View file @
11460b83
// Copyright (c) 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.
import
'dart:async'
;
import
'dart:io'
;
import
'package:flutter_devicelab/framework/framework.dart'
;
import
'package:flutter_devicelab/framework/utils.dart'
;
import
'package:path/path.dart'
as
path
;
final
String
gradlew
=
Platform
.
isWindows
?
'gradlew.bat'
:
'gradlew'
;
final
String
gradlewExecutable
=
Platform
.
isWindows
?
gradlew
:
'./
$gradlew
'
;
/// Tests that AARs can be built on module projects.
Future
<
void
>
main
()
async
{
await
task
(()
async
{
section
(
'Find Java'
);
final
String
javaHome
=
await
findJavaHome
();
if
(
javaHome
==
null
)
return
TaskResult
.
failure
(
'Could not find Java'
);
print
(
'
\n
Using JAVA_HOME=
$javaHome
'
);
section
(
'Create module project'
);
final
Directory
tempDir
=
Directory
.
systemTemp
.
createTempSync
(
'flutter_module_test.'
);
final
Directory
projectDir
=
Directory
(
path
.
join
(
tempDir
.
path
,
'hello'
));
try
{
await
inDirectory
(
tempDir
,
()
async
{
await
flutter
(
'create'
,
options:
<
String
>[
'--org'
,
'io.flutter.devicelab'
,
'--template'
,
'module'
,
'hello'
],
);
});
section
(
'Add plugins'
);
final
File
pubspec
=
File
(
path
.
join
(
projectDir
.
path
,
'pubspec.yaml'
));
String
content
=
pubspec
.
readAsStringSync
();
content
=
content
.
replaceFirst
(
'
\n
dependencies:
\n
'
,
'
\n
dependencies:
\n
device_info:
\n
package_info:
\n
'
,
);
pubspec
.
writeAsStringSync
(
content
,
flush:
true
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'packages'
,
options:
<
String
>[
'get'
],
);
});
section
(
'Build release AAR'
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'aar'
,
'--verbose'
],
);
});
final
String
repoPath
=
path
.
join
(
projectDir
.
path
,
'build'
,
'host'
,
'outputs'
,
'repo'
,
);
checkFileExists
(
path
.
join
(
repoPath
,
'io'
,
'flutter'
,
'devicelab'
,
'hello'
,
'flutter_release'
,
'1.0'
,
'flutter_release-1.0.aar'
,
));
checkFileExists
(
path
.
join
(
repoPath
,
'io'
,
'flutter'
,
'devicelab'
,
'hello'
,
'flutter_release'
,
'1.0'
,
'flutter_release-1.0.pom'
,
));
checkFileExists
(
path
.
join
(
repoPath
,
'io'
,
'flutter'
,
'plugins'
,
'deviceinfo'
,
'device_info_release'
,
'1.0'
,
'device_info_release-1.0.aar'
,
));
checkFileExists
(
path
.
join
(
repoPath
,
'io'
,
'flutter'
,
'plugins'
,
'deviceinfo'
,
'device_info_release'
,
'1.0'
,
'device_info_release-1.0.pom'
,
));
checkFileExists
(
path
.
join
(
repoPath
,
'io'
,
'flutter'
,
'plugins'
,
'packageinfo'
,
'package_info_release'
,
'1.0'
,
'package_info_release-1.0.aar'
,
));
checkFileExists
(
path
.
join
(
repoPath
,
'io'
,
'flutter'
,
'plugins'
,
'packageinfo'
,
'package_info_release'
,
'1.0'
,
'package_info_release-1.0.pom'
,
));
section
(
'Build debug AAR'
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'aar'
,
'--verbose'
,
'--debug'
],
);
});
checkFileExists
(
path
.
join
(
repoPath
,
'io'
,
'flutter'
,
'devicelab'
,
'hello'
,
'flutter_release'
,
'1.0'
,
'flutter_release-1.0.aar'
,
));
checkFileExists
(
path
.
join
(
repoPath
,
'io'
,
'flutter'
,
'devicelab'
,
'hello'
,
'flutter_debug'
,
'1.0'
,
'flutter_debug-1.0.pom'
,
));
checkFileExists
(
path
.
join
(
repoPath
,
'io'
,
'flutter'
,
'plugins'
,
'deviceinfo'
,
'device_info_debug'
,
'1.0'
,
'device_info_debug-1.0.aar'
,
));
checkFileExists
(
path
.
join
(
repoPath
,
'io'
,
'flutter'
,
'plugins'
,
'deviceinfo'
,
'device_info_debug'
,
'1.0'
,
'device_info_debug-1.0.pom'
,
));
checkFileExists
(
path
.
join
(
repoPath
,
'io'
,
'flutter'
,
'plugins'
,
'packageinfo'
,
'package_info_debug'
,
'1.0'
,
'package_info_debug-1.0.aar'
,
));
checkFileExists
(
path
.
join
(
repoPath
,
'io'
,
'flutter'
,
'plugins'
,
'packageinfo'
,
'package_info_debug'
,
'1.0'
,
'package_info_debug-1.0.pom'
,
));
return
TaskResult
.
success
(
null
);
}
catch
(
e
)
{
return
TaskResult
.
failure
(
e
.
toString
());
}
finally
{
rmTree
(
tempDir
);
}
});
}
dev/devicelab/bin/tasks/build_aar_plugin_test.dart
deleted
100644 → 0
View file @
11460b83
// Copyright (c) 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.
import
'dart:async'
;
import
'dart:io'
;
import
'package:flutter_devicelab/framework/framework.dart'
;
import
'package:flutter_devicelab/framework/utils.dart'
;
import
'package:path/path.dart'
as
path
;
final
String
gradlew
=
Platform
.
isWindows
?
'gradlew.bat'
:
'gradlew'
;
final
String
gradlewExecutable
=
Platform
.
isWindows
?
gradlew
:
'./
$gradlew
'
;
/// Tests that AARs can be built on plugin projects.
Future
<
void
>
main
()
async
{
await
task
(()
async
{
section
(
'Find Java'
);
final
String
javaHome
=
await
findJavaHome
();
if
(
javaHome
==
null
)
return
TaskResult
.
failure
(
'Could not find Java'
);
print
(
'
\n
Using JAVA_HOME=
$javaHome
'
);
section
(
'Create plugin project'
);
final
Directory
tempDir
=
Directory
.
systemTemp
.
createTempSync
(
'flutter_module_test.'
);
final
Directory
projectDir
=
Directory
(
path
.
join
(
tempDir
.
path
,
'hello'
));
try
{
await
inDirectory
(
tempDir
,
()
async
{
await
flutter
(
'create'
,
options:
<
String
>[
'--org'
,
'io.flutter.devicelab'
,
'--template'
,
'plugin'
,
'hello'
,
],
);
});
section
(
'Build release AAR'
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'aar'
,
'--verbose'
],
);
});
final
String
repoPath
=
path
.
join
(
projectDir
.
path
,
'build'
,
'outputs'
,
'repo'
,
);
final
File
releaseAar
=
File
(
path
.
join
(
repoPath
,
'io'
,
'flutter'
,
'devicelab'
,
'hello'
,
'hello_release'
,
'1.0'
,
'hello_release-1.0.aar'
,
));
if
(!
exists
(
releaseAar
))
{
return
TaskResult
.
failure
(
'Failed to build the release AAR file.'
);
}
final
File
releasePom
=
File
(
path
.
join
(
repoPath
,
'io'
,
'flutter'
,
'devicelab'
,
'hello'
,
'hello_release'
,
'1.0'
,
'hello_release-1.0.pom'
,
));
if
(!
exists
(
releasePom
))
{
return
TaskResult
.
failure
(
'Failed to build the release POM file.'
);
}
section
(
'Build debug AAR'
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'aar'
,
'--verbose'
,
'--debug'
,
],
);
});
final
File
debugAar
=
File
(
path
.
join
(
repoPath
,
'io'
,
'flutter'
,
'devicelab'
,
'hello'
,
'hello_debug'
,
'1.0'
,
'hello_debug-1.0.aar'
,
));
if
(!
exists
(
debugAar
))
{
return
TaskResult
.
failure
(
'Failed to build the debug AAR file.'
);
}
final
File
debugPom
=
File
(
path
.
join
(
repoPath
,
'io'
,
'flutter'
,
'devicelab'
,
'hello'
,
'hello_debug'
,
'1.0'
,
'hello_debug-1.0.pom'
,
));
if
(!
exists
(
debugPom
))
{
return
TaskResult
.
failure
(
'Failed to build the debug POM file.'
);
}
return
TaskResult
.
success
(
null
);
}
catch
(
e
)
{
return
TaskResult
.
failure
(
e
.
toString
());
}
finally
{
rmTree
(
tempDir
);
}
});
}
dev/devicelab/bin/tasks/gradle_jetifier_test.dart
deleted
100644 → 0
View file @
11460b83
// Copyright (c) 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.
import
'dart:async'
;
import
'dart:io'
;
import
'package:flutter_devicelab/framework/apk_utils.dart'
;
import
'package:flutter_devicelab/framework/framework.dart'
;
import
'package:flutter_devicelab/framework/utils.dart'
;
import
'package:path/path.dart'
as
path
;
final
String
gradlew
=
Platform
.
isWindows
?
'gradlew.bat'
:
'gradlew'
;
final
String
gradlewExecutable
=
Platform
.
isWindows
?
gradlew
:
'./
$gradlew
'
;
/// Tests that Jetifier can translate plugins that use support libraries.
Future
<
void
>
main
()
async
{
await
task
(()
async
{
section
(
'Find Java'
);
final
String
javaHome
=
await
findJavaHome
();
if
(
javaHome
==
null
)
return
TaskResult
.
failure
(
'Could not find Java'
);
print
(
'
\n
Using JAVA_HOME=
$javaHome
'
);
section
(
'Create Flutter AndroidX app project'
);
final
Directory
tempDir
=
Directory
.
systemTemp
.
createTempSync
(
'flutter_module_test.'
);
final
Directory
projectDir
=
Directory
(
path
.
join
(
tempDir
.
path
,
'hello'
));
try
{
await
inDirectory
(
tempDir
,
()
async
{
await
flutter
(
'create'
,
options:
<
String
>[
'--org'
,
'io.flutter.devicelab'
,
'--androidx'
,
'hello'
,
],
);
});
section
(
'Add plugin that uses support libraries'
);
final
File
pubspec
=
File
(
path
.
join
(
projectDir
.
path
,
'pubspec.yaml'
));
String
content
=
pubspec
.
readAsStringSync
();
content
=
content
.
replaceFirst
(
'
\n
dependencies:
\n
'
,
'
\n
dependencies:
\n
firebase_auth: 0.7.0
\n
'
,
);
pubspec
.
writeAsStringSync
(
content
,
flush:
true
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'packages'
,
options:
<
String
>[
'get'
],
);
});
section
(
'Build release APK'
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'apk'
,
'--target-platform'
,
'android-arm'
,
'--verbose'
,
],
);
});
final
File
releaseApk
=
File
(
path
.
join
(
projectDir
.
path
,
'build'
,
'app'
,
'outputs'
,
'apk'
,
'release'
,
'app-release.apk'
,
));
if
(!
exists
(
releaseApk
))
{
return
TaskResult
.
failure
(
'Failed to build release APK.'
);
}
checkApkContainsClasses
(
releaseApk
,
<
String
>[
// The plugin class defined by `firebase_auth`.
'io.flutter.plugins.firebaseauth.FirebaseAuthPlugin'
,
// Used by `firebase_auth`.
'com.google.firebase.FirebaseApp'
,
// Base class for activities that enables composition of higher level components.
'androidx.core.app.ComponentActivity'
,
]);
section
(
'Build debug APK'
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'apk'
,
'--target-platform'
,
'android-arm'
,
'--debug'
,
'--verbose'
,
],
);
});
final
File
debugApk
=
File
(
path
.
join
(
projectDir
.
path
,
'build'
,
'app'
,
'outputs'
,
'apk'
,
'debug'
,
'app-debug.apk'
,
));
if
(!
exists
(
debugApk
))
{
return
TaskResult
.
failure
(
'Failed to build debug APK.'
);
}
checkApkContainsClasses
(
debugApk
,
<
String
>[
// The plugin class defined by `firebase_auth`.
'io.flutter.plugins.firebaseauth.FirebaseAuthPlugin'
,
// Used by `firebase_auth`.
'com.google.firebase.FirebaseApp'
,
// Base class for activities that enables composition of higher level components.
'androidx.core.app.ComponentActivity'
,
]);
return
TaskResult
.
success
(
null
);
}
catch
(
e
)
{
return
TaskResult
.
failure
(
e
.
toString
());
}
finally
{
rmTree
(
tempDir
);
}
});
}
dev/devicelab/bin/tasks/gradle_migrate_settings_test.dart
deleted
100644 → 0
View file @
11460b83
// Copyright (c) 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.
import
'dart:async'
;
import
'dart:io'
;
import
'package:flutter_devicelab/framework/framework.dart'
;
import
'package:flutter_devicelab/framework/utils.dart'
;
import
'package:path/path.dart'
as
path
;
final
String
gradlew
=
Platform
.
isWindows
?
'gradlew.bat'
:
'gradlew'
;
final
String
gradlewExecutable
=
Platform
.
isWindows
?
gradlew
:
'./
$gradlew
'
;
/// Tests that [settings_aar.gradle] is created when possible.
Future
<
void
>
main
()
async
{
await
task
(()
async
{
section
(
'Find Java'
);
final
String
javaHome
=
await
findJavaHome
();
if
(
javaHome
==
null
)
return
TaskResult
.
failure
(
'Could not find Java'
);
print
(
'
\n
Using JAVA_HOME=
$javaHome
'
);
section
(
'Create app project'
);
final
Directory
tempDir
=
Directory
.
systemTemp
.
createTempSync
(
'flutter_module_test.'
);
final
Directory
projectDir
=
Directory
(
path
.
join
(
tempDir
.
path
,
'hello'
));
try
{
await
inDirectory
(
tempDir
,
()
async
{
await
flutter
(
'create'
,
options:
<
String
>[
'hello'
],
);
});
section
(
'Override settings.gradle V1'
);
final
String
relativeNewSettingsGradle
=
path
.
join
(
'android'
,
'settings_aar.gradle'
);
section
(
'Build APK'
);
String
stdout
;
await
inDirectory
(
projectDir
,
()
async
{
stdout
=
await
evalFlutter
(
'build'
,
options:
<
String
>[
'apk'
,
'--flavor'
,
'does-not-exist'
,
],
canFail:
true
,
// The flavor doesn't exist.
);
});
const
String
newFileContent
=
'include
\'
:app
\'
'
;
final
File
settingsGradle
=
File
(
path
.
join
(
projectDir
.
path
,
'android'
,
'settings.gradle'
));
final
File
newSettingsGradle
=
File
(
path
.
join
(
projectDir
.
path
,
'android'
,
'settings_aar.gradle'
));
if
(!
newSettingsGradle
.
existsSync
())
{
return
TaskResult
.
failure
(
'Expected file: `
${newSettingsGradle.path}
`.'
);
}
if
(
newSettingsGradle
.
readAsStringSync
().
trim
()
!=
newFileContent
)
{
return
TaskResult
.
failure
(
'Expected to create `
${newSettingsGradle.path}
` V1.'
);
}
if
(!
stdout
.
contains
(
'Creating `
$relativeNewSettingsGradle
`'
)
||
!
stdout
.
contains
(
'`
$relativeNewSettingsGradle
` created successfully'
))
{
return
TaskResult
.
failure
(
'Expected update message in stdout.'
);
}
section
(
'Override settings.gradle V2'
);
const
String
deprecatedFileContentV2
=
'''
include '
:
app
'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '
.
flutter
-
plugins
')
if (pluginsFile.exists()) {
pluginsFile.withInputStream { stream -> plugins.load(stream) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('
android
').toFile()
include ":
\
$name
"
project(":
\
$name
").projectDir = pluginDirectory
}
'''
;
settingsGradle
.
writeAsStringSync
(
deprecatedFileContentV2
,
flush:
true
);
newSettingsGradle
.
deleteSync
();
section
(
'Build APK'
);
await
inDirectory
(
projectDir
,
()
async
{
stdout
=
await
evalFlutter
(
'build'
,
options:
<
String
>[
'apk'
,
'--flavor'
,
'does-not-exist'
,
],
canFail:
true
,
// The flavor doesn't exist.
);
});
if
(
newSettingsGradle
.
readAsStringSync
().
trim
()
!=
newFileContent
)
{
return
TaskResult
.
failure
(
'Expected to create `
${newSettingsGradle.path}
` V2.'
);
}
if
(!
stdout
.
contains
(
'Creating `
$relativeNewSettingsGradle
`'
)
||
!
stdout
.
contains
(
'`
$relativeNewSettingsGradle
` created successfully'
))
{
return
TaskResult
.
failure
(
'Expected update message in stdout.'
);
}
section
(
'Override settings.gradle with custom logic'
);
const
String
customDeprecatedFileContent
=
'''
include '
:
app
'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '
.
flutter
-
plugins
')
if (pluginsFile.exists()) {
pluginsFile.withInputStream { stream -> plugins.load(stream) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('
android
').toFile()
include ":
\
$name
"
project(":
\
$name
").projectDir = pluginDirectory
}
// some custom logic
'''
;
settingsGradle
.
writeAsStringSync
(
customDeprecatedFileContent
,
flush:
true
);
newSettingsGradle
.
deleteSync
();
section
(
'Build APK'
);
final
StringBuffer
stderr
=
StringBuffer
();
await
inDirectory
(
projectDir
,
()
async
{
stdout
=
await
evalFlutter
(
'build'
,
options:
<
String
>[
'apk'
,
'--flavor'
,
'does-not-exist'
,
],
canFail:
true
,
// The flavor doesn't exist.
stderr:
stderr
,
);
});
if
(
newSettingsGradle
.
existsSync
())
{
return
TaskResult
.
failure
(
'Unexpected file: `
${newSettingsGradle.path}
`.'
);
}
if
(!
stdout
.
contains
(
'Creating `
$relativeNewSettingsGradle
`'
))
{
return
TaskResult
.
failure
(
'Expected update message in stdout.'
);
}
if
(
stdout
.
contains
(
'`
$relativeNewSettingsGradle
` created successfully'
))
{
return
TaskResult
.
failure
(
'Unexpected message in stdout.'
);
}
if
(!
stderr
.
toString
().
contains
(
'Flutter tried to create the file '
'`
$relativeNewSettingsGradle
`, but failed.'
))
{
return
TaskResult
.
failure
(
'Expected failure message in stdout.'
);
}
return
TaskResult
.
success
(
null
);
}
catch
(
e
)
{
return
TaskResult
.
failure
(
e
.
toString
());
}
finally
{
rmTree
(
tempDir
);
}
});
}
dev/devicelab/bin/tasks/gradle_plugin_dependencies_test.dart
deleted
100644 → 0
View file @
11460b83
// Copyright (c) 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.
import
'dart:async'
;
import
'dart:io'
;
import
'package:flutter_devicelab/framework/apk_utils.dart'
;
import
'package:flutter_devicelab/framework/framework.dart'
;
import
'package:flutter_devicelab/framework/utils.dart'
;
import
'package:path/path.dart'
as
path
;
final
String
gradlew
=
Platform
.
isWindows
?
'gradlew.bat'
:
'gradlew'
;
final
String
gradlewExecutable
=
Platform
.
isWindows
?
gradlew
:
'./
$gradlew
'
;
/// Tests that projects can include plugins that have a transtive dependency in common.
/// For more info see: https://github.com/flutter/flutter/issues/27254.
Future
<
void
>
main
()
async
{
await
task
(()
async
{
section
(
'Find Java'
);
final
String
javaHome
=
await
findJavaHome
();
if
(
javaHome
==
null
)
return
TaskResult
.
failure
(
'Could not find Java'
);
print
(
'
\n
Using JAVA_HOME=
$javaHome
'
);
section
(
'Create Flutter AndroidX app project'
);
final
Directory
tempDir
=
Directory
.
systemTemp
.
createTempSync
(
'flutter_module_test.'
);
final
Directory
projectDir
=
Directory
(
path
.
join
(
tempDir
.
path
,
'hello'
));
try
{
await
inDirectory
(
tempDir
,
()
async
{
await
flutter
(
'create'
,
options:
<
String
>[
'--org'
,
'io.flutter.devicelab'
,
'--androidx'
,
'hello'
,
],
);
});
section
(
'Add plugin that have conflicting dependencies'
);
final
File
pubspec
=
File
(
path
.
join
(
projectDir
.
path
,
'pubspec.yaml'
));
String
content
=
pubspec
.
readAsStringSync
();
// `flutter_local_notifications` uses `androidx.core:core:1.0.1`
// `firebase_core` and `firebase_messaging` use `androidx.core:core:1.0.0`.
content
=
content
.
replaceFirst
(
'
\n
dependencies:
\n
'
,
'
\n
dependencies:
\n
flutter_local_notifications: 0.7.1+3
\n
firebase_core:
\n
firebase_messaging:
\n
'
,
);
pubspec
.
writeAsStringSync
(
content
,
flush:
true
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'packages'
,
options:
<
String
>[
'get'
],
);
});
section
(
'Build release APK'
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'apk'
,
'--target-platform'
,
'android-arm'
,
'--verbose'
,
],
);
});
final
File
releaseApk
=
File
(
path
.
join
(
projectDir
.
path
,
'build'
,
'app'
,
'outputs'
,
'apk'
,
'release'
,
'app-release.apk'
,
));
if
(!
exists
(
releaseApk
))
{
return
TaskResult
.
failure
(
'Failed to build release APK.'
);
}
checkApkContainsClasses
(
releaseApk
,
<
String
>[
// Used by `flutter_local_notifications`.
'com.google.gson.Gson'
,
// Used by `firebase_core` and `firebase_messaging`.
'com.google.firebase.FirebaseApp'
,
// Used by `firebase_core`.
'com.google.firebase.FirebaseOptions'
,
// Used by `firebase_messaging`.
'com.google.firebase.messaging.FirebaseMessaging'
,
]);
section
(
'Build debug APK'
);
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'build'
,
options:
<
String
>[
'apk'
,
'--target-platform'
,
'android-arm'
,
'--debug'
,
'--verbose'
,
],
);
});
final
File
debugApk
=
File
(
path
.
join
(
projectDir
.
path
,
'build'
,
'app'
,
'outputs'
,
'apk'
,
'debug'
,
'app-debug.apk'
,
));
if
(!
exists
(
debugApk
))
{
return
TaskResult
.
failure
(
'Failed to build debug APK.'
);
}
checkApkContainsClasses
(
debugApk
,
<
String
>[
// Used by `flutter_local_notifications`.
'com.google.gson.Gson'
,
// Used by `firebase_core` and `firebase_messaging`.
'com.google.firebase.FirebaseApp'
,
// Used by `firebase_core`.
'com.google.firebase.FirebaseOptions'
,
// Used by `firebase_messaging`.
'com.google.firebase.messaging.FirebaseMessaging'
,
]);
return
TaskResult
.
success
(
null
);
}
catch
(
e
)
{
return
TaskResult
.
failure
(
e
.
toString
());
}
finally
{
rmTree
(
tempDir
);
}
});
}
dev/devicelab/bin/tasks/module_test.dart
View file @
c9b466f9
...
@@ -42,7 +42,7 @@ Future<void> main() async {
...
@@ -42,7 +42,7 @@ Future<void> main() async {
String
content
=
await
pubspec
.
readAsString
();
String
content
=
await
pubspec
.
readAsString
();
content
=
content
.
replaceFirst
(
content
=
content
.
replaceFirst
(
'
\n
dependencies:
\n
'
,
'
\n
dependencies:
\n
'
,
'
\n
dependencies:
\n
device_info
:
\n
package_info:
\n
'
,
'
\n
dependencies:
\n
battery
:
\n
package_info:
\n
'
,
);
);
await
pubspec
.
writeAsString
(
content
,
flush:
true
);
await
pubspec
.
writeAsString
(
content
,
flush:
true
);
await
inDirectory
(
projectDir
,
()
async
{
await
inDirectory
(
projectDir
,
()
async
{
...
...
dev/devicelab/bin/tasks/module_test_ios.dart
View file @
c9b466f9
...
@@ -143,7 +143,7 @@ Future<void> main() async {
...
@@ -143,7 +143,7 @@ Future<void> main() async {
String
content
=
await
pubspec
.
readAsString
();
String
content
=
await
pubspec
.
readAsString
();
content
=
content
.
replaceFirst
(
content
=
content
.
replaceFirst
(
'
\n
dependencies:
\n
'
,
'
\n
dependencies:
\n
'
,
'
\n
dependencies:
\n
device_info
:
\n
package_info:
\n
'
,
'
\n
dependencies:
\n
battery
:
\n
package_info:
\n
'
,
);
);
await
pubspec
.
writeAsString
(
content
,
flush:
true
);
await
pubspec
.
writeAsString
(
content
,
flush:
true
);
await
inDirectory
(
projectDir
,
()
async
{
await
inDirectory
(
projectDir
,
()
async
{
...
...
dev/devicelab/lib/framework/apk_utils.dart
View file @
c9b466f9
...
@@ -83,93 +83,6 @@ bool hasMultipleOccurrences(String text, Pattern pattern) {
...
@@ -83,93 +83,6 @@ bool hasMultipleOccurrences(String text, Pattern pattern) {
return
text
.
indexOf
(
pattern
)
!=
text
.
lastIndexOf
(
pattern
);
return
text
.
indexOf
(
pattern
)
!=
text
.
lastIndexOf
(
pattern
);
}
}
/// Utility class to analyze the content inside an APK using dexdump,
/// which is provided by the Android SDK.
/// https://android.googlesource.com/platform/art/+/master/dexdump/dexdump.cc
class
ApkExtractor
{
ApkExtractor
(
this
.
apkFile
);
/// The APK.
final
File
apkFile
;
bool
_extracted
=
false
;
Directory
_outputDir
;
Future
<
void
>
_extractApk
()
async
{
if
(
_extracted
)
{
return
;
}
_outputDir
=
apkFile
.
parent
.
createTempSync
(
'apk'
);
if
(
Platform
.
isWindows
)
{
await
eval
(
'7za'
,
<
String
>[
'x'
,
apkFile
.
path
],
workingDirectory:
_outputDir
.
path
);
}
else
{
await
eval
(
'unzip'
,
<
String
>[
apkFile
.
path
],
workingDirectory:
_outputDir
.
path
);
}
_extracted
=
true
;
}
/// Returns the full path to the [dexdump] tool.
Future
<
String
>
_findDexDump
()
async
{
final
String
androidHome
=
Platform
.
environment
[
'ANDROID_HOME'
]
??
Platform
.
environment
[
'ANDROID_SDK_ROOT'
];
if
(
androidHome
==
null
||
androidHome
.
isEmpty
)
{
throw
Exception
(
'Unset env flag: `ANDROID_HOME` or `ANDROID_SDK_ROOT`.'
);
}
String
dexdumps
;
if
(
Platform
.
isWindows
)
{
dexdumps
=
await
eval
(
'dir'
,
<
String
>[
'/s/b'
,
'dexdump.exe'
],
workingDirectory:
androidHome
);
}
else
{
dexdumps
=
await
eval
(
'find'
,
<
String
>[
androidHome
,
'-name'
,
'dexdump'
]);
}
if
(
dexdumps
.
isEmpty
)
{
throw
Exception
(
'Couldn
\'
t find a dexdump executable.'
);
}
return
dexdumps
.
split
(
'
\n
'
).
first
;
}
// Removes any temporary directory.
void
dispose
()
{
if
(!
_extracted
)
{
return
;
}
rmTree
(
_outputDir
);
_extracted
=
true
;
}
/// Returns true if the APK contains a given class.
Future
<
bool
>
containsClass
(
String
className
)
async
{
await
_extractApk
();
final
String
dexDump
=
await
_findDexDump
();
final
String
classesDex
=
path
.
join
(
_outputDir
.
path
,
'classes.dex'
);
if
(!
File
(
classesDex
).
existsSync
())
{
throw
Exception
(
'Couldn
\'
t find classes.dex in the APK.'
);
}
final
String
classDescriptors
=
await
eval
(
dexDump
,
<
String
>[
classesDex
],
printStdout:
false
);
if
(
classDescriptors
.
isEmpty
)
{
throw
Exception
(
'No descriptors found in classes.dex.'
);
}
return
classDescriptors
.
contains
(
className
.
replaceAll
(
'.'
,
'/'
));
}
}
/// Checks that the classes are contained in the APK, throws otherwise.
Future
<
void
>
checkApkContainsClasses
(
File
apk
,
List
<
String
>
classes
)
async
{
final
ApkExtractor
extractor
=
ApkExtractor
(
apk
);
for
(
String
className
in
classes
)
{
if
(!(
await
extractor
.
containsClass
(
className
)))
{
throw
Exception
(
'APK doesn
\'
t contain class `
$className
`.'
);
}
}
extractor
.
dispose
();
}
class
FlutterProject
{
class
FlutterProject
{
FlutterProject
(
this
.
parent
,
this
.
name
);
FlutterProject
(
this
.
parent
,
this
.
name
);
...
...
dev/devicelab/lib/framework/utils.dart
View file @
c9b466f9
...
@@ -303,7 +303,7 @@ Future<int> exec(
...
@@ -303,7 +303,7 @@ Future<int> exec(
/// Executes a command and returns its standard output as a String.
/// Executes a command and returns its standard output as a String.
///
///
/// For logging purposes, the command's output is also printed out
by default
.
/// For logging purposes, the command's output is also printed out.
Future
<
String
>
eval
(
Future
<
String
>
eval
(
String
executable
,
String
executable
,
List
<
String
>
arguments
,
{
List
<
String
>
arguments
,
{
...
@@ -311,8 +311,6 @@ Future<String> eval(
...
@@ -311,8 +311,6 @@ Future<String> eval(
bool
canFail
=
false
,
// as in, whether failures are ok. False means that they are fatal.
bool
canFail
=
false
,
// as in, whether failures are ok. False means that they are fatal.
String
workingDirectory
,
String
workingDirectory
,
StringBuffer
stderr
,
// if not null, the stderr will be written here
StringBuffer
stderr
,
// if not null, the stderr will be written here
bool
printStdout
=
true
,
bool
printStderr
=
true
,
})
async
{
})
async
{
final
Process
process
=
await
startProcess
(
executable
,
arguments
,
environment:
environment
,
workingDirectory:
workingDirectory
);
final
Process
process
=
await
startProcess
(
executable
,
arguments
,
environment:
environment
,
workingDirectory:
workingDirectory
);
...
@@ -323,18 +321,14 @@ Future<String> eval(
...
@@ -323,18 +321,14 @@ Future<String> eval(
.
transform
<
String
>(
utf8
.
decoder
)
.
transform
<
String
>(
utf8
.
decoder
)
.
transform
<
String
>(
const
LineSplitter
())
.
transform
<
String
>(
const
LineSplitter
())
.
listen
((
String
line
)
{
.
listen
((
String
line
)
{
if
(
printStdout
)
{
print
(
'stdout:
$line
'
);
print
(
'stdout:
$line
'
);
}
output
.
writeln
(
line
);
output
.
writeln
(
line
);
},
onDone:
()
{
stdoutDone
.
complete
();
});
},
onDone:
()
{
stdoutDone
.
complete
();
});
process
.
stderr
process
.
stderr
.
transform
<
String
>(
utf8
.
decoder
)
.
transform
<
String
>(
utf8
.
decoder
)
.
transform
<
String
>(
const
LineSplitter
())
.
transform
<
String
>(
const
LineSplitter
())
.
listen
((
String
line
)
{
.
listen
((
String
line
)
{
if
(
printStderr
)
{
print
(
'stderr:
$line
'
);
print
(
'stderr:
$line
'
);
}
stderr
?.
writeln
(
line
);
stderr
?.
writeln
(
line
);
},
onDone:
()
{
stderrDone
.
complete
();
});
},
onDone:
()
{
stderrDone
.
complete
();
});
...
@@ -625,10 +619,3 @@ void setLocalEngineOptionIfNecessary(List<String> options, [String flavor]) {
...
@@ -625,10 +619,3 @@ void setLocalEngineOptionIfNecessary(List<String> options, [String flavor]) {
options
.
add
(
'--local-engine=
${osNames[deviceOperatingSystem]}
_
$flavor
'
);
options
.
add
(
'--local-engine=
${osNames[deviceOperatingSystem]}
_
$flavor
'
);
}
}
}
}
/// Checks that the file exists, otherwise throws a [FileSystemException].
void
checkFileExists
(
String
file
)
{
if
(!
exists
(
File
(
file
)))
{
throw
FileSystemException
(
'Expected file to exit.'
,
file
);
}
}
packages/flutter_tools/gradle/aar_init_script.gradle
deleted
100644 → 0
View file @
11460b83
// 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 initialize the build in a module or plugin project.
// During this phase, the script applies the Maven plugin and configures the
// destination of the local repository.
// The local repository will contain the AAR and POM files.
import
org.gradle.api.Project
import
org.gradle.api.artifacts.Configuration
import
org.gradle.api.artifacts.maven.MavenDeployer
import
org.gradle.api.plugins.MavenPlugin
import
org.gradle.api.tasks.Upload
void
configureProject
(
Project
project
,
File
outputDir
)
{
if
(!
project
.
hasProperty
(
"android"
))
{
throw
new
GradleException
(
"Android property not found."
)
}
if
(!
project
.
android
.
hasProperty
(
"libraryVariants"
))
{
throw
new
GradleException
(
"Can't generate AAR on a non Android library project."
);
}
project
.
apply
plugin:
"maven"
project
.
android
.
libraryVariants
.
all
{
variant
->
addAarTask
(
project
,
variant
)
}
// Snapshot versions include the timestamp in the artifact name.
// Therefore, remove the snapshot part, so new runs of `flutter build aar` overrides existing artifacts.
// This version isn't relevant in Flutter since the pub version is used
// to resolve dependencies.
project
.
version
=
project
.
version
.
replace
(
"-SNAPSHOT"
,
""
)
project
.
uploadArchives
{
repositories
{
mavenDeployer
{
repository
(
url:
"file://${outputDir}/outputs/repo"
)
}
}
}
// Check if the project uses the Flutter plugin (defined in flutter.gradle).
Boolean
usesFlutterPlugin
=
project
.
plugins
.
find
{
it
.
class
.
name
==
"FlutterPlugin"
}
!=
null
if
(!
usesFlutterPlugin
)
{
// Plugins don't include their dependencies under the assumption that the parent project adds them.
if
(
project
.
properties
[
'android.useAndroidX'
])
{
project
.
dependencies
{
compileOnly
"androidx.annotation:annotation:+"
}
}
else
{
project
.
dependencies
{
compileOnly
"com.android.support:support-annotations:+"
}
}
project
.
dependencies
{
// The Flutter plugin already adds `flutter.jar`.
compileOnly
project
.
files
(
"${getFlutterRoot(project)}/bin/cache/artifacts/engine/android-arm-release/flutter.jar"
)
}
}
}
String
getFlutterRoot
(
Project
project
)
{
if
(!
project
.
hasProperty
(
"flutter-root"
))
{
throw
new
GradleException
(
"The `-Pflutter-root` flag must be specified."
)
}
return
project
.
property
(
"flutter-root"
)
}
void
addAarTask
(
Project
project
,
variant
)
{
String
variantName
=
variant
.
name
.
capitalize
()
String
taskName
=
"assembleAar${variantName}"
project
.
tasks
.
create
(
name:
taskName
)
{
// This check is required to be able to configure the archives before `uploadArchives` runs.
if
(!
project
.
gradle
.
startParameter
.
taskNames
.
contains
(
taskName
))
{
return
}
// NOTE(blasten): `android.defaultPublishConfig` must equal the variant name to build.
// Where variant name is `<product-flavor><Build-Type>`. However, it's too late to configure
// `defaultPublishConfig` at this point. Therefore, the code below ensures that the
// default build config uses the artifacts produced for the specific build variant.
Task
bundle
=
project
.
tasks
.
findByName
(
"bundle${variantName}Aar"
)
// gradle:3.2.0
if
(
bundle
==
null
)
{
bundle
=
project
.
tasks
.
findByName
(
"bundle${variantName}"
)
// gradle:3.1.0
}
if
(
bundle
==
null
)
{
throw
new
GradleException
(
"Can't generate AAR for variant ${variantName}."
);
}
project
.
uploadArchives
.
repositories
.
mavenDeployer
{
pom
{
artifactId
=
"${project.name}_${variant.name.toLowerCase()}"
}
}
// Clear the current archives since the current one is assigned based on
// `android.defaultPublishConfig` which defaults to `release`.
project
.
configurations
[
"archives"
].
artifacts
.
clear
()
// Add the artifact that will be published.
project
.
artifacts
.
add
(
"archives"
,
bundle
)
// Generate the Maven artifacts.
finalizedBy
"uploadArchives"
}
}
projectsEvaluated
{
if
(
rootProject
.
property
(
"is-plugin"
).
toBoolean
())
{
if
(
rootProject
.
hasProperty
(
"output-dir"
))
{
rootProject
.
buildDir
=
rootProject
.
property
(
"output-dir"
)
}
else
{
rootProject
.
buildDir
=
"../build"
;
}
// In plugin projects, the Android library is the root project.
configureProject
(
rootProject
,
rootProject
.
buildDir
)
return
}
// In module projects, the Android library project is the `:flutter` subproject.
Project
androidLibrarySubproject
=
rootProject
.
subprojects
.
find
{
it
.
name
==
"flutter"
}
// In module projects, the `buildDir` is defined in the `:app` subproject.
Project
appSubproject
=
rootProject
.
subprojects
.
find
{
it
.
name
==
"app"
}
assert
appSubproject
!=
null
assert
androidLibrarySubproject
!=
null
if
(
appSubproject
.
hasProperty
(
"output-dir"
))
{
appSubproject
.
buildDir
=
appSubproject
.
property
(
"output-dir"
)
}
else
{
appSubproject
.
buildDir
=
"../build/host"
}
configureProject
(
androidLibrarySubproject
,
appSubproject
.
buildDir
)
}
packages/flutter_tools/gradle/deprecated_settings.gradle
deleted
100644 → 0
View file @
11460b83
include
':app'
def
flutterProjectRoot
=
rootProject
.
projectDir
.
parentFile
.
toPath
()
def
plugins
=
new
Properties
()
def
pluginsFile
=
new
File
(
flutterProjectRoot
.
toFile
(),
'.flutter-plugins'
)
if
(
pluginsFile
.
exists
())
{
pluginsFile
.
withReader
(
'UTF-8'
)
{
reader
->
plugins
.
load
(
reader
)
}
}
plugins
.
each
{
name
,
path
->
def
pluginDirectory
=
flutterProjectRoot
.
resolve
(
path
).
resolve
(
'android'
).
toFile
()
include
":$name"
project
(
":$name"
).
projectDir
=
pluginDirectory
}
;
EOF
include
':app'
def
flutterProjectRoot
=
rootProject
.
projectDir
.
parentFile
.
toPath
()
def
plugins
=
new
Properties
()
def
pluginsFile
=
new
File
(
flutterProjectRoot
.
toFile
(),
'.flutter-plugins'
)
if
(
pluginsFile
.
exists
())
{
pluginsFile
.
withInputStream
{
stream
->
plugins
.
load
(
stream
)
}
}
plugins
.
each
{
name
,
path
->
def
pluginDirectory
=
flutterProjectRoot
.
resolve
(
path
).
resolve
(
'android'
).
toFile
()
include
":$name"
project
(
":$name"
).
projectDir
=
pluginDirectory
}
packages/flutter_tools/gradle/flutter.gradle
View file @
c9b466f9
// Copyright 2019 The Chromium Authors. All rights reserved.
import
java.nio.file.Path
// Use of this source code is governed by a BSD-style license that can be
import
java.nio.file.Paths
// found in the LICENSE file.
import
static
groovy
.
io
.
FileType
.
FILES
import
com.android.builder.model.AndroidProject
import
com.android.builder.model.AndroidProject
import
com.android.build.OutputFile
import
com.android.build.OutputFile
import
java.nio.file.Path
import
java.nio.file.Paths
import
org.apache.tools.ant.taskdefs.condition.Os
import
org.apache.tools.ant.taskdefs.condition.Os
import
org.gradle.api.DefaultTask
import
org.gradle.api.DefaultTask
import
org.gradle.api.GradleException
import
org.gradle.api.GradleException
...
@@ -96,7 +91,7 @@ class FlutterPlugin implements Plugin<Project> {
...
@@ -96,7 +91,7 @@ class FlutterPlugin implements Plugin<Project> {
@Override
@Override
void
apply
(
Project
project
)
{
void
apply
(
Project
project
)
{
project
.
extensions
.
create
(
"flutter"
,
FlutterExtension
)
project
.
extensions
.
create
(
"flutter"
,
FlutterExtension
)
project
.
afterEvaluate
this
.&
addFlutterTask
s
project
.
afterEvaluate
this
.&
addFlutterTask
// By default, assembling APKs generates fat APKs if multiple platforms are passed.
// By default, assembling APKs generates fat APKs if multiple platforms are passed.
// Configuring split per ABI allows to generate separate APKs for each abi.
// Configuring split per ABI allows to generate separate APKs for each abi.
...
@@ -208,116 +203,40 @@ class FlutterPlugin implements Plugin<Project> {
...
@@ -208,116 +203,40 @@ class FlutterPlugin implements Plugin<Project> {
})
})
}
}
}
}
}
/**
* Returns the directory where the plugins are built.
*/
private
File
getPluginBuildDir
(
Project
project
)
{
// 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"
)
}
return
project
.
buildDir
}
private
Properties
getPluginList
(
Project
project
)
{
File
pluginsFile
=
new
File
(
project
.
projectDir
.
parentFile
.
parentFile
,
'.flutter-plugins'
)
File
pluginsFile
=
new
File
(
project
.
projectDir
.
parentFile
.
parentFile
,
'.flutter-plugins'
)
return
readPropertiesIfExist
(
pluginsFile
)
Properties
plugins
=
readPropertiesIfExist
(
pluginsFile
)
}
plugins
.
each
{
name
,
_
->
private
void
addPluginTasks
(
Project
project
)
{
def
pluginProject
=
project
.
rootProject
.
findProject
(
":$name"
)
Properties
plugins
=
getPluginList
(
project
)
if
(
pluginProject
!=
null
)
{
project
.
android
.
buildTypes
.
each
{
buildType
->
project
.
dependencies
{
plugins
.
each
{
name
,
path
->
if
(
project
.
getConfigurations
().
findByName
(
"implementation"
))
{
String
buildModeValue
=
buildType
.
debuggable
?
"debug"
:
"release"
implementation
pluginProject
List
<
String
>
taskNameParts
=
[
"build"
,
"plugin"
,
buildModeValue
]
}
else
{
taskNameParts
.
addAll
(
name
.
split
(
"_"
))
compile
pluginProject
String
taskName
=
toCammelCase
(
taskNameParts
)
// Build types can be extended. For example, a build type can extend the `debug` mode.
// In such cases, prevent creating the same task.
if
(
project
.
tasks
.
findByName
(
taskName
)
==
null
)
{
project
.
tasks
.
create
(
name:
taskName
,
type:
FlutterPluginTask
)
{
flutterExecutable
this
.
flutterExecutable
buildMode
buildModeValue
verbose
isVerbose
(
project
)
pluginDir
project
.
file
(
path
)
sourceDir
project
.
file
(
project
.
flutter
.
source
)
intermediateDir
getPluginBuildDir
(
project
)
}
}
}
}
}
pluginProject
.
afterEvaluate
{
}
pluginProject
.
android
.
buildTypes
{
}
profile
{
initWith
debug
private
void
buildPlugins
(
Project
project
,
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.
if
(
project
.
ext
.
has
(
"hostProjects"
))
{
projects
.
addAll
(
project
.
ext
.
get
(
"hostProjects"
))
}
projects
.
each
{
hostProject
->
hostProject
.
repositories
{
maven
{
url
"${getPluginBuildDir(project)}/outputs/repo"
}
}
}
buildTypes
.
each
{
buildType
->
project
.
tasks
.
withType
(
FlutterPluginTask
).
all
{
pluginTask
->
String
buildMode
=
buildType
.
debuggable
?
"debug"
:
"release"
if
(
pluginTask
.
buildMode
!=
buildMode
)
{
return
}
pluginTask
.
execute
()
pluginTask
.
intermediateDir
.
eachFileRecurse
(
FILES
)
{
file
->
if
(
file
.
name
!=
"maven-metadata.xml"
)
{
return
}
}
def
mavenMetadata
=
new
XmlParser
().
parse
(
file
)
String
groupId
=
mavenMetadata
.
groupId
.
text
()
String
artifactId
=
mavenMetadata
.
artifactId
.
text
()
if
(!
artifactId
.
endsWith
(
buildMode
))
{
pluginProject
.
android
.
buildTypes
.
each
{
return
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
]
))
}
}
// Add the plugin dependency based on the Maven metadata.
addApiDependencies
(
project
,
buildType
.
name
,
"$groupId:$artifactId:+@aar"
,
{
transitive
=
true
})
}
}
}
}
/**
* 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
)
{
Set
buildTypes
=
[]
tasksToExecute
.
each
{
task
->
project
.
android
.
buildTypes
.
each
{
buildType
->
if
(
task
==
"androidDependencies"
||
task
.
endsWith
(
"dependencies"
))
{
// The tasks to query the dependencies includes all the build types.
buildTypes
.
add
(
buildType
)
}
else
if
(
task
.
endsWith
(
"assemble"
))
{
// The `assemble` task includes all the build types.
buildTypes
.
add
(
buildType
)
}
else
if
(
task
.
endsWith
(
buildType
.
name
.
capitalize
()))
{
buildTypes
.
add
(
buildType
)
}
}
}
else
{
project
.
logger
.
error
(
"Plugin project :$name not found. Please update settings.gradle."
)
}
}
}
}
return
buildTypes
}
private
static
String
toCammelCase
(
List
<
String
>
parts
)
{
if
(
parts
.
empty
)
{
return
""
}
return
"${parts[0]}${parts[1..-1].collect { it.capitalize() }.join('')}"
}
}
private
String
resolveProperty
(
Project
project
,
String
name
,
String
defaultValue
)
{
private
String
resolveProperty
(
Project
project
,
String
name
,
String
defaultValue
)
{
...
@@ -368,17 +287,6 @@ class FlutterPlugin implements Plugin<Project> {
...
@@ -368,17 +287,6 @@ class FlutterPlugin implements Plugin<Project> {
return
project
.
hasProperty
(
'localEngineOut'
)
return
project
.
hasProperty
(
'localEngineOut'
)
}
}
private
static
Boolean
isVerbose
(
Project
project
)
{
if
(
project
.
hasProperty
(
'verbose'
))
{
return
project
.
property
(
'verbose'
).
toBoolean
()
}
return
false
}
private
static
Boolean
buildPluginAsAar
()
{
return
System
.
getProperty
(
'build-plugins-as-aars'
)
==
'true'
}
/**
/**
* Returns the platform that is used to extract the `libflutter.so` and the .class files.
* Returns the platform that is used to extract the `libflutter.so` and the .class files.
*
*
...
@@ -396,24 +304,30 @@ class FlutterPlugin implements Plugin<Project> {
...
@@ -396,24 +304,30 @@ class FlutterPlugin implements Plugin<Project> {
if
(
project
.
state
.
failure
)
{
if
(
project
.
state
.
failure
)
{
return
return
}
}
String
configuration
;
if
(
project
.
getConfigurations
().
findByName
(
"compileOnly"
))
{
project
.
dependencies
{
configuration
=
"${variantName}CompileOnly"
;
String
configuration
;
}
else
{
if
(
project
.
getConfigurations
().
findByName
(
"compileOnly"
))
{
configuration
=
"${variantName}Provided"
;
configuration
=
"${variantName}CompileOnly"
;
}
else
{
configuration
=
"${variantName}Provided"
;
}
add
(
configuration
,
files
)
}
}
project
.
dependencies
.
add
(
configuration
,
files
)
}
}
private
static
void
addApiDependencies
(
Project
project
,
String
variantName
,
Object
dependency
,
Closure
config
=
null
)
{
private
static
void
addApiDependencies
(
Project
project
,
String
variantName
,
FileCollection
files
)
{
String
configuration
;
project
.
dependencies
{
// `compile` dependencies are now `api` dependencies.
String
configuration
;
if
(
project
.
getConfigurations
().
findByName
(
"api"
))
{
// `compile` dependencies are now `api` dependencies.
configuration
=
"${variantName}Api"
;
if
(
project
.
getConfigurations
().
findByName
(
"api"
))
{
}
else
{
configuration
=
"${variantName}Api"
;
configuration
=
"${variantName}Compile"
;
}
else
{
configuration
=
"${variantName}Compile"
;
}
add
(
configuration
,
files
)
}
}
project
.
dependencies
.
add
(
configuration
,
dependency
,
config
)
}
}
/**
/**
...
@@ -441,13 +355,14 @@ class FlutterPlugin implements Plugin<Project> {
...
@@ -441,13 +355,14 @@ class FlutterPlugin implements Plugin<Project> {
return
"${targetArch}-release"
return
"${targetArch}-release"
}
}
private
void
addFlutterTask
s
(
Project
project
)
{
private
void
addFlutterTask
(
Project
project
)
{
if
(
project
.
state
.
failure
)
{
if
(
project
.
state
.
failure
)
{
return
return
}
}
if
(
project
.
flutter
.
source
==
null
)
{
if
(
project
.
flutter
.
source
==
null
)
{
throw
new
GradleException
(
"Must provide Flutter source directory"
)
throw
new
GradleException
(
"Must provide Flutter source directory"
)
}
}
String
target
=
project
.
flutter
.
target
String
target
=
project
.
flutter
.
target
if
(
target
==
null
)
{
if
(
target
==
null
)
{
target
=
'lib/main.dart'
target
=
'lib/main.dart'
...
@@ -456,6 +371,10 @@ class FlutterPlugin implements Plugin<Project> {
...
@@ -456,6 +371,10 @@ class FlutterPlugin implements Plugin<Project> {
target
=
project
.
property
(
'target'
)
target
=
project
.
property
(
'target'
)
}
}
Boolean
verboseValue
=
null
if
(
project
.
hasProperty
(
'verbose'
))
{
verboseValue
=
project
.
property
(
'verbose'
).
toBoolean
()
}
String
[]
fileSystemRootsValue
=
null
String
[]
fileSystemRootsValue
=
null
if
(
project
.
hasProperty
(
'filesystem-roots'
))
{
if
(
project
.
hasProperty
(
'filesystem-roots'
))
{
fileSystemRootsValue
=
project
.
property
(
'filesystem-roots'
).
split
(
'\\|'
)
fileSystemRootsValue
=
project
.
property
(
'filesystem-roots'
).
split
(
'\\|'
)
...
@@ -521,9 +440,10 @@ class FlutterPlugin implements Plugin<Project> {
...
@@ -521,9 +440,10 @@ class FlutterPlugin implements Plugin<Project> {
}
}
}
}
def
compileTasks
=
targetPlatforms
.
collect
{
targetArch
->
def
flutterTasks
=
[]
targetPlatforms
.
each
{
targetArch
->
String
abiValue
=
PLATFORM_ARCH_MAP
[
targetArch
]
String
abiValue
=
PLATFORM_ARCH_MAP
[
targetArch
]
String
taskName
=
toCammelCase
([
"compile"
,
FLUTTER_BUILD_PREFIX
,
variant
.
name
,
targetArch
.
replace
(
'android-'
,
''
)])
String
taskName
=
"compile${FLUTTER_BUILD_PREFIX}${variant.name.capitalize()}${targetArch.replace('android-', '').capitalize()}"
FlutterTask
compileTask
=
project
.
tasks
.
create
(
name:
taskName
,
type:
FlutterTask
)
{
FlutterTask
compileTask
=
project
.
tasks
.
create
(
name:
taskName
,
type:
FlutterTask
)
{
flutterRoot
this
.
flutterRoot
flutterRoot
this
.
flutterRoot
flutterExecutable
this
.
flutterExecutable
flutterExecutable
this
.
flutterExecutable
...
@@ -532,7 +452,7 @@ class FlutterPlugin implements Plugin<Project> {
...
@@ -532,7 +452,7 @@ class FlutterPlugin implements Plugin<Project> {
localEngineSrcPath
this
.
localEngineSrcPath
localEngineSrcPath
this
.
localEngineSrcPath
abi
abiValue
abi
abiValue
targetPath
target
targetPath
target
verbose
isVerbose
(
project
)
verbose
verboseValue
fileSystemRoots
fileSystemRootsValue
fileSystemRoots
fileSystemRootsValue
fileSystemScheme
fileSystemSchemeValue
fileSystemScheme
fileSystemSchemeValue
trackWidgetCreation
trackWidgetCreationValue
trackWidgetCreation
trackWidgetCreationValue
...
@@ -546,8 +466,8 @@ class FlutterPlugin implements Plugin<Project> {
...
@@ -546,8 +466,8 @@ class FlutterPlugin implements Plugin<Project> {
extraFrontEndOptions
extraFrontEndOptionsValue
extraFrontEndOptions
extraFrontEndOptionsValue
extraGenSnapshotOptions
extraGenSnapshotOptionsValue
extraGenSnapshotOptions
extraGenSnapshotOptionsValue
}
}
flutterTasks
.
add
(
compileTask
)
}
}
def
libJar
=
project
.
file
(
"${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/libs.jar"
)
def
libJar
=
project
.
file
(
"${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}/libs.jar"
)
def
libFlutterPlatforms
=
targetPlatforms
.
collect
()
def
libFlutterPlatforms
=
targetPlatforms
.
collect
()
// x86/x86_64 native library used for debugging only, for now.
// x86/x86_64 native library used for debugging only, for now.
...
@@ -576,13 +496,13 @@ class FlutterPlugin implements Plugin<Project> {
...
@@ -576,13 +496,13 @@ class FlutterPlugin implements Plugin<Project> {
include
'lib/**'
include
'lib/**'
}
}
}
}
dependsOn
compile
Tasks
dependsOn
flutter
Tasks
// Add the ELF library.
// Add the ELF library.
compileTasks
.
each
{
compile
Task
->
flutterTasks
.
each
{
flutter
Task
->
from
(
compile
Task
.
intermediateDir
)
{
from
(
flutter
Task
.
intermediateDir
)
{
include
'*.so'
include
'*.so'
rename
{
String
filename
->
rename
{
String
filename
->
return
"lib/${
compile
Task.abi}/lib${filename}"
return
"lib/${
flutter
Task.abi}/lib${filename}"
}
}
}
}
}
}
...
@@ -596,7 +516,7 @@ class FlutterPlugin implements Plugin<Project> {
...
@@ -596,7 +516,7 @@ class FlutterPlugin implements Plugin<Project> {
Task
packageAssets
=
project
.
tasks
.
findByPath
(
":flutter:package${variant.name.capitalize()}Assets"
)
Task
packageAssets
=
project
.
tasks
.
findByPath
(
":flutter:package${variant.name.capitalize()}Assets"
)
Task
cleanPackageAssets
=
project
.
tasks
.
findByPath
(
":flutter:cleanPackage${variant.name.capitalize()}Assets"
)
Task
cleanPackageAssets
=
project
.
tasks
.
findByPath
(
":flutter:cleanPackage${variant.name.capitalize()}Assets"
)
Task
copyFlutterAssetsTask
=
project
.
tasks
.
create
(
name:
"copyFlutterAssets${variant.name.capitalize()}"
,
type:
Copy
)
{
Task
copyFlutterAssetsTask
=
project
.
tasks
.
create
(
name:
"copyFlutterAssets${variant.name.capitalize()}"
,
type:
Copy
)
{
dependsOn
compile
Tasks
dependsOn
flutter
Tasks
if
(
packageAssets
&&
cleanPackageAssets
)
{
if
(
packageAssets
&&
cleanPackageAssets
)
{
dependsOn
packageAssets
dependsOn
packageAssets
dependsOn
cleanPackageAssets
dependsOn
cleanPackageAssets
...
@@ -607,7 +527,7 @@ class FlutterPlugin implements Plugin<Project> {
...
@@ -607,7 +527,7 @@ class FlutterPlugin implements Plugin<Project> {
variant
.
mergeAssets
.
mustRunAfter
(
"clean${variant.mergeAssets.name.capitalize()}"
)
variant
.
mergeAssets
.
mustRunAfter
(
"clean${variant.mergeAssets.name.capitalize()}"
)
into
variant
.
mergeAssets
.
outputDir
into
variant
.
mergeAssets
.
outputDir
}
}
compile
Tasks
.
each
{
flutterTask
->
flutter
Tasks
.
each
{
flutterTask
->
with
flutterTask
.
assets
with
flutterTask
.
assets
}
}
}
}
...
@@ -630,62 +550,12 @@ class FlutterPlugin implements Plugin<Project> {
...
@@ -630,62 +550,12 @@ class FlutterPlugin implements Plugin<Project> {
processResources
.
dependsOn
(
copyFlutterAssetsTask
)
processResources
.
dependsOn
(
copyFlutterAssetsTask
)
}
}
}
}
if
(
project
.
android
.
hasProperty
(
"applicationVariants"
))
{
if
(
project
.
android
.
hasProperty
(
"applicationVariants"
))
{
project
.
android
.
applicationVariants
.
all
addFlutterDeps
project
.
android
.
applicationVariants
.
all
addFlutterDeps
}
else
{
}
else
{
project
.
android
.
libraryVariants
.
all
addFlutterDeps
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."
)
}
}
}
}
}
}
}
...
@@ -914,59 +784,6 @@ class FlutterTask extends BaseFlutterTask {
...
@@ -914,59 +784,6 @@ class FlutterTask extends BaseFlutterTask {
}
}
}
}
class
FlutterPluginTask
extends
DefaultTask
{
File
flutterExecutable
@Optional
@Input
Boolean
verbose
@Input
String
buildMode
@Input
File
pluginDir
@Input
File
intermediateDir
File
sourceDir
@InputFiles
FileCollection
getSourceFiles
()
{
return
project
.
fileTree
(
dir:
sourceDir
,
exclude:
[
"android"
,
"ios"
],
include:
[
"pubspec.yaml"
]
)
}
@OutputDirectory
File
getOutputDirectory
()
{
return
intermediateDir
}
@TaskAction
void
build
()
{
intermediateDir
.
mkdirs
()
project
.
exec
{
executable
flutterExecutable
.
absolutePath
workingDir
pluginDir
args
"build"
,
"aar"
args
"--quiet"
args
"--suppress-analytics"
args
"--output-dir"
,
"${intermediateDir}"
switch
(
buildMode
)
{
case
'release'
:
args
"--release"
break
case
'debug'
:
args
"--debug"
break
default:
assert
false
}
if
(
verbose
)
{
args
"--verbose"
}
}
}
}
gradle
.
useLogger
(
new
FlutterEventLogger
())
gradle
.
useLogger
(
new
FlutterEventLogger
())
class
FlutterEventLogger
extends
BuildAdapter
implements
TaskExecutionListener
{
class
FlutterEventLogger
extends
BuildAdapter
implements
TaskExecutionListener
{
...
...
packages/flutter_tools/gradle/manual_migration_settings.gradle.md
deleted
100644 → 0
View file @
11460b83
To manually update
`settings.gradle`
, follow these steps:
1. Copy `settings.gradle` as `settings_aar.gradle`
2. Remove the following code from `settings_aar.gradle`:
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
packages/flutter_tools/gradle/settings_aar.gradle.tmpl
deleted
100644 → 0
View file @
11460b83
include ':app'
packages/flutter_tools/lib/src/android/aar.dart
deleted
100644 → 0
View file @
11460b83
// 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.
import
'dart:async'
;
import
'package:meta/meta.dart'
;
import
'../base/common.dart'
;
import
'../build_info.dart'
;
import
'../project.dart'
;
import
'android_sdk.dart'
;
import
'gradle.dart'
;
/// Provides a method to build a module or plugin as AAR.
abstract
class
AarBuilder
{
/// Builds the AAR artifacts.
Future
<
void
>
build
({
@required
FlutterProject
project
,
@required
AndroidBuildInfo
androidBuildInfo
,
@required
String
target
,
@required
String
outputDir
,
});
}
/// Default implementation of [AarBuilder].
class
AarBuilderImpl
extends
AarBuilder
{
AarBuilderImpl
();
/// Builds the AAR and POM files for the current Flutter module or plugin.
@override
Future
<
void
>
build
({
@required
FlutterProject
project
,
@required
AndroidBuildInfo
androidBuildInfo
,
@required
String
target
,
@required
String
outputDir
,
})
async
{
if
(!
project
.
android
.
isUsingGradle
)
{
throwToolExit
(
'The build process for Android has changed, and the current project configuration
\n
'
'is no longer valid. Please consult
\n\n
'
' https://github.com/flutter/flutter/wiki/Upgrading-Flutter-projects-to-build-with-gradle
\n\n
'
'for details on how to upgrade the project.'
);
}
if
(!
project
.
manifest
.
isModule
&&
!
project
.
manifest
.
isPlugin
)
{
throwToolExit
(
'AARs can only be built for plugin or module projects.'
);
}
// Validate that we can find an Android SDK.
if
(
androidSdk
==
null
)
{
throwToolExit
(
'No Android SDK found. Try setting the `ANDROID_SDK_ROOT` environment variable.'
);
}
await
buildGradleAar
(
project:
project
,
androidBuildInfo:
androidBuildInfo
,
target:
target
,
outputDir:
outputDir
,
);
androidSdk
.
reinitialize
();
}
}
packages/flutter_tools/lib/src/android/gradle.dart
View file @
c9b466f9
...
@@ -17,10 +17,8 @@ import '../base/platform.dart';
...
@@ -17,10 +17,8 @@ import '../base/platform.dart';
import
'../base/process.dart'
;
import
'../base/process.dart'
;
import
'../base/terminal.dart'
;
import
'../base/terminal.dart'
;
import
'../base/utils.dart'
;
import
'../base/utils.dart'
;
import
'../base/version.dart'
;
import
'../build_info.dart'
;
import
'../build_info.dart'
;
import
'../cache.dart'
;
import
'../cache.dart'
;
import
'../features.dart'
;
import
'../flutter_manifest.dart'
;
import
'../flutter_manifest.dart'
;
import
'../globals.dart'
;
import
'../globals.dart'
;
import
'../project.dart'
;
import
'../project.dart'
;
...
@@ -29,10 +27,10 @@ import '../runner/flutter_command.dart';
...
@@ -29,10 +27,10 @@ import '../runner/flutter_command.dart';
import
'android_sdk.dart'
;
import
'android_sdk.dart'
;
import
'android_studio.dart'
;
import
'android_studio.dart'
;
const
String
gradleVersion
=
'4.10.2'
;
final
RegExp
_assembleTaskPattern
=
RegExp
(
r'assemble(\S+)'
);
final
RegExp
_assembleTaskPattern
=
RegExp
(
r'assemble(\S+)'
);
GradleProject
_cachedGradleAppProject
;
GradleProject
_cachedGradleProject
;
GradleProject
_cachedGradleLibraryProject
;
String
_cachedGradleExecutable
;
String
_cachedGradleExecutable
;
enum
FlutterPluginVersion
{
enum
FlutterPluginVersion
{
...
@@ -104,19 +102,14 @@ Future<File> getGradleAppOut(AndroidProject androidProject) async {
...
@@ -104,19 +102,14 @@ Future<File> getGradleAppOut(AndroidProject androidProject) async {
case
FlutterPluginVersion
.
managed
:
case
FlutterPluginVersion
.
managed
:
// Fall through. The managed plugin matches plugin v2 for now.
// Fall through. The managed plugin matches plugin v2 for now.
case
FlutterPluginVersion
.
v2
:
case
FlutterPluginVersion
.
v2
:
return
fs
.
file
((
await
_gradle
App
Project
()).
apkDirectory
.
childFile
(
'app.apk'
));
return
fs
.
file
((
await
_gradleProject
()).
apkDirectory
.
childFile
(
'app.apk'
));
}
}
return
null
;
return
null
;
}
}
Future
<
GradleProject
>
_gradleAppProject
()
async
{
Future
<
GradleProject
>
_gradleProject
()
async
{
_cachedGradleAppProject
??=
await
_readGradleProject
(
isLibrary:
false
);
_cachedGradleProject
??=
await
_readGradleProject
();
return
_cachedGradleAppProject
;
return
_cachedGradleProject
;
}
Future
<
GradleProject
>
_gradleLibraryProject
()
async
{
_cachedGradleLibraryProject
??=
await
_readGradleProject
(
isLibrary:
true
);
return
_cachedGradleLibraryProject
;
}
}
/// Runs `gradlew dependencies`, ensuring that dependencies are resolved and
/// Runs `gradlew dependencies`, ensuring that dependencies are resolved and
...
@@ -134,98 +127,32 @@ Future<void> checkGradleDependencies() async {
...
@@ -134,98 +127,32 @@ Future<void> checkGradleDependencies() async {
progress
.
stop
();
progress
.
stop
();
}
}
/// Tries to create `settings_aar.gradle` in an app project by removing the subprojects
/// from the existing `settings.gradle` file. This operation will fail if the existing
/// `settings.gradle` file has local edits.
void
createSettingsAarGradle
(
Directory
androidDirectory
)
{
final
File
newSettingsFile
=
androidDirectory
.
childFile
(
'settings_aar.gradle'
);
if
(
newSettingsFile
.
existsSync
())
{
return
;
}
final
File
currentSettingsFile
=
androidDirectory
.
childFile
(
'settings.gradle'
);
if
(!
currentSettingsFile
.
existsSync
())
{
return
;
}
final
String
currentFileContent
=
currentSettingsFile
.
readAsStringSync
();
final
String
newSettingsRelativeFile
=
fs
.
path
.
relative
(
newSettingsFile
.
path
);
final
Status
status
=
logger
.
startProgress
(
'✏️ Creating `
$newSettingsRelativeFile
`...'
,
timeout:
timeoutConfiguration
.
fastOperation
);
final
String
flutterRoot
=
fs
.
path
.
absolute
(
Cache
.
flutterRoot
);
final
File
deprecatedFile
=
fs
.
file
(
fs
.
path
.
join
(
flutterRoot
,
'packages'
,
'flutter_tools'
,
'gradle'
,
'deprecated_settings.gradle'
));
assert
(
deprecatedFile
.
existsSync
());
// Get the `settings.gradle` content variants that should be patched.
final
List
<
String
>
deprecatedFilesContent
=
deprecatedFile
.
readAsStringSync
().
split
(
';EOF'
);
bool
exactMatch
=
false
;
for
(
String
deprecatedFileContent
in
deprecatedFilesContent
)
{
if
(
currentFileContent
.
trim
()
==
deprecatedFileContent
.
trim
())
{
exactMatch
=
true
;
break
;
}
}
if
(!
exactMatch
)
{
status
.
cancel
();
printError
(
'*******************************************************************************************'
);
printError
(
'Flutter tried to create the file `
$newSettingsRelativeFile
`, but failed.'
);
// Print how to manually update the file.
printError
(
fs
.
file
(
fs
.
path
.
join
(
flutterRoot
,
'packages'
,
'flutter_tools'
,
'gradle'
,
'manual_migration_settings.gradle.md'
)).
readAsStringSync
());
printError
(
'*******************************************************************************************'
);
throwToolExit
(
'Please create the file and run this command again.'
);
}
// Copy the new file.
final
String
settingsAarContent
=
fs
.
file
(
fs
.
path
.
join
(
flutterRoot
,
'packages'
,
'flutter_tools'
,
'gradle'
,
'settings_aar.gradle.tmpl'
)).
readAsStringSync
();
newSettingsFile
.
writeAsStringSync
(
settingsAarContent
);
status
.
stop
();
printStatus
(
'✅ `
$newSettingsRelativeFile
` created successfully.'
);
}
// Note: Dependencies are resolved and possibly downloaded as a side-effect
// Note: Dependencies are resolved and possibly downloaded as a side-effect
// of calculating the app properties using Gradle. This may take minutes.
// of calculating the app properties using Gradle. This may take minutes.
Future
<
GradleProject
>
_readGradleProject
(
{
bool
isLibrary
=
false
}
)
async
{
Future
<
GradleProject
>
_readGradleProject
()
async
{
final
FlutterProject
flutterProject
=
FlutterProject
.
current
();
final
FlutterProject
flutterProject
=
FlutterProject
.
current
();
final
String
gradle
=
await
_ensureGradle
(
flutterProject
);
final
String
gradle
=
await
_ensureGradle
(
flutterProject
);
updateLocalProperties
(
project:
flutterProject
);
updateLocalProperties
(
project:
flutterProject
);
final
FlutterManifest
manifest
=
flutterProject
.
manifest
;
final
Directory
hostAppGradleRoot
=
flutterProject
.
android
.
hostAppGradleRoot
;
if
(
featureFlags
.
isPluginAsAarEnabled
&&
!
manifest
.
isPlugin
&&
!
manifest
.
isModule
)
{
createSettingsAarGradle
(
hostAppGradleRoot
);
}
if
(
manifest
.
isPlugin
)
{
assert
(
isLibrary
);
return
GradleProject
(
<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
// Plugins don't have flavors.
flutterProject
.
directory
.
childDirectory
(
'build'
).
path
,
);
}
final
Status
status
=
logger
.
startProgress
(
'Resolving dependencies...'
,
timeout:
timeoutConfiguration
.
slowOperation
);
final
Status
status
=
logger
.
startProgress
(
'Resolving dependencies...'
,
timeout:
timeoutConfiguration
.
slowOperation
);
GradleProject
project
;
GradleProject
project
;
// Get the properties and tasks from Gradle, so we can determinate the `buildDir`,
// flavors and build types defined in the project. If gradle fails, then check if the failure is due to t
try
{
try
{
final
RunResult
propertiesRunResult
=
await
runCheckedAsync
(
final
RunResult
propertiesRunResult
=
await
runCheckedAsync
(
<
String
>[
gradle
,
isLibrary
?
'properties'
:
'app:properties'
],
<
String
>[
gradle
,
'app:properties'
],
workingDirectory:
hostAppGradleRoot
.
path
,
workingDirectory:
flutterProject
.
android
.
hostAppGradleRoot
.
path
,
environment:
_gradleEnv
,
environment:
_gradleEnv
,
);
);
final
RunResult
tasksRunResult
=
await
runCheckedAsync
(
final
RunResult
tasksRunResult
=
await
runCheckedAsync
(
<
String
>[
gradle
,
isLibrary
?
'tasks'
:
'app:tasks'
,
'--all'
,
'--console=auto'
],
<
String
>[
gradle
,
'app:tasks'
,
'--all'
,
'--console=auto'
],
workingDirectory:
hostAppGradleRoot
.
path
,
workingDirectory:
flutterProject
.
android
.
hostAppGradleRoot
.
path
,
environment:
_gradleEnv
,
environment:
_gradleEnv
,
);
);
project
=
GradleProject
.
fromAppProperties
(
propertiesRunResult
.
stdout
,
tasksRunResult
.
stdout
);
project
=
GradleProject
.
fromAppProperties
(
propertiesRunResult
.
stdout
,
tasksRunResult
.
stdout
);
}
catch
(
exception
)
{
}
catch
(
exception
)
{
if
(
getFlutterPluginVersion
(
flutterProject
.
android
)
==
FlutterPluginVersion
.
managed
)
{
if
(
getFlutterPluginVersion
(
flutterProject
.
android
)
==
FlutterPluginVersion
.
managed
)
{
status
.
cancel
();
status
.
cancel
();
// Handle known exceptions.
// Handle known exceptions. This will exit if handled.
throwToolExitIfLicenseNotAccepted
(
exception
);
handleKnownGradleExceptions
(
exception
.
toString
());
// Print a general Gradle error and exit.
// Print a general Gradle error and exit.
printError
(
'* Error running Gradle:
\n
$exception
\n
'
);
printError
(
'* Error running Gradle:
\n
$exception
\n
'
);
throwToolExit
(
'Please review your Gradle project setup in the android/ folder.'
);
throwToolExit
(
'Please review your Gradle project setup in the android/ folder.'
);
...
@@ -233,23 +160,23 @@ Future<GradleProject> _readGradleProject({bool isLibrary = false}) async {
...
@@ -233,23 +160,23 @@ Future<GradleProject> _readGradleProject({bool isLibrary = false}) async {
// Fall back to the default
// Fall back to the default
project
=
GradleProject
(
project
=
GradleProject
(
<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
<
String
>[],
flutterProject
.
android
.
gradleAppOutV1Directory
,
fs
.
path
.
join
(
flutterProject
.
android
.
hostAppGradleRoot
.
path
,
'app'
,
'build'
)
flutterProject
.
android
.
gradleAppBundleOutV1Directory
,
);
);
}
}
status
.
stop
();
status
.
stop
();
return
project
;
return
project
;
}
}
/// Handle Gradle error thrown when Gradle needs to download additional
void
handleKnownGradleExceptions
(
String
exceptionString
)
{
/// Android SDK components (e.g. Platform Tools), and the license
// Handle Gradle error thrown when Gradle needs to download additional
/// for that component has not been accepted.
// Android SDK components (e.g. Platform Tools), and the license
void
throwToolExitIfLicenseNotAccepted
(
Exception
exception
)
{
// for that component has not been accepted.
const
String
licenseNotAcceptedM
atcher
=
const
String
m
atcher
=
r'You have not accepted the license agreements of the following SDK components:'
r'You have not accepted the license agreements of the following SDK components:'
r'\s*\[(.+)\]'
;
r'\s*\[(.+)\]'
;
final
RegExp
licenseFailure
=
RegExp
(
licenseNotAcceptedM
atcher
,
multiLine:
true
);
final
RegExp
licenseFailure
=
RegExp
(
m
atcher
,
multiLine:
true
);
final
Match
licenseMatch
=
licenseFailure
.
firstMatch
(
exception
.
toString
()
);
final
Match
licenseMatch
=
licenseFailure
.
firstMatch
(
exception
String
);
if
(
licenseMatch
!=
null
)
{
if
(
licenseMatch
!=
null
)
{
final
String
missingLicenses
=
licenseMatch
.
group
(
1
);
final
String
missingLicenses
=
licenseMatch
.
group
(
1
);
final
String
errorMessage
=
final
String
errorMessage
=
...
@@ -306,7 +233,6 @@ void injectGradleWrapper(Directory directory) {
...
@@ -306,7 +233,6 @@ void injectGradleWrapper(Directory directory) {
_locateGradlewExecutable
(
directory
);
_locateGradlewExecutable
(
directory
);
final
File
propertiesFile
=
directory
.
childFile
(
fs
.
path
.
join
(
'gradle'
,
'wrapper'
,
'gradle-wrapper.properties'
));
final
File
propertiesFile
=
directory
.
childFile
(
fs
.
path
.
join
(
'gradle'
,
'wrapper'
,
'gradle-wrapper.properties'
));
if
(!
propertiesFile
.
existsSync
())
{
if
(!
propertiesFile
.
existsSync
())
{
final
String
gradleVersion
=
getGradleVersionForAndroidPlugin
(
directory
);
propertiesFile
.
writeAsStringSync
(
'''
propertiesFile
.
writeAsStringSync
(
'''
distributionBase=GRADLE_USER_HOME
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionPath=wrapper/dists
...
@@ -318,78 +244,6 @@ distributionUrl=https\\://services.gradle.org/distributions/gradle-$gradleVersio
...
@@ -318,78 +244,6 @@ distributionUrl=https\\://services.gradle.org/distributions/gradle-$gradleVersio
}
}
}
}
/// Returns true if [targetVersion] is within the range [min] and [max] inclusive.
bool
_isWithinVersionRange
(
String
targetVersion
,
{
String
min
,
String
max
})
{
final
Version
parsedTargetVersion
=
Version
.
parse
(
targetVersion
);
return
parsedTargetVersion
>=
Version
.
parse
(
min
)
&&
parsedTargetVersion
<=
Version
.
parse
(
max
);
}
const
String
defaultGradleVersion
=
'4.10.2'
;
/// Returns the Gradle version that is required by the given Android Gradle plugin version
/// by picking the largest compatible version from
/// https://developer.android.com/studio/releases/gradle-plugin#updating-gradle
String
getGradleVersionFor
(
String
androidPluginVersion
)
{
if
(
_isWithinVersionRange
(
androidPluginVersion
,
min:
'1.0.0'
,
max:
'1.1.3'
))
{
return
'2.3'
;
}
if
(
_isWithinVersionRange
(
androidPluginVersion
,
min:
'1.2.0'
,
max:
'1.3.1'
))
{
return
'2.9'
;
}
if
(
_isWithinVersionRange
(
androidPluginVersion
,
min:
'1.5.0'
,
max:
'1.5.0'
))
{
return
'2.2.1'
;
}
if
(
_isWithinVersionRange
(
androidPluginVersion
,
min:
'2.0.0'
,
max:
'2.1.2'
))
{
return
'2.13'
;
}
if
(
_isWithinVersionRange
(
androidPluginVersion
,
min:
'2.1.3'
,
max:
'2.2.3'
))
{
return
'2.14.1'
;
}
if
(
_isWithinVersionRange
(
androidPluginVersion
,
min:
'2.3.0'
,
max:
'2.9.9'
))
{
return
'3.3'
;
}
if
(
_isWithinVersionRange
(
androidPluginVersion
,
min:
'3.0.0'
,
max:
'3.0.9'
))
{
return
'4.1'
;
}
if
(
_isWithinVersionRange
(
androidPluginVersion
,
min:
'3.1.0'
,
max:
'3.1.9'
))
{
return
'4.4'
;
}
if
(
_isWithinVersionRange
(
androidPluginVersion
,
min:
'3.2.0'
,
max:
'3.2.1'
))
{
return
'4.6'
;
}
if
(
_isWithinVersionRange
(
androidPluginVersion
,
min:
'3.3.0'
,
max:
'3.3.2'
))
{
return
'4.10.2'
;
}
if
(
_isWithinVersionRange
(
androidPluginVersion
,
min:
'3.4.0'
,
max:
'3.5.0'
))
{
return
'5.1.1'
;
}
throwToolExit
(
'Unsuported Android Plugin version:
$androidPluginVersion
.'
);
return
''
;
}
final
RegExp
_androidPluginRegExp
=
RegExp
(
'com
\
.android
\
.tools
\
.build
\
:gradle
\
:(
\\
d+
\
.
\\
d+
\
.
\\
d+
\
)'
);
/// Returns the Gradle version that the current Android plugin depends on when found,
/// otherwise it returns a default version.
///
/// The Android plugin version is specified in the [build.gradle] file within
/// the project's Android directory.
String
getGradleVersionForAndroidPlugin
(
Directory
directory
)
{
final
File
buildFile
=
directory
.
childFile
(
'build.gradle'
);
if
(!
buildFile
.
existsSync
())
{
return
defaultGradleVersion
;
}
final
String
buildFileContent
=
buildFile
.
readAsStringSync
();
final
Iterable
<
Match
>
pluginMatches
=
_androidPluginRegExp
.
allMatches
(
buildFileContent
);
if
(
pluginMatches
.
isEmpty
)
{
return
defaultGradleVersion
;
}
final
String
androidPluginVersion
=
pluginMatches
.
first
.
group
(
1
);
return
getGradleVersionFor
(
androidPluginVersion
);
}
/// Overwrite local.properties in the specified Flutter project's Android
/// Overwrite local.properties in the specified Flutter project's Android
/// sub-project, if needed.
/// sub-project, if needed.
///
///
...
@@ -493,95 +347,6 @@ Future<void> buildGradleProject({
...
@@ -493,95 +347,6 @@ Future<void> buildGradleProject({
}
}
}
}
Future
<
void
>
buildGradleAar
({
@required
FlutterProject
project
,
@required
AndroidBuildInfo
androidBuildInfo
,
@required
String
target
,
@required
String
outputDir
,
})
async
{
final
FlutterManifest
manifest
=
project
.
manifest
;
GradleProject
gradleProject
;
if
(
manifest
.
isModule
)
{
gradleProject
=
await
_gradleAppProject
();
}
else
if
(
manifest
.
isPlugin
)
{
gradleProject
=
await
_gradleLibraryProject
();
}
else
{
throwToolExit
(
'AARs can only be built for plugin or module projects.'
);
}
if
(
outputDir
!=
null
&&
outputDir
.
isNotEmpty
)
{
gradleProject
.
buildDirectory
=
outputDir
;
}
final
String
aarTask
=
gradleProject
.
aarTaskFor
(
androidBuildInfo
.
buildInfo
);
if
(
aarTask
==
null
)
{
printUndefinedTask
(
gradleProject
,
androidBuildInfo
.
buildInfo
);
throwToolExit
(
'Gradle build aborted.'
);
}
final
Status
status
=
logger
.
startProgress
(
'Running Gradle task
\'
$aarTask
\'
...'
,
timeout:
timeoutConfiguration
.
slowOperation
,
multilineOutput:
true
,
);
final
String
gradle
=
await
_ensureGradle
(
project
);
final
String
gradlePath
=
fs
.
file
(
gradle
).
absolute
.
path
;
final
String
flutterRoot
=
fs
.
path
.
absolute
(
Cache
.
flutterRoot
);
final
String
initScript
=
fs
.
path
.
join
(
flutterRoot
,
'packages'
,
'flutter_tools'
,
'gradle'
,
'aar_init_script.gradle'
);
final
List
<
String
>
command
=
<
String
>[
gradlePath
,
'-I=
$initScript
'
,
'-Pflutter-root=
$flutterRoot
'
,
'-Poutput-dir=
${gradleProject.buildDirectory}
'
,
'-Pis-plugin=
${manifest.isPlugin}
'
,
'-Dbuild-plugins-as-aars=true'
,
];
if
(
target
!=
null
&&
target
.
isNotEmpty
)
{
command
.
add
(
'-Ptarget=
$target
'
);
}
if
(
androidBuildInfo
.
targetArchs
.
isNotEmpty
)
{
final
String
targetPlatforms
=
androidBuildInfo
.
targetArchs
.
map
(
getPlatformNameForAndroidArch
).
join
(
','
);
command
.
add
(
'-Ptarget-platform=
$targetPlatforms
'
);
}
command
.
add
(
aarTask
);
final
Stopwatch
sw
=
Stopwatch
()..
start
();
int
exitCode
=
1
;
try
{
exitCode
=
await
runCommandAndStreamOutput
(
command
,
workingDirectory:
project
.
android
.
hostAppGradleRoot
.
path
,
allowReentrantFlutter:
true
,
environment:
_gradleEnv
,
mapFunction:
(
String
line
)
{
// Always print the full line in verbose mode.
if
(
logger
.
isVerbose
)
{
return
line
;
}
return
null
;
},
);
}
finally
{
status
.
stop
();
}
flutterUsage
.
sendTiming
(
'build'
,
'gradle-aar'
,
Duration
(
milliseconds:
sw
.
elapsedMilliseconds
));
if
(
exitCode
!=
0
)
{
throwToolExit
(
'Gradle task
$aarTask
failed with exit code
$exitCode
'
,
exitCode:
exitCode
);
}
final
Directory
repoDirectory
=
gradleProject
.
repoDirectory
;
if
(!
repoDirectory
.
existsSync
())
{
throwToolExit
(
'Gradle task
$aarTask
failed to produce
$repoDirectory
'
,
exitCode:
exitCode
);
}
printStatus
(
'Built
${fs.path.relative(repoDirectory.path)}
.'
,
color:
TerminalColor
.
green
);
}
Future
<
void
>
_buildGradleProjectV1
(
FlutterProject
project
,
String
gradle
)
async
{
Future
<
void
>
_buildGradleProjectV1
(
FlutterProject
project
,
String
gradle
)
async
{
// Run 'gradlew build'.
// Run 'gradlew build'.
final
Status
status
=
logger
.
startProgress
(
final
Status
status
=
logger
.
startProgress
(
...
@@ -624,22 +389,6 @@ String _calculateSha(File file) {
...
@@ -624,22 +389,6 @@ String _calculateSha(File file) {
return
sha
;
return
sha
;
}
}
void
printUndefinedTask
(
GradleProject
project
,
BuildInfo
buildInfo
)
{
printError
(
''
);
printError
(
'The Gradle project does not define a task suitable for the requested build.'
);
if
(!
project
.
buildTypes
.
contains
(
buildInfo
.
modeName
))
{
printError
(
'Review the android/app/build.gradle file and ensure it defines a
${buildInfo.modeName}
build type.'
);
return
;
}
if
(
project
.
productFlavors
.
isEmpty
)
{
printError
(
'The android/app/build.gradle file does not define any custom product flavors.'
);
printError
(
'You cannot use the --flavor option.'
);
}
else
{
printError
(
'The android/app/build.gradle file defines product flavors:
${project.productFlavors.join(', ')}
'
);
printError
(
'You must specify a --flavor option to select one of them.'
);
}
}
Future
<
void
>
_buildGradleProjectV2
(
Future
<
void
>
_buildGradleProjectV2
(
FlutterProject
flutterProject
,
FlutterProject
flutterProject
,
String
gradle
,
String
gradle
,
...
@@ -647,7 +396,7 @@ Future<void> _buildGradleProjectV2(
...
@@ -647,7 +396,7 @@ Future<void> _buildGradleProjectV2(
String
target
,
String
target
,
bool
isBuildingBundle
,
bool
isBuildingBundle
,
)
async
{
)
async
{
final
GradleProject
project
=
await
_gradle
App
Project
();
final
GradleProject
project
=
await
_gradleProject
();
final
BuildInfo
buildInfo
=
androidBuildInfo
.
buildInfo
;
final
BuildInfo
buildInfo
=
androidBuildInfo
.
buildInfo
;
String
assembleTask
;
String
assembleTask
;
...
@@ -657,9 +406,22 @@ Future<void> _buildGradleProjectV2(
...
@@ -657,9 +406,22 @@ Future<void> _buildGradleProjectV2(
}
else
{
}
else
{
assembleTask
=
project
.
assembleTaskFor
(
buildInfo
);
assembleTask
=
project
.
assembleTaskFor
(
buildInfo
);
}
}
if
(
assembleTask
==
null
)
{
if
(
assembleTask
==
null
)
{
printUndefinedTask
(
project
,
buildInfo
);
printError
(
''
);
throwToolExit
(
'Gradle build aborted.'
);
printError
(
'The Gradle project does not define a task suitable for the requested build.'
);
if
(!
project
.
buildTypes
.
contains
(
buildInfo
.
modeName
))
{
printError
(
'Review the android/app/build.gradle file and ensure it defines a
${buildInfo.modeName}
build type.'
);
}
else
{
if
(
project
.
productFlavors
.
isEmpty
)
{
printError
(
'The android/app/build.gradle file does not define any custom product flavors.'
);
printError
(
'You cannot use the --flavor option.'
);
}
else
{
printError
(
'The android/app/build.gradle file defines product flavors:
${project.productFlavors.join(', ')}
'
);
printError
(
'You must specify a --flavor option to select one of them.'
);
}
throwToolExit
(
'Gradle build aborted.'
);
}
}
}
final
Status
status
=
logger
.
startProgress
(
final
Status
status
=
logger
.
startProgress
(
'Running Gradle task
\'
$assembleTask
\'
...'
,
'Running Gradle task
\'
$assembleTask
\'
...'
,
...
@@ -698,14 +460,6 @@ Future<void> _buildGradleProjectV2(
...
@@ -698,14 +460,6 @@ Future<void> _buildGradleProjectV2(
.
map
(
getPlatformNameForAndroidArch
).
join
(
','
);
.
map
(
getPlatformNameForAndroidArch
).
join
(
','
);
command
.
add
(
'-Ptarget-platform=
$targetPlatforms
'
);
command
.
add
(
'-Ptarget-platform=
$targetPlatforms
'
);
}
}
if
(
featureFlags
.
isPluginAsAarEnabled
)
{
// Pass a system flag instead of a project flag, so this flag can be
// read from include_flutter.groovy.
command
.
add
(
'-Dbuild-plugins-as-aars=true'
);
if
(!
flutterProject
.
manifest
.
isModule
)
{
command
.
add
(
'--settings-file=settings_aar.gradle'
);
}
}
command
.
add
(
assembleTask
);
command
.
add
(
assembleTask
);
bool
potentialAndroidXFailure
=
false
;
bool
potentialAndroidXFailure
=
false
;
final
Stopwatch
sw
=
Stopwatch
()..
start
();
final
Stopwatch
sw
=
Stopwatch
()..
start
();
...
@@ -850,6 +604,7 @@ Map<String, String> get _gradleEnv {
...
@@ -850,6 +604,7 @@ Map<String, String> get _gradleEnv {
// Use java bundled with Android Studio.
// Use java bundled with Android Studio.
env
[
'JAVA_HOME'
]
=
javaPath
;
env
[
'JAVA_HOME'
]
=
javaPath
;
}
}
// Don't log analytics for downstream Flutter commands.
// Don't log analytics for downstream Flutter commands.
// e.g. `flutter build bundle`.
// e.g. `flutter build bundle`.
env
[
'FLUTTER_SUPPRESS_ANALYTICS'
]
=
'true'
;
env
[
'FLUTTER_SUPPRESS_ANALYTICS'
]
=
'true'
;
...
@@ -857,15 +612,11 @@ Map<String, String> get _gradleEnv {
...
@@ -857,15 +612,11 @@ Map<String, String> get _gradleEnv {
}
}
class
GradleProject
{
class
GradleProject
{
GradleProject
(
GradleProject
(
this
.
buildTypes
,
this
.
productFlavors
,
this
.
apkDirectory
,
this
.
bundleDirectory
);
this
.
buildTypes
,
this
.
productFlavors
,
this
.
buildDirectory
,
);
factory
GradleProject
.
fromAppProperties
(
String
properties
,
String
tasks
)
{
factory
GradleProject
.
fromAppProperties
(
String
properties
,
String
tasks
)
{
// Extract build directory.
// Extract build directory.
final
String
buildDir
ectory
=
properties
final
String
buildDir
=
properties
.
split
(
'
\n
'
)
.
split
(
'
\n
'
)
.
firstWhere
((
String
s
)
=>
s
.
startsWith
(
'buildDir: '
))
.
firstWhere
((
String
s
)
=>
s
.
startsWith
(
'buildDir: '
))
.
substring
(
'buildDir: '
.
length
)
.
substring
(
'buildDir: '
.
length
)
...
@@ -897,36 +648,17 @@ class GradleProject {
...
@@ -897,36 +648,17 @@ class GradleProject {
if
(
productFlavors
.
isEmpty
)
if
(
productFlavors
.
isEmpty
)
buildTypes
.
addAll
(
variants
);
buildTypes
.
addAll
(
variants
);
return
GradleProject
(
return
GradleProject
(
buildTypes
.
toList
(),
buildTypes
.
toList
(),
productFlavors
.
toList
(),
productFlavors
.
toList
(),
buildDirectory
,
fs
.
directory
(
fs
.
path
.
join
(
buildDir
,
'outputs'
,
'apk'
)),
);
fs
.
directory
(
fs
.
path
.
join
(
buildDir
,
'outputs'
,
'bundle'
)),
);
}
}
/// The build types such as [release] or [debug].
final
List
<
String
>
buildTypes
;
final
List
<
String
>
buildTypes
;
/// The product flavors defined in build.gradle.
final
List
<
String
>
productFlavors
;
final
List
<
String
>
productFlavors
;
final
Directory
apkDirectory
;
/// The build directory. This is typically <project>build/.
final
Directory
bundleDirectory
;
String
buildDirectory
;
/// The directory where the APK artifact is generated.
Directory
get
apkDirectory
{
return
fs
.
directory
(
fs
.
path
.
join
(
buildDirectory
,
'outputs'
,
'apk'
));
}
/// The directory where the app bundle artifact is generated.
Directory
get
bundleDirectory
{
return
fs
.
directory
(
fs
.
path
.
join
(
buildDirectory
,
'outputs'
,
'bundle'
));
}
/// The directory where the repo is generated.
/// Only applicable to AARs.
Directory
get
repoDirectory
{
return
fs
.
directory
(
fs
.
path
.
join
(
buildDirectory
,
'outputs'
,
'repo'
));
}
String
_buildTypeFor
(
BuildInfo
buildInfo
)
{
String
_buildTypeFor
(
BuildInfo
buildInfo
)
{
final
String
modeName
=
camelCase
(
buildInfo
.
modeName
);
final
String
modeName
=
camelCase
(
buildInfo
.
modeName
);
...
@@ -976,14 +708,6 @@ class GradleProject {
...
@@ -976,14 +708,6 @@ class GradleProject {
return
'bundle
${toTitleCase(productFlavor)}${toTitleCase(buildType)}
'
;
return
'bundle
${toTitleCase(productFlavor)}${toTitleCase(buildType)}
'
;
}
}
String
aarTaskFor
(
BuildInfo
buildInfo
)
{
final
String
buildType
=
_buildTypeFor
(
buildInfo
);
final
String
productFlavor
=
_productFlavorFor
(
buildInfo
);
if
(
buildType
==
null
||
productFlavor
==
null
)
return
null
;
return
'assembleAar
${toTitleCase(productFlavor)}${toTitleCase(buildType)}
'
;
}
String
bundleFileFor
(
BuildInfo
buildInfo
)
{
String
bundleFileFor
(
BuildInfo
buildInfo
)
{
// For app bundle all bundle names are called as app.aab. Product flavors
// For app bundle all bundle names are called as app.aab. Product flavors
// & build types are differentiated as folders, where the aab will be added.
// & build types are differentiated as folders, where the aab will be added.
...
...
packages/flutter_tools/lib/src/commands/build.dart
View file @
c9b466f9
...
@@ -9,7 +9,6 @@ import '../commands/build_macos.dart';
...
@@ -9,7 +9,6 @@ import '../commands/build_macos.dart';
import
'../commands/build_windows.dart'
;
import
'../commands/build_windows.dart'
;
import
'../runner/flutter_command.dart'
;
import
'../runner/flutter_command.dart'
;
import
'build_aar.dart'
;
import
'build_aot.dart'
;
import
'build_aot.dart'
;
import
'build_apk.dart'
;
import
'build_apk.dart'
;
import
'build_appbundle.dart'
;
import
'build_appbundle.dart'
;
...
@@ -20,7 +19,6 @@ import 'build_web.dart';
...
@@ -20,7 +19,6 @@ import 'build_web.dart';
class
BuildCommand
extends
FlutterCommand
{
class
BuildCommand
extends
FlutterCommand
{
BuildCommand
({
bool
verboseHelp
=
false
})
{
BuildCommand
({
bool
verboseHelp
=
false
})
{
addSubcommand
(
BuildAarCommand
(
verboseHelp:
verboseHelp
));
addSubcommand
(
BuildApkCommand
(
verboseHelp:
verboseHelp
));
addSubcommand
(
BuildApkCommand
(
verboseHelp:
verboseHelp
));
addSubcommand
(
BuildAppBundleCommand
(
verboseHelp:
verboseHelp
));
addSubcommand
(
BuildAppBundleCommand
(
verboseHelp:
verboseHelp
));
addSubcommand
(
BuildAotCommand
());
addSubcommand
(
BuildAotCommand
());
...
...
packages/flutter_tools/lib/src/commands/build_aar.dart
deleted
100644 → 0
View file @
11460b83
// 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.
import
'dart:async'
;
import
'../android/aar.dart'
;
import
'../base/context.dart'
;
import
'../base/os.dart'
;
import
'../build_info.dart'
;
import
'../project.dart'
;
import
'../reporting/usage.dart'
;
import
'../runner/flutter_command.dart'
show
DevelopmentArtifact
,
FlutterCommandResult
;
import
'build.dart'
;
/// The AAR builder in the current context.
AarBuilder
get
aarBuilder
=>
context
.
get
<
AarBuilder
>()
??
AarBuilderImpl
();
class
BuildAarCommand
extends
BuildSubCommand
{
BuildAarCommand
({
bool
verboseHelp
=
false
})
{
addBuildModeFlags
(
verboseHelp:
verboseHelp
);
usesFlavorOption
();
usesPubOption
();
argParser
..
addMultiOption
(
'target-platform'
,
splitCommas:
true
,
defaultsTo:
<
String
>[
'android-arm'
,
'android-arm64'
],
allowed:
<
String
>[
'android-arm'
,
'android-arm64'
,
'android-x86'
,
'android-x64'
],
help:
'The target platform for which the project is compiled.'
,
)
..
addOption
(
'output-dir'
,
help:
'The absolute path to the directory where the repository is generated.'
'By default, this is
\'
<current-directory>android/build
\'
. '
,
);
}
@override
final
String
name
=
'aar'
;
@override
Future
<
Map
<
String
,
String
>>
get
usageValues
async
{
final
Map
<
String
,
String
>
usage
=
<
String
,
String
>{};
final
FlutterProject
futterProject
=
_getProject
();
if
(
futterProject
==
null
)
{
return
usage
;
}
if
(
futterProject
.
manifest
.
isModule
)
{
usage
[
kCommandBuildAarProjectType
]
=
'module'
;
}
else
if
(
futterProject
.
manifest
.
isPlugin
)
{
usage
[
kCommandBuildAarProjectType
]
=
'plugin'
;
}
else
{
usage
[
kCommandBuildAarProjectType
]
=
'app'
;
}
usage
[
kCommandBuildAarTargetPlatform
]
=
(
argResults
[
'target-platform'
]
as
List
<
String
>).
join
(
','
);
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
'
'To learn more about how to use these artifacts, see '
'https://docs.gradle.org/current/userguide/repository_types.html#sub:maven_local'
;
@override
Future
<
FlutterCommandResult
>
runCommand
()
async
{
final
BuildInfo
buildInfo
=
getBuildInfo
();
final
AndroidBuildInfo
androidBuildInfo
=
AndroidBuildInfo
(
buildInfo
,
targetArchs:
argResults
[
'target-platform'
].
map
<
AndroidArch
>(
getAndroidArchForName
));
await
aarBuilder
.
build
(
project:
_getProject
(),
target:
''
,
// Not needed because this command only builds Android's code.
androidBuildInfo:
androidBuildInfo
,
outputDir:
argResults
[
'output-dir'
],
);
return
null
;
}
/// Returns the [FlutterProject] which is determinated from the remaining command-line
/// argument if any or the current working directory.
FlutterProject
_getProject
()
{
if
(
argResults
.
rest
.
isEmpty
)
{
return
FlutterProject
.
current
();
}
return
FlutterProject
.
fromPath
(
findProjectRoot
(
argResults
.
rest
.
first
));
}
}
packages/flutter_tools/lib/src/features.dart
View file @
c9b466f9
...
@@ -36,9 +36,6 @@ class FeatureFlags {
...
@@ -36,9 +36,6 @@ class FeatureFlags {
/// Whether flutter desktop for Windows is enabled.
/// Whether flutter desktop for Windows is enabled.
bool
get
isWindowsEnabled
=>
_isEnabled
(
flutterWindowsDesktopFeature
);
bool
get
isWindowsEnabled
=>
_isEnabled
(
flutterWindowsDesktopFeature
);
/// Whether plugins are built as AARs in app projects.
bool
get
isPluginAsAarEnabled
=>
_isEnabled
(
flutterBuildPluginAsAarFeature
);
// Calculate whether a particular feature is enabled for the current channel.
// Calculate whether a particular feature is enabled for the current channel.
static
bool
_isEnabled
(
Feature
feature
)
{
static
bool
_isEnabled
(
Feature
feature
)
{
final
String
currentChannel
=
FlutterVersion
.
instance
.
channel
;
final
String
currentChannel
=
FlutterVersion
.
instance
.
channel
;
...
@@ -68,7 +65,6 @@ const List<Feature> allFeatures = <Feature>[
...
@@ -68,7 +65,6 @@ const List<Feature> allFeatures = <Feature>[
flutterLinuxDesktopFeature
,
flutterLinuxDesktopFeature
,
flutterMacOSDesktopFeature
,
flutterMacOSDesktopFeature
,
flutterWindowsDesktopFeature
,
flutterWindowsDesktopFeature
,
flutterBuildPluginAsAarFeature
,
];
];
/// The [Feature] for flutter web.
/// The [Feature] for flutter web.
...
@@ -119,20 +115,6 @@ const Feature flutterWindowsDesktopFeature = Feature(
...
@@ -119,20 +115,6 @@ const Feature flutterWindowsDesktopFeature = Feature(
),
),
);
);
/// The [Feature] for building plugins as AARs in an app project.
const
Feature
flutterBuildPluginAsAarFeature
=
Feature
(
name:
'Build plugins independently as AARs in app projects'
,
configSetting:
'enable-build-plugin-as-aar'
,
master:
FeatureChannelSetting
(
available:
true
,
enabledByDefault:
true
,
),
dev:
FeatureChannelSetting
(
available:
true
,
enabledByDefault:
false
,
),
);
/// A [Feature] is a process for conditionally enabling tool features.
/// A [Feature] is a process for conditionally enabling tool features.
///
///
/// All settings are optional, and if not provided will generally default to
/// All settings are optional, and if not provided will generally default to
...
...
packages/flutter_tools/lib/src/project.dart
View file @
c9b466f9
...
@@ -510,6 +510,10 @@ class AndroidProject {
...
@@ -510,6 +510,10 @@ class AndroidProject {
return
fs
.
directory
(
fs
.
path
.
join
(
hostAppGradleRoot
.
path
,
'app'
,
'build'
,
'outputs'
,
'apk'
));
return
fs
.
directory
(
fs
.
path
.
join
(
hostAppGradleRoot
.
path
,
'app'
,
'build'
,
'outputs'
,
'apk'
));
}
}
Directory
get
gradleAppBundleOutV1Directory
{
return
fs
.
directory
(
fs
.
path
.
join
(
hostAppGradleRoot
.
path
,
'app'
,
'build'
,
'outputs'
,
'bundle'
));
}
/// Whether the current flutter project has an Android sub-project.
/// Whether the current flutter project has an Android sub-project.
bool
existsSync
()
{
bool
existsSync
()
{
return
parent
.
isModule
||
_editableHostAppDirectory
.
existsSync
();
return
parent
.
isModule
||
_editableHostAppDirectory
.
existsSync
();
...
...
packages/flutter_tools/lib/src/reporting/usage.dart
View file @
c9b466f9
...
@@ -57,16 +57,13 @@ const String kCommandBuildBundleIsModule = 'cd25';
...
@@ -57,16 +57,13 @@ const String kCommandBuildBundleIsModule = 'cd25';
const
String
kCommandResult
=
'cd26'
;
const
String
kCommandResult
=
'cd26'
;
const
String
kCommandHasTerminal
=
'cd31'
;
const
String
kCommandHasTerminal
=
'cd31'
;
const
String
kCommandBuildAarTargetPlatform
=
'cd34'
;
const
String
kCommandBuildAarProjectType
=
'cd35'
;
const
String
reloadExceptionTargetPlatform
=
'cd27'
;
const
String
reloadExceptionTargetPlatform
=
'cd27'
;
const
String
reloadExceptionSdkName
=
'cd28'
;
const
String
reloadExceptionSdkName
=
'cd28'
;
const
String
reloadExceptionEmulator
=
'cd29'
;
const
String
reloadExceptionEmulator
=
'cd29'
;
const
String
reloadExceptionFullRestart
=
'cd30'
;
const
String
reloadExceptionFullRestart
=
'cd30'
;
const
String
enabledFlutterFeatures
=
'cd32'
;
const
String
enabledFlutterFeatures
=
'cd32'
;
// Next ID: cd3
6
// Next ID: cd3
4
Usage
get
flutterUsage
=>
Usage
.
instance
;
Usage
get
flutterUsage
=>
Usage
.
instance
;
...
...
packages/flutter_tools/templates/module/android/library/Flutter.tmpl/build.gradle.tmpl
View file @
c9b466f9
...
@@ -26,9 +26,6 @@ if (flutterVersionName == null) {
...
@@ -26,9 +26,6 @@ if (flutterVersionName == null) {
apply plugin: 'com.android.library'
apply plugin: 'com.android.library'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
group '{{androidIdentifier}}'
version '1.0'
android {
android {
compileSdkVersion 28
compileSdkVersion 28
...
...
packages/flutter_tools/templates/module/android/library/include_flutter.groovy.copy.tmpl
View file @
c9b466f9
...
@@ -6,37 +6,24 @@ def flutterProjectRoot = new File(scriptFile).parentFile.parentFile
...
@@ -6,37 +6,24 @@ def flutterProjectRoot = new File(scriptFile).parentFile.parentFile
gradle.include ':flutter'
gradle.include ':flutter'
gradle.project(':flutter').projectDir = new File(flutterProjectRoot, '.android/Flutter')
gradle.project(':flutter').projectDir = new File(flutterProjectRoot, '.android/Flutter')
if (System.getProperty('build-plugins-as-aars') != 'true') {
def plugins = new Properties()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot, '.flutter-plugins')
def pluginsFile = new File(flutterProjectRoot, '.flutter-plugins')
if (pluginsFile.exists()) {
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
}
plugins.each { name, path ->
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.toPath().resolve(path).resolve('android').toFile()
def pluginDirectory = flutterProjectRoot.toPath().resolve(path).resolve('android').toFile()
gradle.include ":$name"
gradle.include ":$name"
gradle.project(":$name").projectDir = pluginDirectory
gradle.project(":$name").projectDir = pluginDirectory
}
}
}
gradle.getGradle().projectsLoaded { g ->
gradle.getGradle().projectsLoaded { g ->
g.rootProject.beforeEvaluate { p ->
g.rootProject.beforeEvaluate { p ->
_mainModuleName = binding.variables['mainModuleName']
_mainModuleName = binding.variables['mainModuleName']
if (_mainModuleName != null && !_mainModuleName.empty) {
if (_mainModuleName != null && !_mainModuleName.empty) {
p.ext.mainModuleName = _mainModuleName
p.ext.mainModuleName = _mainModuleName
}
}
def subprojects = []
def flutterProject
p.subprojects { sp ->
if (sp.name == 'flutter') {
flutterProject = sp
} else {
subprojects.add(sp)
}
}
assert flutterProject != null
flutterProject.ext.hostProjects = subprojects
flutterProject.ext.pluginBuildDir = new File(flutterProjectRoot, 'build/host')
}
}
g.rootProject.afterEvaluate { p ->
g.rootProject.afterEvaluate { p ->
p.subprojects { sp ->
p.subprojects { sp ->
...
...
packages/flutter_tools/templates/plugin/android-java.tmpl/build.gradle.tmpl
View file @
c9b466f9
group '{{androidIdentifier}}'
group '{{androidIdentifier}}'
version '1.0'
version '1.0
-SNAPSHOT
'
buildscript {
buildscript {
repositories {
repositories {
...
...
packages/flutter_tools/templates/plugin/android.tmpl/gradle/wrapper/gradle-wrapper.properties
deleted
100644 → 0
View file @
11460b83
distributionBase
=
GRADLE_USER_HOME
distributionPath
=
wrapper/dists
zipStoreBase
=
GRADLE_USER_HOME
zipStorePath
=
wrapper/dists
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-4.10.2-all.zip
packages/flutter_tools/test/general.shard/android/gradle_test.dart
View file @
c9b466f9
...
@@ -6,9 +6,7 @@ import 'dart:async';
...
@@ -6,9 +6,7 @@ import 'dart:async';
import
'package:file/memory.dart'
;
import
'package:file/memory.dart'
;
import
'package:flutter_tools/src/android/gradle.dart'
;
import
'package:flutter_tools/src/android/gradle.dart'
;
import
'package:flutter_tools/src/base/logger.dart'
;
import
'package:flutter_tools/src/artifacts.dart'
;
import
'package:flutter_tools/src/artifacts.dart'
;
import
'package:flutter_tools/src/base/common.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
...
@@ -170,20 +168,20 @@ someOtherTask
...
@@ -170,20 +168,20 @@ someOtherTask
expect
(
project
.
productFlavors
,
<
String
>[
'free'
,
'paid'
]);
expect
(
project
.
productFlavors
,
<
String
>[
'free'
,
'paid'
]);
});
});
test
(
'should provide apk file name for default build types'
,
()
{
test
(
'should provide apk file name for default build types'
,
()
{
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
'/some/dir'
);
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
fs
.
directory
(
'/some/dir'
),
fs
.
directory
(
'/some/dir'
)
);
expect
(
project
.
apkFilesFor
(
const
AndroidBuildInfo
(
BuildInfo
.
debug
)).
first
,
'app-debug.apk'
);
expect
(
project
.
apkFilesFor
(
const
AndroidBuildInfo
(
BuildInfo
.
debug
)).
first
,
'app-debug.apk'
);
expect
(
project
.
apkFilesFor
(
const
AndroidBuildInfo
(
BuildInfo
.
profile
)).
first
,
'app-profile.apk'
);
expect
(
project
.
apkFilesFor
(
const
AndroidBuildInfo
(
BuildInfo
.
profile
)).
first
,
'app-profile.apk'
);
expect
(
project
.
apkFilesFor
(
const
AndroidBuildInfo
(
BuildInfo
.
release
)).
first
,
'app-release.apk'
);
expect
(
project
.
apkFilesFor
(
const
AndroidBuildInfo
(
BuildInfo
.
release
)).
first
,
'app-release.apk'
);
expect
(
project
.
apkFilesFor
(
const
AndroidBuildInfo
(
BuildInfo
(
BuildMode
.
release
,
'unknown'
))).
isEmpty
,
isTrue
);
expect
(
project
.
apkFilesFor
(
const
AndroidBuildInfo
(
BuildInfo
(
BuildMode
.
release
,
'unknown'
))).
isEmpty
,
isTrue
);
});
});
test
(
'should provide apk file name for flavored build types'
,
()
{
test
(
'should provide apk file name for flavored build types'
,
()
{
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[
'free'
,
'paid'
],
'/some/dir'
);
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[
'free'
,
'paid'
],
fs
.
directory
(
'/some/dir'
),
fs
.
directory
(
'/some/dir'
)
);
expect
(
project
.
apkFilesFor
(
const
AndroidBuildInfo
(
BuildInfo
(
BuildMode
.
debug
,
'free'
))).
first
,
'app-free-debug.apk'
);
expect
(
project
.
apkFilesFor
(
const
AndroidBuildInfo
(
BuildInfo
(
BuildMode
.
debug
,
'free'
))).
first
,
'app-free-debug.apk'
);
expect
(
project
.
apkFilesFor
(
const
AndroidBuildInfo
(
BuildInfo
(
BuildMode
.
release
,
'paid'
))).
first
,
'app-paid-release.apk'
);
expect
(
project
.
apkFilesFor
(
const
AndroidBuildInfo
(
BuildInfo
(
BuildMode
.
release
,
'paid'
))).
first
,
'app-paid-release.apk'
);
expect
(
project
.
apkFilesFor
(
const
AndroidBuildInfo
(
BuildInfo
(
BuildMode
.
release
,
'unknown'
))).
isEmpty
,
isTrue
);
expect
(
project
.
apkFilesFor
(
const
AndroidBuildInfo
(
BuildInfo
(
BuildMode
.
release
,
'unknown'
))).
isEmpty
,
isTrue
);
});
});
test
(
'should provide apks for default build types and each ABI'
,
()
{
test
(
'should provide apks for default build types and each ABI'
,
()
{
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
'/some/dir'
);
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
fs
.
directory
(
'/some/dir'
),
fs
.
directory
(
'/some/dir'
)
);
expect
(
project
.
apkFilesFor
(
expect
(
project
.
apkFilesFor
(
const
AndroidBuildInfo
(
const
AndroidBuildInfo
(
BuildInfo
.
debug
,
BuildInfo
.
debug
,
...
@@ -226,7 +224,7 @@ someOtherTask
...
@@ -226,7 +224,7 @@ someOtherTask
).
isEmpty
,
isTrue
);
).
isEmpty
,
isTrue
);
});
});
test
(
'should provide apks for each ABI and flavored build types'
,
()
{
test
(
'should provide apks for each ABI and flavored build types'
,
()
{
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[
'free'
,
'paid'
],
'/some/dir'
);
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[
'free'
,
'paid'
],
fs
.
directory
(
'/some/dir'
),
fs
.
directory
(
'/some/dir'
)
);
expect
(
project
.
apkFilesFor
(
expect
(
project
.
apkFilesFor
(
const
AndroidBuildInfo
(
const
AndroidBuildInfo
(
BuildInfo
(
BuildMode
.
debug
,
'free'
),
BuildInfo
(
BuildMode
.
debug
,
'free'
),
...
@@ -269,154 +267,54 @@ someOtherTask
...
@@ -269,154 +267,54 @@ someOtherTask
).
isEmpty
,
isTrue
);
).
isEmpty
,
isTrue
);
});
});
test
(
'should provide bundle file name for default build types'
,
()
{
test
(
'should provide bundle file name for default build types'
,
()
{
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
'/some/dir'
);
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
fs
.
directory
(
'/some/dir'
),
fs
.
directory
(
'/some/dir'
)
);
expect
(
project
.
bundleFileFor
(
BuildInfo
.
debug
),
'app.aab'
);
expect
(
project
.
bundleFileFor
(
BuildInfo
.
debug
),
'app.aab'
);
expect
(
project
.
bundleFileFor
(
BuildInfo
.
profile
),
'app.aab'
);
expect
(
project
.
bundleFileFor
(
BuildInfo
.
profile
),
'app.aab'
);
expect
(
project
.
bundleFileFor
(
BuildInfo
.
release
),
'app.aab'
);
expect
(
project
.
bundleFileFor
(
BuildInfo
.
release
),
'app.aab'
);
expect
(
project
.
bundleFileFor
(
const
BuildInfo
(
BuildMode
.
release
,
'unknown'
)),
'app.aab'
);
expect
(
project
.
bundleFileFor
(
const
BuildInfo
(
BuildMode
.
release
,
'unknown'
)),
'app.aab'
);
});
});
test
(
'should provide bundle file name for flavored build types'
,
()
{
test
(
'should provide bundle file name for flavored build types'
,
()
{
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[
'free'
,
'paid'
],
'/some/dir'
);
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[
'free'
,
'paid'
],
fs
.
directory
(
'/some/dir'
),
fs
.
directory
(
'/some/dir'
)
);
expect
(
project
.
bundleFileFor
(
const
BuildInfo
(
BuildMode
.
debug
,
'free'
)),
'app.aab'
);
expect
(
project
.
bundleFileFor
(
const
BuildInfo
(
BuildMode
.
debug
,
'free'
)),
'app.aab'
);
expect
(
project
.
bundleFileFor
(
const
BuildInfo
(
BuildMode
.
release
,
'paid'
)),
'app.aab'
);
expect
(
project
.
bundleFileFor
(
const
BuildInfo
(
BuildMode
.
release
,
'paid'
)),
'app.aab'
);
expect
(
project
.
bundleFileFor
(
const
BuildInfo
(
BuildMode
.
release
,
'unknown'
)),
'app.aab'
);
expect
(
project
.
bundleFileFor
(
const
BuildInfo
(
BuildMode
.
release
,
'unknown'
)),
'app.aab'
);
});
});
test
(
'should provide assemble task name for default build types'
,
()
{
test
(
'should provide assemble task name for default build types'
,
()
{
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
'/some/dir'
);
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
fs
.
directory
(
'/some/dir'
),
fs
.
directory
(
'/some/dir'
)
);
expect
(
project
.
assembleTaskFor
(
BuildInfo
.
debug
),
'assembleDebug'
);
expect
(
project
.
assembleTaskFor
(
BuildInfo
.
debug
),
'assembleDebug'
);
expect
(
project
.
assembleTaskFor
(
BuildInfo
.
profile
),
'assembleProfile'
);
expect
(
project
.
assembleTaskFor
(
BuildInfo
.
profile
),
'assembleProfile'
);
expect
(
project
.
assembleTaskFor
(
BuildInfo
.
release
),
'assembleRelease'
);
expect
(
project
.
assembleTaskFor
(
BuildInfo
.
release
),
'assembleRelease'
);
expect
(
project
.
assembleTaskFor
(
const
BuildInfo
(
BuildMode
.
release
,
'unknown'
)),
isNull
);
expect
(
project
.
assembleTaskFor
(
const
BuildInfo
(
BuildMode
.
release
,
'unknown'
)),
isNull
);
});
});
test
(
'should provide assemble task name for flavored build types'
,
()
{
test
(
'should provide assemble task name for flavored build types'
,
()
{
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[
'free'
,
'paid'
],
'/some/dir'
);
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[
'free'
,
'paid'
],
fs
.
directory
(
'/some/dir'
),
fs
.
directory
(
'/some/dir'
)
);
expect
(
project
.
assembleTaskFor
(
const
BuildInfo
(
BuildMode
.
debug
,
'free'
)),
'assembleFreeDebug'
);
expect
(
project
.
assembleTaskFor
(
const
BuildInfo
(
BuildMode
.
debug
,
'free'
)),
'assembleFreeDebug'
);
expect
(
project
.
assembleTaskFor
(
const
BuildInfo
(
BuildMode
.
release
,
'paid'
)),
'assemblePaidRelease'
);
expect
(
project
.
assembleTaskFor
(
const
BuildInfo
(
BuildMode
.
release
,
'paid'
)),
'assemblePaidRelease'
);
expect
(
project
.
assembleTaskFor
(
const
BuildInfo
(
BuildMode
.
release
,
'unknown'
)),
isNull
);
expect
(
project
.
assembleTaskFor
(
const
BuildInfo
(
BuildMode
.
release
,
'unknown'
)),
isNull
);
});
});
test
(
'should respect format of the flavored build types'
,
()
{
test
(
'should respect format of the flavored build types'
,
()
{
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
],
<
String
>[
'randomFlavor'
],
'/some/dir'
);
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
],
<
String
>[
'randomFlavor'
],
fs
.
directory
(
'/some/dir'
),
fs
.
directory
(
'/some/dir'
)
);
expect
(
project
.
assembleTaskFor
(
const
BuildInfo
(
BuildMode
.
debug
,
'randomFlavor'
)),
'assembleRandomFlavorDebug'
);
expect
(
project
.
assembleTaskFor
(
const
BuildInfo
(
BuildMode
.
debug
,
'randomFlavor'
)),
'assembleRandomFlavorDebug'
);
});
});
test
(
'bundle should provide assemble task name for default build types'
,
()
{
test
(
'bundle should provide assemble task name for default build types'
,
()
{
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
'/some/dir'
);
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[],
fs
.
directory
(
'/some/dir'
),
fs
.
directory
(
'/some/dir'
)
);
expect
(
project
.
bundleTaskFor
(
BuildInfo
.
debug
),
'bundleDebug'
);
expect
(
project
.
bundleTaskFor
(
BuildInfo
.
debug
),
'bundleDebug'
);
expect
(
project
.
bundleTaskFor
(
BuildInfo
.
profile
),
'bundleProfile'
);
expect
(
project
.
bundleTaskFor
(
BuildInfo
.
profile
),
'bundleProfile'
);
expect
(
project
.
bundleTaskFor
(
BuildInfo
.
release
),
'bundleRelease'
);
expect
(
project
.
bundleTaskFor
(
BuildInfo
.
release
),
'bundleRelease'
);
expect
(
project
.
bundleTaskFor
(
const
BuildInfo
(
BuildMode
.
release
,
'unknown'
)),
isNull
);
expect
(
project
.
bundleTaskFor
(
const
BuildInfo
(
BuildMode
.
release
,
'unknown'
)),
isNull
);
});
});
test
(
'bundle should provide assemble task name for flavored build types'
,
()
{
test
(
'bundle should provide assemble task name for flavored build types'
,
()
{
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[
'free'
,
'paid'
],
'/some/dir'
);
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'profile'
,
'release'
],
<
String
>[
'free'
,
'paid'
],
fs
.
directory
(
'/some/dir'
),
fs
.
directory
(
'/some/dir'
)
);
expect
(
project
.
bundleTaskFor
(
const
BuildInfo
(
BuildMode
.
debug
,
'free'
)),
'bundleFreeDebug'
);
expect
(
project
.
bundleTaskFor
(
const
BuildInfo
(
BuildMode
.
debug
,
'free'
)),
'bundleFreeDebug'
);
expect
(
project
.
bundleTaskFor
(
const
BuildInfo
(
BuildMode
.
release
,
'paid'
)),
'bundlePaidRelease'
);
expect
(
project
.
bundleTaskFor
(
const
BuildInfo
(
BuildMode
.
release
,
'paid'
)),
'bundlePaidRelease'
);
expect
(
project
.
bundleTaskFor
(
const
BuildInfo
(
BuildMode
.
release
,
'unknown'
)),
isNull
);
expect
(
project
.
bundleTaskFor
(
const
BuildInfo
(
BuildMode
.
release
,
'unknown'
)),
isNull
);
});
});
test
(
'bundle should respect format of the flavored build types'
,
()
{
test
(
'bundle should respect format of the flavored build types'
,
()
{
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
],
<
String
>[
'randomFlavor'
],
'/some/dir'
);
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
],
<
String
>[
'randomFlavor'
],
fs
.
directory
(
'/some/dir'
),
fs
.
directory
(
'/some/dir'
)
);
expect
(
project
.
bundleTaskFor
(
const
BuildInfo
(
BuildMode
.
debug
,
'randomFlavor'
)),
'bundleRandomFlavorDebug'
);
expect
(
project
.
bundleTaskFor
(
const
BuildInfo
(
BuildMode
.
debug
,
'randomFlavor'
)),
'bundleRandomFlavorDebug'
);
});
});
});
});
group
(
'Config files'
,
()
{
BufferLogger
mockLogger
;
Directory
tempDir
;
setUp
(()
{
mockLogger
=
BufferLogger
();
tempDir
=
fs
.
systemTempDirectory
.
createTempSync
(
'settings_aar_test.'
);
});
testUsingContext
(
'create settings_aar.gradle'
,
()
{
const
String
deprecatedFile
=
'''
include '
:
app
'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '
.
flutter
-
plugins
')
if (pluginsFile.exists()) {
pluginsFile.withReader('
UTF
-
8
') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('
android
').toFile()
include ":
\
$name
"
project(":
\
$name
").projectDir = pluginDirectory
}
'''
;
const
String
settingsAarFile
=
'''
include '
:
app
'
'''
;
tempDir
.
childFile
(
'settings.gradle'
).
writeAsStringSync
(
deprecatedFile
);
final
String
toolGradlePath
=
fs
.
path
.
join
(
fs
.
path
.
absolute
(
Cache
.
flutterRoot
),
'packages'
,
'flutter_tools'
,
'gradle'
);
fs
.
directory
(
toolGradlePath
).
createSync
(
recursive:
true
);
fs
.
file
(
fs
.
path
.
join
(
toolGradlePath
,
'deprecated_settings.gradle'
))
.
writeAsStringSync
(
deprecatedFile
);
fs
.
file
(
fs
.
path
.
join
(
toolGradlePath
,
'settings_aar.gradle.tmpl'
))
.
writeAsStringSync
(
settingsAarFile
);
createSettingsAarGradle
(
tempDir
);
expect
(
mockLogger
.
statusText
,
contains
(
'created successfully'
));
expect
(
tempDir
.
childFile
(
'settings_aar.gradle'
).
existsSync
(),
isTrue
);
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
MemoryFileSystem
(),
Logger:
()
=>
mockLogger
,
});
});
group
(
'Undefined task'
,
()
{
BufferLogger
mockLogger
;
setUp
(()
{
mockLogger
=
BufferLogger
();
});
testUsingContext
(
'print undefined build type'
,
()
{
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'release'
],
const
<
String
>[
'free'
,
'paid'
],
'/some/dir'
);
printUndefinedTask
(
project
,
const
BuildInfo
(
BuildMode
.
profile
,
'unknown'
));
expect
(
mockLogger
.
errorText
,
contains
(
'The Gradle project does not define a task suitable for the requested build'
));
expect
(
mockLogger
.
errorText
,
contains
(
'Review the android/app/build.gradle file and ensure it defines a profile build type'
));
},
overrides:
<
Type
,
Generator
>{
Logger:
()
=>
mockLogger
,
});
testUsingContext
(
'print no flavors'
,
()
{
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'release'
],
const
<
String
>[],
'/some/dir'
);
printUndefinedTask
(
project
,
const
BuildInfo
(
BuildMode
.
debug
,
'unknown'
));
expect
(
mockLogger
.
errorText
,
contains
(
'The Gradle project does not define a task suitable for the requested build'
));
expect
(
mockLogger
.
errorText
,
contains
(
'The android/app/build.gradle file does not define any custom product flavors'
));
expect
(
mockLogger
.
errorText
,
contains
(
'You cannot use the --flavor option'
));
},
overrides:
<
Type
,
Generator
>{
Logger:
()
=>
mockLogger
,
});
testUsingContext
(
'print flavors'
,
()
{
final
GradleProject
project
=
GradleProject
(<
String
>[
'debug'
,
'release'
],
const
<
String
>[
'free'
,
'paid'
],
'/some/dir'
);
printUndefinedTask
(
project
,
const
BuildInfo
(
BuildMode
.
debug
,
'unknown'
));
expect
(
mockLogger
.
errorText
,
contains
(
'The Gradle project does not define a task suitable for the requested build'
));
expect
(
mockLogger
.
errorText
,
contains
(
'The android/app/build.gradle file defines product flavors: free, paid'
));
},
overrides:
<
Type
,
Generator
>{
Logger:
()
=>
mockLogger
,
});
});
group
(
'Gradle local.properties'
,
()
{
group
(
'Gradle local.properties'
,
()
{
MockLocalEngineArtifacts
mockArtifacts
;
MockLocalEngineArtifacts
mockArtifacts
;
MockProcessManager
mockProcessManager
;
MockProcessManager
mockProcessManager
;
...
@@ -642,52 +540,6 @@ flutter:
...
@@ -642,52 +540,6 @@ flutter:
);
);
});
});
});
});
group
(
'gradle version'
,
()
{
test
(
'should be compatible with the Android plugin version'
,
()
{
// Granular versions.
expect
(
getGradleVersionFor
(
'1.0.0'
),
'2.3'
);
expect
(
getGradleVersionFor
(
'1.0.1'
),
'2.3'
);
expect
(
getGradleVersionFor
(
'1.0.2'
),
'2.3'
);
expect
(
getGradleVersionFor
(
'1.0.4'
),
'2.3'
);
expect
(
getGradleVersionFor
(
'1.0.8'
),
'2.3'
);
expect
(
getGradleVersionFor
(
'1.1.0'
),
'2.3'
);
expect
(
getGradleVersionFor
(
'1.1.2'
),
'2.3'
);
expect
(
getGradleVersionFor
(
'1.1.2'
),
'2.3'
);
expect
(
getGradleVersionFor
(
'1.1.3'
),
'2.3'
);
// Version Ranges.
expect
(
getGradleVersionFor
(
'1.2.0'
),
'2.9'
);
expect
(
getGradleVersionFor
(
'1.3.1'
),
'2.9'
);
expect
(
getGradleVersionFor
(
'1.5.0'
),
'2.2.1'
);
expect
(
getGradleVersionFor
(
'2.0.0'
),
'2.13'
);
expect
(
getGradleVersionFor
(
'2.1.2'
),
'2.13'
);
expect
(
getGradleVersionFor
(
'2.1.3'
),
'2.14.1'
);
expect
(
getGradleVersionFor
(
'2.2.3'
),
'2.14.1'
);
expect
(
getGradleVersionFor
(
'2.3.0'
),
'3.3'
);
expect
(
getGradleVersionFor
(
'3.0.0'
),
'4.1'
);
expect
(
getGradleVersionFor
(
'3.1.0'
),
'4.4'
);
expect
(
getGradleVersionFor
(
'3.2.0'
),
'4.6'
);
expect
(
getGradleVersionFor
(
'3.2.1'
),
'4.6'
);
expect
(
getGradleVersionFor
(
'3.3.0'
),
'4.10.2'
);
expect
(
getGradleVersionFor
(
'3.3.2'
),
'4.10.2'
);
expect
(
getGradleVersionFor
(
'3.4.0'
),
'5.1.1'
);
expect
(
getGradleVersionFor
(
'3.5.0'
),
'5.1.1'
);
});
test
(
'throws on unsupported versions'
,
()
{
expect
(()
=>
getGradleVersionFor
(
'3.6.0'
),
throwsA
(
predicate
<
Exception
>((
Exception
e
)
=>
e
is
ToolExit
)));
});
});
}
}
Platform
fakePlatform
(
String
name
)
{
Platform
fakePlatform
(
String
name
)
{
...
...
packages/flutter_tools/test/general.shard/commands/build_aar_test.dart
deleted
100644 → 0
View file @
11460b83
// 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.
import
'package:args/command_runner.dart'
;
import
'package:flutter_tools/src/android/aar.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/commands/build_aar.dart'
;
import
'package:flutter_tools/src/reporting/usage.dart'
;
import
'package:mockito/mockito.dart'
;
import
'../../src/common.dart'
;
import
'../../src/context.dart'
;
void
main
(
)
{
Cache
.
disableLocking
();
group
(
'getUsage'
,
()
{
Directory
tempDir
;
AarBuilder
mockAarBuilder
;
setUp
(()
{
tempDir
=
fs
.
systemTempDirectory
.
createTempSync
(
'flutter_tools_packages_test.'
);
mockAarBuilder
=
MockAarBuilder
();
when
(
mockAarBuilder
.
build
(
project:
anyNamed
(
'project'
),
androidBuildInfo:
anyNamed
(
'androidBuildInfo'
),
target:
anyNamed
(
'target'
),
outputDir:
anyNamed
(
'outputDir'
))).
thenAnswer
((
_
)
=>
Future
<
void
>.
value
());
});
tearDown
(()
{
tryToDelete
(
tempDir
);
});
Future
<
BuildAarCommand
>
runCommandIn
(
String
target
,
{
List
<
String
>
arguments
})
async
{
final
BuildAarCommand
command
=
BuildAarCommand
();
final
CommandRunner
<
void
>
runner
=
createTestCommandRunner
(
command
);
await
runner
.
run
(<
String
>[
'aar'
,
...?
arguments
,
target
,
]);
return
command
;
}
testUsingContext
(
'indicate that project is a module'
,
()
async
{
final
String
projectPath
=
await
createProject
(
tempDir
,
arguments:
<
String
>[
'--no-pub'
,
'--template=module'
]);
final
BuildAarCommand
command
=
await
runCommandIn
(
projectPath
);
expect
(
await
command
.
usageValues
,
containsPair
(
kCommandBuildAarProjectType
,
'module'
));
},
overrides:
<
Type
,
Generator
>{
AarBuilder:
()
=>
mockAarBuilder
,
},
timeout:
allowForCreateFlutterProject
);
testUsingContext
(
'indicate that project is a plugin'
,
()
async
{
final
String
projectPath
=
await
createProject
(
tempDir
,
arguments:
<
String
>[
'--no-pub'
,
'--template=plugin'
,
'--project-name=aar_test'
]);
final
BuildAarCommand
command
=
await
runCommandIn
(
projectPath
);
expect
(
await
command
.
usageValues
,
containsPair
(
kCommandBuildAarProjectType
,
'plugin'
));
},
overrides:
<
Type
,
Generator
>{
AarBuilder:
()
=>
mockAarBuilder
,
},
timeout:
allowForCreateFlutterProject
);
testUsingContext
(
'indicate the target platform'
,
()
async
{
final
String
projectPath
=
await
createProject
(
tempDir
,
arguments:
<
String
>[
'--no-pub'
,
'--template=module'
]);
final
BuildAarCommand
command
=
await
runCommandIn
(
projectPath
,
arguments:
<
String
>[
'--target-platform=android-arm'
]);
expect
(
await
command
.
usageValues
,
containsPair
(
kCommandBuildAarTargetPlatform
,
'android-arm'
));
},
overrides:
<
Type
,
Generator
>{
AarBuilder:
()
=>
mockAarBuilder
,
},
timeout:
allowForCreateFlutterProject
);
});
}
class
MockAarBuilder
extends
Mock
implements
AarBuilder
{}
packages/flutter_tools/test/general.shard/features_test.dart
View file @
c9b466f9
...
@@ -418,21 +418,6 @@ void main() {
...
@@ -418,21 +418,6 @@ void main() {
expect
(
featureFlags
.
isWindowsEnabled
,
false
);
expect
(
featureFlags
.
isWindowsEnabled
,
false
);
}));
}));
/// Plugins as AARS
test
(
'plugins built as AARs with config on master'
,
()
=>
testbed
.
run
(()
{
when
(
mockFlutterVerion
.
channel
).
thenReturn
(
'master'
);
when
<
bool
>(
mockFlutterConfig
.
getValue
(
'enable-build-plugin-as-aar'
)).
thenReturn
(
true
);
expect
(
featureFlags
.
isPluginAsAarEnabled
,
true
);
}));
test
(
'plugins built as AARs with config on dev'
,
()
=>
testbed
.
run
(()
{
when
(
mockFlutterVerion
.
channel
).
thenReturn
(
'dev'
);
when
<
bool
>(
mockFlutterConfig
.
getValue
(
'enable-build-plugin-as-aar'
)).
thenReturn
(
true
);
expect
(
featureFlags
.
isPluginAsAarEnabled
,
true
);
}));
});
});
}
}
...
...
packages/flutter_tools/test/src/testbed.dart
View file @
c9b466f9
...
@@ -697,7 +697,6 @@ class TestFeatureFlags implements FeatureFlags {
...
@@ -697,7 +697,6 @@ class TestFeatureFlags implements FeatureFlags {
this
.
isMacOSEnabled
=
false
,
this
.
isMacOSEnabled
=
false
,
this
.
isWebEnabled
=
false
,
this
.
isWebEnabled
=
false
,
this
.
isWindowsEnabled
=
false
,
this
.
isWindowsEnabled
=
false
,
this
.
isPluginAsAarEnabled
=
false
,
});
});
@override
@override
...
@@ -711,7 +710,4 @@ class TestFeatureFlags implements FeatureFlags {
...
@@ -711,7 +710,4 @@ class TestFeatureFlags implements FeatureFlags {
@override
@override
final
bool
isWindowsEnabled
;
final
bool
isWindowsEnabled
;
@override
final
bool
isPluginAsAarEnabled
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment