diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7d1020aef2..84920600ee 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,7 +8,9 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
##### Enhancements
-* None.
+* Integrate ODR categories into projects.
+ [Dimitris Koutsogiorgas](https://github.com/dnkoutso)
+ [#10855](https://github.com/CocoaPods/CocoaPods/pull/10855)
##### Bug Fixes
diff --git a/Gemfile.lock b/Gemfile.lock
index 203d8bd9e2..c78311d856 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -7,7 +7,7 @@ GIT
GIT
remote: https://github.com/CocoaPods/Core.git
- revision: 609a964026350b86d4c5bf9a30c03c1c699be32c
+ revision: bdfd495cc11162f2e82da157116024ac51d05f4c
branch: 1-11-stable
specs:
cocoapods-core (1.11.0.beta.1)
diff --git a/examples/OnDemandResources Example/OnDemandResourcesDemo.xcworkspace/contents.xcworkspacedata b/examples/OnDemandResources Example/Examples.xcworkspace/contents.xcworkspacedata
similarity index 100%
rename from examples/OnDemandResources Example/OnDemandResourcesDemo.xcworkspace/contents.xcworkspacedata
rename to examples/OnDemandResources Example/Examples.xcworkspace/contents.xcworkspacedata
diff --git a/examples/OnDemandResources Example/OnDemandResourcesDemo.xcodeproj/project.pbxproj b/examples/OnDemandResources Example/OnDemandResourcesDemo.xcodeproj/project.pbxproj
index 631a137148..759b634a7f 100644
--- a/examples/OnDemandResources Example/OnDemandResourcesDemo.xcodeproj/project.pbxproj
+++ b/examples/OnDemandResources Example/OnDemandResourcesDemo.xcodeproj/project.pbxproj
@@ -404,6 +404,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
+ ON_DEMAND_RESOURCES_PREFETCH_ORDER = t2;
PRODUCT_BUNDLE_IDENTIFIER = com.junyixie..OnDemandResourcesDemo;
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
@@ -421,6 +422,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
+ ON_DEMAND_RESOURCES_PREFETCH_ORDER = t2;
PRODUCT_BUNDLE_IDENTIFIER = com.junyixie..OnDemandResourcesDemo;
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
diff --git a/examples/OnDemandResources Example/OnDemandResourcesDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/OnDemandResources Example/OnDemandResourcesDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
deleted file mode 100644
index 18d981003d..0000000000
--- a/examples/OnDemandResources Example/OnDemandResourcesDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- IDEDidComputeMac32BitWarning
-
-
-
diff --git a/examples/OnDemandResources Example/Podfile b/examples/OnDemandResources Example/Podfile
index 7de1493fc9..f700c43d9a 100644
--- a/examples/OnDemandResources Example/Podfile
+++ b/examples/OnDemandResources Example/Podfile
@@ -1,5 +1,5 @@
-# Uncomment the next line to define a global platform for your project
-# platform :ios, '9.0'
+workspace 'Examples.xcworkspace'
+project 'OnDemandResourcesDemo.xcodeproj'
target 'OnDemandResourcesDemo' do
platform :ios, '13.2'
diff --git a/examples/OnDemandResources Example/TestLibrary/TestLibrary.podspec b/examples/OnDemandResources Example/TestLibrary/TestLibrary.podspec
index db8f8de06f..c46340e718 100644
--- a/examples/OnDemandResources Example/TestLibrary/TestLibrary.podspec
+++ b/examples/OnDemandResources Example/TestLibrary/TestLibrary.podspec
@@ -36,7 +36,7 @@ TODO: Add long description of the pod here.
s.on_demand_resources = {
't1' => ['on_demand_bundle1/*'],
- 't2' => ['on_demand_bundle2/*']
+ 't2' => { :paths => ['on_demand_bundle2/*'], :category => :prefetched },
}
s.pod_target_xcconfig = {
@@ -47,7 +47,7 @@ TODO: Add long description of the pod here.
app_spec.source_files = 'App1/Classes/**/*'
app_spec.on_demand_resources = {
- 'a1' => ['App1/app1_on_demand_bundle1/*']
+ 'a1' => { :paths => ['App1/app1_on_demand_bundle1/*'], :category => :initial_install }
}
end
@@ -55,7 +55,7 @@ TODO: Add long description of the pod here.
app_spec.source_files = 'App2/Classes/**/*'
app_spec.on_demand_resources = {
- 'a2' => ['App2/app2_on_demand_bundle1/*']
+ 'a2' => { :paths => ['App2/app2_on_demand_bundle1/*'], :category => :initial_install }
}
end
diff --git a/lib/cocoapods/installer/project_cache/target_cache_key.rb b/lib/cocoapods/installer/project_cache/target_cache_key.rb
index 471294494d..71969f9aff 100644
--- a/lib/cocoapods/installer/project_cache/target_cache_key.rb
+++ b/lib/cocoapods/installer/project_cache/target_cache_key.rb
@@ -162,8 +162,11 @@ def self.from_aggregate_target(sandbox, aggregate_target)
'BUILD_SETTINGS_CHECKSUM' => build_settings,
}
if aggregate_target.includes_resources? || aggregate_target.includes_on_demand_resources?
- relative_file_paths = aggregate_target.resource_paths_by_config.values.flatten.uniq + aggregate_target.on_demand_resources.map(&:to_s)
- contents['FILES'] = relative_file_paths.sort_by(&:downcase)
+ relative_resource_file_paths = aggregate_target.resource_paths_by_config.values.flatten.uniq
+ relative_on_demand_resource_file_paths = aggregate_target.on_demand_resources.map do |res|
+ res.relative_path_from(sandbox.project_path.dirname).to_s
+ end
+ contents['FILES'] = (relative_resource_file_paths + relative_on_demand_resource_file_paths).sort_by(&:downcase)
end
TargetCacheKey.new(sandbox, :aggregate, contents)
end
diff --git a/lib/cocoapods/installer/user_project_integrator/target_integrator.rb b/lib/cocoapods/installer/user_project_integrator/target_integrator.rb
index 02c496efea..caec8dcd39 100644
--- a/lib/cocoapods/installer/user_project_integrator/target_integrator.rb
+++ b/lib/cocoapods/installer/user_project_integrator/target_integrator.rb
@@ -32,7 +32,8 @@ class TargetIntegrator
# For messages extensions, this only applies if it's embedded in a messages
# application.
#
- EMBED_FRAMEWORK_TARGET_TYPES = [:application, :application_on_demand_install_capable, :unit_test_bundle, :ui_test_bundle, :watch2_extension, :messages_application].freeze
+ EMBED_FRAMEWORK_TARGET_TYPES = [:application, :application_on_demand_install_capable, :unit_test_bundle,
+ :ui_test_bundle, :watch2_extension, :messages_application].freeze
# @return [String] the name of the embed frameworks phase
#
@@ -457,9 +458,9 @@ def embed_frameworks_output_paths(framework_paths, xcframeworks)
#
# @return [void]
#
- def add_on_demand_resources(sandbox, project, native_targets, file_accessors, parent_odr_group,
- target_odr_group_name)
- asset_tags_added = Set.new
+ def update_on_demand_resources(sandbox, project, native_targets, file_accessors, parent_odr_group,
+ target_odr_group_name)
+ category_to_tags = {}
file_accessors = Array(file_accessors)
native_targets = Array(native_targets)
@@ -469,8 +470,9 @@ def add_on_demand_resources(sandbox, project, native_targets, file_accessors, pa
old_odr_file_refs = old_target_odr_group&.recursive_children_groups&.each_with_object({}) do |group, hash|
hash[group.name] = group.files
end || {}
- native_targets.each do |user_target|
- user_target.remove_on_demand_resources(old_odr_file_refs)
+ native_targets.each do |native_target|
+ native_target.remove_on_demand_resources(old_odr_file_refs)
+ update_on_demand_resources_build_settings(native_target, nil => old_odr_file_refs.keys)
end
old_target_odr_group&.remove_from_project
return
@@ -480,17 +482,18 @@ def add_on_demand_resources(sandbox, project, native_targets, file_accessors, pa
current_file_refs = target_odr_group.recursive_children_groups.flat_map(&:files)
added_file_refs = file_accessors.flat_map do |file_accessor|
- target_odr_files_refs = Hash[file_accessor.on_demand_resources.map do |tag, resources|
+ target_odr_files_refs = Hash[file_accessor.on_demand_resources.map do |tag, value|
tag_group = target_odr_group[tag] || target_odr_group.new_group(tag)
- asset_tags_added << tag
- resources_file_refs = resources.map do |resource|
+ category_to_tags[value[:category]] ||= []
+ category_to_tags[value[:category]] << tag
+ resources_file_refs = value[:paths].map do |resource|
odr_resource_file_ref = Pathname.new(resource).relative_path_from(sandbox.root)
tag_group.find_file_by_path(odr_resource_file_ref.to_s) || tag_group.new_file(odr_resource_file_ref)
end
[tag, resources_file_refs]
end]
- native_targets.each do |user_target|
- user_target.add_on_demand_resources(target_odr_files_refs)
+ native_targets.each do |native_target|
+ native_target.add_on_demand_resources(target_odr_files_refs)
end
target_odr_files_refs.values.flatten
end
@@ -506,10 +509,42 @@ def add_on_demand_resources(sandbox, project, native_targets, file_accessors, pa
end
target_odr_group.recursive_children_groups.each { |g| g.remove_from_project if g.empty? }
- unless asset_tags_added.empty?
- attributes = project.root_object.attributes
- attributes['KnownAssetTags'] = (attributes['KnownAssetTags'] ||= []) | asset_tags_added.to_a
- project.root_object.attributes = attributes
+ attributes = project.root_object.attributes
+ attributes['KnownAssetTags'] = (attributes['KnownAssetTags'] ||= []) | category_to_tags.values.flatten
+ project.root_object.attributes = attributes
+
+ native_targets.each do |native_target|
+ update_on_demand_resources_build_settings(native_target, category_to_tags)
+ end
+ end
+
+ def update_on_demand_resources_build_settings(native_target, category_to_tags)
+ %w[ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS ON_DEMAND_RESOURCES_PREFETCH_ORDER].each do |category_key|
+ native_target.build_configurations.each do |c|
+ key = case category_key
+ when 'ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS'
+ :initial_install
+ when 'ON_DEMAND_RESOURCES_PREFETCH_ORDER'
+ :prefetched
+ else
+ :download_on_demand
+ end
+ tags_for_category = (c.build_settings[category_key] || '').split
+ category_to_tags_dup = category_to_tags.dup
+ tags_to_add = category_to_tags_dup.delete(key) || []
+ tags_to_delete = category_to_tags_dup.values.flatten
+ tags_for_category = (tags_for_category + tags_to_add - tags_to_delete).flatten.compact.uniq
+ if tags_for_category.empty?
+ val = c.build_settings.delete(category_key)
+ native_target.project.mark_dirty! unless val.nil?
+ else
+ tags = tags_for_category.join(' ')
+ unless c.build_settings[category_key] == tags
+ c.build_settings[category_key] = tags
+ native_target.project.mark_dirty!
+ end
+ end
+ end
end
end
end
@@ -596,10 +631,12 @@ def add_copy_resources_script_phase
output_paths_by_config = {}
if use_input_output_paths
target.resource_paths_by_config.each do |config, resource_paths|
- input_paths_key = XCFileListConfigKey.new(target.copy_resources_script_input_files_path(config), target.copy_resources_script_input_files_relative_path)
+ input_paths_key = XCFileListConfigKey.new(target.copy_resources_script_input_files_path(config),
+ target.copy_resources_script_input_files_relative_path)
input_paths_by_config[input_paths_key] = [script_path] + resource_paths
- output_paths_key = XCFileListConfigKey.new(target.copy_resources_script_output_files_path(config), target.copy_resources_script_output_files_relative_path)
+ output_paths_key = XCFileListConfigKey.new(target.copy_resources_script_output_files_path(config),
+ target.copy_resources_script_output_files_relative_path)
output_paths_by_config[output_paths_key] = TargetIntegrator.resource_output_paths(resource_paths)
end
end
@@ -607,7 +644,9 @@ def add_copy_resources_script_phase
native_targets.each do |native_target|
# Static library targets cannot include resources. Skip this phase from being added instead.
next if native_target.symbol_type == :static_library
- TargetIntegrator.create_or_update_copy_resources_script_phase_to_target(native_target, script_path, input_paths_by_config, output_paths_by_config)
+ TargetIntegrator.create_or_update_copy_resources_script_phase_to_target(native_target, script_path,
+ input_paths_by_config,
+ output_paths_by_config)
end
end
@@ -720,8 +759,8 @@ def add_on_demand_resources
# The 'Pods' group would always be there for production code however for tests its sometimes not added.
# This ensures its always present and makes it easier for existing and new tests.
parent_odr_group = target.user_project.main_group['Pods'] || target.user_project.new_group('Pods')
- TargetIntegrator.add_on_demand_resources(target.sandbox, target.user_project, target.user_targets,
- library_file_accessors, parent_odr_group, target_odr_group_name)
+ TargetIntegrator.update_on_demand_resources(target.sandbox, target.user_project, target.user_targets,
+ library_file_accessors, parent_odr_group, target_odr_group_name)
end
end
diff --git a/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb b/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb
index a9af13d52a..a1df9bb554 100644
--- a/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb
+++ b/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb
@@ -271,17 +271,17 @@ def add_on_demand_resources(native_target, app_spec)
fa.spec.test_specification? && pod_target.test_app_hosts_by_spec[fa.spec]&.first == app_spec
end
target_odr_group_name = "#{pod_target.label}-OnDemandResources"
- UserProjectIntegrator::TargetIntegrator.add_on_demand_resources(target.sandbox, native_target.project,
- native_target, file_accessors,
- parent_odr_group, target_odr_group_name)
+ UserProjectIntegrator::TargetIntegrator.update_on_demand_resources(target.sandbox, native_target.project,
+ native_target, file_accessors,
+ parent_odr_group, target_odr_group_name)
end
# Now add the ODRs of our own app spec declaration.
file_accessor = target.file_accessors.find { |fa| fa.spec == app_spec }
target_odr_group_name = "#{target.subspec_label(app_spec)}-OnDemandResources"
- UserProjectIntegrator::TargetIntegrator.add_on_demand_resources(target.sandbox, native_target.project,
- native_target, file_accessor,
- parent_odr_group, target_odr_group_name)
+ UserProjectIntegrator::TargetIntegrator.update_on_demand_resources(target.sandbox, native_target.project,
+ native_target, file_accessor,
+ parent_odr_group, target_odr_group_name)
end
# @return [String] the message that should be displayed for the target
diff --git a/lib/cocoapods/sandbox/file_accessor.rb b/lib/cocoapods/sandbox/file_accessor.rb
index b85f046a47..b7771a185f 100644
--- a/lib/cocoapods/sandbox/file_accessor.rb
+++ b/lib/cocoapods/sandbox/file_accessor.rb
@@ -219,7 +219,7 @@ def self.all_files(file_accessors)
file_accessors.map(&:preserve_paths),
file_accessors.map(&:readme),
file_accessors.map(&:resources),
- file_accessors.flat_map { |f| f.on_demand_resources.values.flatten },
+ file_accessors.map(&:on_demand_resources_files),
file_accessors.map(&:source_files),
file_accessors.map(&:module_map),
]
@@ -334,20 +334,26 @@ def resource_bundle_files
resource_bundles.values.flatten
end
- # @return [Hash{String => Array}] The paths of the on demand resources specified
- # keyed by their tag.
+ # @return [Hash{String => Hash] The expanded paths of the on demand resources specified
+ # keyed by their tag including their category.
#
def on_demand_resources
result = {}
spec_consumer.on_demand_resources.each do |tag_name, file_patterns|
- paths = expanded_paths(file_patterns,
+ paths = expanded_paths(file_patterns[:paths],
:exclude_patterns => spec_consumer.exclude_files,
:include_dirs => true)
- result[tag_name] = paths
+ result[tag_name] = { :paths => paths, :category => file_patterns[:category] }
end
result
end
+ # @return [Array] The expanded paths of the on demand resources.
+ #
+ def on_demand_resources_files
+ on_demand_resources.values.flat_map { |v| v[:paths] }
+ end
+
# @return [Pathname] The of the prefix header file of the specification.
#
def prefix_header
diff --git a/lib/cocoapods/target/aggregate_target.rb b/lib/cocoapods/target/aggregate_target.rb
index 5cecac06dd..081b642f3b 100644
--- a/lib/cocoapods/target/aggregate_target.rb
+++ b/lib/cocoapods/target/aggregate_target.rb
@@ -288,7 +288,7 @@ def on_demand_resources
@on_demand_resources ||= begin
pod_targets.flat_map do |pod_target|
library_file_accessors = pod_target.file_accessors.select { |fa| fa.spec.library_specification? }
- library_file_accessors.flat_map { |fa| fa.on_demand_resources.values.flatten }
+ library_file_accessors.flat_map(&:on_demand_resources_files)
end.uniq
end
end
diff --git a/lib/cocoapods/target/pod_target.rb b/lib/cocoapods/target/pod_target.rb
index a8957a2e3c..503e143da6 100644
--- a/lib/cocoapods/target/pod_target.rb
+++ b/lib/cocoapods/target/pod_target.rb
@@ -203,7 +203,7 @@ def label
end
end
- # @return [Array] The list of all files tracked.
+ # @return [Array] The list of all files tracked.
#
def all_files
Sandbox::FileAccessor.all_files(file_accessors)
diff --git a/spec/unit/installer/project_cache/target_cache_key_spec.rb b/spec/unit/installer/project_cache/target_cache_key_spec.rb
index a702fe42cd..3595c25711 100644
--- a/spec/unit/installer/project_cache/target_cache_key_spec.rb
+++ b/spec/unit/installer/project_cache/target_cache_key_spec.rb
@@ -38,9 +38,12 @@ module ProjectCache
fixture_target_definition('MyApp'), config.sandbox.root.dirname, nil,
nil, 'Debug' => [@banana_pod_target])
@banana_pod_target.stubs(:resource_paths).returns({})
- @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns('tag1' => ['/path/to/resource'])
+ on_demand_resources = { 'tag1' => { :paths => [Pathname('/path/to/resource')], :category => :download_on_demand } }
+ @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns(on_demand_resources)
aggregate_target_cache_key = TargetCacheKey.from_aggregate_target(config.sandbox, aggregate_target)
- library_on_demand_resources = @banana_pod_target.file_accessors.first.on_demand_resources.values.flatten.sort_by(&:downcase)
+ library_on_demand_resources = @banana_pod_target.file_accessors.first.on_demand_resources_files.map do |p|
+ p.relative_path_from(config.sandbox.root).to_s.downcase
+ end
aggregate_target_cache_key.to_h['FILES'].should.equal(library_on_demand_resources)
end
@@ -48,10 +51,13 @@ module ProjectCache
aggregate_target = AggregateTarget.new(config.sandbox, BuildType.static_library, { 'Debug' => :debug }, [], Platform.ios,
fixture_target_definition('MyApp'), config.sandbox.root.dirname, nil,
nil, 'Debug' => [@banana_pod_target])
- @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns('tag1' => ['/path/to/resource'])
+ on_demand_resources = { 'tag1' => { :paths => [Pathname('/path/to/resource')], :category => :download_on_demand } }
+ @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns(on_demand_resources)
aggregate_target_cache_key = TargetCacheKey.from_aggregate_target(config.sandbox, aggregate_target)
library_resources = @banana_pod_target.resource_paths.values.flatten.sort_by(&:downcase)
- library_on_demand_resources = @banana_pod_target.file_accessors.first.on_demand_resources.values.flatten.sort_by(&:downcase)
+ library_on_demand_resources = @banana_pod_target.file_accessors.first.on_demand_resources_files.map do |p|
+ p.relative_path_from(config.sandbox.root).to_s.downcase
+ end
aggregate_target_cache_key.to_h['FILES'].should.equal(library_resources + library_on_demand_resources)
end
end
diff --git a/spec/unit/installer/user_project_integrator/target_integrator_spec.rb b/spec/unit/installer/user_project_integrator/target_integrator_spec.rb
index 0c819b10f4..22bfb2dffd 100644
--- a/spec/unit/installer/user_project_integrator/target_integrator_spec.rb
+++ b/spec/unit/installer/user_project_integrator/target_integrator_spec.rb
@@ -754,9 +754,8 @@ module Pod
end
it 'adds and remove on demand resources to the user target resources build phase' do
- @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns(
- 'tag1' => [config.sandbox.root + 'banana-lib/path/to/resource.png'],
- )
+ on_demand_resources = { 'tag1' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource.png'], :category => :download_on_demand } }
+ @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns(on_demand_resources)
@target_integrator.integrate!
target = @target_integrator.send(:native_targets).first
target.resources_build_phase.files.map(&:display_name).should == ['InfoPlist.strings', 'resource.png']
@@ -776,10 +775,11 @@ module Pod
end
it 'removes stale on demand resource file references' do
- @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns(
- 'tag1' => [config.sandbox.root + 'banana-lib/path/to/resource.png'],
- 'tag2' => [config.sandbox.root + 'banana-lib/path/to/resource2.png'],
- )
+ on_demand_resources = {
+ 'tag1' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource.png'], :category => :download_on_demand },
+ 'tag2' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource2.png'], :category => :download_on_demand },
+ }
+ @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns(on_demand_resources)
@target_integrator.integrate!
target = @target_integrator.send(:native_targets).first
target.resources_build_phase.files.map(&:display_name).should == ['InfoPlist.strings', 'resource.png', 'resource2.png']
@@ -789,9 +789,8 @@ module Pod
@project['Pods']['BananaLib-OnDemandResources']['tag1'].files.map(&:display_name).should == ['resource.png']
@project['Pods']['BananaLib-OnDemandResources']['tag2'].files.map(&:display_name).should == ['resource2.png']
@project.root_object.attributes['KnownAssetTags'].should == %w[tag1 tag2]
- @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns(
- 'tag2' => [config.sandbox.root + 'banana-lib/path/to/resource2.png'],
- )
+ on_demand_resources = { 'tag2' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource2.png'], :category => :download_on_demand } }
+ @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns(on_demand_resources)
@target_integrator.integrate!
target.resources_build_phase.files.map(&:display_name).should == ['InfoPlist.strings', 'resource2.png']
@project.main_group.find_subpath('Pods/BananaLib-OnDemandResources').should.not.be.nil
@@ -804,6 +803,130 @@ module Pod
@project.root_object.attributes['KnownAssetTags'].should == %w[tag1 tag2]
end
+ it 'completely removes build settings related to on demand resources if they are empty' do
+ on_demand_resources = { 'tag1' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource.png'], :category => :initial_install } }
+ @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns(on_demand_resources)
+ @project.dirty?.should.be.false
+ @target_integrator.integrate!
+ target = @target_integrator.send(:native_targets).first
+ target.build_configurations.each do |bc|
+ bc.build_settings['ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS'].should == 'tag1'
+ end
+ @project.dirty?.should.be.true
+ @project.save
+ @project.dirty?.should.be.false
+ # Now pretend target no longer specifies ODRs.
+ @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns({})
+ @target_integrator.integrate!
+ target.build_configurations.each do |bc|
+ bc.build_settings['ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS'].should.be.nil
+ end
+ @project.dirty?.should.be.true
+ end
+
+ it 'maintains on demand resources build settings when a target no longer specifies on demand resources' do
+ target = @target_integrator.send(:native_targets).first
+ target.build_configurations.each do |bc|
+ bc.build_settings['ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS'] = 'existing_tag'
+ end
+ @project.dirty?.should.be.false
+ on_demand_resources = { 'tag1' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource.png'], :category => :initial_install } }
+ @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns(on_demand_resources)
+ @target_integrator.integrate!
+ target.build_configurations.each do |bc|
+ bc.build_settings['ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS'].should == 'existing_tag tag1'
+ end
+ @project.dirty?.should.be.true
+ @project.save
+ @project.dirty?.should.be.false
+ # Now pretend target no longer specifies ODRs.
+ @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns({})
+ @target_integrator.integrate!
+ target.build_configurations.each do |bc|
+ bc.build_settings['ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS'].should == 'existing_tag'
+ end
+ @project.dirty?.should.be.true
+ end
+
+ it 'does not mark the project as dirty if on demand resources build settings did not change' do
+ on_demand_resources = {
+ 'tag1' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource.png'], :category => :initial_install },
+ 'tag2' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource2.png'], :category => :initial_install },
+ }
+ @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns(on_demand_resources)
+ @target_integrator.integrate!
+ target = @target_integrator.send(:native_targets).first
+ target.build_configurations.each do |bc|
+ bc.build_settings['ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS'].should == 'tag1 tag2'
+ end
+ @project.dirty?.should.be.true
+ @project.save
+ @project.dirty?.should.be.false
+ @target_integrator.integrate!
+ target.build_configurations.each do |bc|
+ bc.build_settings['ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS'].should == 'tag1 tag2'
+ end
+ @project.dirty?.should.be.false
+ end
+
+ it 'sets on demand resource category build settings' do
+ on_demand_resources = {
+ 'tag1' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource.png'], :category => :initial_install },
+ 'tag2' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource2.png'], :category => :prefetched },
+ }
+ @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns(on_demand_resources)
+ @target_integrator.integrate!
+ target = @target_integrator.send(:native_targets).first
+ @project.root_object.attributes['KnownAssetTags'].should == %w[tag1 tag2]
+ target.build_configurations.each do |bc|
+ bc.build_settings['ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS'].should == 'tag1'
+ bc.build_settings['ON_DEMAND_RESOURCES_PREFETCH_ORDER'].should == 'tag2'
+ end
+ end
+
+ it 'sets multiple on demand resource categories on a single build setting' do
+ on_demand_resources = {
+ 'tag1' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource.png'], :category => :initial_install },
+ 'tag2' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource2.png'], :category => :initial_install },
+ }
+ @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns(on_demand_resources)
+ @target_integrator.integrate!
+ target = @target_integrator.send(:native_targets).first
+ @project.root_object.attributes['KnownAssetTags'].should == %w[tag1 tag2]
+ target.build_configurations.each do |bc|
+ bc.build_settings['ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS'].should == 'tag1 tag2'
+ bc.build_settings['ON_DEMAND_RESOURCES_PREFETCH_ORDER'].should.be.nil
+ end
+ end
+
+ it 'updates on demand resources build settings if they change' do
+ on_demand_resources = {
+ 'tag1' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource.png'], :category => :initial_install },
+ 'tag2' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource2.png'], :category => :initial_install },
+ 'tag3' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource3.png'], :category => :initial_install },
+ }
+ @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns(on_demand_resources)
+ @target_integrator.integrate!
+ target = @target_integrator.send(:native_targets).first
+ @project.root_object.attributes['KnownAssetTags'].should == %w[tag1 tag2 tag3]
+ target.build_configurations.each do |bc|
+ bc.build_settings['ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS'].should == 'tag1 tag2 tag3'
+ bc.build_settings['ON_DEMAND_RESOURCES_PREFETCH_ORDER'].should.be.nil
+ end
+ on_demand_resources = {
+ 'tag1' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource.png'], :category => :prefetched },
+ 'tag2' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource2.png'], :category => :initial_install },
+ 'tag3' => { :paths => [config.sandbox.root + 'banana-lib/path/to/resource3.png'], :category => :download_on_demand },
+ }
+ @banana_pod_target.file_accessors.first.stubs(:on_demand_resources).returns(on_demand_resources)
+ @target_integrator.integrate!
+ @project.root_object.attributes['KnownAssetTags'].should == %w[tag1 tag2 tag3]
+ target.build_configurations.each do |bc|
+ bc.build_settings['ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS'].should == 'tag2'
+ bc.build_settings['ON_DEMAND_RESOURCES_PREFETCH_ORDER'].should == 'tag1'
+ end
+ end
+
describe 'Script paths' do
it 'calculates the output paths of the embed frameworks script' do
paths = [
diff --git a/spec/unit/sandbox/file_accessor_spec.rb b/spec/unit/sandbox/file_accessor_spec.rb
index 528bb80918..c6525c6094 100644
--- a/spec/unit/sandbox/file_accessor_spec.rb
+++ b/spec/unit/sandbox/file_accessor_spec.rb
@@ -196,24 +196,45 @@ module Pod
@accessor.resource_bundle_files.should == resource_paths
end
- it 'returns the paths of the files of the on demand resources' do
- @spec_consumer.stubs(:on_demand_resources).returns('OnDemandResources' => 'Resources/*')
+ it 'returns the expanded paths of the files of the on demand resources' do
+ on_demand_resources = { 'OnDemandResources' => { :paths => ['Resources/*'], :category => :download_on_demand } }
+ @spec_consumer.stubs(:on_demand_resources).returns(on_demand_resources)
expected_on_demand_resources = {
- 'OnDemandResources' => [
- @root + 'Resources/logo-sidebar.png',
- @root + 'Resources/Base.lproj',
- @root + 'Resources/de.lproj',
- @root + 'Resources/en.lproj',
- @root + 'Resources/Images.xcassets',
- @root + 'Resources/Migration.xcmappingmodel',
- @root + 'Resources/Sample.rcproject',
- @root + 'Resources/Sample.xcdatamodeld',
- @root + 'Resources/sub_dir',
- ],
+ 'OnDemandResources' => {
+ :paths => [
+ @root + 'Resources/logo-sidebar.png',
+ @root + 'Resources/Base.lproj',
+ @root + 'Resources/de.lproj',
+ @root + 'Resources/en.lproj',
+ @root + 'Resources/Images.xcassets',
+ @root + 'Resources/Migration.xcmappingmodel',
+ @root + 'Resources/Sample.rcproject',
+ @root + 'Resources/Sample.xcdatamodeld',
+ @root + 'Resources/sub_dir',
+ ],
+ :category => :download_on_demand,
+ },
}
@accessor.on_demand_resources.should == expected_on_demand_resources
end
+ it 'returns all the expanded paths of the files of the on demand resources' do
+ on_demand_resources = { 'OnDemandResources' => { :paths => ['Resources/*'], :category => :download_on_demand } }
+ @spec_consumer.stubs(:on_demand_resources).returns(on_demand_resources)
+ expected_on_demand_resources = [
+ @root + 'Resources/logo-sidebar.png',
+ @root + 'Resources/Base.lproj',
+ @root + 'Resources/de.lproj',
+ @root + 'Resources/en.lproj',
+ @root + 'Resources/Images.xcassets',
+ @root + 'Resources/Migration.xcmappingmodel',
+ @root + 'Resources/Sample.rcproject',
+ @root + 'Resources/Sample.xcdatamodeld',
+ @root + 'Resources/sub_dir',
+ ]
+ @accessor.on_demand_resources_files.should == expected_on_demand_resources
+ end
+
it 'takes into account exclude_files when creating the resource bundles of the pod' do
@spec_consumer.stubs(:exclude_files).returns(['**/*.png'])
@spec_consumer.stubs(:resource_bundles).returns('BananaLib' => 'Resources/*')
diff --git a/spec/unit/target/aggregate_target_spec.rb b/spec/unit/target/aggregate_target_spec.rb
index b0c90002f9..6c3cb91f8f 100644
--- a/spec/unit/target/aggregate_target_spec.rb
+++ b/spec/unit/target/aggregate_target_spec.rb
@@ -288,8 +288,10 @@ module Pod
it 'returns on demand resources paths' do
@target.stubs(:pod_targets).returns([@pod_target, @pod_target_release])
- @pod_target.file_accessors.first.stubs(:on_demand_resources).returns('tag1' => ['./banana-lib/path/to/resource'])
- @pod_target_release.file_accessors.first.stubs(:on_demand_resources).returns('othertag1' => ['./coconutlib/path/to/other/resource'])
+ on_demand_resources = { 'tag1' => { :paths => ['./banana-lib/path/to/resource'], :category => :download_on_demand } }
+ @pod_target.file_accessors.first.stubs(:on_demand_resources).returns(on_demand_resources)
+ release_on_demand_resources = { 'othertag1' => { :paths => ['./coconutlib/path/to/other/resource'], :category => :download_on_demand } }
+ @pod_target_release.file_accessors.first.stubs(:on_demand_resources).returns(release_on_demand_resources)
@target.on_demand_resources.should == ['./banana-lib/path/to/resource', './coconutlib/path/to/other/resource']
end
end