blob: 2b9881c56067849a1a47c3c955c38eca3d2f8aea [file] [log] [blame]
// Copyright 2016 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.
#include "tools/gn/bundle_file_rule.h"
#include "base/strings/stringprintf.h"
#include "tools/gn/output_file.h"
#include "tools/gn/settings.h"
#include "tools/gn/substitution_pattern.h"
#include "tools/gn/substitution_writer.h"
#include "tools/gn/target.h"
#include "tools/gn/variables.h"
namespace {
Err ErrMissingPropertyForExpansion(const Settings* settings,
const Target* target,
const BundleFileRule* bundle_file_rule,
const char* property_name) {
std::string label = bundle_file_rule->target()->label().GetUserVisibleName(
settings->default_toolchain_label());
return Err(target->defined_from(),
base::StringPrintf("Property %s is required.", property_name),
base::StringPrintf(
"In order to expand {{%s}} in %s, the "
"property needs to be defined in the create_bundle target.",
property_name, label.c_str()));
}
} // namespace
BundleFileRule::BundleFileRule(const Target* bundle_data_target,
const std::vector<SourceFile> sources,
const SubstitutionPattern& pattern)
: target_(bundle_data_target), sources_(sources), pattern_(pattern) {
// target_ may be null during testing.
DCHECK(!target_ || target_->output_type() == Target::BUNDLE_DATA);
}
BundleFileRule::BundleFileRule(const BundleFileRule& other) = default;
BundleFileRule::~BundleFileRule() = default;
bool BundleFileRule::ApplyPatternToSource(const Settings* settings,
const Target* target,
const BundleData& bundle_data,
const SourceFile& source_file,
SourceFile* expanded_source_file,
Err* err) const {
std::string output_path;
for (const auto& subrange : pattern_.ranges()) {
if (subrange.type == &SubstitutionLiteral) {
output_path.append(subrange.literal);
} else if (subrange.type == &SubstitutionBundleRootDir) {
if (bundle_data.contents_dir().is_null()) {
*err = ErrMissingPropertyForExpansion(settings, target, this,
variables::kBundleRootDir);
return false;
}
output_path.append(bundle_data.root_dir().value());
} else if (subrange.type == &SubstitutionBundleContentsDir) {
if (bundle_data.contents_dir().is_null()) {
*err = ErrMissingPropertyForExpansion(settings, target, this,
variables::kBundleContentsDir);
return false;
}
output_path.append(bundle_data.contents_dir().value());
} else if (subrange.type == &SubstitutionBundleResourcesDir) {
if (bundle_data.resources_dir().is_null()) {
*err = ErrMissingPropertyForExpansion(settings, target, this,
variables::kBundleResourcesDir);
return false;
}
output_path.append(bundle_data.resources_dir().value());
} else if (subrange.type == &SubstitutionBundleExecutableDir) {
if (bundle_data.executable_dir().is_null()) {
*err = ErrMissingPropertyForExpansion(settings, target, this,
variables::kBundleExecutableDir);
return false;
}
output_path.append(bundle_data.executable_dir().value());
} else {
output_path.append(SubstitutionWriter::GetSourceSubstitution(
target_, target_->settings(), source_file, subrange.type,
SubstitutionWriter::OUTPUT_ABSOLUTE, SourceDir()));
}
}
*expanded_source_file = SourceFile(SourceFile::SWAP_IN, &output_path);
return true;
}
bool BundleFileRule::ApplyPatternToSourceAsOutputFile(
const Settings* settings,
const Target* target,
const BundleData& bundle_data,
const SourceFile& source_file,
OutputFile* expanded_output_file,
Err* err) const {
SourceFile expanded_source_file;
if (!ApplyPatternToSource(settings, target, bundle_data, source_file,
&expanded_source_file, err)) {
return false;
}
*expanded_output_file =
OutputFile(settings->build_settings(), expanded_source_file);
return true;
}