cocoapods-binary-cache 0.1.3 → 0.1.9

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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/lib/cocoapods-binary-cache/cache/validation_result.rb +4 -0
  3. data/lib/cocoapods-binary-cache/cache/validator.rb +2 -3
  4. data/lib/cocoapods-binary-cache/cache/validator_base.rb +28 -8
  5. data/lib/cocoapods-binary-cache/cache/validator_dependencies_graph.rb +7 -2
  6. data/lib/cocoapods-binary-cache/cache/validator_dev_pods.rb +21 -13
  7. data/lib/cocoapods-binary-cache/cache/validator_non_dev_pods.rb +1 -1
  8. data/lib/cocoapods-binary-cache/dependencies_graph/dependencies_graph.rb +20 -25
  9. data/lib/cocoapods-binary-cache/dependencies_graph/graph_visualizer.rb +29 -38
  10. data/lib/cocoapods-binary-cache/diagnosis/base.rb +13 -0
  11. data/lib/cocoapods-binary-cache/diagnosis/diagnosis.rb +24 -0
  12. data/lib/cocoapods-binary-cache/diagnosis/integration.rb +23 -0
  13. data/lib/cocoapods-binary-cache/env.rb +32 -0
  14. data/lib/cocoapods-binary-cache/helper/checksum.rb +10 -4
  15. data/lib/cocoapods-binary-cache/helper/lockfile.rb +26 -3
  16. data/lib/cocoapods-binary-cache/helper/podspec.rb +4 -1
  17. data/lib/cocoapods-binary-cache/hooks/post_install.rb +12 -5
  18. data/lib/cocoapods-binary-cache/hooks/pre_install.rb +14 -44
  19. data/lib/cocoapods-binary-cache/main.rb +2 -2
  20. data/lib/cocoapods-binary-cache/pod-binary/helper/build.rb +39 -0
  21. data/lib/cocoapods-binary-cache/pod-binary/helper/detected_prebuilt_pods/installer.rb +2 -2
  22. data/lib/cocoapods-binary-cache/pod-binary/helper/detected_prebuilt_pods/target_definition.rb +3 -10
  23. data/lib/cocoapods-binary-cache/pod-binary/helper/names.rb +2 -11
  24. data/lib/cocoapods-binary-cache/pod-binary/helper/prebuild_sandbox.rb +15 -15
  25. data/lib/cocoapods-binary-cache/pod-binary/helper/target_checker.rb +7 -10
  26. data/lib/cocoapods-binary-cache/pod-binary/integration.rb +1 -3
  27. data/lib/cocoapods-binary-cache/pod-binary/integration/alter_specs.rb +4 -1
  28. data/lib/cocoapods-binary-cache/pod-binary/integration/patch/embed_framework_script.rb +1 -1
  29. data/lib/cocoapods-binary-cache/pod-binary/integration/patch/resolve_dependencies.rb +0 -3
  30. data/lib/cocoapods-binary-cache/pod-binary/integration/patch/sandbox_analyzer_state.rb +29 -0
  31. data/lib/cocoapods-binary-cache/pod-binary/integration/patch/source_installation.rb +29 -12
  32. data/lib/cocoapods-binary-cache/pod-binary/integration/source_installer.rb +57 -61
  33. data/lib/cocoapods-binary-cache/pod-binary/prebuild.rb +49 -115
  34. data/lib/cocoapods-binary-cache/pod-binary/prebuild_dsl.rb +2 -60
  35. data/lib/cocoapods-binary-cache/pod-binary/prebuild_hook.rb +0 -1
  36. data/lib/cocoapods-binary-cache/pod-rome/xcodebuild_command.rb +189 -0
  37. data/lib/cocoapods-binary-cache/pod-rome/xcodebuild_raw.rb +42 -0
  38. data/lib/cocoapods-binary-cache/prebuild_output/metadata.rb +16 -0
  39. data/lib/cocoapods-binary-cache/prebuild_output/output.rb +12 -39
  40. data/lib/cocoapods-binary-cache/state_store.rb +16 -6
  41. data/lib/command/binary.rb +21 -2
  42. data/lib/command/config.rb +179 -10
  43. data/lib/command/executor/base.rb +9 -1
  44. data/lib/command/executor/fetcher.rb +4 -4
  45. data/lib/command/executor/prebuilder.rb +4 -2
  46. data/lib/command/executor/pusher.rb +1 -1
  47. data/lib/command/executor/visualizer.rb +3 -2
  48. data/lib/command/fetch.rb +0 -1
  49. data/lib/command/prebuild.rb +15 -3
  50. data/lib/command/push.rb +22 -0
  51. metadata +13 -11
  52. data/lib/cocoapods-binary-cache/pod-binary/helper/feature_switches.rb +0 -90
  53. data/lib/cocoapods-binary-cache/pod-binary/helper/passer.rb +0 -25
  54. data/lib/cocoapods-binary-cache/pod-binary/integration/remove_target_files.rb +0 -29
  55. data/lib/cocoapods-binary-cache/pod-binary/tool/tool.rb +0 -12
  56. data/lib/cocoapods-binary-cache/pod-rome/build_framework.rb +0 -247
  57. data/lib/cocoapods-binary-cache/prebuild_cache.rb +0 -47
  58. data/lib/cocoapods-binary-cache/scheme_editor.rb +0 -35
