Unverified Commit d8a5f3d1 authored by chunhtai's avatar chunhtai Committed by GitHub

Improves output file path logic in Android analyze (#136981)

parent 2dc81113
...@@ -752,7 +752,7 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -752,7 +752,7 @@ class FlutterPlugin implements Plugin<Project> {
// //
// See https://developer.android.com/training/app-links/ for more information about app link. // See https://developer.android.com/training/app-links/ for more information about app link.
// //
// The json will be stored in <project>/build/app/app-link-settings-<variant>.json // The json will be saved in path stored in outputPath parameter.
// //
// An example json: // An example json:
// { // {
...@@ -830,7 +830,7 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -830,7 +830,7 @@ class FlutterPlugin implements Plugin<Project> {
} }
} }
def generator = new JsonGenerator.Options().build() def generator = new JsonGenerator.Options().build()
new File(project.buildDir, "app-link-settings-${variant.name}.json").write(generator.toJson(appLinkSettings)) new File(project.getProperty("outputPath")).write(generator.toJson(appLinkSettings))
} }
} }
} }
......
...@@ -44,7 +44,9 @@ abstract class AndroidBuilder { ...@@ -44,7 +44,9 @@ abstract class AndroidBuilder {
Future<List<String>> getBuildVariants({required FlutterProject project}); Future<List<String>> getBuildVariants({required FlutterProject project});
/// Outputs app link related project settings into a json file. /// Outputs app link related project settings into a json file.
Future<void> outputsAppLinkSettings( ///
/// The return future resolves to the path of the json file.
Future<String> outputsAppLinkSettings(
String buildVariant, { String buildVariant, {
required FlutterProject project, required FlutterProject project,
}); });
......
...@@ -810,16 +810,22 @@ class AndroidGradleBuilder implements AndroidBuilder { ...@@ -810,16 +810,22 @@ class AndroidGradleBuilder implements AndroidBuilder {
} }
@override @override
Future<void> outputsAppLinkSettings( Future<String> outputsAppLinkSettings(
String buildVariant, { String buildVariant, {
required FlutterProject project, required FlutterProject project,
}) async { }) async {
final String taskName = _getOutputAppLinkSettingsTaskFor(buildVariant); final String taskName = _getOutputAppLinkSettingsTaskFor(buildVariant);
final Directory directory = await project.buildDirectory
.childDirectory('deeplink_data').create(recursive: true);
final String outputPath = globals.fs.path.join(
directory.absolute.path,
'app-link-settings-$buildVariant.json',
);
final Stopwatch sw = Stopwatch() final Stopwatch sw = Stopwatch()
..start(); ..start();
final RunResult result = await _runGradleTask( final RunResult result = await _runGradleTask(
taskName, taskName,
options: const <String>['-q'], options: <String>['-q', '-PoutputPath=$outputPath'],
project: project, project: project,
); );
_usage.sendTiming('outputs', 'app link settings', sw.elapsed); _usage.sendTiming('outputs', 'app link settings', sw.elapsed);
...@@ -827,7 +833,9 @@ class AndroidGradleBuilder implements AndroidBuilder { ...@@ -827,7 +833,9 @@ class AndroidGradleBuilder implements AndroidBuilder {
if (result.exitCode != 0) { if (result.exitCode != 0) {
_logger.printStatus(result.stdout, wrap: false); _logger.printStatus(result.stdout, wrap: false);
_logger.printError(result.stderr, wrap: false); _logger.printError(result.stderr, wrap: false);
throwToolExit(result.stderr);
} }
return outputPath;
} }
} }
......
...@@ -48,8 +48,7 @@ class AndroidAnalyze { ...@@ -48,8 +48,7 @@ class AndroidAnalyze {
logger.printStatus(jsonEncode(await project.android.getBuildVariants())); logger.printStatus(jsonEncode(await project.android.getBuildVariants()));
case AndroidAnalyzeOption.outputAppLinkSettings: case AndroidAnalyzeOption.outputAppLinkSettings:
assert(buildVariant != null); assert(buildVariant != null);
await project.android.outputsAppLinkSettings(variant: buildVariant!); final String filePath = await project.android.outputsAppLinkSettings(variant: buildVariant!);
final String filePath = fileSystem.path.join(project.directory.path, 'build', 'app', 'app-link-settings-$buildVariant.json`');
logger.printStatus('result saved in $filePath'); logger.printStatus('result saved in $filePath');
} }
} }
......
...@@ -501,13 +501,14 @@ class AndroidProject extends FlutterProjectPlatform { ...@@ -501,13 +501,14 @@ class AndroidProject extends FlutterProjectPlatform {
/// Outputs app link related settings into a json file. /// Outputs app link related settings into a json file.
/// ///
/// The file is stored in /// The return future resolves to the path of the json file.
/// `<project>/build/app/app-link-settings-<variant>.json`. ///
Future<void> outputsAppLinkSettings({required String variant}) async { /// The future resolves to null if it fails to retrieve app link settings.
Future<String> outputsAppLinkSettings({required String variant}) async {
if (!existsSync() || androidBuilder == null) { if (!existsSync() || androidBuilder == null) {
return; throwToolExit('Target directory $hostAppGradleRoot is not an Android project');
} }
await androidBuilder!.outputsAppLinkSettings(variant, project: parent); return androidBuilder!.outputsAppLinkSettings(variant, project: parent);
} }
bool _computeSupportedVersion() { bool _computeSupportedVersion() {
......
...@@ -94,6 +94,7 @@ void main() { ...@@ -94,6 +94,7 @@ void main() {
const String buildVariant = 'release'; const String buildVariant = 'release';
await runner.run(<String>['analyze', '--android', '--output-app-link-settings', '--build-variant=$buildVariant', tempDir.path]); await runner.run(<String>['analyze', '--android', '--output-app-link-settings', '--build-variant=$buildVariant', tempDir.path]);
expect(builder.outputVariant, buildVariant); expect(builder.outputVariant, buildVariant);
expect(logger.statusText, contains(builder.outputPath));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
AndroidBuilder: () => builder, AndroidBuilder: () => builder,
}); });
...@@ -116,6 +117,7 @@ void main() { ...@@ -116,6 +117,7 @@ void main() {
class FakeAndroidBuilder extends Fake implements AndroidBuilder { class FakeAndroidBuilder extends Fake implements AndroidBuilder {
List<String> variants = const <String>[]; List<String> variants = const <String>[];
String? outputVariant; String? outputVariant;
final String outputPath = '/';
@override @override
Future<List<String>> getBuildVariants({required FlutterProject project}) async { Future<List<String>> getBuildVariants({required FlutterProject project}) async {
...@@ -123,7 +125,8 @@ class FakeAndroidBuilder extends Fake implements AndroidBuilder { ...@@ -123,7 +125,8 @@ class FakeAndroidBuilder extends Fake implements AndroidBuilder {
} }
@override @override
Future<void> outputsAppLinkSettings(String buildVariant, {required FlutterProject project}) async { Future<String> outputsAppLinkSettings(String buildVariant, {required FlutterProject project}) async {
outputVariant = buildVariant; outputVariant = buildVariant;
return outputPath;
} }
} }
...@@ -914,7 +914,9 @@ Gradle Crashed ...@@ -914,7 +914,9 @@ Gradle Crashed
AndroidStudio: () => FakeAndroidStudio(), AndroidStudio: () => FakeAndroidStudio(),
}); });
testUsingContext('can call custom gradle task getApplicationIdForVariant and parse the result', () async { testUsingContext('can call custom gradle task outputFreeDebugAppLinkSettings and parse the result', () async {
final String expectedOutputPath;
expectedOutputPath = fileSystem.path.join('/build/deeplink_data', 'app-link-settings-freeDebug.json');
final AndroidGradleBuilder builder = AndroidGradleBuilder( final AndroidGradleBuilder builder = AndroidGradleBuilder(
java: FakeJava(), java: FakeJava(),
logger: logger, logger: logger,
...@@ -927,10 +929,11 @@ Gradle Crashed ...@@ -927,10 +929,11 @@ Gradle Crashed
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(), androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(FakeCommand(
command: <String>[ command: <String>[
'gradlew', 'gradlew',
'-q', '-q',
'-PoutputPath=$expectedOutputPath',
'outputFreeDebugAppLinkSettings', 'outputFreeDebugAppLinkSettings',
], ],
)); ));
...@@ -940,6 +943,8 @@ Gradle Crashed ...@@ -940,6 +943,8 @@ Gradle Crashed
); );
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
AndroidStudio: () => FakeAndroidStudio(), AndroidStudio: () => FakeAndroidStudio(),
FileSystem: () => fileSystem,
ProcessManager: () => processManager,
}); });
testUsingContext("doesn't indicate how to consume an AAR when printHowToConsumeAar is false", () async { testUsingContext("doesn't indicate how to consume an AAR when printHowToConsumeAar is false", () async {
......
...@@ -175,16 +175,16 @@ void main() { ...@@ -175,16 +175,16 @@ void main() {
expect(result, const ProcessResultMatcher()); expect(result, const ProcessResultMatcher());
final Directory androidApp = tempDir.childDirectory('android'); final Directory androidApp = tempDir.childDirectory('android');
final io.File fileDump = tempDir.childDirectory('build').childDirectory('app').childFile('app-link-settings-debug.json');
result = await processManager.run(<String>[ result = await processManager.run(<String>[
'.${platform.pathSeparator}${getGradlewFileName(platform)}', '.${platform.pathSeparator}${getGradlewFileName(platform)}',
...getLocalEngineArguments(), ...getLocalEngineArguments(),
'-q', // quiet output. '-q', // quiet output.
'-PoutputPath=${fileDump.path}',
'outputDebugAppLinkSettings', 'outputDebugAppLinkSettings',
], workingDirectory: androidApp.path); ], workingDirectory: androidApp.path);
expect(result, const ProcessResultMatcher()); expect(result, const ProcessResultMatcher());
final io.File fileDump = tempDir.childDirectory('build').childDirectory('app').childFile('app-link-settings-debug.json');
expect(fileDump.existsSync(), true); expect(fileDump.existsSync(), true);
final Map<String, dynamic> json = jsonDecode(fileDump.readAsStringSync()) as Map<String, dynamic>; final Map<String, dynamic> json = jsonDecode(fileDump.readAsStringSync()) as Map<String, dynamic>;
expect(json['applicationId'], 'com.example.testapp'); expect(json['applicationId'], 'com.example.testapp');
...@@ -220,16 +220,16 @@ void main() { ...@@ -220,16 +220,16 @@ void main() {
expect(result, const ProcessResultMatcher()); expect(result, const ProcessResultMatcher());
final Directory androidApp = tempDir.childDirectory('android'); final Directory androidApp = tempDir.childDirectory('android');
final io.File fileDump = tempDir.childDirectory('build').childDirectory('app').childFile('app-link-settings-debug.json');
result = await processManager.run(<String>[ result = await processManager.run(<String>[
'.${platform.pathSeparator}${getGradlewFileName(platform)}', '.${platform.pathSeparator}${getGradlewFileName(platform)}',
...getLocalEngineArguments(), ...getLocalEngineArguments(),
'-q', // quiet output. '-q', // quiet output.
'-PoutputPath=${fileDump.path}',
'outputDebugAppLinkSettings', 'outputDebugAppLinkSettings',
], workingDirectory: androidApp.path); ], workingDirectory: androidApp.path);
expect(result, const ProcessResultMatcher()); expect(result, const ProcessResultMatcher());
final io.File fileDump = tempDir.childDirectory('build').childDirectory('app').childFile('app-link-settings-debug.json');
expect(fileDump.existsSync(), true); expect(fileDump.existsSync(), true);
final Map<String, dynamic> json = jsonDecode(fileDump.readAsStringSync()) as Map<String, dynamic>; final Map<String, dynamic> json = jsonDecode(fileDump.readAsStringSync()) as Map<String, dynamic>;
expect(json['applicationId'], 'com.example.testapp'); expect(json['applicationId'], 'com.example.testapp');
......
...@@ -41,11 +41,10 @@ class FakeAndroidBuilder implements AndroidBuilder { ...@@ -41,11 +41,10 @@ class FakeAndroidBuilder implements AndroidBuilder {
Future<List<String>> getBuildVariants({required FlutterProject project}) async => const <String>[]; Future<List<String>> getBuildVariants({required FlutterProject project}) async => const <String>[];
@override @override
Future<void> outputsAppLinkSettings( Future<String> outputsAppLinkSettings(
String buildVariant, { String buildVariant, {
required FlutterProject project, required FlutterProject project,
}) async {} }) async => '/';
} }
/// Creates a [FlutterProject] in a directory named [flutter_project] /// Creates a [FlutterProject] in a directory named [flutter_project]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment