emerge 0.3.0 → 0.5.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/lib/commands/autofixes/exported_symbols.rb +62 -0
- data/lib/commands/autofixes/minify_strings.rb +99 -0
- data/lib/commands/autofixes/strip_binary_symbols.rb +116 -0
- data/lib/commands/build_distribution/download_and_install.rb +107 -0
- data/lib/commands/build_distribution/validate_app.rb +164 -0
- data/lib/commands/order_files/download_order_files.rb +77 -0
- data/lib/commands/order_files/validate_linkmaps.rb +55 -0
- data/lib/commands/order_files/validate_xcode_project.rb +71 -0
- data/lib/commands/snapshots/validate_app.rb +64 -0
- data/lib/commands/upload/build.rb +140 -0
- data/lib/emerge_cli.rb +33 -0
- data/lib/reaper/ast_parser.rb +17 -16
- data/lib/reaper/code_deleter.rb +3 -1
- data/lib/utils/git.rb +21 -1
- data/lib/utils/macho_parser.rb +325 -0
- data/lib/utils/network.rb +12 -10
- data/lib/version.rb +1 -1
- data/parsers/libtree-sitter-objc-darwin-arm64.dylib +0 -0
- data/parsers/libtree-sitter-objc-linux-x86_64.so +0 -0
- metadata +66 -5
@@ -0,0 +1,325 @@
|
|
1
|
+
require 'macho'
|
2
|
+
|
3
|
+
module EmergeCLI
|
4
|
+
class MachOParser
|
5
|
+
TYPE_METADATA_KIND_MASK = 0x7 << 3
|
6
|
+
TYPE_METADATA_KIND_SHIFT = 3
|
7
|
+
|
8
|
+
# Bind Codes
|
9
|
+
BIND_OPCODE_MASK = 0xF0
|
10
|
+
BIND_IMMEDIATE_MASK = 0x0F
|
11
|
+
BIND_OPCODE_DONE = 0x00
|
12
|
+
BIND_OPCODE_SET_DYLIB_ORDINAL_IMM = 0x10
|
13
|
+
BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB = 0x20
|
14
|
+
BIND_OPCODE_SET_DYLIB_SPECIAL_IMM = 0x30
|
15
|
+
BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM = 0x40
|
16
|
+
BIND_OPCODE_SET_TYPE_IMM = 0x50
|
17
|
+
BIND_OPCODE_SET_ADDEND_SLEB = 0x60
|
18
|
+
BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB = 0x70
|
19
|
+
BIND_OPCODE_ADD_ADDR_ULEB = 0x80
|
20
|
+
BIND_OPCODE_DO_BIND = 0x90
|
21
|
+
BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB = 0xA0
|
22
|
+
BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED = 0xB0
|
23
|
+
BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB = 0xC0
|
24
|
+
|
25
|
+
UINT64_SIZE = 8
|
26
|
+
UINT64_MAX_VALUE = 0xFFFFFFFFFFFFFFFF
|
27
|
+
|
28
|
+
def load_binary(binary_path)
|
29
|
+
@macho_file = MachO::MachOFile.new(binary_path)
|
30
|
+
@binary_data = File.binread(binary_path)
|
31
|
+
end
|
32
|
+
|
33
|
+
def read_linkedit_data_command
|
34
|
+
chained_fixups_command = nil
|
35
|
+
@macho_file.load_commands.each do |lc|
|
36
|
+
chained_fixups_command = lc if lc.type == :LC_DYLD_CHAINED_FIXUPS
|
37
|
+
end
|
38
|
+
|
39
|
+
if chained_fixups_command.nil?
|
40
|
+
Logger.debug 'No LC_DYLD_CHAINED_FIXUPS found'
|
41
|
+
return false, []
|
42
|
+
end
|
43
|
+
|
44
|
+
# linkedit_data_command
|
45
|
+
_, _, dataoff, datasize = @binary_data[chained_fixups_command.offset, 16].unpack('L<L<L<L<')
|
46
|
+
|
47
|
+
header = @binary_data[dataoff, datasize].unpack('L<L<L<L<L<L<L<')
|
48
|
+
# dyld_chained_fixups_header
|
49
|
+
_, _, imports_offset, symbols_offset, imports_count,
|
50
|
+
imports_format, = header
|
51
|
+
|
52
|
+
imports_start = dataoff + imports_offset
|
53
|
+
symbols_start = dataoff + symbols_offset
|
54
|
+
|
55
|
+
imported_symbols = []
|
56
|
+
|
57
|
+
import_size, name_offset_proc =
|
58
|
+
case imports_format
|
59
|
+
when 1, nil # DYLD_CHAINED_IMPORT
|
60
|
+
[4, ->(ptr) { ptr.unpack1('L<') >> 9 }]
|
61
|
+
when 2 # DYLD_CHAINED_IMPORT_ADDEND
|
62
|
+
[8, ->(ptr) { ptr.unpack1('L<') >> 9 }]
|
63
|
+
when 3 # DYLD_CHAINED_IMPORT_ADDEND64
|
64
|
+
[16, ->(ptr) { ptr.unpack1('Q<') >> 32 }]
|
65
|
+
end
|
66
|
+
|
67
|
+
# Extract imported symbol names
|
68
|
+
imports_count.times do |i|
|
69
|
+
import_offset = imports_start + (i * import_size)
|
70
|
+
name_offset = name_offset_proc.call(@binary_data[import_offset, import_size])
|
71
|
+
name_start = symbols_start + name_offset
|
72
|
+
name = read_null_terminated_string(@binary_data[name_start..])
|
73
|
+
imported_symbols << name
|
74
|
+
end
|
75
|
+
|
76
|
+
[true, imported_symbols]
|
77
|
+
end
|
78
|
+
|
79
|
+
def read_dyld_info_only_command
|
80
|
+
dyld_info_only_command = nil
|
81
|
+
@macho_file.load_commands.each do |lc|
|
82
|
+
dyld_info_only_command = lc if lc.type == :LC_DYLD_INFO_ONLY
|
83
|
+
end
|
84
|
+
|
85
|
+
if dyld_info_only_command.nil?
|
86
|
+
Logger.debug 'No LC_DYLD_INFO_ONLY found'
|
87
|
+
return []
|
88
|
+
end
|
89
|
+
|
90
|
+
bound_symbols = []
|
91
|
+
start_address = dyld_info_only_command.bind_off
|
92
|
+
end_address = dyld_info_only_command.bind_off + dyld_info_only_command.bind_size
|
93
|
+
current_address = start_address
|
94
|
+
|
95
|
+
current_symbol = BoundSymbol.new(segment_offset: 0, library: nil, offset: 0, symbol: '')
|
96
|
+
while current_address < end_address
|
97
|
+
results, current_address, current_symbol = read_next_symbol(@binary_data, current_address, end_address,
|
98
|
+
current_symbol)
|
99
|
+
|
100
|
+
# Dup items to avoid pointer issues
|
101
|
+
results.each do |res|
|
102
|
+
bound_symbols << res.dup
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Filter only swift symbols starting with _$s
|
107
|
+
swift_symbols = bound_symbols.select { |bound_symbol| bound_symbol.symbol.start_with?('_$s') }
|
108
|
+
|
109
|
+
load_commands = @macho_file.load_commands.select { |lc| lc.type == :LC_SEGMENT_64 || lc.type == :LC_SEGMENT } # rubocop:disable Naming/VariableNumber
|
110
|
+
|
111
|
+
swift_symbols.each do |swift_symbol|
|
112
|
+
swift_symbol.address = load_commands[swift_symbol.segment_offset].vmaddr + swift_symbol.offset
|
113
|
+
end
|
114
|
+
|
115
|
+
swift_symbols
|
116
|
+
end
|
117
|
+
|
118
|
+
def find_protocols_in_swift_proto(use_chained_fixups, imported_symbols, bound_symbols, search_symbols)
|
119
|
+
found_section = nil
|
120
|
+
@macho_file.segments.each do |segment|
|
121
|
+
segment.sections.each do |section|
|
122
|
+
if section.segname.strip == '__TEXT' && section.sectname.strip == '__swift5_proto'
|
123
|
+
found_section = section
|
124
|
+
break
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
unless found_section
|
130
|
+
Logger.error 'The __swift5_proto section was not found.'
|
131
|
+
return false
|
132
|
+
end
|
133
|
+
|
134
|
+
start = found_section.offset
|
135
|
+
size = found_section.size
|
136
|
+
offsets_list = parse_list(@binary_data, start, size)
|
137
|
+
|
138
|
+
offsets_list.each do |relative_offset, offset_start|
|
139
|
+
type_file_address = offset_start + relative_offset
|
140
|
+
if type_file_address <= 0 || type_file_address >= @binary_data.size
|
141
|
+
Logger.error 'Invalid protocol conformance offset'
|
142
|
+
next
|
143
|
+
end
|
144
|
+
|
145
|
+
# ProtocolConformanceDescriptor -> ProtocolDescriptor
|
146
|
+
protocol_descriptor = read_little_endian_signed_integer(@binary_data, type_file_address)
|
147
|
+
|
148
|
+
# # ProtocolConformanceDescriptor -> ConformanceFlags
|
149
|
+
conformance_flags = read_little_endian_signed_integer(@binary_data, type_file_address + 12)
|
150
|
+
kind = (conformance_flags & TYPE_METADATA_KIND_MASK) >> TYPE_METADATA_KIND_SHIFT
|
151
|
+
|
152
|
+
next unless kind == 0
|
153
|
+
|
154
|
+
indirect_relative_offset = get_indirect_relative_offset(type_file_address, protocol_descriptor)
|
155
|
+
|
156
|
+
bound_symbol = bound_symbols.find { |symbol| symbol.address == indirect_relative_offset }
|
157
|
+
if bound_symbol
|
158
|
+
return true if search_symbols.include?(bound_symbol.symbol)
|
159
|
+
elsif use_chained_fixups
|
160
|
+
descriptor_offset = protocol_descriptor & ~1
|
161
|
+
jump_ptr = type_file_address + descriptor_offset
|
162
|
+
|
163
|
+
address = @binary_data[jump_ptr, 4].unpack1('I<')
|
164
|
+
symbol_name = imported_symbols[address]
|
165
|
+
return true if search_symbols.include?(symbol_name)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
false
|
169
|
+
end
|
170
|
+
|
171
|
+
private
|
172
|
+
|
173
|
+
def read_next_symbol(binary_data, current_address, end_address, current_symbol)
|
174
|
+
while current_address < end_address
|
175
|
+
first_byte = read_byte(binary_data, current_address)
|
176
|
+
current_address += 1
|
177
|
+
immediate = first_byte & BIND_IMMEDIATE_MASK
|
178
|
+
opcode = first_byte & BIND_OPCODE_MASK
|
179
|
+
|
180
|
+
case opcode
|
181
|
+
when BIND_OPCODE_DONE
|
182
|
+
result = current_symbol.dup
|
183
|
+
current_symbol.segment_offset = 0
|
184
|
+
current_symbol.library = 0
|
185
|
+
current_symbol.offset = 0
|
186
|
+
current_symbol.symbol = ''
|
187
|
+
return [result], current_address, current_symbol
|
188
|
+
when BIND_OPCODE_SET_DYLIB_ORDINAL_IMM
|
189
|
+
current_symbol.library = [immediate].pack('L').unpack1('L')
|
190
|
+
when BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
|
191
|
+
current_symbol.symbol = read_null_terminated_string(binary_data[current_address..])
|
192
|
+
# Increase current pointer
|
193
|
+
current_address += current_symbol.symbol.size + 1
|
194
|
+
when BIND_OPCODE_ADD_ADDR_ULEB
|
195
|
+
offset, new_current_address = read_uleb(@binary_data, current_address)
|
196
|
+
current_symbol.offset = (current_symbol.offset + offset) & UINT64_MAX_VALUE
|
197
|
+
current_address = new_current_address
|
198
|
+
when BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB
|
199
|
+
offset, new_current_address = read_uleb(@binary_data, current_address)
|
200
|
+
current_symbol.offset = (current_symbol.offset + offset + UINT64_SIZE) & UINT64_MAX_VALUE
|
201
|
+
current_address = new_current_address
|
202
|
+
return [current_symbol], current_address, current_symbol
|
203
|
+
when BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
|
204
|
+
offset, current_address = read_uleb(@binary_data, current_address)
|
205
|
+
current_symbol.segment_offset = immediate
|
206
|
+
current_symbol.offset = offset
|
207
|
+
when BIND_OPCODE_SET_ADDEND_SLEB
|
208
|
+
_, current_address = read_uleb(@binary_data, current_address)
|
209
|
+
when BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED
|
210
|
+
result = current_symbol.dup
|
211
|
+
current_symbol.offset = (
|
212
|
+
current_symbol.offset + (immediate * UINT64_SIZE) + UINT64_SIZE
|
213
|
+
) & UINT64_MAX_VALUE
|
214
|
+
return [result], current_address, current_symbol
|
215
|
+
when BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB
|
216
|
+
count, current_address = read_uleb(@binary_data, current_address)
|
217
|
+
skipping, current_address = read_uleb(@binary_data, current_address)
|
218
|
+
|
219
|
+
results = []
|
220
|
+
count.times do
|
221
|
+
results << current_symbol.dup
|
222
|
+
current_symbol.offset = (current_symbol.offset + skipping + UINT64_SIZE) & UINT64_MAX_VALUE
|
223
|
+
end
|
224
|
+
|
225
|
+
return results, current_address, current_symbol
|
226
|
+
when BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB
|
227
|
+
count, current_address = read_uleb(@binary_data, current_address)
|
228
|
+
current_symbol.library = count
|
229
|
+
when BIND_OPCODE_DO_BIND
|
230
|
+
result = current_symbol.dup
|
231
|
+
current_symbol.offset = (current_symbol.offset + UINT64_SIZE) & UINT64_MAX_VALUE
|
232
|
+
return [result], current_address, current_symbol
|
233
|
+
end
|
234
|
+
end
|
235
|
+
[[], current_address, current_symbol]
|
236
|
+
end
|
237
|
+
|
238
|
+
def read_byte(binary_data, address)
|
239
|
+
binary_data[address, 1].unpack1('C')
|
240
|
+
end
|
241
|
+
|
242
|
+
def read_little_endian_signed_integer(binary_data, address)
|
243
|
+
binary_data[address, 4].unpack1('l<')
|
244
|
+
end
|
245
|
+
|
246
|
+
def read_uleb(binary_data, address)
|
247
|
+
next_byte = 0
|
248
|
+
size = 0
|
249
|
+
result = 0
|
250
|
+
|
251
|
+
loop do
|
252
|
+
next_byte = read_byte(binary_data, address)
|
253
|
+
address += 1
|
254
|
+
bytes = next_byte & 0x7F
|
255
|
+
shifted = bytes << (size * 7)
|
256
|
+
|
257
|
+
size += 1
|
258
|
+
result |= shifted
|
259
|
+
break if next_byte.nobits?(0x80)
|
260
|
+
end
|
261
|
+
|
262
|
+
[result, address]
|
263
|
+
end
|
264
|
+
|
265
|
+
def read_null_terminated_string(data)
|
266
|
+
data.unpack1('Z*')
|
267
|
+
end
|
268
|
+
|
269
|
+
def vm_address(file_offset, macho)
|
270
|
+
load_commands = macho.load_commands.select { |lc| lc.type == :LC_SEGMENT_64 || lc.type == :LC_SEGMENT } # rubocop:disable Naming/VariableNumber
|
271
|
+
load_commands.each do |lc|
|
272
|
+
next unless file_offset >= lc.fileoff && file_offset < (lc.fileoff + lc.filesize)
|
273
|
+
unless lc.respond_to?(:sections)
|
274
|
+
Logger.error 'Load command does not support sections function'
|
275
|
+
next
|
276
|
+
end
|
277
|
+
|
278
|
+
lc.sections.each do |section|
|
279
|
+
if file_offset >= section.offset && file_offset < (section.offset) + section.size
|
280
|
+
return section.addr + (file_offset - section.offset)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
nil
|
285
|
+
end
|
286
|
+
|
287
|
+
def parse_list(bytes, start, size)
|
288
|
+
data_pointer = bytes[start..]
|
289
|
+
file_offset = start
|
290
|
+
pointer_size = 4
|
291
|
+
class_pointers = []
|
292
|
+
|
293
|
+
(size / pointer_size).to_i.times do
|
294
|
+
pointer = data_pointer.unpack1('l<')
|
295
|
+
class_pointers << [pointer, file_offset]
|
296
|
+
data_pointer = data_pointer[pointer_size..]
|
297
|
+
file_offset += pointer_size
|
298
|
+
end
|
299
|
+
|
300
|
+
class_pointers
|
301
|
+
end
|
302
|
+
|
303
|
+
def get_indirect_relative_offset(type_file_address, protocol_descriptor)
|
304
|
+
vm_start = vm_address(type_file_address, @macho_file)
|
305
|
+
return nil if vm_start.nil?
|
306
|
+
if (vm_start + protocol_descriptor).odd?
|
307
|
+
(vm_start + protocol_descriptor) & ~1
|
308
|
+
elsif vm_start + protocol_descriptor > 0
|
309
|
+
vm_start + protocol_descriptor
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
class BoundSymbol
|
315
|
+
attr_accessor :segment_offset, :library, :offset, :symbol, :address
|
316
|
+
|
317
|
+
def initialize(segment_offset:, library:, offset:, symbol:)
|
318
|
+
@segment_offset = segment_offset
|
319
|
+
@library = library
|
320
|
+
@offset = offset
|
321
|
+
@symbol = symbol
|
322
|
+
@address = 0
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
data/lib/utils/network.rb
CHANGED
@@ -17,16 +17,16 @@ module EmergeCLI
|
|
17
17
|
@internet = Async::HTTP::Internet.new
|
18
18
|
end
|
19
19
|
|
20
|
-
def get(path:, headers: {})
|
21
|
-
request(:get, path, nil, headers)
|
20
|
+
def get(path:, headers: {}, query: nil, max_retries: MAX_RETRIES)
|
21
|
+
request(:get, path, nil, headers, query, max_retries)
|
22
22
|
end
|
23
23
|
|
24
|
-
def post(path:, body:, headers: {}, query: nil)
|
25
|
-
request(:post, path, body, headers, query)
|
24
|
+
def post(path:, body:, headers: {}, query: nil, max_retries: MAX_RETRIES)
|
25
|
+
request(:post, path, body, headers, query, max_retries)
|
26
26
|
end
|
27
27
|
|
28
|
-
def put(path:, body:, headers: {})
|
29
|
-
request(:put, path, body, headers)
|
28
|
+
def put(path:, body:, headers: {}, max_retries: MAX_RETRIES)
|
29
|
+
request(:put, path, body, headers, nil, max_retries)
|
30
30
|
end
|
31
31
|
|
32
32
|
def close
|
@@ -35,7 +35,7 @@ module EmergeCLI
|
|
35
35
|
|
36
36
|
private
|
37
37
|
|
38
|
-
def request(method, path, body, custom_headers, query = nil)
|
38
|
+
def request(method, path, body, custom_headers, query = nil, max_retries = MAX_RETRIES)
|
39
39
|
uri = if path.start_with?('http')
|
40
40
|
URI.parse(path)
|
41
41
|
else
|
@@ -71,10 +71,10 @@ module EmergeCLI
|
|
71
71
|
response
|
72
72
|
rescue StandardError => e
|
73
73
|
retries += 1
|
74
|
-
if retries <=
|
74
|
+
if retries <= max_retries
|
75
75
|
delay = RETRY_DELAY * retries
|
76
76
|
error_message = e.message
|
77
|
-
Logger.warn "Request failed (attempt #{retries}/#{
|
77
|
+
Logger.warn "Request failed (attempt #{retries}/#{max_retries}): #{error_message}"
|
78
78
|
Logger.warn "Retrying in #{delay} seconds..."
|
79
79
|
|
80
80
|
begin
|
@@ -87,7 +87,9 @@ module EmergeCLI
|
|
87
87
|
sleep delay
|
88
88
|
retry
|
89
89
|
else
|
90
|
-
|
90
|
+
unless max_retries == 0
|
91
|
+
Logger.error "Request failed after #{max_retries} attempts: #{absolute_uri} #{e.message}"
|
92
|
+
end
|
91
93
|
raise e
|
92
94
|
end
|
93
95
|
end
|
data/lib/version.rb
CHANGED
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: emerge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emerge Tools
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-01-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async-http
|
@@ -24,6 +24,26 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.86.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: CFPropertyList
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.3'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 2.3.2
|
37
|
+
type: :runtime
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '2.3'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 2.3.2
|
27
47
|
- !ruby/object:Gem::Dependency
|
28
48
|
name: chunky_png
|
29
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +86,20 @@ dependencies:
|
|
66
86
|
- - "~>"
|
67
87
|
- !ruby/object:Gem::Version
|
68
88
|
version: 0.2.1
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: ruby-macho
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: 4.1.0
|
96
|
+
type: :runtime
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 4.1.0
|
69
103
|
- !ruby/object:Gem::Dependency
|
70
104
|
name: ruby_tree_sitter
|
71
105
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +114,20 @@ dependencies:
|
|
80
114
|
- - "~>"
|
81
115
|
- !ruby/object:Gem::Version
|
82
116
|
version: '1.9'
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: rubyzip
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - "~>"
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: 2.3.0
|
124
|
+
type: :runtime
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - "~>"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: 2.3.0
|
83
131
|
- !ruby/object:Gem::Dependency
|
84
132
|
name: tty-prompt
|
85
133
|
requirement: !ruby/object:Gem::Requirement
|
@@ -133,11 +181,21 @@ files:
|
|
133
181
|
- CHANGELOG.md
|
134
182
|
- README.md
|
135
183
|
- exe/emerge
|
184
|
+
- lib/commands/autofixes/exported_symbols.rb
|
185
|
+
- lib/commands/autofixes/minify_strings.rb
|
186
|
+
- lib/commands/autofixes/strip_binary_symbols.rb
|
187
|
+
- lib/commands/build_distribution/download_and_install.rb
|
188
|
+
- lib/commands/build_distribution/validate_app.rb
|
136
189
|
- lib/commands/config/orderfiles/orderfiles_ios.rb
|
137
190
|
- lib/commands/config/snapshots/snapshots_ios.rb
|
138
191
|
- lib/commands/global_options.rb
|
139
192
|
- lib/commands/integrate/fastlane.rb
|
193
|
+
- lib/commands/order_files/download_order_files.rb
|
194
|
+
- lib/commands/order_files/validate_linkmaps.rb
|
195
|
+
- lib/commands/order_files/validate_xcode_project.rb
|
140
196
|
- lib/commands/reaper/reaper.rb
|
197
|
+
- lib/commands/snapshots/validate_app.rb
|
198
|
+
- lib/commands/upload/build.rb
|
141
199
|
- lib/commands/upload/snapshots/client_libraries/default.rb
|
142
200
|
- lib/commands/upload/snapshots/client_libraries/paparazzi.rb
|
143
201
|
- lib/commands/upload/snapshots/client_libraries/roborazzi.rb
|
@@ -151,6 +209,7 @@ files:
|
|
151
209
|
- lib/utils/git_result.rb
|
152
210
|
- lib/utils/github.rb
|
153
211
|
- lib/utils/logger.rb
|
212
|
+
- lib/utils/macho_parser.rb
|
154
213
|
- lib/utils/network.rb
|
155
214
|
- lib/utils/profiler.rb
|
156
215
|
- lib/utils/project_detector.rb
|
@@ -160,6 +219,8 @@ files:
|
|
160
219
|
- parsers/libtree-sitter-java-linux-x86_64.so
|
161
220
|
- parsers/libtree-sitter-kotlin-darwin-arm64.dylib
|
162
221
|
- parsers/libtree-sitter-kotlin-linux-x86_64.so
|
222
|
+
- parsers/libtree-sitter-objc-darwin-arm64.dylib
|
223
|
+
- parsers/libtree-sitter-objc-linux-x86_64.so
|
163
224
|
- parsers/libtree-sitter-swift-darwin-arm64.dylib
|
164
225
|
- parsers/libtree-sitter-swift-linux-x86_64.so
|
165
226
|
homepage: https://github.com/EmergeTools/emerge-cli
|
@@ -170,7 +231,7 @@ metadata:
|
|
170
231
|
source_code_uri: https://github.com/EmergeTools/emerge-cli
|
171
232
|
changelog_uri: https://github.com/EmergeTools/emerge-cli/blob/main/CHANGELOG.md
|
172
233
|
rubygems_mfa_required: 'true'
|
173
|
-
post_install_message:
|
234
|
+
post_install_message:
|
174
235
|
rdoc_options: []
|
175
236
|
require_paths:
|
176
237
|
- lib
|
@@ -186,7 +247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
186
247
|
version: '0'
|
187
248
|
requirements: []
|
188
249
|
rubygems_version: 3.5.11
|
189
|
-
signing_key:
|
250
|
+
signing_key:
|
190
251
|
specification_version: 4
|
191
252
|
summary: Emerge CLI
|
192
253
|
test_files: []
|