carthage_cashier 0.1.5

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ed209e2c77954e6b2435489dc0ef54f5be908d70
4
+ data.tar.gz: b4e5262718c6f7294bf2f73dd6c234f1efc08a16
5
+ SHA512:
6
+ metadata.gz: 73c629e59733e2989541abdcddec71db8eff6f92dac1bfbf10a9f4243b497f593050d4c359139e74b3eb644c75011da77330b6624a95c420afd23f5bdfe59903
7
+ data.tar.gz: 85c23e597a2b8e0ab7f9929ce7e97a8c3269012c701eb4124b00d66bab25155112f4bb5186cc188c79bea9664699c03ffd3833373d3b0b45ea4175437b7c6840
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'carthage_cashier'
4
+ CarthageCashier.run ARGV
@@ -0,0 +1,3 @@
1
+ module CarthageCashier
2
+ VERSION = "0.1.5"
3
+ end
@@ -0,0 +1,303 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "carthage_cache/version"
4
+ require "fileutils"
5
+ require 'digest'
6
+ require 'optparse'
7
+ require 'xcodeproject'
8
+
9
+ module CarthageCashier
10
+
11
+ # Constants
12
+ COMPILER_VER = /(?<=\()(.*)(?= )/.match(`xcrun swift -version`)[0]
13
+ CARTHAGE_RESOLVED_FILE="Cartfile.resolved"
14
+ CARTHAGE_CACHE_DIR="#{ENV['HOME']}/.carthage_cache"
15
+
16
+ module Platform
17
+ IOS = "iOS"
18
+ TVOS = "tvOS"
19
+ OSX = "OSX"
20
+ WATCHOS = "watchOS"
21
+ ALL = [IOS, TVOS, OSX, WATCHOS]
22
+ end
23
+
24
+ # Parse args
25
+ OPTIONS = {}
26
+
27
+ def self.setup_opts_parser()
28
+ opts_parser = OptionParser.new do |opts|
29
+ opts.banner = "Usage: carthage_cache.rb [OPTIONS] project_root"
30
+ opts.separator ""
31
+ opts.separator "Uses cache to load appropriate dependencies. If cached version of the current version is not available,"
32
+ opts.separator "bootstraps it and saves back to cache for further use. Also takes into account compiler version."
33
+ opts.separator ""
34
+ opts.separator "Specific options:"
35
+
36
+ opts.on("-c", "--[no-]clean", "This option will clean (delete) all cached files for all projects.") do |v|
37
+ OPTIONS[:clean] = v
38
+ end
39
+
40
+ opts.on("-w", "--[no-]whole", "Uses MD5 of Cartfile.resolved to check cache and restores the whole image of the folder if available. (worse)") do |v|
41
+ OPTIONS[:whole] = v
42
+ end
43
+
44
+ opts.on("-f", "--[no-]force", "Force bootstrap dependencies without using cached versions and save the built products to cache.") do |v|
45
+ OPTIONS[:force] = v
46
+ end
47
+
48
+ opts.on_tail("-h", "--help", "Show this message") do
49
+ puts opts
50
+ exit
51
+ end
52
+ end
53
+
54
+ return opts_parser
55
+ end
56
+
57
+ def self.get_cache_paths()
58
+ base_path = "#{CARTHAGE_CACHE_DIR}/#{COMPILER_VER}"
59
+ paths = {}
60
+
61
+ if OPTIONS[:whole]
62
+ paths["WHOLE"] = "#{base_path}/whole"
63
+ else
64
+ Platform::ALL.each do |platform|
65
+ paths[platform] = "#{base_path}/intelligent/#{platform}"
66
+ end
67
+ end
68
+
69
+ return paths
70
+ end
71
+
72
+ # Gets the names and hashes from resolved cartfile
73
+ def self.parse_resolved_cartfile(path)
74
+ dependencies = {}
75
+
76
+ # Open file and read line by line
77
+ File.open(path) do |file|
78
+ file.each_line do |line|
79
+
80
+ # Run regex on line
81
+ result = /^git(?>hub)? ".*(?<=\/)([^"]*)" "(.*)"$/.match(line)
82
+
83
+ # If we found match (0) and name capture group (1) and hash/version capture group (2)
84
+ if !result.nil? && result.length == 3
85
+ dependencies[result[2]] = result[1].chomp('.git')
86
+ end
87
+
88
+ end
89
+ end
90
+
91
+ return dependencies
92
+ end
93
+
94
+ def self.find_xcodeproj_files()
95
+ projects = XcodeProject::Project.find("Carthage/Checkouts/**")
96
+
97
+ # Filter out example, test projects
98
+ projects.each do |p|
99
+ projects.delete p unless /[Dd]emo$|[Ee]xample$|[Tt]est[s]*$/.match(p.name).nil?
100
+ end
101
+
102
+ return projects
103
+ end
104
+
105
+ def self.parse_product_name_mappings(xcodeproj_files, dependencies)
106
+ names = {}
107
+
108
+ xcodeproj_files.each do |xp|
109
+ data = xp.read
110
+
111
+ next unless data.targets.first.config("Release").build_settings["DEFINES_MODULE"]
112
+ product_name = data.targets.first.config("Release").build_settings["PRODUCT_NAME"]
113
+
114
+ # If the proj is using target name
115
+ if product_name == "$(TARGET_NAME)"
116
+ product_name = data.targets.first.name
117
+ end
118
+
119
+ key = nil
120
+ file_path = xp.file_path.to_s
121
+ dependencies.values.each do |name|
122
+ next unless file_path.include? name
123
+ key = name
124
+ break
125
+ end
126
+
127
+ next unless key.nil? == false
128
+ names[key] = product_name unless names.values.include?(product_name)
129
+ end
130
+
131
+ return names
132
+ end
133
+
134
+ def self.cache_built_dependencies(dependencies)
135
+ puts("Caching built dependencies.")
136
+
137
+ cache_paths = get_cache_paths
138
+
139
+ if OPTIONS[:whole] == true
140
+ cache_path = "#{cache_paths.values.first}/#{Digest::MD5.file CARTHAGE_RESOLVED_FILE}/"
141
+
142
+ # Get target dir
143
+ src_dir = Dir.getwd + "/Carthage/Build/"
144
+
145
+ # Create the target dir if needed and copy files
146
+ FileUtils.mkdir_p cache_path unless File.exists? cache_path
147
+ FileUtils.cp_r Dir["#{src_dir}/*"], cache_path
148
+ else
149
+ xcodeproj_files = find_xcodeproj_files
150
+ products_name_mapping = parse_product_name_mappings xcodeproj_files, dependencies
151
+
152
+ dependencies.each do |d_ver, d_name|
153
+ next unless products_name_mapping.keys.include?(d_name)
154
+ product_name = products_name_mapping[d_name]
155
+
156
+ get_cache_paths.each do |platform, path|
157
+ target_dir = "#{path}/#{d_name}/#{d_ver}"
158
+ src_dir = "Carthage/Build/#{platform}"
159
+ fmwk_path = "#{src_dir}/#{product_name}.framework"
160
+
161
+ next unless fmwk_path.empty? == false
162
+ next unless Dir.exist? src_dir
163
+
164
+ # Create the target dir if needed and copy files
165
+ if File.exists? target_dir
166
+ FileUtils.rm_rf target_dir
167
+ end
168
+ FileUtils.mkdir_p target_dir
169
+ FileUtils.cp_r fmwk_path, target_dir
170
+ FileUtils.cp_r "#{fmwk_path}.dSYM", target_dir
171
+ end
172
+ end
173
+
174
+ # Steps
175
+ # 1. Find .xcodeproj in Carthage/Checkouts after running carthage checkout
176
+ # 2. Parse Product Name to be able to find corresponding .framework
177
+ # 3. Copy that from each platform folder to cache
178
+ # Question: How to figure out .bcsymbolmap files? Relation to .framework? Metadata? Timestamp?
179
+ end
180
+
181
+ end
182
+
183
+ def self.copy_dependencies_from_cache(dependencies)
184
+ uncached = {}
185
+ cache_paths = get_cache_paths
186
+
187
+ # Whole cache
188
+ if OPTIONS[:whole]
189
+ cache_path = "#{cache_paths.values.first}/#{Digest::MD5.file CARTHAGE_RESOLVED_FILE}/"
190
+ if Dir.exist? cache_path
191
+ found = true
192
+
193
+ # Get target dir
194
+ target_dir = Dir.getwd + "/Carthage/Build"
195
+
196
+ # Create the target dir if needed and copy files
197
+ if File.exists? target_dir
198
+ FileUtils.rm_rf target_dir
199
+ end
200
+ FileUtils.mkdir_p target_dir
201
+ FileUtils.cp_r Dir["#{cache_path}/*"], target_dir
202
+ else
203
+ uncached.replace dependencies
204
+ end
205
+ else
206
+ # Intelligent cache
207
+ dependencies.each do |d_ver, d_name|
208
+ found = false
209
+
210
+ cache_paths.each do |platform, path|
211
+ dep_cache_path = "#{path}/#{d_name}/#{d_ver}"
212
+
213
+ if Dir.exist? dep_cache_path
214
+ found = true
215
+
216
+ target_dir = Dir.getwd + "/Carthage/Build/#{platform}"
217
+
218
+ # Create the target dir if needed and copy files
219
+ FileUtils.mkdir_p target_dir unless File.exists? target_dir
220
+ FileUtils.cp_r Dir["#{dep_cache_path}/*"], target_dir
221
+ end
222
+ end
223
+
224
+ # If not found, put it in uncached
225
+ uncached[d_ver] = d_name unless found
226
+ end
227
+ end
228
+
229
+ puts "Copied dependencies from cache: #{dependencies.values - uncached.values}"
230
+ return uncached
231
+ end
232
+
233
+ def self.boostrap_and_cache(dependencies = {})
234
+
235
+ if dependencies.count == 0
236
+ success = system("carthage bootstrap")
237
+ else
238
+ # Pass only some deps to carthage bootstrap, so we don't build everything
239
+ success = system("carthage bootstrap #{dependencies.values.join(" ")}")
240
+ end
241
+
242
+ # Check result and cache if appropriate
243
+ if success
244
+ cache_built_dependencies dependencies
245
+ exit 0
246
+ else
247
+ puts("ERROR: Carthage bootstrap failed, can't cache built dependencies.")
248
+ exit 1
249
+ end
250
+ end
251
+
252
+ # -----------
253
+ # MAIN
254
+ # -----------
255
+
256
+
257
+ def self.run(arguments = ARGV)
258
+ opts_parser = setup_opts_parser
259
+ opts_parser.parse!(arguments)
260
+
261
+ # Clean cache
262
+ if OPTIONS[:clean]
263
+ puts "Cleaning all cached files."
264
+ FileUtils.rm_rf(CARTHAGE_CACHE_DIR)
265
+ exit 0
266
+ end
267
+
268
+ # Safety check
269
+ if arguments.count != 1
270
+ puts opts_parser.help
271
+ exit 1
272
+ end
273
+
274
+ # Change to project dir
275
+ Dir.chdir arguments[0]
276
+
277
+ # Get Cartfile.resolved
278
+ if !File.exist?(CARTHAGE_RESOLVED_FILE)
279
+ puts("No #{CARTHAGE_RESOLVED_FILE} found in specified directory. Bootstrapping instead.")
280
+ boostrap_and_cache
281
+ end
282
+
283
+ # Get dependencies
284
+ deps = parse_resolved_cartfile CARTHAGE_RESOLVED_FILE
285
+
286
+ # Force bootstrap or try loading dependencies from cache
287
+ if OPTIONS[:force]
288
+ puts "Force bootstrapping and caching results."
289
+ boostrap_and_cache deps
290
+ else
291
+ remaining_deps = copy_dependencies_from_cache deps
292
+ if remaining_deps.count == 0
293
+ puts "Loaded all dependencies from cache."
294
+ exit 0
295
+ end
296
+ end
297
+
298
+ # Bootstrapping remaining dependencies
299
+ puts "Following dependencies not cached, bootstrapping them now: #{remaining_deps.values}"
300
+ boostrap_and_cache remaining_deps
301
+
302
+ end
303
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: carthage_cashier
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.5
5
+ platform: ruby
6
+ authors:
7
+ - Dominik Hadl
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-08-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: xcodeproject
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.12'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.12'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ description:
56
+ email:
57
+ - doha@nodes.dk
58
+ executables:
59
+ - carthage_cashier
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - bin/carthage_cashier
64
+ - lib/carthage_cashier.rb
65
+ - lib/carthage_cashier/version.rb
66
+ homepage: https://www.github.com/nodes-ios/carthage_cache
67
+ licenses:
68
+ - MIT
69
+ metadata: {}
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 2.5.1
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: Caches files produced by carthage for faster build times, especially on CI
90
+ servers.
91
+ test_files: []