@@ -1,67 +1,9 @@
1
- require_relative "tool/tool"
2
-
3
1
  module Pod
4
2
  class Podfile
5
3
  module DSL
6
4
  def config_cocoapods_binary_cache(options)
7
- apply_config = lambda do |config|
8
- DSL.send("#{config}=", options[config]) unless options[config].nil?
9
- end
10
-
11
- apply_config.call(:prebuild_config)
12
- apply_config.call(:prebuild_all) # TODO (thuyen): Revise this option
13
- apply_config.call(:prebuild_all_vendor_pods)
14
- apply_config.call(:excluded_pods)
15
- apply_config.call(:dev_pods_enabled)
16
- apply_config.call(:bitcode_enabled)
17
- apply_config.call(:dont_remove_source_code)
18
- apply_config.call(:custom_device_build_options)
19
- apply_config.call(:custom_simulator_build_options)
20
- apply_config.call(:save_cache_validation_to)
21
- apply_config.call(:validate_prebuilt_settings)
22
- end
23
-
24
- @prebuild_config = "Debug"
25
- @prebuild_job = false
26
- @prebuild_all = false
27
- @prebuild_all_vendor_pods = false
28
- @excluded_pods = Set.new
29
- @dev_pods_enabled = false
30
- @bitcode_enabled = false
31
- @dont_remove_source_code = false
32
- @custom_device_build_options = []
33
- @custom_simulator_build_options = []
34
- @save_cache_validation_to = nil
35
- # A proc to validate the provided build settings (per target) with the build settings of the prebuilt frameworks
36
- # For example, in Podfile:
37
- # -----------------------------------------------
38
- # validate_prebuilt_settings do |target|
39
- # settings = {}
40
- # settings["MACH_O_TYPE"] == "staticlib"
41
- # settings["SWIFT_VERSION"] == swift_version_of(target)
42
- # settings
43
- # end
44
- # -----------------------------------------------
45
- @validate_prebuilt_settings = nil
46
-
47
- class << self
48
- attr_accessor :prebuild_config
49
- attr_accessor :prebuild_job
50
- attr_accessor :prebuild_all
51
- attr_accessor :prebuild_all_vendor_pods
52
- attr_accessor :excluded_pods
53
- attr_accessor :dev_pods_enabled
54
- attr_accessor :bitcode_enabled
55
- attr_accessor :dont_remove_source_code
56
- attr_accessor :custom_device_build_options
57
- attr_accessor :custom_simulator_build_options
58
- attr_accessor :save_cache_validation_to
59
- attr_accessor :validate_prebuilt_settings
60
-
61
- alias prebuild_job? prebuild_job
62
- alias prebuild_all? prebuild_all
63
- alias prebuild_all_vendor_pods? prebuild_all_vendor_pods
64
- alias dev_pods_enabled? dev_pods_enabled
5
+ PodPrebuild.config.dsl_config = options
6
+ PodPrebuild.config.validate_dsl_config
65
7
  end
