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.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/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..13d3328982 100644 --- a/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +++ b/lib/cocoapods/installer/user_project_integrator/target_integrator.rb @@ -459,7 +459,7 @@ def embed_frameworks_output_paths(framework_paths, xcframeworks) # def add_on_demand_resources(sandbox, project, native_targets, file_accessors, parent_odr_group, target_odr_group_name) - asset_tags_added = Set.new + category_to_tags = {} file_accessors = Array(file_accessors) native_targets = Array(native_targets) @@ -469,8 +469,8 @@ 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) end old_target_odr_group&.remove_from_project return @@ -480,17 +480,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 +507,34 @@ 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 + + %w[ON_DEMAND_RESOURCES_INITIAL_INSTALL_TAGS ON_DEMAND_RESOURCES_PREFETCH_ORDER].each do |category_key| + native_targets.each do |native_target| + 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? + c.build_settings.delete(category_key) + else + c.build_settings[category_key] = tags_for_category.join(' ') + end + native_target.project.mark_dirty! + end + end end end end diff --git a/lib/cocoapods/sandbox/file_accessor.rb b/lib/cocoapods/sandbox/file_accessor.rb index b85f046a47..193a26bc94 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 specified. + # + 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..01072e6069 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,64 @@ module Pod @project.root_object.attributes['KnownAssetTags'].should == %w[tag1 tag2] 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