zimt 0.0.1
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/.gitignore +4 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/Rakefile +8 -0
- data/bin/zimt +6 -0
- data/lib/zimt.rb +47 -0
- data/lib/zimt/cli.rb +11 -0
- data/lib/zimt/pbxproj.rb +300 -0
- data/lib/zimt/sprinkle.rb +41 -0
- data/lib/zimt/version.rb +3 -0
- data/zimt.gemspec +25 -0
- metadata +128 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use system
|
data/Gemfile
ADDED
data/Rakefile
ADDED
data/bin/zimt
ADDED
data/lib/zimt.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'json'
|
3
|
+
require 'open-uri'
|
4
|
+
require 'pathname'
|
5
|
+
require 'thor'
|
6
|
+
require "zimt/cli"
|
7
|
+
require "zimt/pbxproj"
|
8
|
+
require "zimt/sprinkle"
|
9
|
+
require "zimt/version"
|
10
|
+
|
11
|
+
module Zimt
|
12
|
+
def self.xcodeproj
|
13
|
+
@xcodeproj ||= find_xcodeproj
|
14
|
+
raise "Could not locate .xcodeproj" unless @xcodeproj
|
15
|
+
Pathname.new(@xcodeproj)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.pbxproj
|
19
|
+
path = Pathname.new(File.join(self.xcodeproj, 'project.pbxproj'))
|
20
|
+
@pbxproj ||= PBXProj.new(path)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.zimts_dir
|
24
|
+
Pathname.new(File.expand_path(File.join(self.xcodeproj, '..', 'zimts')))
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def self.find_xcodeproj
|
30
|
+
given = ENV['ZIMT_XCODEPROJ']
|
31
|
+
return given if given && !given.empty?
|
32
|
+
|
33
|
+
previous = nil
|
34
|
+
current = File.expand_path(Dir.pwd)
|
35
|
+
|
36
|
+
until !File.directory?(current) || current == previous
|
37
|
+
# otherwise return the Gemfile if it's there
|
38
|
+
filenames = Dir.glob(File.join(current, '*.xcodeproj'))
|
39
|
+
raise "More than one .xcodeproj found: #{filenames}" if filenames.length > 1
|
40
|
+
filename = filenames.first
|
41
|
+
return filename if File.directory?(filename) and File.file?(File.join(filename, 'project.pbxproj'))
|
42
|
+
current, previous = File.expand_path("..", current), current
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
data/lib/zimt/cli.rb
ADDED
data/lib/zimt/pbxproj.rb
ADDED
@@ -0,0 +1,300 @@
|
|
1
|
+
module Zimt
|
2
|
+
class PBXProj
|
3
|
+
def self.plutil(file)
|
4
|
+
`plutil -convert json -o - #{file}`
|
5
|
+
end
|
6
|
+
|
7
|
+
def randhex(length=1)
|
8
|
+
@buffer = ""
|
9
|
+
length.times do
|
10
|
+
@buffer << rand(16).to_s(16).upcase
|
11
|
+
end
|
12
|
+
@buffer
|
13
|
+
end
|
14
|
+
|
15
|
+
# Documentation on PBXObjectId by @tjw
|
16
|
+
# http://lists.apple.com/archives/projectbuilder-users/2003/Jan/msg00263.html
|
17
|
+
#
|
18
|
+
# ObjectId gets generated in the following format:
|
19
|
+
# +----------------------------------------------------------------------+
|
20
|
+
# | RANDOM | SEQ | TIME | PID | IP (2) |
|
21
|
+
# | byte byte | byte byte | byte byte byte byte | byte byte | byte byte |
|
22
|
+
# +----------------------------------------------------------------------+
|
23
|
+
# RANDOM = 2 bytes of random number for distribution
|
24
|
+
# SEQ = Unsigned short sequence counter that starts randomly.
|
25
|
+
# TIME = Seconds since epoch (1/1/1970)
|
26
|
+
# PID = Process ID
|
27
|
+
# This is only two bytes even though most pids are longs.
|
28
|
+
# Here you would take the lower 2 bytes.
|
29
|
+
# IP = IP Address of the machine (subnet.hostId)
|
30
|
+
def uuid
|
31
|
+
# TODO
|
32
|
+
@prefix ||= randhex(4)
|
33
|
+
@suffix ||= Time.now.to_i.to_s(16).upcase + randhex(8)
|
34
|
+
@count ||= rand(16**4)
|
35
|
+
@count += 1
|
36
|
+
if @count.to_s(16).length < 4
|
37
|
+
@count = @count * 16
|
38
|
+
end
|
39
|
+
uuid = "#{@prefix}#{@count.to_s(16).upcase}#{@suffix}"
|
40
|
+
if uuid.length != 24
|
41
|
+
puts "uuid length wrong: #{uuid}"
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
uuid
|
45
|
+
end
|
46
|
+
|
47
|
+
attr_reader :content, :hash, :objects, :root
|
48
|
+
attr_accessor :position
|
49
|
+
|
50
|
+
def initialize(file)
|
51
|
+
@filename = file
|
52
|
+
@content = File.readlines(file)
|
53
|
+
self.parse
|
54
|
+
end
|
55
|
+
|
56
|
+
def parse
|
57
|
+
@hash = JSON.parse(PBXProj.plutil(@filename)).freeze
|
58
|
+
@objects = @hash['objects']
|
59
|
+
@root = PBXHash.new(self, @hash['rootObject'], @objects[@hash['rootObject']])
|
60
|
+
end
|
61
|
+
|
62
|
+
def save!
|
63
|
+
File.open(@filename, "w") { |f|
|
64
|
+
f.write(self.content.join(''))
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def zimt_group
|
69
|
+
self.root.mainGroup.children.select{ |g| g.path == 'Zimt' }.first
|
70
|
+
end
|
71
|
+
|
72
|
+
def ensure_zimt_group
|
73
|
+
zimt_group = self.zimt_group
|
74
|
+
if zimt_group.nil?
|
75
|
+
self.add_zimt_group
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# C5FE9B6F13BA7537004CCA66 = {
|
80
|
+
# isa = PBXGroup;
|
81
|
+
# children = (
|
82
|
+
# C5FE9B8413BA7537004CCA66 /* Sources */,
|
83
|
+
# C7826AD313D9137D00661EEC /* Resources */,
|
84
|
+
# C5FE9B7D13BA7537004CCA66 /* Frameworks */,
|
85
|
+
# C5FE9B7B13BA7537004CCA66 /* Products */,
|
86
|
+
# C5E20A8613F4507D00C5DDF3 /* Zimt */,
|
87
|
+
# );
|
88
|
+
# sourceTree = "<group>";
|
89
|
+
# };
|
90
|
+
def add_zimt_group
|
91
|
+
# Add Zimt reference to mainGroup
|
92
|
+
groupid = self.root.mainGroup.pbxid
|
93
|
+
scan_to "\t\t#{groupid}"
|
94
|
+
scan_to "\t\t\t);"
|
95
|
+
newgroup = self.uuid
|
96
|
+
self.content.insert(@position, "\t\t\t\t#{newgroup} /* Zimt */,\n")
|
97
|
+
|
98
|
+
# Find position for Zimt reference in PBXGRoup section
|
99
|
+
@position = 0
|
100
|
+
scan_to "/* Begin PBXGroup section */"
|
101
|
+
begin_position = @position
|
102
|
+
scan_to "/* End PBXGroup section */"
|
103
|
+
end_position = @position
|
104
|
+
|
105
|
+
@position = begin_position
|
106
|
+
while @position < end_position
|
107
|
+
line = self.content[@position]
|
108
|
+
if (line.end_with? " = {\n")
|
109
|
+
groupname = line.split(' ')[0]
|
110
|
+
if groupname > newgroup
|
111
|
+
break
|
112
|
+
end
|
113
|
+
end
|
114
|
+
@position += 1
|
115
|
+
end
|
116
|
+
|
117
|
+
# Add Zimt Group
|
118
|
+
self.content.insert(@position,
|
119
|
+
"\t\t#{newgroup} /* Zimt */ = {\n",
|
120
|
+
"\t\t\tisa = PBXGroup;\n",
|
121
|
+
"\t\t\tchildren = (\n",
|
122
|
+
"\t\t\t);\n",
|
123
|
+
"\t\t\tpath = Zimt;\n",
|
124
|
+
"\t\t\tsourceTree = \"<group>\";\n",
|
125
|
+
"\t\t};\n")
|
126
|
+
|
127
|
+
self.save!
|
128
|
+
self.parse
|
129
|
+
end
|
130
|
+
|
131
|
+
#/* Begin PBXFileReference section */
|
132
|
+
# C5D0CB021406C3AA002E631F /* Hans.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Hans.h; sourceTree = "<group>"; };
|
133
|
+
#/* End PBXFileReference section */
|
134
|
+
def add_file(file, file_type)
|
135
|
+
zimt_group_id = self.zimt_group.pbxid
|
136
|
+
# Add file to Zimt group
|
137
|
+
groupid = self.root.mainGroup.pbxid
|
138
|
+
scan_to "\t\t#{zimt_group_id}"
|
139
|
+
scan_to "\t\t\t);"
|
140
|
+
newgroup = self.uuid
|
141
|
+
self.content.insert(@position, "\t\t\t\t#{newgroup} /* #{file} */,\n")
|
142
|
+
|
143
|
+
# Find position for Zimt reference in PBXGRoup section
|
144
|
+
@position = 0
|
145
|
+
scan_to "/* Begin PBXFileReference section */"
|
146
|
+
begin_position = @position
|
147
|
+
scan_to "/* End PBXFileReference section */"
|
148
|
+
end_position = @position
|
149
|
+
|
150
|
+
@position = begin_position
|
151
|
+
while @position < end_position
|
152
|
+
line = self.content[@position]
|
153
|
+
groupname = line.split(' ')[0]
|
154
|
+
if groupname > newgroup
|
155
|
+
break
|
156
|
+
end
|
157
|
+
@position += 1
|
158
|
+
end
|
159
|
+
|
160
|
+
# Add Zimt Group
|
161
|
+
self.content.insert(@position,
|
162
|
+
"\t\t#{newgroup} /* #{file} */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = #{file_type}; path = #{file}; sourceTree = \"<group>\"; };\n")
|
163
|
+
|
164
|
+
self.save!
|
165
|
+
self.parse
|
166
|
+
return newgroup
|
167
|
+
end
|
168
|
+
|
169
|
+
def add_h_file(file)
|
170
|
+
add_file(file, "sourcecode.c.h")
|
171
|
+
end
|
172
|
+
|
173
|
+
def add_m_file(file)
|
174
|
+
fileref = self.add_file(file, "sourcecode.c.objc")
|
175
|
+
buildfileref = self.add_buildfile(file, fileref)
|
176
|
+
add_buildfileref_to_build_phase(file, buildfileref)
|
177
|
+
end
|
178
|
+
|
179
|
+
#/* Begin PBXBuildFile section */
|
180
|
+
# C53D93B21406F98300F4CDDE /* Hans.m in Sources */ = {isa = PBXBuildFile; fileRef = C53D93B11406F98300F4CDDE /* Hans.m */; };
|
181
|
+
#/* End PBXBuildFile section */
|
182
|
+
def add_buildfile(file, fileref)
|
183
|
+
newgroup = self.uuid
|
184
|
+
# Find position for Zimt reference in PBXGRoup section
|
185
|
+
@position = 0
|
186
|
+
scan_to "/* Begin PBXBuildFile section */"
|
187
|
+
begin_position = @position
|
188
|
+
scan_to "/* End PBXBuildFile section */"
|
189
|
+
end_position = @position
|
190
|
+
|
191
|
+
@position = begin_position
|
192
|
+
while @position < end_position
|
193
|
+
line = self.content[@position]
|
194
|
+
groupname = line.split(' ')[0]
|
195
|
+
if groupname > newgroup
|
196
|
+
break
|
197
|
+
end
|
198
|
+
@position += 1
|
199
|
+
end
|
200
|
+
|
201
|
+
# Add Zimt Group
|
202
|
+
self.content.insert(@position,
|
203
|
+
"\t\t#{newgroup} /* #{file} in Sources */ = {isa = PBXBuildFile; fileRef = #{fileref} /* #{file} */; };\n")
|
204
|
+
|
205
|
+
self.save!
|
206
|
+
self.parse
|
207
|
+
return newgroup
|
208
|
+
end
|
209
|
+
|
210
|
+
#/* Begin PBXSourcesBuildPhase section */
|
211
|
+
# 8D11072C0486CEB800E47090 /* Sources */ = {
|
212
|
+
# files = (
|
213
|
+
# C53D93B21406F98300F4CDDE /* Hans.m in Sources */,
|
214
|
+
# );
|
215
|
+
# C56D96C81385E71800070608 /* Sources */ = {
|
216
|
+
#/* End PBXSourcesBuildPhase section */
|
217
|
+
def add_buildfileref_to_build_phase(file, buildfileref)
|
218
|
+
@position = 0
|
219
|
+
scan_to "/* Begin PBXSourcesBuildPhase section */"
|
220
|
+
begin_position = @position
|
221
|
+
scan_to "/* End PBXSourcesBuildPhase section */"
|
222
|
+
end_position = @position
|
223
|
+
|
224
|
+
@position = begin_position
|
225
|
+
while @position < end_position
|
226
|
+
line = self.content[@position]
|
227
|
+
if (line.end_with? " = {\n")
|
228
|
+
old_position = @position
|
229
|
+
scan_to(" );\n")
|
230
|
+
self.content.insert(@position,
|
231
|
+
" #{buildfileref} /* #{file} in Sources */,\n")
|
232
|
+
@position = old_position + 1 # offset for added line
|
233
|
+
break
|
234
|
+
end
|
235
|
+
@position += 1
|
236
|
+
end
|
237
|
+
|
238
|
+
self.save!
|
239
|
+
self.parse
|
240
|
+
end
|
241
|
+
|
242
|
+
def scan_to(what)
|
243
|
+
@position ||= 0
|
244
|
+
while true
|
245
|
+
line = self.content[@position]
|
246
|
+
if line.nil?
|
247
|
+
raise "#{what} not found"
|
248
|
+
end
|
249
|
+
if line.start_with? what
|
250
|
+
return
|
251
|
+
end
|
252
|
+
@position += 1
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def current_line
|
257
|
+
@position ||= 0
|
258
|
+
self.content[@position]
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
class PBXHash
|
263
|
+
attr_reader :pbxid
|
264
|
+
|
265
|
+
def initialize(pbxproj, pbxid, node)
|
266
|
+
@pbxproj = pbxproj
|
267
|
+
@pbxid = pbxid
|
268
|
+
@node = node
|
269
|
+
end
|
270
|
+
|
271
|
+
def keys
|
272
|
+
@node.keys
|
273
|
+
end
|
274
|
+
|
275
|
+
def inspect
|
276
|
+
"<PBX: #{keys.join(', ')}>"
|
277
|
+
end
|
278
|
+
|
279
|
+
private
|
280
|
+
def wrap(raw, recurse=true, id=nil)
|
281
|
+
if raw.is_a? Array
|
282
|
+
raw.map { |i| wrap(i, recurse) }
|
283
|
+
elsif raw.is_a? Hash
|
284
|
+
new_hash = raw.inject({}) { |h,(k,v)| h[k] = wrap(v, recurse) ; h }
|
285
|
+
PBXHash.new(@pbxproj, id, new_hash)
|
286
|
+
else
|
287
|
+
if recurse and @pbxproj.objects.include? raw
|
288
|
+
wrap(@pbxproj.objects[raw], false, raw)
|
289
|
+
else
|
290
|
+
raw
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
def method_missing(sym)
|
296
|
+
wrap(@node[sym.to_s])
|
297
|
+
end
|
298
|
+
|
299
|
+
end
|
300
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Zimt
|
2
|
+
class Sprinkle
|
3
|
+
attr_accessor :name, :url, :files
|
4
|
+
|
5
|
+
def self.get(name)
|
6
|
+
if name.start_with?('http://') || name.start_with?('https://')
|
7
|
+
url = name
|
8
|
+
else
|
9
|
+
url = "https://raw.github.com/zimt/sprinkles/stable/#{name.downcase}.sprinkle.yml"
|
10
|
+
end
|
11
|
+
spec = open(url) { |f| YAML::load(f) }
|
12
|
+
self.new(spec)
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(spec)
|
16
|
+
@spec = spec
|
17
|
+
@name = spec["name"]
|
18
|
+
@url = spec["url"]
|
19
|
+
@files = spec["files"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def install
|
23
|
+
puts "Installing #{name}"
|
24
|
+
FileUtils.mkdir "Zimt"
|
25
|
+
Zimt.pbxproj.ensure_zimt_group
|
26
|
+
files.each do |url|
|
27
|
+
file = Pathname.new(URI.parse(url).path).basename('.sprinkle.yml').to_s
|
28
|
+
puts "Adding #{file}..."
|
29
|
+
open(Pathname.new("Zimt").join(file), "w") do |io|
|
30
|
+
io.write(open(url).read)
|
31
|
+
end
|
32
|
+
if file.end_with? ".m"
|
33
|
+
Zimt.pbxproj.add_m_file(file)
|
34
|
+
else
|
35
|
+
Zimt.pbxproj.add_h_file(file)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
puts "All done"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/zimt/version.rb
ADDED
data/zimt.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "zimt/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "zimt"
|
7
|
+
s.version = Zimt::VERSION
|
8
|
+
s.authors = ["Martin Schürrer"]
|
9
|
+
s.email = ["martin@schuerrer.org"]
|
10
|
+
s.homepage = "https://github.com/zimt/zimt"
|
11
|
+
s.summary = "Zimt is a collection of Cocoa extensions with clever package management"
|
12
|
+
s.description = "Zimt downloads and adds files to your .xcodeproj."
|
13
|
+
|
14
|
+
s.rubyforge_project = "zimt"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency 'json', '~> 1.5.0'
|
22
|
+
s.add_dependency 'thor', '~> 0.14.0'
|
23
|
+
s.add_development_dependency 'bacon', '~> 1.1.0'
|
24
|
+
s.add_development_dependency 'ruby-debug', '~> 0.10.0'
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: zimt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- "Martin Schu\xCC\x88rrer"
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-08-29 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ~>
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
segments:
|
26
|
+
- 1
|
27
|
+
- 5
|
28
|
+
- 0
|
29
|
+
version: 1.5.0
|
30
|
+
requirement: *id001
|
31
|
+
name: json
|
32
|
+
prerelease: false
|
33
|
+
type: :runtime
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ~>
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 0
|
41
|
+
- 14
|
42
|
+
- 0
|
43
|
+
version: 0.14.0
|
44
|
+
requirement: *id002
|
45
|
+
name: thor
|
46
|
+
prerelease: false
|
47
|
+
type: :runtime
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
segments:
|
54
|
+
- 1
|
55
|
+
- 1
|
56
|
+
- 0
|
57
|
+
version: 1.1.0
|
58
|
+
requirement: *id003
|
59
|
+
name: bacon
|
60
|
+
prerelease: false
|
61
|
+
type: :development
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ~>
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
- 10
|
70
|
+
- 0
|
71
|
+
version: 0.10.0
|
72
|
+
requirement: *id004
|
73
|
+
name: ruby-debug
|
74
|
+
prerelease: false
|
75
|
+
type: :development
|
76
|
+
description: Zimt downloads and adds files to your .xcodeproj.
|
77
|
+
email:
|
78
|
+
- martin@schuerrer.org
|
79
|
+
executables:
|
80
|
+
- zimt
|
81
|
+
extensions: []
|
82
|
+
|
83
|
+
extra_rdoc_files: []
|
84
|
+
|
85
|
+
files:
|
86
|
+
- .gitignore
|
87
|
+
- .rvmrc
|
88
|
+
- Gemfile
|
89
|
+
- Rakefile
|
90
|
+
- bin/zimt
|
91
|
+
- lib/zimt.rb
|
92
|
+
- lib/zimt/cli.rb
|
93
|
+
- lib/zimt/pbxproj.rb
|
94
|
+
- lib/zimt/sprinkle.rb
|
95
|
+
- lib/zimt/version.rb
|
96
|
+
- zimt.gemspec
|
97
|
+
has_rdoc: true
|
98
|
+
homepage: https://github.com/zimt/zimt
|
99
|
+
licenses: []
|
100
|
+
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options: []
|
103
|
+
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
segments:
|
111
|
+
- 0
|
112
|
+
version: "0"
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
segments:
|
118
|
+
- 0
|
119
|
+
version: "0"
|
120
|
+
requirements: []
|
121
|
+
|
122
|
+
rubyforge_project: zimt
|
123
|
+
rubygems_version: 1.3.6
|
124
|
+
signing_key:
|
125
|
+
specification_version: 3
|
126
|
+
summary: Zimt is a collection of Cocoa extensions with clever package management
|
127
|
+
test_files: []
|
128
|
+
|