66
8
  end
67
9
  end
@@ -1,4 +1,3 @@
1
- require_relative "helper/passer"
2
1
  require_relative "helper/podfile_options"
3
2
  require_relative "helper/prebuild_sandbox"
4
3
 
@@ -0,0 +1,189 @@
1
+ require_relative "xcodebuild_raw"
2
+
3
+ class XcodebuildCommand # rubocop:disable Metrics/ClassLength
4
+ def initialize(options)
5
+ @options = options
6
+ case options[:targets][0].platform.name
7
+ when :ios
8
+ @options[:device] = "iphoneos"
9
+ @options[:simulator] = "iphonesimulator"
10
+ when :tvos
11
+ @options[:device] = "appletvos"
12
+ @options[:simulator] = "appletvsimulator"
13
+ when :watchos
14
+ @options[:device] = "watchos"
15
+ @options[:simulator] = "watchsimulator"
16
+ end
17
+ @build_args = make_up_build_args(options[:args] || {})
18
+ end
19
+
20
+ def run
21
+ build_for_sdk(simulator) if build_types.include?(:simulator)
22
+ build_for_sdk(device) if build_types.include?(:device)
23
+
24
+ targets.each do |target|
25
+ case build_types
26
+ when [:simulator]
27
+ collect_output(target, Dir[target_products_dir_of(target, simulator) + "/*"])
28
+ when [:device]
29
+ collect_output(target, Dir[target_products_dir_of(target, device) + "/*"])
30
+ else
31
+ # When merging contents of `simulator` & `device`, prefer contents of `device` over `simulator`
32
+ # https://github.com/grab/cocoapods-binary-cache/issues/25
33
+ collect_output(target, Dir[target_products_dir_of(target, device) + "/*"])
34
+ create_universal_framework(target)
35
+ end
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def build_types
42
+ @build_types ||= begin
43
+ # TODO (thuyen): Add DSL options `build_for_types` to specify build types
44
+ types = [:simulator]
45
+ types << :device if device_build_enabled?
46
+ types
47
+ end
48
+ end
49
+
50
+ def make_up_build_args(args)
51
+ args_ = args.clone
52
+ args_[:default] ||= []
53
+ args_[:simulator] ||= []
54
+ args_[:device] ||= []
55
+ args_[:default] += ["BITCODE_GENERATION_MODE=bitcode"] if bitcode_enabled?
56
+ args_[:default] += ["DEBUG_INFORMATION_FORMAT=dwarf"] if disable_dsym?
57
+ args_[:simulator] += ["ARCHS=x86_64", "ONLY_ACTIVE_ARCH=NO"] if simulator == "iphonesimulator"
58
+ args_[:simulator] += args_[:default]
59
+ args_[:device] += args_[:default]
60
+ args_
61
+ end
62
+
63
+ def build_for_sdk(sdk)
64
+ xcodebuild(
65
+ sandbox: sandbox,
66
+ scheme: scheme,
67
+ targets: targets.map(&:label),
68
+ configuration: configuration,
69
+ sdk: sdk,
70
+ deployment_target: targets.map { |t| t.platform.deployment_target }.max.to_s,
71
+ args: sdk == simulator ? @build_args[:simulator] : @build_args[:device]
72
+ )
73
+ end
74
+
75
+ def create_universal_framework(target)
76
+ merge_framework_binary(target)
77
+ merge_framework_dsym(target)
78
+ merge_swift_headers(target)
79
+ merge_swift_modules(target)
80
+ end
81
+
82
+ def merge_framework_binary(target)
83
+ merge_contents(target, "/#{target.product_module_name}", &method(:create_fat_binary))
84
+ end
85
+
86
+ def merge_framework_dsym(target)
87
+ merge_contents(target, ".dSYM/Contents/Resources/DWARF/#{target.product_module_name}", &method(:create_fat_binary))
88
+ end
89
+
90
+ def merge_swift_headers(target)
91
+ merge_contents(target, "/Headers/#{target.product_module_name}-Swift.h") do |options|
92
+ merged_header = <<~HEREDOC
93
+ #if TARGET_OS_SIMULATOR // merged by cocoapods-binary
94
+ #{File.read(options[:simulator])}
95
+ #else // merged by cocoapods-binary
96
+ #{File.read(options[:device])}
97
+ #endif // merged by cocoapods-binary
98
+ HEREDOC
99
+ File.write(options[:output], merged_header.strip)
100
+ end
101
+ end
102
+
103
+ def merge_swift_modules(target)
104
+ merge_contents(target, "/Modules/#{target.product_module_name}.swiftmodule") do |options|
105
+ # Note: swiftmodules of `device` were copied beforehand,
106
+ # here, we only need to copy swiftmodules of `simulator`
107
+ FileUtils.cp_r(options[:simulator] + "/.", options[:output])
108
+ end
109
+ end
110
+
111
+ def merge_contents(target, path_suffix, &merger)
112
+ simulator_, device_, output_ = [
113
+ framework_path_of(target, simulator),
114
+ framework_path_of(target, device),
115
+ "#{output_path(target)}/#{target.product_module_name}.framework"
116
+ ].map { |p| p + path_suffix }
117
+ return unless File.exist?(simulator_) && File.exist?(device_)
118
+
119
+ merger.call(simulator: simulator_, device: device_, output: output_)
120
+ end
121
+
122
+ def create_fat_binary(options)
123
+ cmd = ["lipo", " -create"]
124
+ cmd << "-output" << options[:output]
125
+ cmd << options[:simulator] << options[:device]
126
+ `#{cmd.join(" ")}`
127
+ end
128
+
129
+ def collect_output(target, paths)
130
+ FileUtils.mkdir_p(output_path(target))
131
+ paths = [paths] unless paths.is_a?(Array)
132
+ paths.each do |path|
133
+ FileUtils.rm_rf(File.join(output_path(target), File.basename(path)))
134
+ FileUtils.cp_r(path, output_path(target))
135
+ end
136
+ end
137
+
138
+ def target_products_dir_of(target, sdk)
139
+ "#{build_dir}/#{configuration}-#{sdk}/#{target.name}"
140
+ end
141
+
142
+ def framework_path_of(target, sdk)
143
+ "#{target_products_dir_of(target, sdk)}/#{target.product_module_name}.framework"
144
+ end
145
+
146
+ def sandbox
147
+ @options[:sandbox]
148
+ end
149
+
150
+ def build_dir
151
+ @options[:build_dir]
152
+ end
153
+
154
+ def output_path(target)
155
+ "#{@options[:output_path]}/#{target.label}"
156
+ end
157
+
158
+ def scheme
159
+ @options[:scheme]
160
+ end
161
+
162
+ def targets
163
+ @options[:targets]
164
+ end
165
+
166
+ def configuration
167
+ @options[:configuration]
168
+ end
169
+
170
+ def bitcode_enabled?
171
+ @options[:bitcode_enabled]
172
+ end
173
+
174
+ def device_build_enabled?
175
+ @options[:device_build_enabled]
176
+ end
177
+
178
+ def device
179
+ @options[:device] || "iphoneos"
180
+ end
181
+
182
+ def simulator
183
+ @options[:simulator] || "iphonesimulator"
184
+ end
185
+
186
+ def disable_dsym?
187
+ @options[:disable_dsym]
188
+ end
189
+ end
@@ -0,0 +1,42 @@
1
+ require "fourflusher"
2
+
3
+ PLATFORM_OF_SDK = {
4
+ "iphonesimulator" => "iOS",
5
+ "appletvsimulator" => "tvOS",
6
+ "watchsimulator" => "watchOS"
7
+ }.freeze
8
+
9
+ def xcodebuild(options)
10
+ sdk = options[:sdk] || "iphonesimulator"
11
+ targets = options[:targets] || [options[:target]]
12
+ platform = PLATFORM_OF_SDK[sdk]
13
+
14
+ cmd = ["xcodebuild"]
15
+ cmd << "-project" << options[:sandbox].project_path.realdirpath
16
+ targets.each { |target| cmd << "-target" << target }
17
+ cmd << "-configuration" << options[:configuration]
18
+ cmd << "-sdk" << sdk
19
+ cmd << Fourflusher::SimControl.new.destination(:oldest, platform, options[:deployment_target]) unless platform.nil?
20
+ cmd += options[:args] if options[:args]
21
+ cmd << "build"
22
+ cmd << "2>&1"
23
+ cmd = cmd.join(" ")
24
+
25
+ Pod::UI.puts_indented "$ #{cmd}"
26
+ log = `#{cmd}`
27
+ return if $?.exitstatus.zero? # rubocop:disable Style/SpecialGlobalVars
28
+
29
+ begin
30
+ require "xcpretty" # TODO (thuyen): Revise this dependency
31
+ # use xcpretty to print build log
32
+ # 64 represent command invalid. http://www.manpagez.com/man/3/sysexits/
33
+ printer = XCPretty::Printer.new({:formatter => XCPretty::Simple, :colorize => "auto"})
34
+ log.each_line do |line|
35
+ printer.pretty_print(line)
36
+ end
37
+ rescue
38
+ Pod::UI.puts log.red
39
+ ensure
40
+ raise "Fail to build targets: #{targets}"
41
+ end
42
+ end
@@ -43,5 +43,21 @@ module PodPrebuild
43
43
  def build_settings=(value)
