From c25ff76afa7b6a0a205b20300f6a609bb4ef4242 Mon Sep 17 00:00:00 2001 From: Alexander Guschin Date: Wed, 1 May 2019 19:21:34 +0300 Subject: [PATCH 01/10] Add shared cache helper --- lib/cocoapods-binary/helper/shared_cache.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 lib/cocoapods-binary/helper/shared_cache.rb diff --git a/lib/cocoapods-binary/helper/shared_cache.rb b/lib/cocoapods-binary/helper/shared_cache.rb new file mode 100644 index 0000000..20e31c3 --- /dev/null +++ b/lib/cocoapods-binary/helper/shared_cache.rb @@ -0,0 +1,15 @@ +require_relative '../tool/tool' + +module Pod + class Prebuild + class SharedCache + # Keeps current xcode version. + # Converts from "Xcode 10.2.1\nBuild version 10E1001\n" to "10.2.1". + # + # @return [String] + # private + class_attr_accessor :xcode_version + self.xcode_version = `xcodebuild -version`.split("\n").first.split().last || "Unkwown" + end + end + end \ No newline at end of file From 5359b5b9f63cc7db419a1c36e96d1052bb4bafd8 Mon Sep 17 00:00:00 2001 From: Alexander Guschin Date: Thu, 2 May 2019 00:16:52 +0300 Subject: [PATCH 02/10] Add DSL for using shared cache --- lib/cocoapods-binary/Main.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/cocoapods-binary/Main.rb b/lib/cocoapods-binary/Main.rb index 78fcf41..5d76729 100644 --- a/lib/cocoapods-binary/Main.rb +++ b/lib/cocoapods-binary/Main.rb @@ -24,6 +24,11 @@ def keep_source_code_for_prebuilt_frameworks! DSL.dont_remove_source_code = true end + # Enable shared cache of prebuild frameworks + def use_shared_cache! + DSL.shared_cache_enabled = true + end + # Add custom xcodebuild option to the prebuilding action # # You may use this for your special demands. For example: the default archs in dSYMs @@ -65,6 +70,9 @@ def set_custom_xcodebuild_options_for_prebuilt_frameworks(options) class_attr_accessor :dont_remove_source_code dont_remove_source_code = false + class_attr_accessor :shared_cache_enabled + shared_cache_enabled = false + class_attr_accessor :custom_build_options class_attr_accessor :custom_build_options_simulator self.custom_build_options = [] From 3c700dd3669e62c486819067cc99b568370331a1 Mon Sep 17 00:00:00 2001 From: Alexander Guschin Date: Thu, 2 May 2019 00:17:26 +0300 Subject: [PATCH 03/10] Implement shared cache logic --- lib/cocoapods-binary/Prebuild.rb | 10 ++++- lib/cocoapods-binary/helper/shared_cache.rb | 50 +++++++++++++++++++-- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/lib/cocoapods-binary/Prebuild.rb b/lib/cocoapods-binary/Prebuild.rb index 77bc834..2246118 100644 --- a/lib/cocoapods-binary/Prebuild.rb +++ b/lib/cocoapods-binary/Prebuild.rb @@ -123,7 +123,15 @@ def prebuild_frameworks! output_path = sandbox.framework_folder_path_for_target_name(target.name) output_path.mkpath unless output_path.exist? - Pod::Prebuild.build(sandbox_path, target, output_path, bitcode_enabled, Podfile::DSL.custom_build_options, Podfile::DSL.custom_build_options_simulator) + + if Prebuild::SharedCache.has?(target) + framework_cache_path = Prebuild::SharedCache.framework_cache_path_for(target) + UI.puts "Using #{target.label} from cache" + FileUtils.cp_r "#{framework_cache_path}/.", output_path + else + Pod::Prebuild.build(sandbox_path, target, output_path, bitcode_enabled, Podfile::DSL.custom_build_options, Podfile::DSL.custom_build_options_simulator) + Prebuild::SharedCache.cache(target, output_path) + end # save the resource paths for later installing if target.static_framework? and !target.resource_paths.empty? diff --git a/lib/cocoapods-binary/helper/shared_cache.rb b/lib/cocoapods-binary/helper/shared_cache.rb index 20e31c3..2591288 100644 --- a/lib/cocoapods-binary/helper/shared_cache.rb +++ b/lib/cocoapods-binary/helper/shared_cache.rb @@ -3,13 +3,55 @@ module Pod class Prebuild class SharedCache - # Keeps current xcode version. - # Converts from "Xcode 10.2.1\nBuild version 10E1001\n" to "10.2.1". + extend Config::Mixin + + # `true` if there is cache for the target + # `false` otherwise + # + # @return [Boolean] + def self.has?(target) + if Podfile::DSL.shared_cache_enabled + framework_cache_path_for(target).exist? + else + false + end + end + + # Copies input_path to target's cache + def self.cache(target, input_path) + if not Podfile::DSL.shared_cache_enabled + return + end + cache_path = framework_cache_path_for(target) + cache_path.mkpath unless cache_path.exist? + FileUtils.cp_r "#{input_path}/.", cache_path + end + + # Path of the target's cache + # + # @return [Pathname] + def self.framework_cache_path_for(target) + framework_cache_path = cache_root + xcode_version + framework_cache_path = framework_cache_path + target.name + framework_cache_path = framework_cache_path + target.version + end + + # Current xcode version. # # @return [String] - # private + private class_attr_accessor :xcode_version + # Converts from "Xcode 10.2.1\nBuild version 10E1001\n" to "10.2.1". self.xcode_version = `xcodebuild -version`.split("\n").first.split().last || "Unkwown" + + # Path of the cache folder + # Reusing cache_root from cocoapods's config + # `~Library/Caches/CocoaPods` is default value + # + # @return [Pathname] + private + class_attr_accessor :cache_root + self.cache_root = config.cache_root + 'Prebuild' end end - end \ No newline at end of file +end \ No newline at end of file From 649e6acf0486e6499a705bb3a1495368696da47e Mon Sep 17 00:00:00 2001 From: Alexander Guschin Date: Thu, 2 May 2019 01:13:09 +0300 Subject: [PATCH 04/10] Improve cache by respecting options --- lib/cocoapods-binary/Prebuild.rb | 15 ++++++++++----- lib/cocoapods-binary/helper/shared_cache.rb | 12 +++++++----- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/lib/cocoapods-binary/Prebuild.rb b/lib/cocoapods-binary/Prebuild.rb index 2246118..6d61969 100644 --- a/lib/cocoapods-binary/Prebuild.rb +++ b/lib/cocoapods-binary/Prebuild.rb @@ -1,6 +1,7 @@ require_relative 'rome/build_framework' require_relative 'helper/passer' require_relative 'helper/target_checker' +require_relative 'helper/shared_cache' # patch prebuild ability @@ -70,7 +71,11 @@ def prebuild_frameworks! # build options sandbox_path = sandbox.root existed_framework_folder = sandbox.generate_framework_path - bitcode_enabled = Pod::Podfile::DSL.bitcode_enabled + options = [ + Podfile::DSL.bitcode_enabled, + Podfile::DSL.custom_build_options, + Podfile::DSL.custom_build_options_simulator + ] targets = [] if local_manifest != nil @@ -124,13 +129,13 @@ def prebuild_frameworks! output_path = sandbox.framework_folder_path_for_target_name(target.name) output_path.mkpath unless output_path.exist? - if Prebuild::SharedCache.has?(target) - framework_cache_path = Prebuild::SharedCache.framework_cache_path_for(target) + if Prebuild::SharedCache.has?(target, options) + framework_cache_path = Prebuild::SharedCache.framework_cache_path_for(target, options) UI.puts "Using #{target.label} from cache" FileUtils.cp_r "#{framework_cache_path}/.", output_path else - Pod::Prebuild.build(sandbox_path, target, output_path, bitcode_enabled, Podfile::DSL.custom_build_options, Podfile::DSL.custom_build_options_simulator) - Prebuild::SharedCache.cache(target, output_path) + Pod::Prebuild.build(sandbox_path, target, output_path, *options) + Prebuild::SharedCache.cache(target, output_path, options) end # save the resource paths for later installing diff --git a/lib/cocoapods-binary/helper/shared_cache.rb b/lib/cocoapods-binary/helper/shared_cache.rb index 2591288..c177d2b 100644 --- a/lib/cocoapods-binary/helper/shared_cache.rb +++ b/lib/cocoapods-binary/helper/shared_cache.rb @@ -1,3 +1,4 @@ +require 'digest' require_relative '../tool/tool' module Pod @@ -9,20 +10,20 @@ class SharedCache # `false` otherwise # # @return [Boolean] - def self.has?(target) + def self.has?(target, options) if Podfile::DSL.shared_cache_enabled - framework_cache_path_for(target).exist? + framework_cache_path_for(target, options).exist? else false end end # Copies input_path to target's cache - def self.cache(target, input_path) + def self.cache(target, input_path, options) if not Podfile::DSL.shared_cache_enabled return end - cache_path = framework_cache_path_for(target) + cache_path = framework_cache_path_for(target, options) cache_path.mkpath unless cache_path.exist? FileUtils.cp_r "#{input_path}/.", cache_path end @@ -30,10 +31,11 @@ def self.cache(target, input_path) # Path of the target's cache # # @return [Pathname] - def self.framework_cache_path_for(target) + def self.framework_cache_path_for(target, options) framework_cache_path = cache_root + xcode_version framework_cache_path = framework_cache_path + target.name framework_cache_path = framework_cache_path + target.version + framework_cache_path = framework_cache_path + Digest::MD5.hexdigest(options.to_s).to_s end # Current xcode version. From 0e3a6de255cef4e9d01e9c5f1ba8f5f859804fc9 Mon Sep 17 00:00:00 2001 From: Alexander Guschin Date: Thu, 2 May 2019 01:32:42 +0300 Subject: [PATCH 05/10] Improve cache by respecting target platform --- lib/cocoapods-binary/helper/shared_cache.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/cocoapods-binary/helper/shared_cache.rb b/lib/cocoapods-binary/helper/shared_cache.rb index c177d2b..b1338fe 100644 --- a/lib/cocoapods-binary/helper/shared_cache.rb +++ b/lib/cocoapods-binary/helper/shared_cache.rb @@ -35,7 +35,8 @@ def self.framework_cache_path_for(target, options) framework_cache_path = cache_root + xcode_version framework_cache_path = framework_cache_path + target.name framework_cache_path = framework_cache_path + target.version - framework_cache_path = framework_cache_path + Digest::MD5.hexdigest(options.to_s).to_s + options_with_platform = options + [target.platform.name] + framework_cache_path = framework_cache_path + Digest::MD5.hexdigest(options_with_platform.to_s).to_s end # Current xcode version. From 23d7c29d899eb624708c05d2f180062b75dbef6c Mon Sep 17 00:00:00 2001 From: Alexander Guschin Date: Thu, 2 May 2019 01:35:03 +0300 Subject: [PATCH 06/10] Update readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a1aa947..9403466 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,8 @@ If your `Pods` folder is excluded from git, you may add `keep_source_code_for_pr If bitcode is needed, add a `enable_bitcode_for_prebuilt_frameworks!` before all targets in Podfile +if you want to share prebuild frameworks for different projects or for CI builds, you may add `use_shared_cache!` in the head of Podfile to speed up pod install, as it will reuse frameworks from common cache folder(`~Library/Caches/CocoaPods/Prebuild` by default). + #### Known Issues @@ -74,5 +76,3 @@ If bitcode is needed, add a `enable_bitcode_for_prebuilt_frameworks!` before all MIT Appreciate a 🌟 if you like it. - - From 57c96ce983c1e1c95f8eb565b76e8f58bdb349e9 Mon Sep 17 00:00:00 2001 From: Alexander Guschin Date: Thu, 2 May 2019 01:41:47 +0300 Subject: [PATCH 07/10] Improve documentation for shared cache --- README.md | 2 +- lib/cocoapods-binary/Main.rb | 8 ++++++++ lib/cocoapods-binary/helper/shared_cache.rb | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9403466..7aa2152 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ If your `Pods` folder is excluded from git, you may add `keep_source_code_for_pr If bitcode is needed, add a `enable_bitcode_for_prebuilt_frameworks!` before all targets in Podfile -if you want to share prebuild frameworks for different projects or for CI builds, you may add `use_shared_cache!` in the head of Podfile to speed up pod install, as it will reuse frameworks from common cache folder(`~Library/Caches/CocoaPods/Prebuild` by default). +if you want to share prebuilt frameworks for different projects or for CI builds, you may add `use_shared_cache!` in the head of Podfile to speed up pod install, as it will reuse frameworks from common cache folder(`~Library/Caches/CocoaPods/Prebuilt` by default). #### Known Issues diff --git a/lib/cocoapods-binary/Main.rb b/lib/cocoapods-binary/Main.rb index 5d76729..0a9b012 100644 --- a/lib/cocoapods-binary/Main.rb +++ b/lib/cocoapods-binary/Main.rb @@ -25,6 +25,14 @@ def keep_source_code_for_prebuilt_frameworks! end # Enable shared cache of prebuild frameworks + # Frameworks are stored inside cocoapods cache folder + # + # Location: ~/Library/Caches/CocoaPods/Prebuilt/ + # Structure: //// + # Options hash depends on: + # - bitcode(enable_bitcode_for_prebuilt_frameworks!); + # - custom options(set_custom_xcodebuild_options_for_prebuilt_frameworks); + # - platform name(ios, osx); def use_shared_cache! DSL.shared_cache_enabled = true end diff --git a/lib/cocoapods-binary/helper/shared_cache.rb b/lib/cocoapods-binary/helper/shared_cache.rb index b1338fe..2c0160b 100644 --- a/lib/cocoapods-binary/helper/shared_cache.rb +++ b/lib/cocoapods-binary/helper/shared_cache.rb @@ -54,7 +54,7 @@ def self.framework_cache_path_for(target, options) # @return [Pathname] private class_attr_accessor :cache_root - self.cache_root = config.cache_root + 'Prebuild' + self.cache_root = config.cache_root + 'Prebuilt' end end end \ No newline at end of file From 8a373b32570fef7a58605df0a4b2c8f5b407fe05 Mon Sep 17 00:00:00 2001 From: jaximan <20654361+jaximan@users.noreply.github.com> Date: Fri, 10 May 2019 22:04:33 -0700 Subject: [PATCH 08/10] Update Prebuild.rb [WIP] fix condition when target shouldn't build, but target_folder not exists --- lib/cocoapods-binary/Prebuild.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/cocoapods-binary/Prebuild.rb b/lib/cocoapods-binary/Prebuild.rb index 6d61969..866d2c4 100644 --- a/lib/cocoapods-binary/Prebuild.rb +++ b/lib/cocoapods-binary/Prebuild.rb @@ -178,6 +178,7 @@ def prebuild_frameworks! # This is for target with only .a and .h files if not target.should_build? Prebuild::Passer.target_names_to_skip_integration_framework << target.name + target_folder.mkpath unless target_folder.exist? FileUtils.cp_r(root_path, target_folder, :remove_destination => true) next end @@ -244,4 +245,4 @@ def prebuild_frameworks! end -end \ No newline at end of file +end From d5d97f7eb940f80f405dc54d8300289ef3a99df6 Mon Sep 17 00:00:00 2001 From: yrainik Date: Fri, 10 May 2019 22:21:35 -0700 Subject: [PATCH 09/10] Add s3 integration --- cocoapods-binary.gemspec | 1 + lib/cocoapods-binary/Main.rb | 18 ++++++ lib/cocoapods-binary/helper/shared_cache.rb | 72 +++++++++++++++++++-- 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/cocoapods-binary.gemspec b/cocoapods-binary.gemspec index 697aeb2..4a0d9ff 100644 --- a/cocoapods-binary.gemspec +++ b/cocoapods-binary.gemspec @@ -21,6 +21,7 @@ Gem::Specification.new do |spec| spec.add_dependency "cocoapods", ">= 1.5.0", "< 2.0" spec.add_dependency "fourflusher", "~> 2.0" spec.add_dependency "xcpretty", "~> 0.3.0" + spec.add_dependency "aws-sdk-s3", "~> 1" spec.add_development_dependency 'bundler', '~> 1.3' spec.add_development_dependency 'rake' diff --git a/lib/cocoapods-binary/Main.rb b/lib/cocoapods-binary/Main.rb index 0a9b012..5908478 100644 --- a/lib/cocoapods-binary/Main.rb +++ b/lib/cocoapods-binary/Main.rb @@ -37,6 +37,20 @@ def use_shared_cache! DSL.shared_cache_enabled = true end + # Enable s3 shared cache, requires use_shared_cache! + # Frameworks also stored in s3 bucket + # Options hash depends on: + # - login(optional) : if not provided default aws creds strategy will be applied + # - password(optional) : if not provided default aws creds strategy will be applied + # - region(optional): if not provided default aws region strategy will be applied + # - endpoint(optional): if not provided default aws endpoint will be used, supported for custom s3 like implementation, like Ceph + # - bucket(required): s3 bucket name + # - prefix(optional): prefix for object key + def use_s3_cache(options) + DSL.shared_s3_cache_enabled = true + DSL.s3_options = options + end + # Add custom xcodebuild option to the prebuilding action # # You may use this for your special demands. For example: the default archs in dSYMs @@ -80,6 +94,10 @@ def set_custom_xcodebuild_options_for_prebuilt_frameworks(options) class_attr_accessor :shared_cache_enabled shared_cache_enabled = false + class_attr_accessor :shared_s3_cache_enabled + shared_s3_cache_enabled = false + class_attr_accessor :s3_options + s3_options = {} class_attr_accessor :custom_build_options class_attr_accessor :custom_build_options_simulator diff --git a/lib/cocoapods-binary/helper/shared_cache.rb b/lib/cocoapods-binary/helper/shared_cache.rb index 2c0160b..bbbc61f 100644 --- a/lib/cocoapods-binary/helper/shared_cache.rb +++ b/lib/cocoapods-binary/helper/shared_cache.rb @@ -1,5 +1,7 @@ +require 'aws-sdk-s3' require 'digest' require_relative '../tool/tool' +require 'zip' module Pod class Prebuild @@ -12,27 +14,89 @@ class SharedCache # @return [Boolean] def self.has?(target, options) if Podfile::DSL.shared_cache_enabled - framework_cache_path_for(target, options).exist? + path = framework_cache_path_for(target, options, true) + result = path.exist? + if not result and Podfile::DSL.shared_s3_cache_enabled + s3_cache_path = framework_cache_path_for(target, options, false) + s3_cache_path = Podfile::DSL.s3_options[:prefix] + s3_cache_path unless Podfile::DSL.s3_options[:prefix].nil? + s3 = Aws::S3::Resource.new(create_s3_options) + if s3.bucket(Podfile::DSL.s3_options[:bucket]).object("#{s3_cache_path}").exists? + Dir.mktmpdir {|dir| + s3.bucket(Podfile::DSL.s3_options[:bucket]).object("#{s3_cache_path}").get(response_target: "#{dir}/framework.zip") + unzip("#{dir}/framework.zip", path) + return true + } + end + end + result else false end end - # Copies input_path to target's cache + # @return [{}] AWS connection options + def self.create_s3_options + options = {} + creds = Aws::Credentials.new(Podfile::DSL.s3_options[:login], Podfile::DSL.s3_options[:password]) unless Podfile::DSL.s3_options[:login].nil? and Podfile::DSL.s3_options[:password].nil? + options[:credentials] = creds unless creds.nil? + options[:region] = Podfile::DSL.s3_options[:region] unless Podfile::DSL.s3_options[:region].nil? + options[:endpoint] = Podfile::DSL.s3_options[:endpoint] unless Podfile::DSL.s3_options[:endpoint].nil? + + options + end + + def self.zip(dir, zip_dir) + Zip::File.open(zip_dir, Zip::File::CREATE)do |zipfile| + Find.find(dir) do |path| + Find.prune if File.basename(path)[0] == ?. + dest = /#{dir}\/(\w.*)/.match(path) + # Skip files if they exists + begin + zipfile.add(dest[1],path) if dest + rescue Zip::ZipEntryExistsError + end + end + end + end + + def self.unzip(zip, unzip_dir, remove_after = false) + Zip::File.open(zip) do |zip_file| + zip_file.each do |f| + f_path=File.join(unzip_dir, f.name) + FileUtils.mkdir_p(File.dirname(f_path)) + zip_file.extract(f, f_path) unless File.exist?(f_path) + end + end + FileUtils.rm(zip) if remove_after + end + + # Copies input_path to target's cache and save to s3 if applicable def self.cache(target, input_path, options) if not Podfile::DSL.shared_cache_enabled return end - cache_path = framework_cache_path_for(target, options) + cache_path = framework_cache_path_for(target, options, true) cache_path.mkpath unless cache_path.exist? FileUtils.cp_r "#{input_path}/.", cache_path + if Podfile::DSL.shared_s3_cache_enabled + s3_cache_path = framework_cache_path_for(target, options, false) + s3 = Aws::S3::Resource.new(create_s3_options) + Dir.mktmpdir {|dir| + zip(cache_path, "#{dir}/framework.zip") + s3.bucket(Podfile::DSL.s3_options[:bucket]).object("#{Podfile::DSL.s3_options[:prefix]}/#{s3_cache_path}").upload_file("#{dir}/framework.zip") + } + end end # Path of the target's cache # # @return [Pathname] def self.framework_cache_path_for(target, options) - framework_cache_path = cache_root + xcode_version + framework_cache_path = Pathname.new('') + if include_cache_root + framework_cache_path = cache_root + end + framework_cache_path = framework_cache_path + xcode_version framework_cache_path = framework_cache_path + target.name framework_cache_path = framework_cache_path + target.version options_with_platform = options + [target.platform.name] From 762afd7308522518db815a29bb4872b0082e4703 Mon Sep 17 00:00:00 2001 From: yrainik Date: Mon, 20 May 2019 11:10:40 -0700 Subject: [PATCH 10/10] Resolve PR comments --- lib/cocoapods-binary/Prebuild.rb | 2 +- lib/cocoapods-binary/helper/shared_cache.rb | 71 ++++++++++++++------- 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/lib/cocoapods-binary/Prebuild.rb b/lib/cocoapods-binary/Prebuild.rb index 866d2c4..59266b0 100644 --- a/lib/cocoapods-binary/Prebuild.rb +++ b/lib/cocoapods-binary/Prebuild.rb @@ -130,7 +130,7 @@ def prebuild_frameworks! output_path.mkpath unless output_path.exist? if Prebuild::SharedCache.has?(target, options) - framework_cache_path = Prebuild::SharedCache.framework_cache_path_for(target, options) + framework_cache_path = Prebuild::SharedCache.local_framework_cache_path_for(target, options) UI.puts "Using #{target.label} from cache" FileUtils.cp_r "#{framework_cache_path}/.", output_path else diff --git a/lib/cocoapods-binary/helper/shared_cache.rb b/lib/cocoapods-binary/helper/shared_cache.rb index bbbc61f..0c5ace7 100644 --- a/lib/cocoapods-binary/helper/shared_cache.rb +++ b/lib/cocoapods-binary/helper/shared_cache.rb @@ -13,27 +13,43 @@ class SharedCache # # @return [Boolean] def self.has?(target, options) + has_local_cache_for(target, options) || has_s3_cache_for(target, options) + end + + # `true` if there is local cache for the target + # `false` otherwise + # + # @return [Boolean] + def self.has_local_cache_for?(target, options) if Podfile::DSL.shared_cache_enabled - path = framework_cache_path_for(target, options, true) - result = path.exist? - if not result and Podfile::DSL.shared_s3_cache_enabled - s3_cache_path = framework_cache_path_for(target, options, false) - s3_cache_path = Podfile::DSL.s3_options[:prefix] + s3_cache_path unless Podfile::DSL.s3_options[:prefix].nil? - s3 = Aws::S3::Resource.new(create_s3_options) - if s3.bucket(Podfile::DSL.s3_options[:bucket]).object("#{s3_cache_path}").exists? - Dir.mktmpdir {|dir| - s3.bucket(Podfile::DSL.s3_options[:bucket]).object("#{s3_cache_path}").get(response_target: "#{dir}/framework.zip") - unzip("#{dir}/framework.zip", path) - return true - } - end - end - result + path = local_framework_cache_path_for(target, options) + path.exist? else false end end + # `true` if there is s3 cache for the target + # `false` otherwise + # + # @return [Boolean] + def has_s3_cache_for?(target, options) + result = false + if Podfile::DSL.shared_s3_cache_enabled + s3_cache_path = s3_framework_cache_path_for(target, options) + s3_cache_path = Podfile::DSL.s3_options[:prefix] + s3_cache_path unless Podfile::DSL.s3_options[:prefix].nil? + s3 = Aws::S3::Resource.new(create_s3_options) + if s3.bucket(Podfile::DSL.s3_options[:bucket]).object("#{s3_cache_path}").exists? + Dir.mktmpdir {|dir| + s3.bucket(Podfile::DSL.s3_options[:bucket]).object("#{s3_cache_path}").get(response_target: "#{dir}/framework.zip") + unzip("#{dir}/framework.zip", path) + result = true + } + end + end + result + end + # @return [{}] AWS connection options def self.create_s3_options options = {} @@ -75,11 +91,11 @@ def self.cache(target, input_path, options) if not Podfile::DSL.shared_cache_enabled return end - cache_path = framework_cache_path_for(target, options, true) + cache_path = local_framework_cache_path_for(target, options) cache_path.mkpath unless cache_path.exist? FileUtils.cp_r "#{input_path}/.", cache_path if Podfile::DSL.shared_s3_cache_enabled - s3_cache_path = framework_cache_path_for(target, options, false) + s3_cache_path = s3_framework_cache_path_for(target, options) s3 = Aws::S3::Resource.new(create_s3_options) Dir.mktmpdir {|dir| zip(cache_path, "#{dir}/framework.zip") @@ -88,15 +104,22 @@ def self.cache(target, input_path, options) end end - # Path of the target's cache + # Path of the target's local cache # # @return [Pathname] - def self.framework_cache_path_for(target, options) - framework_cache_path = Pathname.new('') - if include_cache_root - framework_cache_path = cache_root - end - framework_cache_path = framework_cache_path + xcode_version + def self.local_framework_cache_path_for(target, options) + framework_cache_path = cache_root + xcode_version + framework_cache_path = framework_cache_path + target.name + framework_cache_path = framework_cache_path + target.version + options_with_platform = options + [target.platform.name] + framework_cache_path = framework_cache_path + Digest::MD5.hexdigest(options_with_platform.to_s).to_s + end + + # Path of the target's s3 cache + # + # @return [Pathname] + def self.s3_framework_cache_path_for(target, options) + framework_cache_path = Pathname.new('') + xcode_version framework_cache_path = framework_cache_path + target.name framework_cache_path = framework_cache_path + target.version options_with_platform = options + [target.platform.name]