@@ -8,72 +8,100 @@ import 'dart:io';
88import 'package:flutter_devicelab/framework/apk_utils.dart' ;
99import 'package:flutter_devicelab/framework/framework.dart' ;
1010import 'package:flutter_devicelab/framework/task_result.dart' ;
11- import 'package:flutter_devicelab/framework/utils.dart' ;
11+ import 'package:flutter_devicelab/framework/utils.dart' as utils ;
1212import 'package:path/path.dart' as path;
1313
1414Future <void > main () async {
1515 await task (() async {
1616 try {
1717 await runProjectTest ((FlutterProject flutterProject) async {
18+ utils.section (
19+ 'Configure plugins to be marked as dev dependencies in .flutter-plugins-dependencies file' ,
20+ );
21+
1822 // Enable plugins being marked as dev dependncies in the .flutter-plugins-dependencies file.
19- await flutter ('config' , options: < String > ['--explicit-package-dependencies' ]);
23+ await utils. flutter ('config' , options: < String > ['--explicit-package-dependencies' ]);
2024
2125 // Create dev_dependency plugin to use for test.
2226 final Directory tempDir = Directory .systemTemp.createTempSync (
2327 'android_release_builds_exclude_dev_dependencies_test.' ,
2428 );
2529 const String devDependencyPluginOrg = 'com.example.dev_dependency_plugin' ;
30+
31+ utils.section ('Create plugin dev_dependency_plugin that supports Android' );
32+
2633 await FlutterPluginProject .create (
2734 tempDir,
2835 'dev_dependency_plugin' ,
2936 options: < String > ['--platforms=android' , '--org=$devDependencyPluginOrg ' ],
3037 );
3138
39+ utils.section ('Add dev_dependency_plugin as a dev dependency to the Flutter app project' );
40+
3241 // Add devDependencyPlugin as dependency of flutterProject.
3342 await flutterProject.addPlugin (
34- 'dev_dependency_plugin' ,
43+ 'dev: dev_dependency_plugin' ,
3544 options: < String > ['--path' , path.join (tempDir.path, 'dev_dependency_plugin' )],
3645 );
3746
47+ utils.section (
48+ 'Verify the app includes/excludes dev_dependency_plugin as dependency in each build mode as expected' ,
49+ );
3850 final List <String > buildModesToTest = < String > ['debug' , 'profile' , 'release' ];
3951 for (final String buildMode in buildModesToTest) {
40- section ('APK does contain methods from dev dependency in $buildMode mode' );
52+ final String gradlew = Platform .isWindows ? 'gradlew.bat' : 'gradlew' ;
53+ final String gradlewExecutable = Platform .isWindows ? '.\\ $gradlew ' : './$gradlew ' ;
54+ final RegExp regExpToMatchDevDependencyPlugin = RegExp (
55+ r'--- project :dev_dependency_plugin' ,
56+ );
57+ final RegExp regExpToMatchDevDependencyPluginWithTransitiveDependencies = RegExp (
58+ r'--- project :dev_dependency_plugin\n(\s)*\+--- org.jetbrains.kotlin.*\s\(\*\)\n(\s)*\\---\sio.flutter:flutter_embedding_' +
59+ buildMode,
60+ );
61+ const String stringToMatchFlutterEmbedding = '+--- io.flutter:flutter_embedding_release:' ;
62+ final bool isTestingReleaseMode = buildMode == 'release' ;
4163
42- // Build APK in buildMode and check that devDependencyPlugin is included/excluded in the APK as expected.
43- await inDirectory (flutterProject.rootPath, () async {
44- await flutter (
45- 'build' ,
46- options: < String > ['apk' , '--$buildMode ' , '--target-platform=android-arm' ],
47- );
64+ utils.section ('Query the dependencies of the app built with $buildMode ' );
4865
49- final File apk = File (
50- path.join (
51- flutterProject.rootPath,
52- 'build' ,
53- 'app' ,
54- 'outputs' ,
55- 'flutter-apk' ,
56- 'app-$buildMode .apk' ,
57- ),
58- );
59- if (! apk.existsSync ()) {
60- throw TaskResult .failure ("Expected ${apk .path } to exist, but it doesn't." );
61- }
66+ final String appDependencies = await utils.eval (gradlewExecutable, < String > [
67+ 'app:dependencies' ,
68+ '--configuration' ,
69+ '${buildMode }RuntimeClasspath' ,
70+ ], workingDirectory: flutterProject.androidPath);
6271
63- // We expect the APK to include the devDependencyPlugin except in release mode.
64- final bool isTestingReleaseMode = buildMode == 'release' ;
65- final bool apkIncludesDevDependency = await checkApkContainsMethodsFromLibrary (
66- apk,
67- devDependencyPluginOrg,
72+ if (isTestingReleaseMode) {
73+ utils.section (
74+ 'Check that the release build includes Flutter embedding as a direct dependency' ,
6875 );
69- final bool apkIncludesDevDependencyAsExpected =
70- isTestingReleaseMode ? ! apkIncludesDevDependency : apkIncludesDevDependency;
71- if (! apkIncludesDevDependencyAsExpected) {
76+
77+ if (! appDependencies.contains (stringToMatchFlutterEmbedding)) {
78+ // We expect dev_dependency_plugin to not be included in the dev dependency, but the Flutter
79+ // embedding should still be a dependency of the app project (regardless of the fact
80+ // that the app does not depend on any plugins that support Android, which would cause the
81+ // Flutter embedding to be included as a transitive dependency).
7282 throw TaskResult .failure (
73- 'Expected to${ isTestingReleaseMode ? ' not' : '' } find dev_dependency_plugin in APK built with debug mode but did${ isTestingReleaseMode ? '' : ' not' } .' ,
83+ 'Expected to find the Flutter embedding as a dependency of the release app build, but did not.' ,
7484 );
7585 }
76- });
86+ }
87+
88+ utils.section (
89+ 'Check that the $buildMode build includes/excludes the dev dependency plugin as expected' ,
90+ );
91+
92+ // Ensure that release builds have no reference to the dev dependency plugin and make sure
93+ // that it is included with expected transitive dependencies for debug, profile builds.
94+ final bool appIncludesDevDependencyAsExpected =
95+ isTestingReleaseMode
96+ ? ! appDependencies.contains (regExpToMatchDevDependencyPlugin)
97+ : appDependencies.contains (
98+ regExpToMatchDevDependencyPluginWithTransitiveDependencies,
99+ );
100+ if (! appIncludesDevDependencyAsExpected) {
101+ throw TaskResult .failure (
102+ 'Expected to${isTestingReleaseMode ? ' not' : '' } find dev_dependency_plugin as a dependency of the app built in $buildMode mode but did${isTestingReleaseMode ? '' : ' not' }.' ,
103+ );
104+ }
77105 }
78106 });
79107 return TaskResult .success (null );
0 commit comments