cocoapods-binary-gcp 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/ISSUE_TEMPLATE +10 -0
- data/.gitignore +33 -0
- data/.travis.yml +24 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +78 -0
- data/Rakefile +13 -0
- data/cocoapods-binary.gemspec +29 -0
- data/lib/cocoapods-binary.rb +1 -0
- data/lib/cocoapods-binary/Integration.rb +289 -0
- data/lib/cocoapods-binary/Main.rb +199 -0
- data/lib/cocoapods-binary/Prebuild.rb +273 -0
- data/lib/cocoapods-binary/gem_version.rb +3 -0
- data/lib/cocoapods-binary/helper/feature_switches.rb +101 -0
- data/lib/cocoapods-binary/helper/names.rb +78 -0
- data/lib/cocoapods-binary/helper/passer.rb +41 -0
- data/lib/cocoapods-binary/helper/podfile_options.rb +133 -0
- data/lib/cocoapods-binary/helper/prebuild_sandbox.rb +73 -0
- data/lib/cocoapods-binary/helper/shared_cache.rb +133 -0
- data/lib/cocoapods-binary/helper/target_checker.rb +49 -0
- data/lib/cocoapods-binary/rome/build_framework.rb +216 -0
- data/lib/cocoapods-binary/tool/tool.rb +12 -0
- data/lib/cocoapods_plugin.rb +2 -0
- data/spec/spec_helper.rb +50 -0
- metadata +177 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
require_relative '../tool/tool'
|
2
|
+
require_relative 'prebuild_sandbox'
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
|
6
|
+
# a flag that indicate stages
|
7
|
+
class_attr_accessor :is_prebuild_stage
|
8
|
+
|
9
|
+
|
10
|
+
# a switch for the `pod` DSL to make it only valid for ':binary => true'
|
11
|
+
class Podfile
|
12
|
+
module DSL
|
13
|
+
|
14
|
+
@@enable_prebuild_patch = false
|
15
|
+
|
16
|
+
# when enable, `pod` function will skip all pods without 'prebuild => true'
|
17
|
+
def self.enable_prebuild_patch(value)
|
18
|
+
@@enable_prebuild_patch = value
|
19
|
+
end
|
20
|
+
|
21
|
+
# --- patch ---
|
22
|
+
old_method = instance_method(:pod)
|
23
|
+
|
24
|
+
define_method(:pod) do |name, *args|
|
25
|
+
if !@@enable_prebuild_patch
|
26
|
+
old_method.bind(self).(name, *args)
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
# patched content
|
31
|
+
should_prebuild = Pod::Podfile::DSL.prebuild_all
|
32
|
+
local = false
|
33
|
+
|
34
|
+
options = args.last
|
35
|
+
if options.is_a?(Hash) and options[Pod::Prebuild.keyword] != nil
|
36
|
+
should_prebuild = options[Pod::Prebuild.keyword]
|
37
|
+
local = (options[:path] != nil)
|
38
|
+
end
|
39
|
+
|
40
|
+
if not Pod::Podfile::DSL.except_binary_list.nil?
|
41
|
+
should_prebuild = !Pod::Podfile::DSL.except_binary_list.include?(name)
|
42
|
+
end
|
43
|
+
|
44
|
+
if should_prebuild and (not local)
|
45
|
+
old_method.bind(self).(name, *args)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
# a force disable option for integral
|
53
|
+
class Installer
|
54
|
+
def self.force_disable_integration(value)
|
55
|
+
@@force_disable_integration = value
|
56
|
+
end
|
57
|
+
|
58
|
+
old_method = instance_method(:integrate_user_project)
|
59
|
+
define_method(:integrate_user_project) do
|
60
|
+
if @@force_disable_integration
|
61
|
+
return
|
62
|
+
end
|
63
|
+
old_method.bind(self).()
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# a option to disable install complete message
|
68
|
+
class Installer
|
69
|
+
def self.disable_install_complete_message(value)
|
70
|
+
@@disable_install_complete_message = value
|
71
|
+
end
|
72
|
+
|
73
|
+
old_method = instance_method(:print_post_install_message)
|
74
|
+
define_method(:print_post_install_message) do
|
75
|
+
if @@disable_install_complete_message
|
76
|
+
return
|
77
|
+
end
|
78
|
+
old_method.bind(self).()
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# option to disable write lockfiles
|
83
|
+
class Config
|
84
|
+
|
85
|
+
@@force_disable_write_lockfile = false
|
86
|
+
def self.force_disable_write_lockfile(value)
|
87
|
+
@@force_disable_write_lockfile = value
|
88
|
+
end
|
89
|
+
|
90
|
+
old_method = instance_method(:lockfile_path)
|
91
|
+
define_method(:lockfile_path) do
|
92
|
+
if @@force_disable_write_lockfile
|
93
|
+
# As config is a singleton, sandbox_root refer to the standard sandbox.
|
94
|
+
return PrebuildSandbox.from_standard_sanbox_path(sandbox_root).root + 'Manifest.lock.tmp'
|
95
|
+
else
|
96
|
+
return old_method.bind(self).()
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# ABOUT NAMES
|
2
|
+
#
|
3
|
+
# There are many kinds of name in cocoapods. Two main names are widely used in this plugin.
|
4
|
+
# - root_spec.name (spec.root_name, targe.pod_name):
|
5
|
+
# aka "pod_name"
|
6
|
+
# the name we use in podfile. the concept.
|
7
|
+
#
|
8
|
+
# - target.name:
|
9
|
+
# aka "target_name"
|
10
|
+
# the name of the final target in xcode project. the final real thing.
|
11
|
+
#
|
12
|
+
# One pod may have multiple targets in xcode project, due to one pod can be used in mutiple
|
13
|
+
# platform simultaneously. So one `root_spec.name` may have multiple coresponding `target.name`s.
|
14
|
+
# Therefore, map a spec to/from targets is a little complecated. It's one to many.
|
15
|
+
#
|
16
|
+
|
17
|
+
# Tool to transform Pod_name to target efficiently
|
18
|
+
module Pod
|
19
|
+
def self.fast_get_targets_for_pod_name(pod_name, targets, cache)
|
20
|
+
pod_name_to_targets_hash = nil
|
21
|
+
if cache.empty?
|
22
|
+
pod_name_to_targets_hash = targets.reduce({}) do |sum, target|
|
23
|
+
array = sum[target.pod_name] || []
|
24
|
+
array << target
|
25
|
+
sum[target.pod_name] = array
|
26
|
+
sum
|
27
|
+
end
|
28
|
+
cache << pod_name_to_targets_hash
|
29
|
+
else
|
30
|
+
pod_name_to_targets_hash = cache.first
|
31
|
+
end
|
32
|
+
|
33
|
+
pod_name_to_targets_hash[pod_name] || []
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
# Target:
|
43
|
+
|
44
|
+
# def pod_name
|
45
|
+
# root_spec.name
|
46
|
+
# end
|
47
|
+
|
48
|
+
# def name
|
49
|
+
# pod_name + #{scope_suffix}
|
50
|
+
# end
|
51
|
+
|
52
|
+
# def product_module_name
|
53
|
+
# root_spec.module_name
|
54
|
+
# end
|
55
|
+
|
56
|
+
# def framework_name
|
57
|
+
# "#{product_module_name}.framework"
|
58
|
+
# end
|
59
|
+
|
60
|
+
# def product_name
|
61
|
+
# if requires_frameworks?
|
62
|
+
# framework_name
|
63
|
+
# else
|
64
|
+
# static_library_name
|
65
|
+
# end
|
66
|
+
# end
|
67
|
+
|
68
|
+
# def product_basename
|
69
|
+
# if requires_frameworks?
|
70
|
+
# product_module_name
|
71
|
+
# else
|
72
|
+
# label
|
73
|
+
# end
|
74
|
+
# end
|
75
|
+
|
76
|
+
# def framework_name
|
77
|
+
# "#{product_module_name}.framework"
|
78
|
+
# end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative '../tool/tool'
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class Prebuild
|
5
|
+
|
6
|
+
# Pass the data between the 2 steps
|
7
|
+
#
|
8
|
+
# At step 2, the normal pod install, it needs some info of the
|
9
|
+
# prebuilt step. So we store it here.
|
10
|
+
#
|
11
|
+
class Passer
|
12
|
+
|
13
|
+
# indicate the add/remove/update of prebuit pods
|
14
|
+
# @return [Analyzer::SpecsState]
|
15
|
+
#
|
16
|
+
class_attr_accessor :prebuild_pods_changes
|
17
|
+
|
18
|
+
|
19
|
+
# represent the path of resurces to copy
|
20
|
+
class ResourcePath
|
21
|
+
attr_accessor :real_file_path
|
22
|
+
attr_accessor :target_file_path
|
23
|
+
end
|
24
|
+
# Save the resoures for static framework, and used when installing the prebuild framework
|
25
|
+
# static framework needs copy the resurces mannully
|
26
|
+
#
|
27
|
+
# @return [Hash<String, [Passer::ResourcePath]>]
|
28
|
+
class_attr_accessor :resources_to_copy_for_static_framework
|
29
|
+
self.resources_to_copy_for_static_framework = {}
|
30
|
+
|
31
|
+
# Some pod won't be build in prebuild stage even if it have `binary=>true`.
|
32
|
+
# The targets of this pods have `oshould_build? == true`.
|
33
|
+
# We should skip integration (patch spec) for this pods
|
34
|
+
#
|
35
|
+
# @return [Array<String>]
|
36
|
+
class_attr_accessor :target_names_to_skip_integration_framework
|
37
|
+
self.target_names_to_skip_integration_framework = []
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
module Pod
|
2
|
+
|
3
|
+
class Prebuild
|
4
|
+
def self.keyword
|
5
|
+
:binary
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Podfile
|
10
|
+
class TargetDefinition
|
11
|
+
|
12
|
+
## --- option for setting using prebuild framework ---
|
13
|
+
def parse_prebuild_framework(name, requirements)
|
14
|
+
should_prebuild = Pod::Podfile::DSL.prebuild_all
|
15
|
+
|
16
|
+
options = requirements.last
|
17
|
+
if options.is_a?(Hash) && options[Pod::Prebuild.keyword] != nil
|
18
|
+
should_prebuild = options.delete(Pod::Prebuild.keyword)
|
19
|
+
requirements.pop if options.empty?
|
20
|
+
end
|
21
|
+
|
22
|
+
pod_name = Specification.root_name(name)
|
23
|
+
set_prebuild_for_pod(pod_name, should_prebuild)
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_prebuild_for_pod(pod_name, should_prebuild)
|
27
|
+
|
28
|
+
if should_prebuild == true
|
29
|
+
@prebuild_framework_pod_names ||= []
|
30
|
+
@prebuild_framework_pod_names.push pod_name
|
31
|
+
else
|
32
|
+
@should_not_prebuild_framework_pod_names ||= []
|
33
|
+
@should_not_prebuild_framework_pod_names.push pod_name
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def prebuild_framework_pod_names
|
38
|
+
names = @prebuild_framework_pod_names || []
|
39
|
+
if parent != nil and parent.kind_of? TargetDefinition
|
40
|
+
names += parent.prebuild_framework_pod_names
|
41
|
+
end
|
42
|
+
names
|
43
|
+
end
|
44
|
+
def should_not_prebuild_framework_pod_names
|
45
|
+
names = @should_not_prebuild_framework_pod_names || []
|
46
|
+
if parent != nil and parent.kind_of? TargetDefinition
|
47
|
+
names += parent.should_not_prebuild_framework_pod_names
|
48
|
+
end
|
49
|
+
names
|
50
|
+
end
|
51
|
+
|
52
|
+
# ---- patch method ----
|
53
|
+
# We want modify `store_pod` method, but it's hard to insert a line in the
|
54
|
+
# implementation. So we patch a method called in `store_pod`.
|
55
|
+
old_method = instance_method(:parse_inhibit_warnings)
|
56
|
+
|
57
|
+
define_method(:parse_inhibit_warnings) do |name, requirements|
|
58
|
+
parse_prebuild_framework(name, requirements)
|
59
|
+
old_method.bind(self).(name, requirements)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
module Pod
|
68
|
+
class Installer
|
69
|
+
|
70
|
+
def prebuild_pod_targets
|
71
|
+
@prebuild_pod_targets ||= (
|
72
|
+
all = []
|
73
|
+
|
74
|
+
aggregate_targets = self.aggregate_targets
|
75
|
+
aggregate_targets.each do |aggregate_target|
|
76
|
+
target_definition = aggregate_target.target_definition
|
77
|
+
targets = aggregate_target.pod_targets || []
|
78
|
+
|
79
|
+
# filter prebuild
|
80
|
+
prebuild_names = target_definition.prebuild_framework_pod_names
|
81
|
+
if not Podfile::DSL.prebuild_all
|
82
|
+
targets = targets.select { |pod_target| prebuild_names.include?(pod_target.pod_name) }
|
83
|
+
end
|
84
|
+
dependency_targets = targets.map {|t| t.recursive_dependent_targets }.flatten.uniq || []
|
85
|
+
targets = (targets + dependency_targets).uniq
|
86
|
+
|
87
|
+
# filter should not prebuild
|
88
|
+
explict_should_not_names = target_definition.should_not_prebuild_framework_pod_names
|
89
|
+
targets = targets.reject { |pod_target| explict_should_not_names.include?(pod_target.pod_name) }
|
90
|
+
|
91
|
+
if not Pod::Podfile::DSL.except_binary_list.nil?
|
92
|
+
targets = targets.reject { |pod_target| Pod::Podfile::DSL.except_binary_list.include?(pod_target.pod_name) }
|
93
|
+
end
|
94
|
+
|
95
|
+
all += targets
|
96
|
+
end
|
97
|
+
|
98
|
+
all = all.reject {|pod_target| sandbox.local?(pod_target.pod_name) }
|
99
|
+
all.uniq
|
100
|
+
)
|
101
|
+
end
|
102
|
+
|
103
|
+
# the root names who needs prebuild, including dependency pods.
|
104
|
+
def prebuild_pod_names
|
105
|
+
@prebuild_pod_names ||= self.prebuild_pod_targets.map(&:pod_name)
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
def validate_every_pod_only_have_one_form
|
110
|
+
|
111
|
+
multi_targets_pods = self.pod_targets.group_by do |t|
|
112
|
+
t.pod_name
|
113
|
+
end.select do |k, v|
|
114
|
+
v.map{|t| t.platform.name }.count > 1
|
115
|
+
end
|
116
|
+
|
117
|
+
multi_targets_pods = multi_targets_pods.reject do |name, targets|
|
118
|
+
contained = targets.map{|t| self.prebuild_pod_targets.include? t }
|
119
|
+
contained.uniq.count == 1 # all equal
|
120
|
+
end
|
121
|
+
|
122
|
+
return if multi_targets_pods.empty?
|
123
|
+
|
124
|
+
warnings = "One pod can only be prebuilt or not prebuilt. These pod have different forms in multiple targets:\n"
|
125
|
+
warnings += multi_targets_pods.map{|name, targets| " #{name}: #{targets.map{|t|t.platform.name}}"}.join("\n")
|
126
|
+
raise Informative, warnings
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require_relative "names"
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class PrebuildSandbox < Sandbox
|
5
|
+
|
6
|
+
# [String] standard_sandbox_path
|
7
|
+
def self.from_standard_sanbox_path(path)
|
8
|
+
prebuild_sandbox_path = Pathname.new(path).realpath + "_Prebuild"
|
9
|
+
self.new(prebuild_sandbox_path)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.from_standard_sandbox(sandbox)
|
13
|
+
self.from_standard_sanbox_path(sandbox.root)
|
14
|
+
end
|
15
|
+
|
16
|
+
def standard_sanbox_path
|
17
|
+
self.root.parent
|
18
|
+
end
|
19
|
+
|
20
|
+
def generate_framework_path
|
21
|
+
self.root + "GeneratedFrameworks"
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param name [String] pass the target.name (may containing platform suffix)
|
25
|
+
# @return [Pathname] the folder containing the framework file.
|
26
|
+
def framework_folder_path_for_target_name(name)
|
27
|
+
self.generate_framework_path + name
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def exsited_framework_target_names
|
32
|
+
exsited_framework_name_pairs.map {|pair| pair[0]}.uniq
|
33
|
+
end
|
34
|
+
def exsited_framework_pod_names
|
35
|
+
exsited_framework_name_pairs.map {|pair| pair[1]}.uniq
|
36
|
+
end
|
37
|
+
def existed_target_names_for_pod_name(pod_name)
|
38
|
+
exsited_framework_name_pairs.select {|pair| pair[1] == pod_name }.map { |pair| pair[0]}
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
def save_pod_name_for_target(target)
|
44
|
+
folder = framework_folder_path_for_target_name(target.name)
|
45
|
+
return unless folder.exist?
|
46
|
+
flag_file_path = folder + "#{target.pod_name}.pod_name"
|
47
|
+
File.write(flag_file_path.to_s, "")
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def pod_name_for_target_folder(target_folder_path)
|
54
|
+
name = Pathname.new(target_folder_path).children.find do |child|
|
55
|
+
child.to_s.end_with? ".pod_name"
|
56
|
+
end
|
57
|
+
name = name.basename(".pod_name").to_s unless name.nil?
|
58
|
+
name ||= Pathname.new(target_folder_path).basename.to_s # for compatibility with older version
|
59
|
+
end
|
60
|
+
|
61
|
+
# Array<[target_name, pod_name]>
|
62
|
+
def exsited_framework_name_pairs
|
63
|
+
return [] unless generate_framework_path.exist?
|
64
|
+
generate_framework_path.children().map do |framework_path|
|
65
|
+
if framework_path.directory? && (not framework_path.children.empty?)
|
66
|
+
[framework_path.basename.to_s, pod_name_for_target_folder(framework_path)]
|
67
|
+
else
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
end.reject(&:nil?).uniq
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'digest'
|
2
|
+
require_relative '../tool/tool'
|
3
|
+
require "google/cloud/storage"
|
4
|
+
require 'zip'
|
5
|
+
|
6
|
+
module Pod
|
7
|
+
class Prebuild
|
8
|
+
class SharedCache
|
9
|
+
extend Config::Mixin
|
10
|
+
|
11
|
+
# `true` if there is cache for the target
|
12
|
+
# `false` otherwise
|
13
|
+
#
|
14
|
+
# @return [Boolean]
|
15
|
+
def self.has?(target, options)
|
16
|
+
if Podfile::DSL.shared_cache_enabled
|
17
|
+
path = framework_cache_path_for(target, options)
|
18
|
+
if path.exist?
|
19
|
+
Pod::UI.puts "Local cache for #{target.name} found"
|
20
|
+
true
|
21
|
+
else
|
22
|
+
Pod::UI.puts "Local cache for #{target.name} not found"
|
23
|
+
if Podfile::DSL.shared_gcp_cache_enabled
|
24
|
+
cloud_path = cloud_framework_path_for(target, options)
|
25
|
+
storage = Google::Cloud::Storage.new
|
26
|
+
bucket = storage.bucket(Podfile::DSL.gcp_options[:bucket])
|
27
|
+
file = bucket.file "#{cloud_path}"
|
28
|
+
if not file.nil?
|
29
|
+
Pod::UI.puts "GCP cache for #{target.name} found, downloading..."
|
30
|
+
Dir.mktmpdir {|dir|
|
31
|
+
file.download "#{dir}/framework.zip"
|
32
|
+
unzip("#{dir}/framework.zip", path)
|
33
|
+
}
|
34
|
+
true
|
35
|
+
else
|
36
|
+
Pod::UI.puts "GCP cache for #{target.name} not found"
|
37
|
+
false
|
38
|
+
end
|
39
|
+
else
|
40
|
+
false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
else
|
44
|
+
false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Copies input_path to target's cache
|
49
|
+
def self.cache(target, input_path, options)
|
50
|
+
if not Podfile::DSL.shared_cache_enabled
|
51
|
+
return
|
52
|
+
end
|
53
|
+
cache_path = framework_cache_path_for(target, options)
|
54
|
+
cache_path.mkpath unless cache_path.exist?
|
55
|
+
FileUtils.cp_r "#{input_path}/.", cache_path
|
56
|
+
|
57
|
+
if Podfile::DSL.shared_gcp_cache_enabled
|
58
|
+
cloud_path = cloud_framework_path_for(target, options)
|
59
|
+
storage = Google::Cloud::Storage.new
|
60
|
+
bucket = storage.bucket(Podfile::DSL.gcp_options[:bucket])
|
61
|
+
|
62
|
+
Pod::UI.puts "Save to remote cache"
|
63
|
+
Dir.mktmpdir {|dir|
|
64
|
+
zip(cache_path, "#{dir}/framework.zip")
|
65
|
+
bucket.create_file "#{dir}/framework.zip",
|
66
|
+
"#{cloud_path}"
|
67
|
+
}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Path of the target's cache
|
72
|
+
#
|
73
|
+
# @return [Pathname]
|
74
|
+
def self.framework_cache_path_for(target, options)
|
75
|
+
framework_cache_path = cache_root + xcode_version
|
76
|
+
framework_cache_path = framework_cache_path + target.name
|
77
|
+
framework_cache_path = framework_cache_path + target.version
|
78
|
+
options_with_platform = options + [target.platform.name]
|
79
|
+
framework_cache_path = framework_cache_path + Digest::MD5.hexdigest(options_with_platform.to_s).to_s
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.cloud_framework_path_for(target, options)
|
83
|
+
cloud_cache_path = Pathname.new('').to_s + xcode_version
|
84
|
+
cloud_cache_path = cloud_cache_path + target.name
|
85
|
+
cloud_cache_path = cloud_cache_path + target.version
|
86
|
+
options_with_platform = options + [target.platform.name]
|
87
|
+
cloud_cache_path = cloud_cache_path + Digest::MD5.hexdigest(options_with_platform.to_s).to_s
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.zip(dir, zip_dir)
|
91
|
+
Zip::File.open(zip_dir, Zip::File::CREATE)do |zipfile|
|
92
|
+
Find.find(dir) do |path|
|
93
|
+
Find.prune if File.basename(path)[0] == ?.
|
94
|
+
dest = /#{dir}\/(\w.*)/.match(path)
|
95
|
+
# Skip files if they exists
|
96
|
+
begin
|
97
|
+
zipfile.add(dest[1],path) if dest
|
98
|
+
rescue Zip::ZipEntryExistsError
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.unzip(zip, unzip_dir, remove_after = false)
|
105
|
+
Zip::File.open(zip) do |zip_file|
|
106
|
+
zip_file.each do |f|
|
107
|
+
f_path=File.join(unzip_dir, f.name)
|
108
|
+
FileUtils.mkdir_p(File.dirname(f_path))
|
109
|
+
zip_file.extract(f, f_path) unless File.exist?(f_path)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
FileUtils.rm(zip) if remove_after
|
113
|
+
end
|
114
|
+
|
115
|
+
# Current xcode version.
|
116
|
+
#
|
117
|
+
# @return [String]
|
118
|
+
private
|
119
|
+
class_attr_accessor :xcode_version
|
120
|
+
# Converts from "Xcode 10.2.1\nBuild version 10E1001\n" to "10.2.1".
|
121
|
+
self.xcode_version = `xcodebuild -version`.split("\n").first.split().last || "Unkwown"
|
122
|
+
|
123
|
+
# Path of the cache folder
|
124
|
+
# Reusing cache_root from cocoapods's config
|
125
|
+
# `~Library/Caches/CocoaPods` is default value
|
126
|
+
#
|
127
|
+
# @return [Pathname]
|
128
|
+
private
|
129
|
+
class_attr_accessor :cache_root
|
130
|
+
self.cache_root = config.cache_root + 'Prebuilt'
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|