44
44
  @data["build_settings"] = value
45
45
  end
46
+
47
+ def source_hash
48
+ @data["source_hash"] || {}
49
+ end
50
+
51
+ def source_hash=(value)
52
+ @data["source_hash"] = value
53
+ end
54
+
55
+ def project_root
56
+ @data["project_root"]
57
+ end
58
+
59
+ def project_root=(value)
60
+ @data["project_root"] = value
61
+ end
46
62
  end
47
63
  end
@@ -7,65 +7,38 @@ module PodPrebuild
7
7
  @sandbox = prebuild_sandbox
8
8
  end
9
9
 
10
- def delta_dir
11
- @delta_dir ||= File.expand_path("#{@sandbox.root}/../_Prebuild_delta")
10
+ def prebuild_delta_path
11
+ @prebuild_delta_path ||= PodPrebuild.config.prebuild_delta_path
12
12
  end
13
13
 
14
- def delta_file_path
15
- # TODO (thuyen): Unify this path with PodPrebuild::Config#delta_file_path
16
- "#{delta_dir}/changes.json"
14
+ def delta_dir
15
+ @delta_dir ||= File.dirname(prebuild_delta_path)
17
16
  end
18
17
 
19
18
  def clean_delta_file
20
- puts "Clean delta file: #{delta_file_path}"
21
- FileUtils.rm_rf(delta_file_path)
19
+ Pod::UI.message "Clean delta file: #{prebuild_delta_path}"
20
+ FileUtils.rm_rf(prebuild_delta_path)
22
21
  end
