| OLD | NEW | 
|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "tools/gn/bundle_data.h" | 5 #include "tools/gn/bundle_data.h" | 
| 6 | 6 | 
| 7 #include "base/logging.h" | 7 #include "base/logging.h" | 
| 8 #include "tools/gn/filesystem_utils.h" | 8 #include "tools/gn/filesystem_utils.h" | 
| 9 #include "tools/gn/output_file.h" | 9 #include "tools/gn/output_file.h" | 
| 10 #include "tools/gn/settings.h" | 10 #include "tools/gn/settings.h" | 
| 11 #include "tools/gn/substitution_writer.h" | 11 #include "tools/gn/substitution_writer.h" | 
| 12 #include "tools/gn/target.h" | 12 #include "tools/gn/target.h" | 
| 13 | 13 | 
| 14 namespace { | 14 namespace { | 
| 15 | 15 | 
| 16 // Return directory of |path| without the trailing directory separator. | 16 // Return directory of |path| without the trailing directory separator. | 
| 17 base::StringPiece FindDirNoTrailingSeparator(const base::StringPiece& path) { | 17 base::StringPiece FindDirNoTrailingSeparator(base::StringPiece path) { | 
| 18   base::StringPiece::size_type pos = path.find_last_of("/\\"); | 18   base::StringPiece::size_type pos = path.find_last_of("/\\"); | 
| 19   if (pos == base::StringPiece::npos) | 19   if (pos == base::StringPiece::npos) | 
| 20     return base::StringPiece(); | 20     return base::StringPiece(); | 
| 21   return base::StringPiece(path.data(), pos); | 21   return base::StringPiece(path.data(), pos); | 
| 22 } | 22 } | 
| 23 | 23 | 
| 24 }  // namespace | 24 bool IsSourceFileFromAssetsCatalog(base::StringPiece source, | 
| 25 | 25                                    SourceFile* asset_catalog) { | 
| 26 bool IsSourceFileFromAssetCatalog(const SourceFile& source, | 26   // Check whether |source| matches one of the following pattern: | 
| 27                                   SourceFile* asset_catalog) { | 27   //    .*\.xcassets/Contents.json | 
| 28   // Check that the file matches the following pattern: | 28   //    .*\.xcassets/[^/]*\.appiconset/[^/]* | 
| 29   //    .*\.xcassets/[^/]*\.imageset/[^/]* | 29   //    .*\.xcassets/[^/]*\.imageset/[^/]* | 
| 30   base::StringPiece dir; | 30   //    .*\.xcassets/[^/]*\.launchimage/[^/]* | 
| 31   dir = FindDirNoTrailingSeparator(source.value()); | 31   bool is_file_from_asset_catalog = false; | 
| 32   if (!dir.ends_with(".imageset")) | 32   base::StringPiece dir = FindDirNoTrailingSeparator(source); | 
| 33     return false; | 33   if (source.ends_with("/Contents.json") && dir.ends_with(".xcassets")) { | 
| 34   dir = FindDirNoTrailingSeparator(dir); | 34     is_file_from_asset_catalog = true; | 
| 35   if (!dir.ends_with(".xcassets")) | 35   } else if (dir.ends_with(".appiconset") || dir.ends_with(".imageset") || | 
| 36     return false; | 36              dir.ends_with(".launchimage")) { | 
| 37   if (asset_catalog) { | 37     dir = FindDirNoTrailingSeparator(dir); | 
|  | 38     is_file_from_asset_catalog = dir.ends_with(".xcassets"); | 
|  | 39   } | 
|  | 40   if (is_file_from_asset_catalog && asset_catalog) { | 
| 38     std::string asset_catalog_path = dir.as_string(); | 41     std::string asset_catalog_path = dir.as_string(); | 
| 39     *asset_catalog = SourceFile(SourceFile::SWAP_IN, &asset_catalog_path); | 42     *asset_catalog = SourceFile(SourceFile::SWAP_IN, &asset_catalog_path); | 
| 40   } | 43   } | 
| 41   return true; | 44   return is_file_from_asset_catalog; | 
| 42 } | 45 } | 
| 43 | 46 | 
|  | 47 }  // namespace | 
|  | 48 | 
| 44 BundleData::BundleData() {} | 49 BundleData::BundleData() {} | 
| 45 | 50 | 
| 46 BundleData::~BundleData() {} | 51 BundleData::~BundleData() {} | 
| 47 | 52 | 
| 48 void BundleData::AddBundleData(const Target* target) { | 53 void BundleData::AddBundleData(const Target* target) { | 
| 49   DCHECK_EQ(target->output_type(), Target::BUNDLE_DATA); | 54   DCHECK_EQ(target->output_type(), Target::BUNDLE_DATA); | 
| 50   bundle_deps_.push_back(target); | 55   bundle_deps_.push_back(target); | 
| 51 } | 56 } | 
| 52 | 57 | 
| 53 void BundleData::OnTargetResolved(Target* owning_target) { | 58 void BundleData::OnTargetResolved(Target* owning_target) { | 
| 54   // Only initialize file_rules_ and asset_catalog_sources for "create_bundle" | 59   // Only initialize file_rules_ and assets_catalog_sources for "create_bundle" | 
| 55   // target (properties are only used by those targets). | 60   // target (properties are only used by those targets). | 
| 56   if (owning_target->output_type() != Target::CREATE_BUNDLE) | 61   if (owning_target->output_type() != Target::CREATE_BUNDLE) | 
| 57     return; | 62     return; | 
| 58 | 63 | 
|  | 64   UniqueVector<const Target*> assets_catalog_deps; | 
|  | 65   UniqueVector<SourceFile> assets_catalog_sources; | 
|  | 66 | 
| 59   for (const Target* target : bundle_deps_) { | 67   for (const Target* target : bundle_deps_) { | 
| 60     SourceFiles file_rule_sources; | 68     SourceFiles file_rule_sources; | 
| 61     for (const SourceFile& source_file : target->sources()) { | 69     for (const SourceFile& source_file : target->sources()) { | 
| 62       if (IsSourceFileFromAssetCatalog(source_file, nullptr)) { | 70       SourceFile assets_catalog; | 
| 63         asset_catalog_sources_.push_back(source_file); | 71       if (IsSourceFileFromAssetsCatalog(source_file.value(), &assets_catalog)) { | 
|  | 72         assets_catalog_sources.push_back(assets_catalog); | 
|  | 73         assets_catalog_deps.push_back(target); | 
| 64       } else { | 74       } else { | 
| 65         file_rule_sources.push_back(source_file); | 75         file_rule_sources.push_back(source_file); | 
| 66       } | 76       } | 
| 67     } | 77     } | 
| 68 | 78 | 
| 69     if (!file_rule_sources.empty()) { | 79     if (!file_rule_sources.empty()) { | 
| 70       DCHECK_EQ(target->action_values().outputs().list().size(), 1u); | 80       DCHECK_EQ(target->action_values().outputs().list().size(), 1u); | 
| 71       file_rules_.push_back(BundleFileRule( | 81       file_rules_.push_back( | 
| 72           file_rule_sources, target->action_values().outputs().list()[0])); | 82           BundleFileRule(target, file_rule_sources, | 
|  | 83                          target->action_values().outputs().list()[0])); | 
| 73     } | 84     } | 
| 74   } | 85   } | 
| 75 | 86 | 
|  | 87   assets_catalog_deps_.insert(assets_catalog_deps_.end(), | 
|  | 88                               assets_catalog_deps.begin(), | 
|  | 89                               assets_catalog_deps.end()); | 
|  | 90   assets_catalog_sources_.insert(assets_catalog_sources_.end(), | 
|  | 91                                  assets_catalog_sources.begin(), | 
|  | 92                                  assets_catalog_sources.end()); | 
|  | 93 | 
| 76   GetSourceFiles(&owning_target->sources()); | 94   GetSourceFiles(&owning_target->sources()); | 
| 77 } | 95 } | 
| 78 | 96 | 
| 79 void BundleData::GetSourceFiles(SourceFiles* sources) const { | 97 void BundleData::GetSourceFiles(SourceFiles* sources) const { | 
| 80   for (const BundleFileRule& file_rule : file_rules_) { | 98   for (const BundleFileRule& file_rule : file_rules_) { | 
| 81     sources->insert(sources->end(), file_rule.sources().begin(), | 99     sources->insert(sources->end(), file_rule.sources().begin(), | 
| 82                     file_rule.sources().end()); | 100                     file_rule.sources().end()); | 
| 83   } | 101   } | 
| 84   sources->insert(sources->end(), asset_catalog_sources_.begin(), | 102   sources->insert(sources->end(), assets_catalog_sources_.begin(), | 
| 85                   asset_catalog_sources_.end()); | 103                   assets_catalog_sources_.end()); | 
| 86   if (!code_signing_script_.is_null()) { | 104   if (!code_signing_script_.is_null()) { | 
| 87     sources->insert(sources->end(), code_signing_sources_.begin(), | 105     sources->insert(sources->end(), code_signing_sources_.begin(), | 
| 88                     code_signing_sources_.end()); | 106                     code_signing_sources_.end()); | 
| 89   } | 107   } | 
| 90 } | 108 } | 
| 91 | 109 | 
| 92 void BundleData::GetOutputFiles(const Settings* settings, | 110 void BundleData::GetOutputFiles(const Settings* settings, | 
| 93                                 OutputFiles* outputs) const { | 111                                 OutputFiles* outputs) const { | 
| 94   SourceFiles outputs_as_sources; | 112   SourceFiles outputs_as_sources; | 
| 95   GetOutputsAsSourceFiles(settings, &outputs_as_sources); | 113   GetOutputsAsSourceFiles(settings, &outputs_as_sources); | 
| 96   for (const SourceFile& source_file : outputs_as_sources) | 114   for (const SourceFile& source_file : outputs_as_sources) | 
| 97     outputs->push_back(OutputFile(settings->build_settings(), source_file)); | 115     outputs->push_back(OutputFile(settings->build_settings(), source_file)); | 
| 98 } | 116 } | 
| 99 | 117 | 
| 100 void BundleData::GetOutputsAsSourceFiles( | 118 void BundleData::GetOutputsAsSourceFiles( | 
| 101     const Settings* settings, | 119     const Settings* settings, | 
| 102     SourceFiles* outputs_as_source) const { | 120     SourceFiles* outputs_as_source) const { | 
| 103   for (const BundleFileRule& file_rule : file_rules_) { | 121   for (const BundleFileRule& file_rule : file_rules_) { | 
| 104     for (const SourceFile& source : file_rule.sources()) { | 122     for (const SourceFile& source : file_rule.sources()) { | 
| 105       outputs_as_source->push_back( | 123       outputs_as_source->push_back( | 
| 106           file_rule.ApplyPatternToSource(settings, *this, source)); | 124           file_rule.ApplyPatternToSource(settings, *this, source)); | 
| 107     } | 125     } | 
| 108   } | 126   } | 
| 109 | 127 | 
| 110   if (!asset_catalog_sources_.empty()) | 128   if (!assets_catalog_sources_.empty()) | 
| 111     outputs_as_source->push_back(GetCompiledAssetCatalogPath()); | 129     outputs_as_source->push_back(GetCompiledAssetCatalogPath()); | 
| 112 | 130 | 
| 113   if (!code_signing_script_.is_null()) { | 131   if (!code_signing_script_.is_null()) { | 
| 114     std::vector<SourceFile> code_signing_output_files; | 132     std::vector<SourceFile> code_signing_output_files; | 
| 115     SubstitutionWriter::GetListAsSourceFiles(code_signing_outputs_, | 133     SubstitutionWriter::GetListAsSourceFiles(code_signing_outputs_, | 
| 116                                              &code_signing_output_files); | 134                                              &code_signing_output_files); | 
| 117     outputs_as_source->insert(outputs_as_source->end(), | 135     outputs_as_source->insert(outputs_as_source->end(), | 
| 118                               code_signing_output_files.begin(), | 136                               code_signing_output_files.begin(), | 
| 119                               code_signing_output_files.end()); | 137                               code_signing_output_files.end()); | 
| 120   } | 138   } | 
| 121 | 139 | 
| 122   if (!root_dir_.is_null()) | 140   if (!root_dir_.is_null()) | 
| 123     outputs_as_source->push_back(GetBundleRootDirOutput(settings)); | 141     outputs_as_source->push_back(GetBundleRootDirOutput(settings)); | 
| 124 } | 142 } | 
| 125 | 143 | 
| 126 SourceFile BundleData::GetCompiledAssetCatalogPath() const { | 144 SourceFile BundleData::GetCompiledAssetCatalogPath() const { | 
| 127   DCHECK(!asset_catalog_sources_.empty()); | 145   DCHECK(!assets_catalog_sources_.empty()); | 
| 128   std::string assets_car_path = resources_dir_.value() + "/Assets.car"; | 146   std::string assets_car_path = resources_dir_.value() + "/Assets.car"; | 
| 129   return SourceFile(SourceFile::SWAP_IN, &assets_car_path); | 147   return SourceFile(SourceFile::SWAP_IN, &assets_car_path); | 
| 130 } | 148 } | 
| 131 | 149 | 
| 132 SourceFile BundleData::GetBundleRootDirOutput(const Settings* settings) const { | 150 SourceFile BundleData::GetBundleRootDirOutput(const Settings* settings) const { | 
| 133   const SourceDir& build_dir = settings->build_settings()->build_dir(); | 151   const SourceDir& build_dir = settings->build_settings()->build_dir(); | 
| 134   std::string bundle_root_relative = RebasePath(root_dir().value(), build_dir); | 152   std::string bundle_root_relative = RebasePath(root_dir().value(), build_dir); | 
| 135 | 153 | 
| 136   size_t first_component = bundle_root_relative.find('/'); | 154   size_t first_component = bundle_root_relative.find('/'); | 
| 137   if (first_component != std::string::npos) { | 155   if (first_component != std::string::npos) { | 
| 138     base::StringPiece outermost_bundle_dir = | 156     base::StringPiece outermost_bundle_dir = | 
| 139         base::StringPiece(bundle_root_relative).substr(0, first_component); | 157         base::StringPiece(bundle_root_relative).substr(0, first_component); | 
| 140     std::string return_value(build_dir.value()); | 158     std::string return_value(build_dir.value()); | 
| 141     outermost_bundle_dir.AppendToString(&return_value); | 159     outermost_bundle_dir.AppendToString(&return_value); | 
| 142     return SourceFile(SourceFile::SWAP_IN, &return_value); | 160     return SourceFile(SourceFile::SWAP_IN, &return_value); | 
| 143   } | 161   } | 
| 144   return SourceFile(root_dir().value()); | 162   return SourceFile(root_dir().value()); | 
| 145 } | 163 } | 
| 146 | 164 | 
| 147 SourceDir BundleData::GetBundleRootDirOutputAsDir( | 165 SourceDir BundleData::GetBundleRootDirOutputAsDir( | 
| 148     const Settings* settings) const { | 166     const Settings* settings) const { | 
| 149   return SourceDir(GetBundleRootDirOutput(settings).value()); | 167   return SourceDir(GetBundleRootDirOutput(settings).value()); | 
| 150 } | 168 } | 
| OLD | NEW | 
|---|