cupertino 0.3.3 → 0.4.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.
- data/Gemfile.lock +1 -1
- data/README.md +8 -2
- data/bin/ios +0 -2
- data/lib/cupertino/provisioning_portal/agent.rb +86 -5
- data/lib/cupertino/provisioning_portal/commands/certificates.rb +20 -0
- data/lib/cupertino/provisioning_portal/commands/profiles.rb +38 -0
- data/lib/cupertino/provisioning_portal/commands.rb +6 -8
- data/lib/cupertino/provisioning_portal.rb +28 -11
- data/lib/cupertino.rb +1 -1
- metadata +73 -120
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -51,6 +51,12 @@ $ ios profiles:list
|
|
51
51
|
+----------------------------------+--------------+---------+
|
52
52
|
```
|
53
53
|
|
54
|
+
```sh
|
55
|
+
$ ios profiles:manage:devices
|
56
|
+
```
|
57
|
+
|
58
|
+
_Opens an editor with a list of devices, each of which can be commented or uncommented to turn them off or on for that provisioning profile._
|
59
|
+
|
54
60
|
### App IDs
|
55
61
|
|
56
62
|
```sh
|
@@ -92,12 +98,12 @@ _Crossed out commands are not yet implemented_
|
|
92
98
|
- ~~`devices:remove`~~
|
93
99
|
|
94
100
|
- `profiles:list`
|
101
|
+
- `profiles:manage:devices`
|
95
102
|
- ~~`profiles:add`~~
|
96
103
|
- ~~`profiles:edit`~~
|
97
104
|
|
98
105
|
- `certificates:list [development|distribution]`
|
99
|
-
-
|
100
|
-
- ~~`certificates:download CERTIFICATE_NAME`~~
|
106
|
+
- `certificates:download CERTIFICATE_NAME`
|
101
107
|
- ~~`certificates:revoke CERTIFICATE_NAME`~~
|
102
108
|
|
103
109
|
- `app_ids:list`
|
data/bin/ios
CHANGED
@@ -10,13 +10,17 @@ module Cupertino
|
|
10
10
|
super
|
11
11
|
self.user_agent_alias = 'Mac Safari'
|
12
12
|
|
13
|
-
@username, @password = Netrc.read[
|
13
|
+
@username, @password = Netrc.read[Cupertino::HOSTNAME]
|
14
14
|
end
|
15
15
|
|
16
16
|
def get(uri, parameters = [], referer = nil, headers = {})
|
17
|
+
uri = ::File.join("https://#{Cupertino::HOSTNAME}", uri) unless /^https?/ === uri
|
18
|
+
|
17
19
|
3.times do
|
18
20
|
super(uri, parameters, referer, headers)
|
19
21
|
|
22
|
+
return page unless page.respond_to?(:title)
|
23
|
+
|
20
24
|
case page.title
|
21
25
|
when %r{Sign in with your Apple ID}
|
22
26
|
login! and redo
|
@@ -46,6 +50,7 @@ module Cupertino
|
|
46
50
|
page.parser.xpath('//div[@class="nt_multi"]/table/tbody/tr').each do |row|
|
47
51
|
certificate = Certificate.new
|
48
52
|
certificate.name = row.at_xpath('td[@class="name"]//p/text()').to_s.strip rescue nil
|
53
|
+
certificate.type = type
|
49
54
|
certificate.provisioning_profiles = row.at_xpath('td[@class="profiles"]/text()').to_s.strip.split(/\n+/) rescue []
|
50
55
|
certificate.expiration_date = row.at_xpath('td[@class="date"]/text()').to_s.strip rescue nil
|
51
56
|
certificate.status = row.at_xpath('td[@class="status"]/text()').to_s.strip rescue nil
|
@@ -54,6 +59,25 @@ module Cupertino
|
|
54
59
|
certificates
|
55
60
|
end
|
56
61
|
|
62
|
+
def download_certificate(certificate)
|
63
|
+
list_certificates(certificate.type)
|
64
|
+
|
65
|
+
page.parser.xpath('//div[@class="nt_multi"]/table/tbody/tr').each do |row|
|
66
|
+
name = row.at_xpath('td[@class="name"]//p/text()').to_s.strip rescue nil
|
67
|
+
|
68
|
+
if name == certificate.name
|
69
|
+
download_url = row.at_xpath('td[@class="last"]/a')['href'].to_s.strip rescue nil
|
70
|
+
|
71
|
+
self.pluggable_parser.default = Mechanize::Download
|
72
|
+
download = get(download_url)
|
73
|
+
download.save
|
74
|
+
return download.filename
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
return nil
|
79
|
+
end
|
80
|
+
|
57
81
|
def list_devices
|
58
82
|
get("https://developer.apple.com/ios/manage/devices/index.action")
|
59
83
|
|
@@ -65,7 +89,6 @@ module Cupertino
|
|
65
89
|
devices << device
|
66
90
|
end
|
67
91
|
|
68
|
-
|
69
92
|
if message = page.parser.at_xpath('//p[@class="devicesannounce"]/strong/text()').to_s.strip rescue nil
|
70
93
|
number_of_devices_available = message.scan(/\d{1,3}/).first.to_i
|
71
94
|
number_of_devices_available.times do
|
@@ -114,7 +137,8 @@ module Cupertino
|
|
114
137
|
profiles = []
|
115
138
|
page.parser.xpath('//fieldset[@id="fs-0"]/table/tbody/tr').each do |row|
|
116
139
|
profile = ProvisioningProfile.new
|
117
|
-
profile.name = row.at_xpath('td[@class="profile"]
|
140
|
+
profile.name = row.at_xpath('td[@class="profile"]//text()').to_s.strip rescue nil
|
141
|
+
profile.type = type
|
118
142
|
profile.app_id = row.at_xpath('td[@class="appid"]/text()').to_s.strip rescue nil
|
119
143
|
profile.status = row.at_xpath('td[@class="statusXcode"]/text()').to_s.strip rescue nil
|
120
144
|
profiles << profile
|
@@ -122,6 +146,63 @@ module Cupertino
|
|
122
146
|
profiles
|
123
147
|
end
|
124
148
|
|
149
|
+
def manage_devices_for_profile(profile)
|
150
|
+
raise ArgumentError unless block_given?
|
151
|
+
|
152
|
+
list_profiles(profile.type)
|
153
|
+
|
154
|
+
modify_url = nil
|
155
|
+
page.parser.xpath('//fieldset[@id="fs-0"]/table/tbody/tr').each do |row|
|
156
|
+
break if modify_url
|
157
|
+
|
158
|
+
name = row.at_xpath('td[@class="profile"]//text()').to_s.strip rescue nil
|
159
|
+
|
160
|
+
if name == profile.name
|
161
|
+
row.css('td.action a').each do |a|
|
162
|
+
if /edit\.action/ === a['href']
|
163
|
+
modify_url = a['href']
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
if modify_url
|
170
|
+
get(modify_url)
|
171
|
+
|
172
|
+
on, off = [], []
|
173
|
+
page.parser.css('.checkboxlist.last td').each do |td|
|
174
|
+
checkbox = td.at_xpath('input[@type="checkbox"]')
|
175
|
+
|
176
|
+
device = Device.new
|
177
|
+
device.name = td.at_xpath('label/text()').to_s.strip rescue nil
|
178
|
+
device.udid = checkbox['value'].to_s.strip rescue nil
|
179
|
+
|
180
|
+
if checkbox['checked']
|
181
|
+
on << device
|
182
|
+
else
|
183
|
+
off << device
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
devices = yield on, off
|
188
|
+
|
189
|
+
form = page.form_with(:name => 'save')
|
190
|
+
form.checkboxes_with(:name => "selectedDevices").each do |checkbox|
|
191
|
+
checkbox.check
|
192
|
+
if devices.detect{|device| device.udid == checkbox['value']}
|
193
|
+
checkbox.check
|
194
|
+
else
|
195
|
+
checkbox.uncheck
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
button = form.button_with(:name => 'submit')
|
200
|
+
form.click_button(button)
|
201
|
+
end
|
202
|
+
|
203
|
+
return nil
|
204
|
+
end
|
205
|
+
|
125
206
|
def list_app_ids
|
126
207
|
get("https://developer.apple.com/ios/manage/bundles/index.action")
|
127
208
|
|
@@ -159,8 +240,8 @@ module Cupertino
|
|
159
240
|
team_option = team_list.option_with(:text => self.team)
|
160
241
|
team_option.select
|
161
242
|
|
162
|
-
|
163
|
-
form.click_button(
|
243
|
+
button = form.button_with(:name => 'action:saveTeamSelection!save')
|
244
|
+
form.click_button(button)
|
164
245
|
end
|
165
246
|
end
|
166
247
|
end
|
@@ -29,3 +29,23 @@ command :'certificates:list' do |c|
|
|
29
29
|
end
|
30
30
|
|
31
31
|
alias_command :certificates, :'certificates:list'
|
32
|
+
|
33
|
+
command :'certificates:download' do |c|
|
34
|
+
c.syntax = 'ios certificates:download [development|distribution]'
|
35
|
+
c.summary = 'Downloads the Certificates'
|
36
|
+
c.description = ''
|
37
|
+
|
38
|
+
c.action do |args, options|
|
39
|
+
type = args.first.downcase.to_sym rescue nil
|
40
|
+
certificates = try{agent.list_certificates(type ||= :development)}
|
41
|
+
|
42
|
+
say_warning "No #{type} certificates found." and abort if certificates.empty?
|
43
|
+
|
44
|
+
certificate = choose "Select a certificate to download:", *certificates
|
45
|
+
if filename = agent.download_certificate(certificate)
|
46
|
+
say_ok "Successfully downloaded: '#{filename}'"
|
47
|
+
else
|
48
|
+
say_error "Could not download certificate"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -29,3 +29,41 @@ command :'profiles:list' do |c|
|
|
29
29
|
end
|
30
30
|
|
31
31
|
alias_command :profiles, :'profiles:list'
|
32
|
+
|
33
|
+
command :'profiles:manage:devices' do |c|
|
34
|
+
c.syntax = 'ios profiles:manage:devices'
|
35
|
+
c.summary = 'Manage active devices for a development provisioning profile'
|
36
|
+
c.description = ''
|
37
|
+
|
38
|
+
c.action do |args, options|
|
39
|
+
type = args.first.downcase.to_sym rescue nil
|
40
|
+
profiles = try{agent.list_profiles(:development)}
|
41
|
+
|
42
|
+
say_warning "No #{type} provisioning profiles found." and abort if profiles.empty?
|
43
|
+
|
44
|
+
profile = choose "Select a provisioning profile to manage:", *profiles
|
45
|
+
|
46
|
+
agent.manage_devices_for_profile(profile) do |on, off|
|
47
|
+
lines = ["# Comment / Uncomment Devices to Turn Off / On for Provisioning Profile"]
|
48
|
+
lines += on.collect{|device| "#{device}"}
|
49
|
+
lines += off.collect{|device| "# #{device}"}
|
50
|
+
result = ask_editor lines.join("\n")
|
51
|
+
|
52
|
+
devices = []
|
53
|
+
result.split(/\n+/).each do |line|
|
54
|
+
next if /^\#/ === line
|
55
|
+
components = line.split(/\s+/)
|
56
|
+
device = Device.new
|
57
|
+
device.udid = components.pop
|
58
|
+
device.name = components.join(" ")
|
59
|
+
devices << device
|
60
|
+
end
|
61
|
+
|
62
|
+
devices
|
63
|
+
end
|
64
|
+
|
65
|
+
say_ok "Successfully managed devices"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
alias_command :'profiles:manage', :'profiles:manage:devices'
|
@@ -1,11 +1,9 @@
|
|
1
1
|
include Cupertino::ProvisioningPortal
|
2
2
|
include Cupertino::ProvisioningPortal::Helpers
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
require 'commands/
|
7
|
-
require 'commands/
|
8
|
-
require 'commands/
|
9
|
-
require 'commands/
|
10
|
-
require 'commands/login'
|
11
|
-
require 'commands/logout'
|
4
|
+
require 'cupertino/provisioning_portal/commands/certificates'
|
5
|
+
require 'cupertino/provisioning_portal/commands/devices'
|
6
|
+
require 'cupertino/provisioning_portal/commands/profiles'
|
7
|
+
require 'cupertino/provisioning_portal/commands/app_ids'
|
8
|
+
require 'cupertino/provisioning_portal/commands/login'
|
9
|
+
require 'cupertino/provisioning_portal/commands/logout'
|
@@ -1,18 +1,35 @@
|
|
1
1
|
require 'mechanize'
|
2
2
|
|
3
3
|
module Cupertino
|
4
|
-
module ProvisioningPortal
|
5
|
-
class Device < Struct.new(:name, :udid)
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
module ProvisioningPortal
|
5
|
+
class Device < Struct.new(:name, :udid)
|
6
|
+
def to_s
|
7
|
+
"#{self.name} #{self.udid}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Certificate < Struct.new(:name, :type, :provisioning_profiles, :expiration_date, :status)
|
12
|
+
def to_s
|
13
|
+
"#{self.name}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class AppID < Struct.new(:bundle_seed_id, :description, :development_properties, :distribution_properties)
|
18
|
+
def to_s
|
19
|
+
"#{self.bundle_seed_id}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class ProvisioningProfile < Struct.new(:name, :type, :app_id, :status)
|
24
|
+
def to_s
|
25
|
+
"#{self.name}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
10
29
|
class UnsuccessfulAuthenticationError < RuntimeError; end
|
11
30
|
end
|
12
31
|
end
|
13
32
|
|
14
|
-
|
15
|
-
|
16
|
-
require 'provisioning_portal/
|
17
|
-
require 'provisioning_portal/agent'
|
18
|
-
require 'provisioning_portal/commands'
|
33
|
+
require 'cupertino/provisioning_portal/helpers'
|
34
|
+
require 'cupertino/provisioning_portal/agent'
|
35
|
+
require 'cupertino/provisioning_portal/commands'
|
data/lib/cupertino.rb
CHANGED
metadata
CHANGED
@@ -1,143 +1,100 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: cupertino
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 3
|
9
|
-
- 3
|
10
|
-
version: 0.3.3
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Mattt Thompson
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
type: :development
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
12
|
+
date: 2012-07-15 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &70144971248520 !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
18
|
+
requirements:
|
26
19
|
- - ~>
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
hash: 5
|
29
|
-
segments:
|
30
|
-
- 0
|
31
|
-
- 6
|
32
|
-
- 1
|
20
|
+
- !ruby/object:Gem::Version
|
33
21
|
version: 0.6.1
|
34
|
-
name: rspec
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
prerelease: false
|
38
22
|
type: :development
|
39
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70144971248520
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &70144972093640 !ruby/object:Gem::Requirement
|
40
28
|
none: false
|
41
|
-
requirements:
|
29
|
+
requirements:
|
42
30
|
- - ~>
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
hash: 63
|
45
|
-
segments:
|
46
|
-
- 0
|
47
|
-
- 9
|
48
|
-
- 2
|
31
|
+
- !ruby/object:Gem::Version
|
49
32
|
version: 0.9.2
|
50
|
-
|
51
|
-
version_requirements: *id002
|
52
|
-
- !ruby/object:Gem::Dependency
|
33
|
+
type: :development
|
53
34
|
prerelease: false
|
54
|
-
|
55
|
-
|
35
|
+
version_requirements: *70144972093640
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: commander
|
38
|
+
requirement: &70144974129360 !ruby/object:Gem::Requirement
|
56
39
|
none: false
|
57
|
-
requirements:
|
40
|
+
requirements:
|
58
41
|
- - ~>
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
hash: 63
|
61
|
-
segments:
|
62
|
-
- 4
|
63
|
-
- 1
|
64
|
-
- 2
|
42
|
+
- !ruby/object:Gem::Version
|
65
43
|
version: 4.1.2
|
66
|
-
name: commander
|
67
|
-
version_requirements: *id003
|
68
|
-
- !ruby/object:Gem::Dependency
|
69
|
-
prerelease: false
|
70
44
|
type: :runtime
|
71
|
-
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70144974129360
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: terminal-table
|
49
|
+
requirement: &70144974134820 !ruby/object:Gem::Requirement
|
72
50
|
none: false
|
73
|
-
requirements:
|
51
|
+
requirements:
|
74
52
|
- - ~>
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
hash: 13
|
77
|
-
segments:
|
78
|
-
- 1
|
79
|
-
- 4
|
80
|
-
- 5
|
53
|
+
- !ruby/object:Gem::Version
|
81
54
|
version: 1.4.5
|
82
|
-
name: terminal-table
|
83
|
-
version_requirements: *id004
|
84
|
-
- !ruby/object:Gem::Dependency
|
85
|
-
prerelease: false
|
86
55
|
type: :runtime
|
87
|
-
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70144974134820
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: term-ansicolor
|
60
|
+
requirement: &70144975372120 !ruby/object:Gem::Requirement
|
88
61
|
none: false
|
89
|
-
requirements:
|
62
|
+
requirements:
|
90
63
|
- - ~>
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
hash: 25
|
93
|
-
segments:
|
94
|
-
- 1
|
95
|
-
- 0
|
96
|
-
- 7
|
64
|
+
- !ruby/object:Gem::Version
|
97
65
|
version: 1.0.7
|
98
|
-
name: term-ansicolor
|
99
|
-
version_requirements: *id005
|
100
|
-
- !ruby/object:Gem::Dependency
|
101
|
-
prerelease: false
|
102
66
|
type: :runtime
|
103
|
-
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70144975372120
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mechanize
|
71
|
+
requirement: &70144976016960 !ruby/object:Gem::Requirement
|
104
72
|
none: false
|
105
|
-
requirements:
|
73
|
+
requirements:
|
106
74
|
- - ~>
|
107
|
-
- !ruby/object:Gem::Version
|
108
|
-
hash: 25
|
109
|
-
segments:
|
110
|
-
- 2
|
111
|
-
- 5
|
112
|
-
- 1
|
75
|
+
- !ruby/object:Gem::Version
|
113
76
|
version: 2.5.1
|
114
|
-
name: mechanize
|
115
|
-
version_requirements: *id006
|
116
|
-
- !ruby/object:Gem::Dependency
|
117
|
-
prerelease: false
|
118
77
|
type: :runtime
|
119
|
-
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70144976016960
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: netrc
|
82
|
+
requirement: &70144976088360 !ruby/object:Gem::Requirement
|
120
83
|
none: false
|
121
|
-
requirements:
|
84
|
+
requirements:
|
122
85
|
- - ~>
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
hash: 7
|
125
|
-
segments:
|
126
|
-
- 0
|
127
|
-
- 7
|
128
|
-
- 2
|
86
|
+
- !ruby/object:Gem::Version
|
129
87
|
version: 0.7.2
|
130
|
-
|
131
|
-
|
88
|
+
type: :runtime
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *70144976088360
|
132
91
|
description: A command-line interface for the iOS Provisioning Portal
|
133
92
|
email: m@mattt.me
|
134
|
-
executables:
|
93
|
+
executables:
|
135
94
|
- ios
|
136
95
|
extensions: []
|
137
|
-
|
138
96
|
extra_rdoc_files: []
|
139
|
-
|
140
|
-
files:
|
97
|
+
files:
|
141
98
|
- ./cupertino.gemspec
|
142
99
|
- ./Gemfile
|
143
100
|
- ./Gemfile.lock
|
@@ -158,36 +115,32 @@ files:
|
|
158
115
|
- bin/ios
|
159
116
|
homepage: http://mattt.me
|
160
117
|
licenses: []
|
161
|
-
|
162
118
|
post_install_message:
|
163
119
|
rdoc_options: []
|
164
|
-
|
165
|
-
require_paths:
|
120
|
+
require_paths:
|
166
121
|
- lib
|
167
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
168
123
|
none: false
|
169
|
-
requirements:
|
170
|
-
- -
|
171
|
-
- !ruby/object:Gem::Version
|
172
|
-
|
173
|
-
segments:
|
124
|
+
requirements:
|
125
|
+
- - ! '>='
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
segments:
|
174
129
|
- 0
|
175
|
-
|
176
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
hash: 3169719571408403656
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
177
132
|
none: false
|
178
|
-
requirements:
|
179
|
-
- -
|
180
|
-
- !ruby/object:Gem::Version
|
181
|
-
|
182
|
-
segments:
|
133
|
+
requirements:
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
segments:
|
183
138
|
- 0
|
184
|
-
|
139
|
+
hash: 3169719571408403656
|
185
140
|
requirements: []
|
186
|
-
|
187
141
|
rubyforge_project:
|
188
142
|
rubygems_version: 1.8.15
|
189
143
|
signing_key:
|
190
144
|
specification_version: 3
|
191
145
|
summary: Cupertino
|
192
146
|
test_files: []
|
193
|
-
|