cocoapods-binary-cache 0.1.2 → 0.1.8

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 (59) 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 +5 -1
  17. data/lib/cocoapods-binary-cache/helper/prebuild_order.rb +12 -0
  18. data/lib/cocoapods-binary-cache/hooks/post_install.rb +20 -2
  19. data/lib/cocoapods-binary-cache/hooks/pre_install.rb +14 -44
  20. data/lib/cocoapods-binary-cache/main.rb +2 -1
  21. data/lib/cocoapods-binary-cache/pod-binary/helper/build.rb +40 -0
  22. data/lib/cocoapods-binary-cache/pod-binary/helper/detected_prebuilt_pods/installer.rb +2 -2
  23. data/lib/cocoapods-binary-cache/pod-binary/helper/detected_prebuilt_pods/target_definition.rb +3 -10
  24. data/lib/cocoapods-binary-cache/pod-binary/helper/names.rb +2 -11
  25. data/lib/cocoapods-binary-cache/pod-binary/helper/prebuild_sandbox.rb +15 -15
  26. data/lib/cocoapods-binary-cache/pod-binary/helper/target_checker.rb +7 -10
  27. data/lib/cocoapods-binary-cache/pod-binary/integration.rb +1 -3
  28. data/lib/cocoapods-binary-cache/pod-binary/integration/alter_specs.rb +4 -1
  29. data/lib/cocoapods-binary-cache/pod-binary/integration/patch/embed_framework_script.rb +1 -1
  30. data/lib/cocoapods-binary-cache/pod-binary/integration/patch/resolve_dependencies.rb +0 -3
  31. data/lib/cocoapods-binary-cache/pod-binary/integration/patch/sandbox_analyzer_state.rb +29 -0
  32. data/lib/cocoapods-binary-cache/pod-binary/integration/patch/source_installation.rb +6 -3
  33. data/lib/cocoapods-binary-cache/pod-binary/integration/source_installer.rb +42 -50
  34. data/lib/cocoapods-binary-cache/pod-binary/prebuild.rb +45 -110
  35. data/lib/cocoapods-binary-cache/pod-binary/prebuild_dsl.rb +2 -61
  36. data/lib/cocoapods-binary-cache/pod-binary/prebuild_hook.rb +0 -1
  37. data/lib/cocoapods-binary-cache/pod-rome/xcodebuild_command.rb +192 -0
  38. data/lib/cocoapods-binary-cache/pod-rome/xcodebuild_raw.rb +43 -0
  39. data/lib/cocoapods-binary-cache/prebuild_output/metadata.rb +16 -0
  40. data/lib/cocoapods-binary-cache/prebuild_output/output.rb +12 -39
  41. data/lib/cocoapods-binary-cache/scheme_editor.rb +17 -16
  42. data/lib/cocoapods-binary-cache/state_store.rb +16 -6
  43. data/lib/command/binary.rb +21 -2
  44. data/lib/command/config.rb +173 -10
  45. data/lib/command/executor/base.rb +7 -0
  46. data/lib/command/executor/fetcher.rb +4 -4
  47. data/lib/command/executor/prebuilder.rb +2 -2
  48. data/lib/command/executor/pusher.rb +1 -1
  49. data/lib/command/executor/visualizer.rb +3 -2
  50. data/lib/command/fetch.rb +0 -1
  51. data/lib/command/prebuild.rb +14 -2
  52. data/lib/command/push.rb +22 -0
  53. metadata +15 -11
  54. data/lib/cocoapods-binary-cache/pod-binary/helper/feature_switches.rb +0 -90
  55. data/lib/cocoapods-binary-cache/pod-binary/helper/passer.rb +0 -25
  56. data/lib/cocoapods-binary-cache/pod-binary/integration/remove_target_files.rb +0 -29
  57. data/lib/cocoapods-binary-cache/pod-binary/tool/tool.rb +0 -12
  58. data/lib/cocoapods-binary-cache/pod-rome/build_framework.rb +0 -247
  59. data/lib/cocoapods-binary-cache/prebuild_cache.rb +0 -49
