Previously, aapt2 would read arguments from files but they all have to be in one line, separated by spaces. Now they can be spread over multiple lines in the file. Bug: 297373084 Bug: 315329624 Test: Called `aapt2 link ... --feature_flags @args.txt` with args.txt containing flag values over multiple lines. Verified the resulting APK has the expected output. Change-Id: I91be6c7a869f63eafd88c04de69401d248f05545
147 lines
4.3 KiB
C++
147 lines
4.3 KiB
C++
/*
|
|
* Copyright (C) 2016 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "util/Files.h"
|
|
|
|
#include <sstream>
|
|
|
|
#include "android-base/stringprintf.h"
|
|
#include "android-base/utf8.h"
|
|
|
|
#include "test/Test.h"
|
|
|
|
using ::android::base::StringPrintf;
|
|
|
|
using ::testing::ElementsAre;
|
|
using ::testing::UnorderedElementsAre;
|
|
|
|
namespace aapt {
|
|
namespace file {
|
|
|
|
#ifdef _WIN32
|
|
constexpr const char sTestDirSep = '\\';
|
|
#else
|
|
constexpr const char sTestDirSep = '/';
|
|
#endif
|
|
|
|
class FilesTest : public TestDirectoryFixture {
|
|
public:
|
|
void SetUp() override {
|
|
TestDirectoryFixture::SetUp();
|
|
|
|
std::stringstream builder;
|
|
builder << "hello" << sDirSep << "there";
|
|
expected_path_ = builder.str();
|
|
}
|
|
|
|
protected:
|
|
std::string expected_path_;
|
|
};
|
|
|
|
TEST_F(FilesTest, AppendPath) {
|
|
std::string base = "hello";
|
|
AppendPath(&base, "there");
|
|
EXPECT_EQ(expected_path_, base);
|
|
}
|
|
|
|
TEST_F(FilesTest, AppendPathWithLeadingOrTrailingSeparators) {
|
|
std::string base = StringPrintf("hello%c", sTestDirSep);
|
|
AppendPath(&base, "there");
|
|
EXPECT_EQ(expected_path_, base);
|
|
|
|
base = "hello";
|
|
AppendPath(&base, StringPrintf("%cthere", sTestDirSep));
|
|
EXPECT_EQ(expected_path_, base);
|
|
|
|
base = StringPrintf("hello%c", sTestDirSep);
|
|
AppendPath(&base, StringPrintf("%cthere", sTestDirSep));
|
|
EXPECT_EQ(expected_path_, base);
|
|
}
|
|
|
|
TEST_F(FilesTest, AppendArgsFromFile) {
|
|
const std::string args_file = GetTestPath("args.txt");
|
|
WriteFile(args_file,
|
|
" \n"
|
|
"arg1 arg2 arg3 \n"
|
|
" arg4 arg5");
|
|
std::vector<std::string> args;
|
|
std::string error;
|
|
ASSERT_TRUE(AppendArgsFromFile(args_file, &args, &error));
|
|
EXPECT_THAT(args, ElementsAre("arg1", "arg2", "arg3", "arg4", "arg5"));
|
|
}
|
|
|
|
TEST_F(FilesTest, AppendArgsFromFile_InvalidFile) {
|
|
std::vector<std::string> args;
|
|
std::string error;
|
|
ASSERT_FALSE(AppendArgsFromFile(GetTestPath("not_found.txt"), &args, &error));
|
|
}
|
|
|
|
TEST_F(FilesTest, AppendSetArgsFromFile) {
|
|
const std::string args_file = GetTestPath("args.txt");
|
|
WriteFile(args_file,
|
|
" \n"
|
|
"arg2 arg4 arg1 \n"
|
|
" arg5 arg3");
|
|
std::unordered_set<std::string> args;
|
|
std::string error;
|
|
ASSERT_TRUE(AppendSetArgsFromFile(args_file, &args, &error));
|
|
EXPECT_THAT(args, UnorderedElementsAre("arg1", "arg2", "arg3", "arg4", "arg5"));
|
|
}
|
|
|
|
TEST_F(FilesTest, AppendSetArgsFromFile_InvalidFile) {
|
|
std::unordered_set<std::string> args;
|
|
std::string error;
|
|
ASSERT_FALSE(AppendSetArgsFromFile(GetTestPath("not_found.txt"), &args, &error));
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
TEST_F(FilesTest, WindowsMkdirsLongPath) {
|
|
// Creating directory paths longer than the Windows maximum path length (260 charatcers) should
|
|
// succeed.
|
|
const std::string kDirName = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
|
const size_t kRecursiveDepth = 10u;
|
|
|
|
// Recursively create the test file path and clean up the created directories after the files have
|
|
// been created.
|
|
std::function<void(std::string, size_t)> CreateResursiveDirs =
|
|
[&kDirName, &CreateResursiveDirs](std::string current_path, const size_t n) -> void {
|
|
AppendPath(¤t_path, kDirName);
|
|
|
|
if (n == 0) {
|
|
ASSERT_TRUE(file::mkdirs(current_path)) << "Failed to create path " << current_path;
|
|
} else {
|
|
CreateResursiveDirs(current_path, n - 1);
|
|
}
|
|
|
|
// Clean up the created directories.
|
|
_rmdir(current_path.data());
|
|
};
|
|
|
|
CreateResursiveDirs(
|
|
android::base::StringPrintf(R"(\\?\%s)", android::base::GetExecutableDirectory().data()),
|
|
kRecursiveDepth);
|
|
}
|
|
|
|
TEST_F(FilesTest, WindowsMkdirsLongPathMissingDrive) {
|
|
ASSERT_FALSE(file::mkdirs(R"(\\?\local\path\to\file)"));
|
|
ASSERT_FALSE(file::mkdirs(R"(\\?\:local\path\to\file)"));
|
|
ASSERT_FALSE(file::mkdirs(R"(\\?\\local\path\to\file)"));
|
|
}
|
|
#endif
|
|
|
|
} // namespace files
|
|
} // namespace aapt
|