23
22
 
24
23
  def create_dir_if_needed(dir)
25
24
  FileUtils.mkdir_p dir unless File.directory?(dir)
26
25
  end
27
26
 
28
- # Input 2 arrays of library names
29
- def write_delta_file(updated, deleted)
27
+ def write_delta_file(options)
28
+ updated = options[:updated]
29
+ deleted = options[:deleted]
30
+
30
31
  if updated.empty? && deleted.empty?
31
32
  Pod::UI.puts "No changes in prebuild"
32
33
  return
33
34
  end
34
35
 
35
- Pod::UI.puts "Write prebuild changes to: #{delta_file_path}"
36
+ Pod::UI.message "Write prebuild changes to: #{prebuild_delta_path}"
36
37
  create_dir_if_needed(delta_dir)
37
- changes = PodPrebuild::JSONFile.new(delta_file_path)
38
+ changes = PodPrebuild::JSONFile.new(prebuild_delta_path)
38
39
  changes["updated"] = updated
39
40
  changes["deleted"] = deleted
40
41
  changes.save!
41
42
  end
42
-
43
- def process_prebuilt_dev_pods
44
- devpod_output_path = "#{delta_dir}/devpod_prebuild_output/"
45
- create_dir_if_needed(devpod_output_path)
46
- Pod::UI.puts "Copy prebuilt devpod frameworks to output dir: #{devpod_output_path}"
47
-
48
- # Inject project path (where the framework is built) to support generating code coverage later
49
- project_root = PathUtils.remove_last_path_component(@sandbox.standard_sanbox_path.to_s)
50
- template_file_path = devpod_output_path + "prebuilt_map"
51
- File.open(template_file_path, "w") do |file|
52
- file.write(project_root)
53
- end
54
-
55
- # FIXME (thuyen): Revise usage of cache_miss_dev_pods_dic
56
- # The behavior of processing outputs of dev pods and non-dev pods should be very SIMILAR
57
- cache_miss_dev_pods_dic = {}
58
-
59
- cache_miss_dev_pods_dic.each do |name, hash|
60
- Pod::UI.puts "Output dev pod lib: #{name} hash: #{hash}"
61
- built_lib_path = @sandbox.framework_folder_path_for_target_name(name)
62
- next unless File.directory?(built_lib_path)
63
-
64
- FileUtils.cp(template_file_path, "#{built_lib_path}/#{name}.framework")
65
- target_dir = "#{devpod_output_path}#{name}_#{hash}"
66
- Pod::UI.puts "From: #{built_lib_path} -> #{target_dir}"
67
- FileUtils.cp_r(built_lib_path, target_dir)
68
- end
69
- end
70
43
  end