@@ -1,68 +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_job)
13
- apply_config.call(:prebuild_all) # TODO (thuyen): Revise this option
14
- apply_config.call(:prebuild_all_vendor_pods)
15
- apply_config.call(:excluded_pods)
16
- apply_config.call(:dev_pods_enabled)
17
- apply_config.call(:bitcode_enabled)
18
- apply_config.call(:dont_remove_source_code)
19
- apply_config.call(:custom_device_build_options)
20
- apply_config.call(:custom_simulator_build_options)
21
- apply_config.call(:save_cache_validation_to)
22
- apply_config.call(:validate_prebuilt_settings)
23
- end
24
-
25
- @prebuild_config = "Debug"
26
- @prebuild_job = false
27
- @prebuild_all = false
28
- @prebuild_all_vendor_pods = false
29
- @excluded_pods = Set.new
30
- @dev_pods_enabled = false
31
- @bitcode_enabled = false
32
- @dont_remove_source_code = false
33
- @custom_device_build_options = []
34
- @custom_simulator_build_options = []
35
- @save_cache_validation_to = nil
36
- # A proc to validate the provided build settings (per target) with the build settings of the prebuilt frameworks
37
- # For example, in Podfile:
38
- # -----------------------------------------------
39
- # validate_prebuilt_settings do |target|
40
- # settings = {}
41
- # settings["MACH_O_TYPE"] == "staticlib"
42
- # settings["SWIFT_VERSION"] == swift_version_of(target)
43
- # settings
44
- # end
45
- # -----------------------------------------------
46
- @validate_prebuilt_settings = nil
47
-
48
- class << self
49
- attr_accessor :prebuild_config
50
- attr_accessor :prebuild_job
51
- attr_accessor :prebuild_all
52
- attr_accessor :prebuild_all_vendor_pods
53
- attr_accessor :excluded_pods
54
- attr_accessor :dev_pods_enabled
55
- attr_accessor :bitcode_enabled
56
- attr_accessor :dont_remove_source_code
57
- attr_accessor :custom_device_build_options
58
- attr_accessor :custom_simulator_build_options
59
- attr_accessor :save_cache_validation_to
60
- attr_accessor :validate_prebuilt_settings
61
-
62
- alias prebuild_job? prebuild_job
63
- alias prebuild_all? prebuild_all
64
- alias prebuild_all_vendor_pods? prebuild_all_vendor_pods
65
- alias dev_pods_enabled? dev_pods_enabled
5
+ PodPrebuild.config.dsl_config = options
6
+ PodPrebuild.config.validate_dsl_config
66
7
  end
67
8
  end
