• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "gn/bundle_data_target_generator.h"
6 
7 #include "gn/parse_tree.h"
8 #include "gn/scope.h"
9 #include "gn/substitution_type.h"
10 #include "gn/target.h"
11 #include "gn/value.h"
12 #include "gn/variables.h"
13 
BundleDataTargetGenerator(Target * target,Scope * scope,const FunctionCallNode * function_call,Err * err)14 BundleDataTargetGenerator::BundleDataTargetGenerator(
15     Target* target,
16     Scope* scope,
17     const FunctionCallNode* function_call,
18     Err* err)
19     : TargetGenerator(target, scope, function_call, err) {}
20 
21 BundleDataTargetGenerator::~BundleDataTargetGenerator() = default;
22 
DoRun()23 void BundleDataTargetGenerator::DoRun() {
24   target_->set_output_type(Target::BUNDLE_DATA);
25 
26   if (!FillSources())
27     return;
28   if (!FillOutputs())
29     return;
30   if (!FillProductType())
31     return;
32 
33   if (target_->sources().empty()) {
34     *err_ = Err(function_call_,
35                 "Empty sources for bundle_data target."
36                 "You have to specify at least one file in the \"sources\".");
37     return;
38   }
39   if (target_->action_values().outputs().list().size() != 1) {
40     *err_ = Err(
41         function_call_, "Target bundle_data must have exactly one output.",
42         "You must specify exactly one value in the \"output\" array for the"
43         "destination\ninto the generated bundle (see \"gn help bundle_data\"). "
44         "If there are multiple\nsources to copy, use source expansion (see "
45         "\"gn help source_expansion\").");
46     return;
47   }
48 }
49 
FillOutputs()50 bool BundleDataTargetGenerator::FillOutputs() {
51   const Value* value = scope_->GetValue(variables::kOutputs, true);
52   if (!value)
53     return true;
54 
55   SubstitutionList& outputs = target_->action_values().outputs();
56   if (!outputs.Parse(*value, err_))
57     return false;
58 
59   // Check the substitutions used are valid for this purpose.
60   for (const Substitution* type : outputs.required_types()) {
61     if (!IsValidBundleDataSubstitution(type)) {
62       *err_ = Err(value->origin(), "Invalid substitution type.",
63                   "The substitution " + std::string(type->name) +
64                       " isn't valid for something\n"
65                       "operating on a bundle_data file such as this.");
66       return false;
67     }
68   }
69 
70   // Validate that outputs are in the bundle.
71   CHECK(outputs.list().size() == value->list_value().size());
72   for (size_t i = 0; i < outputs.list().size(); i++) {
73     if (!EnsureSubstitutionIsInBundleDir(outputs.list()[i],
74                                          value->list_value()[i]))
75       return false;
76   }
77 
78   return true;
79 }
80 
FillProductType()81 bool BundleDataTargetGenerator::FillProductType() {
82   const Value* value = scope_->GetValue(variables::kProductType, true);
83   if (!value)
84     return true;
85 
86   if (!value->VerifyTypeIs(Value::STRING, err_))
87     return false;
88 
89   target_->bundle_data().product_type().assign(value->string_value());
90   return true;
91 }
92 
EnsureSubstitutionIsInBundleDir(const SubstitutionPattern & pattern,const Value & original_value)93 bool BundleDataTargetGenerator::EnsureSubstitutionIsInBundleDir(
94     const SubstitutionPattern& pattern,
95     const Value& original_value) {
96   if (pattern.ranges().empty()) {
97     // Pattern is empty, error out (this prevents weirdness below).
98     *err_ = Err(original_value, "This has an empty value in it.");
99     return false;
100   }
101 
102   if (SubstitutionIsInBundleDir(pattern.ranges()[0].type))
103     return true;
104 
105   *err_ = Err(original_value, "File is not inside bundle directory.",
106               "The given file should be in the output directory. Normally you\n"
107               "would specify {{bundle_resources_dir}} or such substitution.");
108   return false;
109 }
110