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