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..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