71
44
  end
@@ -1,11 +1,21 @@
1
1
  module PodPrebuild
2
- class StateStore
3
- @excluded_pods = Set.new
4
- @cache_validation = CacheValidationResult.new
2
+ def self.state
3
+ @state ||= State.new
4
+ end
5
+
6
+ class State
7
+ def initialize
8
+ @store = {
9
+ :cache_validation => CacheValidationResult.new
10
+ }
11
+ end
12
+
13
+ def update(data)
14
+ @store.merge!(data)
15
+ end
5
16
 
6
- class << self
7
- attr_accessor :excluded_pods
8
- attr_accessor :cache_validation
17
+ def cache_validation
18
+ @store[:cache_validation]
9
19
  end
10
20
  end
11
21
  end
@@ -2,16 +2,35 @@ require "fileutils"
2
2
  require_relative "config"
3
3
  require_relative "fetch"
4
4
  require_relative "prebuild"
5
+ require_relative "push"
5
6
  require_relative "visualize"
6
7
 
7
8
  module Pod
8
9
  class Command
9
10
  class Binary < Command
10
11
  self.abstract_command = true
11
- self.default_subcommand = "fetch"
12
+ def self.options
13
+ [
14
+ ["--repo", "Cache repo (in accordance with `cache_repo` in `config_cocoapods_binary_cache`)"]
15
+ ]
16
+ end
17
+
18
+ def initialize(argv)
19
+ super
20
+ load_podfile
21
+ update_cli_config(:repo => argv.option("repo"))
22
+ end
12
23
 
13
24
  def prebuild_config
14
- @prebuild_config ||= PodPrebuild::Config.new("PodBinaryCacheConfig.json")
25
+ @prebuild_config ||= PodPrebuild.config
26
+ end
27
+
28
+ def load_podfile
29
+ Pod::Config.instance.podfile
30
+ end
31
+
32
+ def update_cli_config(options)
33
+ PodPrebuild.config.cli_config.merge!(options)
15
34
  end
16
35
  end
17
36
  end