68
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,192 @@
1
+ require_relative "xcodebuild_raw"
2
+
3
+ class XcodebuildCommand # rubocop:disable Metrics/ClassLength
4
+ def initialize(options)
5
+ @options = options
6
+ case options[:target].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
+ case build_types
25
+ when [:simulator]
26
+ collect_output(Dir[target_products_dir_of(simulator) + "/*"])
27
+ when [:device]
28
+ collect_output(Dir[target_products_dir_of(device) + "/*"])
29
+ else
30
+ # When merging contents of `simulator` & `device`, prefer contents of `device` over `simulator`
31
+ # https://github.com/grab/cocoapods-binary-cache/issues/25
32
+ collect_output(Dir[target_products_dir_of(device) + "/*"])
33
+ create_universal_framework
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def build_types
40
+ @build_types ||= begin
41
+ # TODO (thuyen): Add DSL options `build_for_types` to specify build types
42
+ types = [:simulator]
43
+ types << :device if device_build_enabled?
44
+ types
45
+ end
46
+ end
47
+
48
+ def make_up_build_args(args)
49
+ args_ = args.clone
50
+ args_[:default] ||= []
51
+ args_[:simulator] ||= []
52
+ args_[:device] ||= []
53
+ args_[:default] += ["BITCODE_GENERATION_MODE=bitcode"] if bitcode_enabled?
54
+ args_[:default] += ["DEBUG_INFORMATION_FORMAT=dwarf"] if disable_dsym?
55
+ args_[:simulator] += ["ARCHS=x86_64", "ONLY_ACTIVE_ARCH=NO"] if simulator == "iphonesimulator"
56
+ args_[:simulator] += args_[:default]
57
+ args_[:device] += args_[:default]
58
+ args_
59
+ end
60
+
61
+ def build_for_sdk(sdk)
62
+ framework_path = framework_path_of(sdk)
63
+ if Dir.exist?(framework_path)
64
+ Pod::UI.puts_indented "--> Framework already exists at: #{framework_path}"
65
+ return
66
+ end
67
+
68
+ succeeded, = xcodebuild(
69
+ sandbox: sandbox,
70
+ target: target.label,
71
+ configuration: configuration,
72
+ sdk: sdk,
73
+ deployment_target: target.platform.deployment_target.to_s,
74
+ args: sdk == simulator ? @build_args[:simulator] : @build_args[:device]
75
+ )
76
+ raise "Build framework failed: #{target.label}" unless succeeded
77
+ end
78
+
79
+ def create_universal_framework
80
+ merge_framework_binary
81
+ merge_framework_dsym
82
+ merge_swift_headers
83
+ merge_swift_modules
84
+ end
85
+
86
+ def merge_framework_binary
87
+ merge_contents("/#{module_name}", &method(:create_fat_binary))
88
+ end
89
+
90
+ def merge_framework_dsym
91
+ merge_contents(".dSYM/Contents/Resources/DWARF/#{module_name}", &method(:create_fat_binary))
92
+ end
93
+
94
+ def merge_swift_headers
95
+ merge_contents("/Headers/#{module_name}-Swift.h") do |options|
96
+ merged_header = <<~HEREDOC
97
+ #if TARGET_OS_SIMULATOR // merged by cocoapods-binary
98
+ #{File.read(options[:simulator])}
99
+ #else // merged by cocoapods-binary
100
+ #{File.read(options[:device])}
101
+ #endif // merged by cocoapods-binary
102
+ HEREDOC
103
+ File.write(options[:output], merged_header.strip)
104
+ end
105
+ end
106
+
107
+ def merge_swift_modules
108
+ merge_contents("/Modules/#{module_name}.swiftmodule") do |options|
109
+ # Note: swiftmodules of `device` were copied beforehand,
110
+ # here, we only need to copy swiftmodules of `simulator`
111
+ FileUtils.cp_r(options[:simulator] + "/.", options[:output])
112
+ end
113
+ end
114
+
115
+ def merge_contents(path_suffix, &merger)
116
+ simulator_, device_, output_ = [
117
+ framework_path_of(simulator),
118
+ framework_path_of(device),
119
+ "#{output_path}/#{module_name}.framework"
120
+ ].map { |p| p + path_suffix }
121
+ return unless File.exist?(simulator_) && File.exist?(device_)
122
+
123
+ merger.call(simulator: simulator_, device: device_, output: output_)
124
+ end
125
+
126
+ def create_fat_binary(options)
127
+ cmd = ["lipo", " -create"]
128
+ cmd << "-output" << options[:output]
129
+ cmd << options[:simulator] << options[:device]
130
+ Pod::UI.puts `#{cmd.join(" ")}`
131
+ end
132
+
133
+ def collect_output(paths)
134
+ paths = [paths] unless paths.is_a?(Array)
135
+ paths.each do |path|
136
+ FileUtils.rm_rf(File.join(output_path, File.basename(path)))
137
+ FileUtils.cp_r(path, output_path)
138
+ end
139
+ end
140
+
141
+ def target_products_dir_of(sdk)
142
+ "#{build_dir}/#{configuration}-#{sdk}/#{target.name}"
143
+ end
144
+
145
+ def framework_path_of(sdk)
146
+ "#{target_products_dir_of(sdk)}/#{module_name}.framework"
147
+ end
148
+
149
+ def module_name
150
+ target.product_module_name
151
+ end
152
+
153
+ def sandbox
154
+ @options[:sandbox]
155
+ end
156
+
157
+ def build_dir
158
+ @options[:build_dir]
159
+ end
160
+
161
+ def output_path
162
+ @options[:output_path]
163
+ end
164
+
165
+ def target
166
+ @options[:target]
167
+ end
168
+
169
+ def configuration
170
+ @options[:configuration]
171
+ end
172
+
173
+ def bitcode_enabled?
174
+ @options[:bitcode_enabled]
175
+ end
176
+
177
+ def device_build_enabled?
178
+ @options[:device_build_enabled]
179
+ end
180
+
181
+ def device
182
+ @options[:device] || "iphoneos"
183
+ end
184
+
185
+ def simulator
186
+ @options[:simulator] || "iphonesimulator"
187
+ end
188
+
189
+ def disable_dsym?
190
+ @options[:disable_dsym]
191
+ end
192
+ end
@@ -0,0 +1,43 @@
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
+ platform = PLATFORM_OF_SDK[sdk]
12
+
13
+ cmd = ["xcodebuild"]
14
+ cmd << "-project" << options[:sandbox].project_path.realdirpath
15
+ cmd << "-scheme" << options[:target]
16
+ cmd << "-configuration" << options[:configuration]
17
+ cmd << "-sdk" << sdk
18
+ cmd << Fourflusher::SimControl.new.destination(:oldest, platform, options[:deployment_target]) unless platform.nil?
19
+ cmd += options[:args] if options[:args]
20
+ cmd << "2>&1"
21
+ cmd = cmd.join(" ")
22
+
23
+ Pod::UI.puts_indented "$ #{cmd}"
24
+ log = `#{cmd}`
25
+
26
+ succeeded = $?.exitstatus.zero? # rubocop:disable Style/SpecialGlobalVars
27
+ unless succeeded
28
+ begin
29
+ raise "Unexpected error" unless log.include?("** BUILD FAILED **")
30
+
31
+ require "xcpretty" # TODO (thuyen): Revise this dependency
32
+ # use xcpretty to print build log
33
+ # 64 represent command invalid. http://www.manpagez.com/man/3/sysexits/
34
+ printer = XCPretty::Printer.new({:formatter => XCPretty::Simple, :colorize => "auto"})
35
+ log.each_line do |line|
36
+ printer.pretty_print(line)
37
+ end
38
+ rescue
39
+ Pod::UI.puts log.red
40
+ end
41
+ end
42
+ [succeeded, log]
43
+ 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,35 +1,36 @@
1
1
  # Copyright 2019 Grabtaxi Holdings PTE LTE (GRAB), All rights reserved.
