AAPT2: Add flag to print multi APK artifact names.
- Added new flag that exits after printing the list of artifact names
that would be generated from the combination of the configuration file
and input APK.
- Cleaned up the code to generate the artifact names which also involved
adding some more test cases for corner cases.
Test: Unit tests
Test: Manually ran new command
Test: Manually ran old command
Change-Id: I8d30e7a4a070af26945b8f544a13f23bdf1ba169
diff --git a/tools/aapt2/configuration/ConfigurationParser.cpp b/tools/aapt2/configuration/ConfigurationParser.cpp
index 424e9be..1735a50 100644
--- a/tools/aapt2/configuration/ConfigurationParser.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser.cpp
@@ -30,6 +30,7 @@
#include "io/File.h"
#include "io/FileSystem.h"
#include "io/StringInputStream.h"
+#include "util/Files.h"
#include "util/Maybe.h"
#include "util/Util.h"
#include "xml/XmlActionExecutor.h"
@@ -149,24 +150,49 @@
return true;
}
-Maybe<std::string> Artifact::ToArtifactName(const StringPiece& format, IDiagnostics* diag,
- const StringPiece& base_name,
- const StringPiece& ext) const {
- std::string result = format.to_string();
+/**
+ * Returns the common artifact base name from a template string.
+ */
+Maybe<std::string> ToBaseName(std::string result, const StringPiece& apk_name, IDiagnostics* diag) {
+ const StringPiece ext = file::GetExtension(apk_name);
+ size_t end_index = apk_name.to_string().rfind(ext.to_string());
+ const std::string base_name =
+ (end_index != std::string::npos) ? std::string{apk_name.begin(), end_index} : "";
- Maybe<StringPiece> maybe_base_name =
- base_name.empty() ? Maybe<StringPiece>{} : Maybe<StringPiece>{base_name};
- if (!ReplacePlaceholder("${basename}", maybe_base_name, &result, diag)) {
- return {};
+ // Base name is optional.
+ if (result.find("${basename}") != std::string::npos) {
+ Maybe<StringPiece> maybe_base_name =
+ base_name.empty() ? Maybe<StringPiece>{} : Maybe<StringPiece>{base_name};
+ if (!ReplacePlaceholder("${basename}", maybe_base_name, &result, diag)) {
+ return {};
+ }
}
// Extension is optional.
if (result.find("${ext}") != std::string::npos) {
- if (!ReplacePlaceholder("${ext}", {ext}, &result, diag)) {
+ // Make sure we disregard the '.' in the extension when replacing the placeholder.
+ if (!ReplacePlaceholder("${ext}", {ext.substr(1)}, &result, diag)) {
return {};
}
+ } else {
+ // If no extension is specified, and the name template does not end in the current extension,
+ // add the existing extension.
+ if (!util::EndsWith(result, ext)) {
+ result.append(ext.to_string());
+ }
}
+ return result;
+}
+
+Maybe<std::string> Artifact::ToArtifactName(const StringPiece& format, const StringPiece& apk_name,
+ IDiagnostics* diag) const {
+ Maybe<std::string> base = ToBaseName(format.to_string(), apk_name, diag);
+ if (!base) {
+ return {};
+ }
+ std::string result = std::move(base.value());
+
if (!ReplacePlaceholder("${abi}", abi_group, &result, diag)) {
return {};
}
@@ -194,29 +220,37 @@
return result;
}
-Maybe<std::string> Artifact::Name(const StringPiece& base_name, const StringPiece& ext,
- IDiagnostics* diag) const {
+Maybe<std::string> Artifact::Name(const StringPiece& apk_name, IDiagnostics* diag) const {
if (!name) {
return {};
}
- std::string result = name.value();
+ return ToBaseName(name.value(), apk_name, diag);
+}
- // Base name is optional.
- if (result.find("${basename}") != std::string::npos) {
- if (!ReplacePlaceholder("${basename}", {base_name}, &result, diag)) {
- return {};
+bool PostProcessingConfiguration::AllArtifactNames(const StringPiece& apk_name,
+ std::vector<std::string>* artifact_names,
+ IDiagnostics* diag) const {
+ for (const auto& artifact : artifacts) {
+ Maybe<std::string> name;
+ if (artifact.name) {
+ name = artifact.Name(apk_name, diag);
+ } else {
+ if (!artifact_format) {
+ diag->Error(DiagMessage() << "No global artifact template and an artifact name is missing");
+ return false;
+ }
+ name = artifact.ToArtifactName(artifact_format.value(), apk_name, diag);
}
+
+ if (!name) {
+ return false;
+ }
+
+ artifact_names->push_back(std::move(name.value()));
}
- // Extension is optional.
- if (result.find("${ext}") != std::string::npos) {
- if (!ReplacePlaceholder("${ext}", {ext}, &result, diag)) {
- return {};
- }
- }
-
- return result;
+ return true;
}
} // namespace configuration
diff --git a/tools/aapt2/configuration/ConfigurationParser.h b/tools/aapt2/configuration/ConfigurationParser.h
index 6259ce8..a58685e 100644
--- a/tools/aapt2/configuration/ConfigurationParser.h
+++ b/tools/aapt2/configuration/ConfigurationParser.h
@@ -51,13 +51,11 @@
Maybe<std::string> gl_texture_group;
/** Convert an artifact name template into a name string based on configuration contents. */
- Maybe<std::string> ToArtifactName(const android::StringPiece& format, IDiagnostics* diag,
- const android::StringPiece& base_name = "",
- const android::StringPiece& ext = "apk") const;
+ Maybe<std::string> ToArtifactName(const android::StringPiece& format,
+ const android::StringPiece& apk_name, IDiagnostics* diag) const;
/** Convert an artifact name template into a name string based on configuration contents. */
- Maybe<std::string> Name(const android::StringPiece& base_name, const android::StringPiece& ext,
- IDiagnostics* diag) const;
+ Maybe<std::string> Name(const android::StringPiece& apk_name, IDiagnostics* diag) const;
};
/** Enumeration of currently supported ABIs. */
@@ -139,6 +137,10 @@
Group<AndroidSdk> android_sdk_groups;
Group<DeviceFeature> device_feature_groups;
Group<GlTexture> gl_texture_groups;
+
+ /** Helper method that generates a list of artifact names and returns true on success. */
+ bool AllArtifactNames(const android::StringPiece& apk_name,
+ std::vector<std::string>* artifact_names, IDiagnostics* diag) const;
};
} // namespace configuration
diff --git a/tools/aapt2/configuration/ConfigurationParser_test.cpp b/tools/aapt2/configuration/ConfigurationParser_test.cpp
index ece70a9..d3bfd33 100644
--- a/tools/aapt2/configuration/ConfigurationParser_test.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser_test.cpp
@@ -414,16 +414,36 @@
Artifact x86;
x86.abi_group = {"x86"};
- auto x86_result = x86.ToArtifactName("something.${abi}.apk", &diag);
+ auto x86_result = x86.ToArtifactName("something.${abi}.apk", "", &diag);
ASSERT_TRUE(x86_result);
EXPECT_EQ(x86_result.value(), "something.x86.apk");
Artifact arm;
arm.abi_group = {"armeabi-v7a"};
- auto arm_result = arm.ToArtifactName("app.${abi}.apk", &diag);
- ASSERT_TRUE(arm_result);
- EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
+ {
+ auto arm_result = arm.ToArtifactName("app.${abi}.apk", "", &diag);
+ ASSERT_TRUE(arm_result);
+ EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
+ }
+
+ {
+ auto arm_result = arm.ToArtifactName("app.${abi}.apk", "different_name.apk", &diag);
+ ASSERT_TRUE(arm_result);
+ EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
+ }
+
+ {
+ auto arm_result = arm.ToArtifactName("${basename}.${abi}.apk", "app.apk", &diag);
+ ASSERT_TRUE(arm_result);
+ EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
+ }
+
+ {
+ auto arm_result = arm.ToArtifactName("app.${abi}.${ext}", "app.apk", &diag);
+ ASSERT_TRUE(arm_result);
+ EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
+ }
}
TEST(ArtifactTest, Complex) {
@@ -436,10 +456,40 @@
artifact.locale_group = {"en-AU"};
artifact.android_sdk_group = {"26"};
- auto result = artifact.ToArtifactName(
- "app.${density}_${locale}_${feature}_${gl}.sdk${sdk}.${abi}.apk", &diag);
- ASSERT_TRUE(result);
- EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.sdk26.mips64.apk");
+ {
+ auto result = artifact.ToArtifactName(
+ "app.${density}_${locale}_${feature}_${gl}.sdk${sdk}.${abi}.apk", "", &diag);
+ ASSERT_TRUE(result);
+ EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.sdk26.mips64.apk");
+ }
+
+ {
+ auto result = artifact.ToArtifactName(
+ "app.${density}_${locale}_${feature}_${gl}.sdk${sdk}.${abi}.apk", "app.apk", &diag);
+ ASSERT_TRUE(result);
+ EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.sdk26.mips64.apk");
+ }
+
+ {
+ auto result = artifact.ToArtifactName(
+ "${basename}.${density}_${locale}_${feature}_${gl}.sdk${sdk}.${abi}.apk", "app.apk", &diag);
+ ASSERT_TRUE(result);
+ EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.sdk26.mips64.apk");
+ }
+
+ {
+ auto result = artifact.ToArtifactName(
+ "app.${density}_${locale}_${feature}_${gl}.sdk${sdk}.${abi}.${ext}", "app.apk", &diag);
+ ASSERT_TRUE(result);
+ EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.sdk26.mips64.apk");
+ }
+
+ {
+ auto result = artifact.ToArtifactName(
+ "${basename}.${density}_${locale}_${feature}_${gl}.sdk${sdk}.${abi}", "app.apk", &diag);
+ ASSERT_TRUE(result);
+ EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.sdk26.mips64.apk");
+ }
}
TEST(ArtifactTest, Missing) {
@@ -447,16 +497,20 @@
Artifact x86;
x86.abi_group = {"x86"};
- EXPECT_FALSE(x86.ToArtifactName("something.${density}.apk", &diag));
- EXPECT_FALSE(x86.ToArtifactName("something.apk", &diag));
+ EXPECT_FALSE(x86.ToArtifactName("something.${density}.apk", "", &diag));
+ EXPECT_FALSE(x86.ToArtifactName("something.apk", "", &diag));
+ EXPECT_FALSE(x86.ToArtifactName("something.${density}.apk", "something.apk", &diag));
+ EXPECT_FALSE(x86.ToArtifactName("something.apk", "something.apk", &diag));
}
TEST(ArtifactTest, Empty) {
StdErrDiagnostics diag;
Artifact artifact;
- EXPECT_FALSE(artifact.ToArtifactName("something.${density}.apk", &diag));
- EXPECT_TRUE(artifact.ToArtifactName("something.apk", &diag));
+ EXPECT_FALSE(artifact.ToArtifactName("something.${density}.apk", "", &diag));
+ EXPECT_TRUE(artifact.ToArtifactName("something.apk", "", &diag));
+ EXPECT_FALSE(artifact.ToArtifactName("something.${density}.apk", "something.apk", &diag));
+ EXPECT_TRUE(artifact.ToArtifactName("something.apk", "something.apk", &diag));
}
TEST(ArtifactTest, Repeated) {
@@ -464,8 +518,9 @@
Artifact artifact;
artifact.screen_density_group = {"mdpi"};
- ASSERT_TRUE(artifact.ToArtifactName("something.${density}.apk", &diag));
- EXPECT_FALSE(artifact.ToArtifactName("something.${density}.${density}.apk", &diag));
+ ASSERT_TRUE(artifact.ToArtifactName("something.${density}.apk", "", &diag));
+ EXPECT_FALSE(artifact.ToArtifactName("something.${density}.${density}.apk", "", &diag));
+ ASSERT_TRUE(artifact.ToArtifactName("something.${density}.apk", "something.apk", &diag));
}
TEST(ArtifactTest, Nesting) {
@@ -473,9 +528,9 @@
Artifact x86;
x86.abi_group = {"x86"};
- EXPECT_FALSE(x86.ToArtifactName("something.${abi${density}}.apk", &diag));
+ EXPECT_FALSE(x86.ToArtifactName("something.${abi${density}}.apk", "", &diag));
- const Maybe<std::string>& name = x86.ToArtifactName("something.${abi${abi}}.apk", &diag);
+ const Maybe<std::string>& name = x86.ToArtifactName("something.${abi${abi}}.apk", "", &diag);
ASSERT_TRUE(name);
EXPECT_EQ(name.value(), "something.${abix86}.apk");
}
@@ -486,12 +541,12 @@
artifact.device_feature_group = {"${gl}"};
artifact.gl_texture_group = {"glx1"};
- EXPECT_FALSE(artifact.ToArtifactName("app.${feature}.${gl}.apk", &diag));
+ EXPECT_FALSE(artifact.ToArtifactName("app.${feature}.${gl}.apk", "", &diag));
artifact.device_feature_group = {"df1"};
artifact.gl_texture_group = {"${feature}"};
{
- const auto& result = artifact.ToArtifactName("app.${feature}.${gl}.apk", &diag);
+ const auto& result = artifact.ToArtifactName("app.${feature}.${gl}.apk", "", &diag);
ASSERT_TRUE(result);
EXPECT_EQ(result.value(), "app.df1.${feature}.apk");
}
@@ -501,7 +556,7 @@
artifact.device_feature_group = {"${gl}"};
artifact.gl_texture_group = {"glx1"};
{
- const auto& result = artifact.ToArtifactName("app.${feature}.apk", &diag);
+ const auto& result = artifact.ToArtifactName("app.${feature}.apk", "", &diag);
ASSERT_TRUE(result);
EXPECT_EQ(result.value(), "app.glx1.apk");
}