appsendr 0.0.6 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest DELETED
@@ -1,25 +0,0 @@
1
- Manifest
2
- README.rdoc
3
- Rakefile
4
- bin/appsendr
5
- lib/appsendr.rb
6
- lib/appsendr/binary_plist.rb
7
- lib/appsendr/client.rb
8
- lib/appsendr/command.rb
9
- lib/appsendr/commands/app.rb
10
- lib/appsendr/commands/auth.rb
11
- lib/appsendr/commands/base.rb
12
- lib/appsendr/commands/build.rb
13
- lib/appsendr/commands/collaborators.rb
14
- lib/appsendr/commands/common.rb
15
- lib/appsendr/commands/deploy.rb
16
- lib/appsendr/commands/groups.rb
17
- lib/appsendr/commands/help.rb
18
- lib/appsendr/commands/portal.rb
19
- lib/appsendr/commands/testers.rb
20
- lib/appsendr/commands/version.rb
21
- lib/appsendr/constants.rb
22
- lib/appsendr/helpers.rb
23
- lib/appsendr/progressbar.rb
24
- portal.rb
25
- terms
@@ -1,49 +0,0 @@
1
- # == Synopsis
2
- # Ruby command-line app that interacts with Xcode and the AppSendr webservice
3
- #
4
- # == Examples
5
- # Calling this in a Xcode project directory will build the project with an active configuration of AdHoc
6
- # appsendr build AdHoc
7
- #
8
- # Other examples:
9
- # appsendr deploy AdHoc
10
- #
11
- # == Usage
12
- # appsendr [options]
13
- #
14
- #
15
- # == Author
16
- # Nolan Brown
17
- #
18
- # == Copyright
19
- # Copyright (c) 2010 Nolan Brown. Licensed under the MIT License:
20
- # http://www.opensource.org/licenses/mit-license.php
21
-
22
-
23
- === General Commands
24
-
25
- help # show this usage
26
- version # show the gem version
27
-
28
- list # list your apps
29
- link # link your app with an exsiting one in appsendr
30
- create <name> # create a new app
31
-
32
- url # get the latest version install url. pass --copy to copy to the clipboard
33
-
34
- build <active configuration> # build your xcode project and deploy
35
- build:clean # clean your xcode project
36
-
37
- deploy <active configuration> # deploy the current build. pass --notify to send notification to all testers
38
-
39
- testers # list testers
40
- testers:add <email> <name> # add a tester
41
- testers:remove <email> # remove a tester
42
- testers:clear # remove all testers
43
- testers:notify <group> # notify testers about the latest build. group is optional.
44
-
45
- groups # list groups
46
-
47
- collaborators # list collaborators
48
- collaborators:add <email> # add collaborators
49
- collaborators:remove <email> # add collaborators
@@ -1,494 +0,0 @@
1
- require "date"
2
- require "nkf"
3
- require "set"
4
- require "stringio"
5
-
6
- # Binary Plist implementation is from @schlueter
7
- # https://github.com/schlueter/Ipa-Reader/blob/master/lib/ipa_reader/plist_binary.rb
8
- #
9
-
10
- module AppSendr
11
- module Plist
12
- module Binary
13
- # Encodes +obj+ as a binary property list. If +obj+ is an Array, Hash, or
14
- # Set, the property list includes its contents.
15
- def self.binary_plist(obj)
16
- encoded_objs = flatten_collection(obj)
17
- ref_byte_size = min_byte_size(encoded_objs.length - 1)
18
- encoded_objs.collect! {|o| binary_plist_obj(o, ref_byte_size)}
19
- # Write header and encoded objects.
20
- plist = "bplist00" + encoded_objs.join
21
- # Write offset table.
22
- offset_table_addr = plist.length
23
- offset = 8
24
- offset_table = []
25
- encoded_objs.each do |o|
26
- offset_table << offset
27
- offset += o.length
28
- end
29
- offset_byte_size = min_byte_size(offset)
30
- offset_table.each do |offset|
31
- plist += pack_int(offset, offset_byte_size)
32
- end
33
- # Write trailer.
34
- plist += "\0\0\0\0\0\0" # Six unused bytes
35
- plist += [
36
- offset_byte_size,
37
- ref_byte_size,
38
- encoded_objs.length >> 32, encoded_objs.length & 0xffffffff,
39
- 0, 0, # Index of root object
40
- offset_table_addr >> 32, offset_table_addr & 0xffffffff
41
- ].pack("CCNNNNNN")
42
- plist
43
- end
44
-
45
- def self.decode_binary_plist(plist)
46
- # Check header.
47
- unless plist[0, 6] == "bplist"
48
- raise ArgumentError, "argument is not a binary property list"
49
- end
50
- version = plist[6, 2]
51
- unless version == "00"
52
- raise ArgumentError,
53
- "don't know how to decode format version #{version}"
54
- end
55
- # Read trailer.
56
- trailer = plist[-26, 26].unpack("CCNNNNNN")
57
- offset_byte_size = trailer[0]
58
- ref_byte_size = trailer[1]
59
- encoded_objs_length = combine_ints(32, trailer[2], trailer[3])
60
- root_index = combine_ints(32, trailer[4], trailer[5])
61
- offset_table_addr = combine_ints(32, trailer[6], trailer[7])
62
- # Decode objects.
63
- root_offset = offset_for_index(plist, offset_table_addr,
64
- offset_byte_size, root_index)
65
- root_obj = decode_binary_plist_obj(plist, root_offset, ref_byte_size)
66
- unflatten_collection(root_obj, [root_obj], plist, offset_table_addr,
67
- offset_byte_size, ref_byte_size)
68
- end
69
-
70
- private
71
-
72
- # These marker bytes are prefixed to objects in a binary property list to
73
- # indicate the type of the object.
74
- CFBinaryPlistMarkerNull = 0x00 # :nodoc:
75
- CFBinaryPlistMarkerFalse = 0x08 # :nodoc:
76
- CFBinaryPlistMarkerTrue = 0x09 # :nodoc:
77
- CFBinaryPlistMarkerFill = 0x0F # :nodoc:
78
- CFBinaryPlistMarkerInt = 0x10 # :nodoc:
79
- CFBinaryPlistMarkerReal = 0x20 # :nodoc:
80
- CFBinaryPlistMarkerDate = 0x33 # :nodoc:
81
- CFBinaryPlistMarkerData = 0x40 # :nodoc:
82
- CFBinaryPlistMarkerASCIIString = 0x50 # :nodoc:
83
- CFBinaryPlistMarkerUnicode16String = 0x60 # :nodoc:
84
- CFBinaryPlistMarkerUID = 0x80 # :nodoc:
85
- CFBinaryPlistMarkerArray = 0xA0 # :nodoc:
86
- CFBinaryPlistMarkerSet = 0xC0 # :nodoc:
87
- CFBinaryPlistMarkerDict = 0xD0 # :nodoc:
88
-
89
- # POSIX uses a reference time of 1970-01-01T00:00:00Z; Cocoa's reference
90
- # time is in 2001. This interval is for converting between the two.
91
- NSTimeIntervalSince1970 = 978307200.0 # :nodoc:
92
-
93
- # Takes an object (nominally a collection, like an Array, Set, or Hash, but
94
- # any object is acceptable) and flattens it into a one-dimensional array.
95
- # Non-collection objects appear in the array as-is, but the contents of
96
- # Arrays, Sets, and Hashes are modified like so: (1) The contents of the
97
- # collection are added, one-by-one, to the one-dimensional array. (2) The
98
- # collection itself is modified so that it contains indexes pointing to the
99
- # objects in the one-dimensional array. Here's an example with an Array:
100
- #
101
- # ary = [:a, :b, :c]
102
- # flatten_collection(ary) # => [[1, 2, 3], :a, :b, :c]
103
- #
104
- # In the case of a Hash, keys and values are both appended to the one-
105
- # dimensional array and then replaced with indexes.
106
- #
107
- # hsh = {:a => "blue", :b => "purple", :c => "green"}
108
- # flatten_collection(hsh)
109
- # # => [{1 => 2, 3 => 4, 5 => 6}, :a, "blue", :b, "purple", :c, "green"]
110
- #
111
- # An object will never be added to the one-dimensional array twice. If a
112
- # collection refers to an object more than once, the object will be added
113
- # to the one-dimensional array only once.
114
- #
115
- # ary = [:a, :a, :a]
116
- # flatten_collection(ary) # => [[1, 1, 1], :a]
117
- #
118
- # The +obj_list+ and +id_refs+ parameters are private; they're used for
119
- # descending into sub-collections recursively.
120
- def self.flatten_collection(collection, obj_list = [], id_refs = {})
121
- case collection
122
- when Array, Set
123
- if id_refs[collection.object_id]
124
- return obj_list[id_refs[collection.object_id]]
125
- end
126
- obj_refs = collection.class.new
127
- id_refs[collection.object_id] = obj_list.length
128
- obj_list << obj_refs
129
- collection.each do |obj|
130
- flatten_collection(obj, obj_list, id_refs)
131
- obj_refs << id_refs[obj.object_id]
132
- end
133
- return obj_list
134
- when Hash
135
- if id_refs[collection.object_id]
136
- return obj_list[id_refs[collection.object_id]]
137
- end
138
- obj_refs = {}
139
- id_refs[collection.object_id] = obj_list.length
140
- obj_list << obj_refs
141
- collection.each do |key, value|
142
- key = key.to_s if key.is_a?(Symbol)
143
- flatten_collection(key, obj_list, id_refs)
144
- flatten_collection(value, obj_list, id_refs)
145
- obj_refs[id_refs[key.object_id]] = id_refs[value.object_id]
146
- end
147
- return obj_list
148
- else
149
- unless id_refs[collection.object_id]
150
- id_refs[collection.object_id] = obj_list.length
151
- obj_list << collection
152
- end
153
- return obj_list
154
- end
155
- end
156
-
157
- def self.unflatten_collection(collection, obj_list, plist,
158
- offset_table_addr, offset_byte_size, ref_byte_size)
159
- case collection
160
- when Array, Set
161
- collection.collect! do |index|
162
- if obj = obj_list[index]
163
- obj
164
- else
165
- offset = offset_for_index(plist, offset_table_addr, offset_byte_size,
166
- index)
167
- obj = decode_binary_plist_obj(plist, offset, ref_byte_size)
168
- obj_list[index] = obj
169
- unflatten_collection(obj, obj_list, plist, offset_table_addr,
170
- offset_byte_size, ref_byte_size)
171
- end
172
- end
173
- when Hash
174
- hsh = {}
175
- collection.each do |key, value|
176
- unless key_obj = obj_list[key]
177
- offset = offset_for_index(plist, offset_table_addr, offset_byte_size,
178
- key)
179
- key_obj = decode_binary_plist_obj(plist, offset, ref_byte_size)
180
- obj_list[key] = key_obj
181
- key_obj = unflatten_collection(key_obj, obj_list, plist,
182
- offset_table_addr, offset_byte_size, ref_byte_size)
183
- end
184
- unless value_obj = obj_list[value]
185
- offset = offset_for_index(plist, offset_table_addr, offset_byte_size,
186
- value)
187
- value_obj = decode_binary_plist_obj(plist, offset, ref_byte_size)
188
- obj_list[value] = value_obj
189
- value_obj = unflatten_collection(value_obj, obj_list, plist,
190
- offset_table_addr, offset_byte_size, ref_byte_size)
191
- end
192
- hsh[key_obj] = value_obj
193
- end
194
- collection.replace(hsh)
195
- end
196
- return collection
197
- end
198
-
199
- # Returns a binary property list fragment that represents +obj+. The
200
- # returned string is not a complete property list, just a fragment that
201
- # describes +obj+, and is not useful without a header, offset table, and
202
- # trailer.
203
- #
204
- # The following classes are recognized: String, Float, Integer, the Boolean
205
- # classes, Time, IO, StringIO, Array, Set, and Hash. IO and StringIO
206
- # objects are rewound, read, and the contents stored as data (i.e., Cocoa
207
- # applications will decode them as NSData). All other classes are dumped
208
- # with Marshal and stored as data.
209
- #
210
- # Note that subclasses of the supported classes will be encoded as though
211
- # they were the supported superclass. Thus, a subclass of (for example)
212
- # String will be encoded and decoded as a String, not as the subclass:
213
- #
214
- # class ExampleString < String
215
- # ...
216
- # end
217
- #
218
- # s = ExampleString.new("disquieting plantlike mystery")
219
- # encoded_s = binary_plist_obj(s)
220
- # decoded_s = decode_binary_plist_obj(encoded_s)
221
- # puts decoded_s.class # => String
222
- #
223
- # +ref_byte_size+ is the number of bytes to use for storing references to
224
- # other objects.
225
- def self.binary_plist_obj(obj, ref_byte_size = 4)
226
- case obj
227
- when String
228
- obj = obj.to_s if obj.is_a?(Symbol)
229
- # This doesn't really work. NKF's guess method is really, really bad
230
- # at discovering UTF8 when only a handful of characters are multi-byte.
231
- encoding = NKF.guess2(obj)
232
- if encoding == NKF::ASCII && obj =~ /[\x80-\xff]/
233
- encoding = NKF::UTF8
234
- end
235
- if [NKF::ASCII, NKF::BINARY, NKF::UNKNOWN].include?(encoding)
236
- result = (CFBinaryPlistMarkerASCIIString |
237
- (obj.length < 15 ? obj.length : 0xf)).chr
238
- result += binary_plist_obj(obj.length) if obj.length >= 15
239
- result += obj
240
- return result
241
- else
242
- # Convert to UTF8.
243
- if encoding == NKF::UTF8
244
- utf8 = obj
245
- else
246
- utf8 = NKF.nkf("-m0 -w", obj)
247
- end
248
- # Decode each character's UCS codepoint.
249
- codepoints = []
250
- i = 0
251
- while i < utf8.length
252
- byte = utf8[i]
253
- if byte & 0xe0 == 0xc0
254
- codepoints << ((byte & 0x1f) << 6) + (utf8[i+1] & 0x3f)
255
- i += 1
256
- elsif byte & 0xf0 == 0xe0
257
- codepoints << ((byte & 0xf) << 12) + ((utf8[i+1] & 0x3f) << 6) +
258
- (utf8[i+2] & 0x3f)
259
- i += 2
260
- elsif byte & 0xf8 == 0xf0
261
- codepoints << ((byte & 0xe) << 18) + ((utf8[i+1] & 0x3f) << 12) +
262
- ((utf8[i+2] & 0x3f) << 6) + (utf8[i+3] & 0x3f)
263
- i += 3
264
- else
265
- codepoints << byte
266
- end
267
- if codepoints.last > 0xffff
268
- raise(ArgumentError, "codepoint too high - only the Basic Multilingual Plane can be encoded")
269
- end
270
- i += 1
271
- end
272
- # Return string of 16-bit codepoints.
273
- data = codepoints.pack("n*")
274
- result = (CFBinaryPlistMarkerUnicode16String |
275
- (codepoints.length < 15 ? codepoints.length : 0xf)).chr
276
- result += binary_plist_obj(codepoints.length) if codepoints.length >= 15
277
- result += data
278
- return result
279
- end
280
- when Float
281
- return (CFBinaryPlistMarkerReal | 3).chr + [obj].pack("G")
282
- when Integer
283
- nbytes = min_byte_size(obj)
284
- size_bits = { 1 => 0, 2 => 1, 4 => 2, 8 => 3, 16 => 4 }[nbytes]
285
- return (CFBinaryPlistMarkerInt | size_bits).chr + pack_int(obj, nbytes)
286
- when TrueClass
287
- return CFBinaryPlistMarkerTrue.chr
288
- when FalseClass
289
- return CFBinaryPlistMarkerFalse.chr
290
- when Time
291
- return CFBinaryPlistMarkerDate.chr +
292
- [obj.to_f - NSTimeIntervalSince1970].pack("G")
293
- when IO, StringIO
294
- obj.rewind
295
- return binary_plist_data(obj.read)
296
- when Array
297
- # Must be an array of object references as returned by flatten_collection.
298
- result = (CFBinaryPlistMarkerArray | (obj.length < 15 ? obj.length : 0xf)).chr
299
- result += binary_plist_obj(obj.length) if obj.length >= 15
300
- result += obj.collect! { |i| pack_int(i, ref_byte_size) }.join
301
- when Set
302
- # Must be a set of object references as returned by flatten_collection.
303
- result = (CFBinaryPlistMarkerSet | (obj.length < 15 ? obj.length : 0xf)).chr
304
- result += binary_plist_obj(obj.length) if obj.length >= 15
305
- result += obj.to_a.collect! { |i| pack_int(i, ref_byte_size) }.join
306
- when Hash
307
- # Must be a table of object references as returned by flatten_collection.
308
- result = (CFBinaryPlistMarkerDict | (obj.length < 15 ? obj.length : 0xf)).chr
309
- result += binary_plist_obj(obj.length) if obj.length >= 15
310
- result += obj.keys.collect! { |i| pack_int(i, ref_byte_size) }.join
311
- result += obj.values.collect! { |i| pack_int(i, ref_byte_size) }.join
312
- else
313
- return binary_plist_data(Marshal.dump(obj))
314
- end
315
- end
316
-
317
- def self.decode_binary_plist_obj(plist, offset, ref_byte_size)
318
- case plist[offset]
319
- when CFBinaryPlistMarkerASCIIString..(CFBinaryPlistMarkerASCIIString | 0xf)
320
- length, offset = decode_length(plist, offset)
321
- return plist[offset, length]
322
- when CFBinaryPlistMarkerUnicode16String..(CFBinaryPlistMarkerUnicode16String | 0xf)
323
- length, offset = decode_length(plist, offset)
324
- codepoints = plist[offset, length * 2].unpack("n*")
325
- str = ""
326
- codepoints.each do |codepoint|
327
- if codepoint <= 0x7f
328
- ch = ' '
329
- ch[0] = to_i
330
- elsif codepoint <= 0x7ff
331
- ch = ' '
332
- ch[0] = ((codepoint & 0x7c0) >> 6) | 0xc0
333
- ch[1] = codepoint & 0x3f | 0x80
334
- else
335
- ch = ' '
336
- ch[0] = ((codepoint & 0xf000) >> 12) | 0xe0
337
- ch[1] = ((codepoint & 0xfc0) >> 6) | 0x80
338
- ch[2] = codepoint & 0x3f | 0x80
339
- end
340
- str << ch
341
- end
342
- return str
343
- when CFBinaryPlistMarkerReal | 3
344
- return plist[offset+1, 8].unpack("G").first
345
- when CFBinaryPlistMarkerInt..(CFBinaryPlistMarkerInt | 0xf)
346
- num_bytes = 2 ** (plist[offset] & 0xf)
347
- return unpack_int(plist[offset+1, num_bytes])
348
- when CFBinaryPlistMarkerTrue
349
- return true
350
- when CFBinaryPlistMarkerFalse
351
- return false
352
- when CFBinaryPlistMarkerDate
353
- secs = plist[offset+1, 8].unpack("G").first + NSTimeIntervalSince1970
354
- return Time.at(secs)
355
- when CFBinaryPlistMarkerData..(CFBinaryPlistMarkerData | 0xf)
356
- length, offset = decode_length(plist, offset)
357
- return StringIO.new(plist[offset, length])
358
- when CFBinaryPlistMarkerArray..(CFBinaryPlistMarkerArray | 0xf)
359
- ary = []
360
- length, offset = decode_length(plist, offset)
361
- length.times do
362
- ary << unpack_int(plist[offset, ref_byte_size])
363
- offset += ref_byte_size
364
- end
365
- return ary
366
- when CFBinaryPlistMarkerDict..(CFBinaryPlistMarkerDict | 0xf)
367
- hsh = {}
368
- keys = []
369
- length, offset = decode_length(plist, offset)
370
- length.times do
371
- keys << unpack_int(plist[offset, ref_byte_size])
372
- offset += ref_byte_size
373
- end
374
- length.times do |i|
375
- hsh[keys[i]] = unpack_int(plist[offset, ref_byte_size])
376
- offset += ref_byte_size
377
- end
378
- return hsh
379
- end
380
- end
381
-
382
- # Returns a binary property list fragment that represents a data object
383
- # with the contents of the string +data+. A Cocoa application would decode
384
- # this fragment as NSData. Like binary_plist_obj, the value returned by
385
- # this method is not usable by itself; it is only useful as part of a
386
- # complete binary property list with a header, offset table, and trailer.
387
- def self.binary_plist_data(data)
388
- result = (CFBinaryPlistMarkerData |
389
- (data.length < 15 ? data.length : 0xf)).chr
390
- result += binary_plist_obj(data.length) if data.length > 15
391
- result += data
392
- return result
393
- end
394
-
395
- # Determines the minimum number of bytes that is a power of two and can
396
- # represent the integer +i+. Raises a RangeError if the number of bytes
397
- # exceeds 16. Note that the property list format considers integers of 1,
398
- # 2, and 4 bytes to be unsigned, while 8- and 16-byte integers are signed;
399
- # thus negative integers will always require at least 8 bytes of storage.
400
- def self.min_byte_size(i)
401
- if i < 0
402
- i = i.abs - 1
403
- else
404
- if i <= 0xff
405
- return 1
406
- elsif i <= 0xffff
407
- return 2
408
- elsif i <= 0xffffffff
409
- return 4
410
- end
411
- end
412
- if i <= 0x7fffffffffffffff
413
- return 8
414
- elsif i <= 0x7fffffffffffffffffffffffffffffff
415
- return 16
416
- end
417
- raise(RangeError, "integer too big - exceeds 128 bits")
418
- end
419
-
420
- # Packs an integer +i+ into its binary representation in the specified
421
- # number of bytes. Byte order is big-endian. Negative integers cannot be
422
- # stored in 1, 2, or 4 bytes.
423
- def self.pack_int(i, num_bytes)
424
- if i < 0 && num_bytes < 8
425
- raise(ArgumentError, "negative integers require 8 or 16 bytes of storage")
426
- end
427
- case num_bytes
428
- when 1
429
- [i].pack("c")
430
- when 2
431
- [i].pack("n")
432
- when 4
433
- [i].pack("N")
434
- when 8
435
- [(i >> 32) & 0xffffffff, i & 0xffffffff].pack("NN")
436
- when 16
437
- [i >> 96, (i >> 64) & 0xffffffff, (i >> 32) & 0xffffffff,
438
- i & 0xffffffff].pack("NNNN")
439
- else
440
- raise(ArgumentError, "num_bytes must be 1, 2, 4, 8, or 16")
441
- end
442
- end
443
-
444
- def self.combine_ints(num_bits, *ints)
445
- i = ints.pop
446
- shift_bits = num_bits
447
- ints.reverse.each do |i_part|
448
- i += i_part << shift_bits
449
- shift_bits += num_bits
450
- end
451
- return i
452
- end
453
-
454
- def self.offset_for_index(plist, table_addr, offset_byte_size, index)
455
- offset = plist[table_addr + index * offset_byte_size, offset_byte_size]
456
- unpack_int(offset)
457
- end
458
-
459
- def self.unpack_int(s)
460
- case s.length
461
- when 1
462
- s.unpack("C").first
463
- when 2
464
- s.unpack("n").first
465
- when 4
466
- s.unpack("N").first
467
- when 8
468
- i = combine_ints(32, *(s.unpack("NN")))
469
- (i & 0x80000000_00000000 == 0) ?
470
- i :
471
- -(i ^ 0xffffffff_ffffffff) - 1
472
- when 16
473
- i = combine_ints(32, *(s.unpack("NNNN")))
474
- (i & 0x80000000_00000000_00000000_00000000 == 0) ?
475
- i :
476
- -(i ^ 0xffffffff_ffffffff_ffffffff_ffffffff) - 1
477
- else
478
- raise(ArgumentError, "length must be 1, 2, 4, 8, or 16 bytes")
479
- end
480
- end
481
-
482
- def self.decode_length(plist, offset)
483
- if plist[offset] & 0xf == 0xf
484
- offset += 1
485
- length = decode_binary_plist_obj(plist, offset, 0)
486
- offset += min_byte_size(length) + 1
487
- return length, offset
488
- else
489
- return (plist[offset] & 0xf), (offset + 1)
490
- end
491
- end
492
- end
493
- end
494
- end