2
2
  # Use of this source code is governed by an MIT-style license that can be found in the LICENSE file
3
3
 
4
- require 'rexml/document'
4
+ require "rexml/document"
5
5
 
6
6
  class SchemeEditor
7
7
  def self.edit_to_support_code_coverage(sandbox)
8
8
  pod_proj_path = sandbox.project_path
9
- puts "Modify schemes of pod project to support code coverage of prebuilt local pod: #{pod_proj_path}"
9
+ Pod::UI.message "Modify schemes of pod project to support code coverage of prebuilt local pod: #{pod_proj_path}"
10
10
  scheme_files = Dir["#{pod_proj_path}/**/*.xcscheme"]
11
11
  scheme_files.each do |file_path|
12
- scheme_name = File.basename(file_path, '.*')
12
+ scheme_name = File.basename(file_path, ".*")
13
13
  next unless sandbox.local?(scheme_name)
14
14
 
15
- puts "Modify scheme to enable coverage symbol when prebuild: #{scheme_name}"
15
+ Pod::UI.message "Modify scheme to enable coverage symbol when prebuild: #{scheme_name}"
16
16
 
17
- doc = File.open(file_path, 'r') { |f| REXML::Document.new(f) }
18
- scheme = doc.elements['Scheme']
19
- test_action = scheme.elements['TestAction']
20
- next if test_action.attributes['codeCoverageEnabled'] == 'YES'
17
+ doc = File.open(file_path, "r") { |f| REXML::Document.new(f) }
18
+ scheme = doc.elements["Scheme"]
19
+ test_action = scheme.elements["TestAction"]
20
+ next if test_action.attributes["codeCoverageEnabled"] == "YES"
21
21
 
22
- test_action.add_attribute('codeCoverageEnabled', 'YES')
23
- test_action.add_attribute('onlyGenerateCoverageForSpecifiedTargets', 'YES')
24
- coverage_targets = REXML::Element.new('CodeCoverageTargets')
25
- buildable_ref = scheme.elements['BuildAction'] \
26
- .elements['BuildActionEntries'] \
27
- .elements['BuildActionEntry'] \
28
- .elements['BuildableReference']
22
+ test_action.add_attribute("codeCoverageEnabled", "YES")
23
+ test_action.add_attribute("onlyGenerateCoverageForSpecifiedTargets", "YES")
24
+ coverage_targets = REXML::Element.new("CodeCoverageTargets")
25
+ buildable_ref = scheme
26
+ .elements["BuildAction"]
27
+ .elements["BuildActionEntries"]
28
+ .elements["BuildActionEntry"]
29
+ .elements["BuildableReference"]
29
30
  new_buildable_ref = buildable_ref.clone # Need to clone, otherwise the original one will be move to new place
30
31
  coverage_targets.add_element(new_buildable_ref)
31
32
  test_action.add_element(coverage_targets)
32
- File.open(file_path, 'w') { |f| doc.write(f) }
33
+ File.open(file_path, "w") { |f| doc.write(f) }
33
34
  end
34
35
  end
35
36
  end