sproutcore 1.0.1031 → 1.0.1035
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +12 -0
- data/VERSION.yml +3 -3
- data/buildtasks/manifest.rake +2 -0
- data/frameworks/sproutcore/frameworks/datastore/models/record.js +1 -0
- data/frameworks/sproutcore/frameworks/datastore/tests/models/record/destroy.js +11 -0
- data/frameworks/sproutcore/frameworks/desktop/views/stacked.js +10 -1
- data/lib/sproutcore/buildfile/task.rb +31 -3
- data/lib/sproutcore/models/manifest_entry.rb +51 -7
- data/lib/sproutcore/models/target.rb +81 -3
- data/lib/sproutcore/rack/proxy.rb +3 -1
- data/lib/sproutcore/tools.rb +5 -0
- data/spec/lib/models/target/compute_build_number_spec.rb +5 -5
- data/spec/lib/models/target/required_targets_spec.rb +10 -0
- data/spec/lib/tools/build_number_spec.rb +10 -3
- data/spec/lib/tools/tools_spec.rb +16 -0
- data/spec/spec_helper.rb +12 -0
- metadata +2 -2
data/History.txt
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
== 1.0.1034
|
2
|
+
|
3
|
+
- Fixed bug with the new proxy. HTTP method names were not capitalized, causing some servers to throw an exception
|
4
|
+
|
5
|
+
== 1.0.1033
|
6
|
+
|
7
|
+
- Updated SproutCore JS
|
8
|
+
- Build tools now work as a distribution. We can include resources from other projects as well
|
9
|
+
|
10
|
+
== 1.0.1009
|
11
|
+
|
12
|
+
First release of SproutCore 1.0 RC1
|
1
13
|
|
2
14
|
== 1.0.0.a1 / 2009-04-04
|
3
15
|
|
data/VERSION.yml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
:patch:
|
3
|
-
:digest:
|
2
|
+
:patch: 1035
|
3
|
+
:digest: 6adcb96d3bfd9d5a101f0ff1ae272a5044854a84
|
4
4
|
:dist:
|
5
|
-
frameworks/sproutcore:
|
5
|
+
frameworks/sproutcore: edcf66df94134f479ddad658d95b27e94b685c2a
|
6
6
|
:major: 1
|
7
7
|
:minor: 0
|
data/buildtasks/manifest.rake
CHANGED
@@ -79,3 +79,14 @@ test("should return receiver", function() {
|
|
79
79
|
equals(MyApp.foo.destroy(), MyApp.foo, 'should return receiver');
|
80
80
|
});
|
81
81
|
|
82
|
+
test("destroy should update status cache", function() {
|
83
|
+
var st = MyApp.foo.get('status');
|
84
|
+
ok(st !== SC.Record.DESTROYED_CLEAN, 'precond - foo should not be destroyed');
|
85
|
+
|
86
|
+
SC.RunLoop.begin();
|
87
|
+
MyApp.foo.destroy();
|
88
|
+
equals(MyApp.foo.get('status'), SC.Record.DESTROYED_CLEAN, 'status should be DESTROYED_CLEAN immediately when destroyed directly by record');
|
89
|
+
SC.RunLoop.end();
|
90
|
+
});
|
91
|
+
|
92
|
+
|
@@ -39,6 +39,15 @@ SC.StackedView = SC.CollectionView.extend(
|
|
39
39
|
adjust the height of the view.
|
40
40
|
*/
|
41
41
|
layout: { top: 0, left: 0, right: 0, height: 1 },
|
42
|
+
|
43
|
+
/**
|
44
|
+
Return full range of its indexes for nowShowing
|
45
|
+
|
46
|
+
@returns {SC.IndexSet} full range of indexes
|
47
|
+
*/
|
48
|
+
computeNowShowing: function(rect) {
|
49
|
+
return this.get('allContentIndexes');
|
50
|
+
},
|
42
51
|
|
43
52
|
/**
|
44
53
|
Updates the height of the stacked view to reflect the current content of
|
@@ -98,4 +107,4 @@ SC.StackedView = SC.CollectionView.extend(
|
|
98
107
|
*/
|
99
108
|
didCreateLayer: function() { return this.updateHeight(); }
|
100
109
|
|
101
|
-
});
|
110
|
+
});
|
@@ -148,6 +148,18 @@ module SC
|
|
148
148
|
invoke_with_call_chain(task_args, InvocationChain::EMPTY)
|
149
149
|
end
|
150
150
|
|
151
|
+
def self.log_indent
|
152
|
+
@task_indent ||= ''
|
153
|
+
end
|
154
|
+
|
155
|
+
def self.indent_logs
|
156
|
+
@task_indent = (@task_indent || '') + ' '
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.outdent_logs
|
160
|
+
@task_indent = (@task_indent || '')[0..-3]
|
161
|
+
end
|
162
|
+
|
151
163
|
# Same as invoke, but explicitly pass a call chain to detect
|
152
164
|
# circular dependencies.
|
153
165
|
def invoke_with_call_chain(task_args, invocation_chain) # :nodoc:
|
@@ -155,23 +167,37 @@ module SC
|
|
155
167
|
invocation_chain = InvocationChain.append(self, invocation_chain)
|
156
168
|
@lock.synchronize do
|
157
169
|
|
170
|
+
indent = self.class.indent_logs
|
171
|
+
|
158
172
|
# Use logging options to decide what to output
|
159
173
|
# one of :env, :name, :none
|
160
|
-
log_opt = task_options[:log] || :
|
174
|
+
log_opt = task_options[:log] || :none
|
161
175
|
if [:name, :env].include?(log_opt)
|
162
|
-
SC.logger.debug "invoke ~ #{name} #{format_trace_flags}"
|
176
|
+
SC.logger.debug "#{indent}invoke ~ #{name} #{format_trace_flags}"
|
163
177
|
end
|
164
178
|
|
165
179
|
if log_opt == :env
|
166
180
|
TASK_ENV.each do |key, value|
|
167
181
|
next if %w(config task_env).include?(key.to_s.downcase)
|
168
|
-
SC.logger.debug " #{key} = #{value.inspect}"
|
182
|
+
SC.logger.debug "#{indent} #{key} = #{value.inspect}"
|
169
183
|
end
|
170
184
|
end
|
171
185
|
|
186
|
+
t_start = Time.now.to_f * 1000
|
187
|
+
|
172
188
|
invocation_chain = invoke_prerequisites(task_args, invocation_chain)
|
173
189
|
@invoke_count += 1
|
174
190
|
execute(task_args) if needed?
|
191
|
+
|
192
|
+
t_end = Time.now.to_f * 1000
|
193
|
+
t_diff = t_end - t_start
|
194
|
+
|
195
|
+
# ignore short tasks
|
196
|
+
if t_diff > 10
|
197
|
+
SC.logger.debug "#{indent}long task ~ #{name}: #{t_diff.to_i} msec"
|
198
|
+
end
|
199
|
+
self.class.outdent_logs
|
200
|
+
|
175
201
|
end
|
176
202
|
end
|
177
203
|
return invocation_chain
|
@@ -199,6 +225,7 @@ module SC
|
|
199
225
|
|
200
226
|
# Execute the actions associated with this task.
|
201
227
|
def execute(args=nil)
|
228
|
+
|
202
229
|
@execute_count += 1
|
203
230
|
args ||= EMPTY_TASK_ARGS
|
204
231
|
return if SC.env.dryrun
|
@@ -211,6 +238,7 @@ module SC
|
|
211
238
|
act.call(self, args)
|
212
239
|
end
|
213
240
|
end
|
241
|
+
|
214
242
|
end
|
215
243
|
|
216
244
|
# Is this task needed?
|
@@ -127,7 +127,8 @@ module SC
|
|
127
127
|
end
|
128
128
|
timestamps.max
|
129
129
|
elsif composite?
|
130
|
-
|
130
|
+
|
131
|
+
source_entries.map { |e| e.timestamp || 0 }.max || Time.now.to_i
|
131
132
|
else
|
132
133
|
File.exist?(source_path) ? File.mtime(source_path).to_i : 0
|
133
134
|
end
|
@@ -158,11 +159,21 @@ module SC
|
|
158
159
|
if paths = self.source_paths
|
159
160
|
paths.each do |path|
|
160
161
|
next unless File.exist?(path)
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
162
|
+
|
163
|
+
# fine all directives in the source. use file cache to make this
|
164
|
+
# fast later on.
|
165
|
+
results = target.file_attr('scan_source', path) do
|
166
|
+
ret = []
|
167
|
+
File.readlines(path).each do |line|
|
168
|
+
if (line.valid_encoding?)
|
169
|
+
line.scan(regexp) { |result| ret << result }
|
170
|
+
end
|
171
|
+
end
|
172
|
+
ret
|
173
|
+
end
|
174
|
+
|
175
|
+
results.each { |result| yield(result) }
|
176
|
+
|
166
177
|
end
|
167
178
|
end
|
168
179
|
end
|
@@ -175,6 +186,9 @@ module SC
|
|
175
186
|
# results on all other file types.
|
176
187
|
#
|
177
188
|
def discover_build_directives!
|
189
|
+
|
190
|
+
target.begin_attr_changes
|
191
|
+
|
178
192
|
self.required = []
|
179
193
|
entry = self.transform? ? self.source_entry : self
|
180
194
|
entry.scan_source(BUILD_DIRECTIVES_REGEX) do |matches|
|
@@ -189,6 +203,9 @@ module SC
|
|
189
203
|
self.resource = filename
|
190
204
|
end
|
191
205
|
end
|
206
|
+
|
207
|
+
target.end_attr_changes
|
208
|
+
|
192
209
|
end
|
193
210
|
|
194
211
|
######################################################
|
@@ -218,8 +235,34 @@ module SC
|
|
218
235
|
return self
|
219
236
|
end
|
220
237
|
|
238
|
+
# Diagnostic function. Indicates what will happen if you called build
|
239
|
+
def inspect_build_state
|
240
|
+
inspect_build_to self.build_path
|
241
|
+
end
|
242
|
+
|
243
|
+
def inspect_staging_state
|
244
|
+
inspect_build_to self.staging_path
|
245
|
+
end
|
246
|
+
|
221
247
|
private
|
222
248
|
|
249
|
+
def inspect_build_to(dst_path)
|
250
|
+
return "#{filename}: dst #{dst_path} not found" if !File.exist?(dst_path)
|
251
|
+
dst_mtime = File.mtime(dst_path).to_i
|
252
|
+
self.source_paths.each do |path|
|
253
|
+
if path.nil?
|
254
|
+
puts "WARN: nil path in #{filename}"
|
255
|
+
next
|
256
|
+
end
|
257
|
+
|
258
|
+
return "#{filename}: src #{path} not found" if !File.exist?(path)
|
259
|
+
|
260
|
+
src_mtime = File.mtime(path).to_i
|
261
|
+
return "#{filename}: src #{path} is newer [#{dst_mtime} < #{src_mtime}]" if dst_mtime < src_mtime
|
262
|
+
end
|
263
|
+
return "#{filename}: will not build"
|
264
|
+
end
|
265
|
+
|
223
266
|
def build_to(dst_path)
|
224
267
|
if self.build_task.nil?
|
225
268
|
raise "no build task defined for #{self.filename}"
|
@@ -245,7 +288,8 @@ module SC
|
|
245
288
|
:dst_path => dst_path
|
246
289
|
|
247
290
|
return self
|
248
|
-
end
|
291
|
+
end
|
292
|
+
|
249
293
|
|
250
294
|
end
|
251
295
|
|
@@ -5,6 +5,9 @@
|
|
5
5
|
# and contributors
|
6
6
|
# ===========================================================================
|
7
7
|
|
8
|
+
require 'yaml'
|
9
|
+
require 'fileutils'
|
10
|
+
|
8
11
|
module SC
|
9
12
|
|
10
13
|
# Defines a build target in a project. A build target is a component that
|
@@ -286,6 +289,76 @@ module SC
|
|
286
289
|
return false
|
287
290
|
end
|
288
291
|
|
292
|
+
# path to attr_cache file
|
293
|
+
def file_attr_cache_path
|
294
|
+
@file_attr_cache_path ||= (self.cache_root / '__file_attr_cache.yml')
|
295
|
+
end
|
296
|
+
|
297
|
+
# suspend writing the file cache out if needed
|
298
|
+
def begin_attr_changes
|
299
|
+
@attr_change_level = (@attr_change_level || 0)+1
|
300
|
+
end
|
301
|
+
|
302
|
+
# resume writing file cache out if needed
|
303
|
+
def end_attr_changes
|
304
|
+
@attr_change_level = (@attr_change_level || 0) - 1
|
305
|
+
if @attr_change_level <= 0
|
306
|
+
@attr_change_level = 0
|
307
|
+
_write_file_attr_cache if @attr_cache_has_changes
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
def _write_file_attr_cache
|
312
|
+
if (@attr_change_level||0) > 0
|
313
|
+
@attr_cache_has_changes = true
|
314
|
+
|
315
|
+
else
|
316
|
+
@attr_cache_has_changes = false
|
317
|
+
if @file_attr_cache
|
318
|
+
FileUtils.mkdir_p(File.dirname(file_attr_cache_path))
|
319
|
+
fp = File.open(file_attr_cache_path, 'w+')
|
320
|
+
fp.write @file_attr_cache.to_yaml
|
321
|
+
fp.close
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
end
|
326
|
+
|
327
|
+
|
328
|
+
# returns or computes an attribute on a given file. this will keep the
|
329
|
+
# named attribute in a cache keyed against the mtime of the named path.
|
330
|
+
# if the mtime matches, the cached value is returned. otherwise, yields
|
331
|
+
# to the passed block to compute again.
|
332
|
+
def file_attr(attr_name, path, &block)
|
333
|
+
|
334
|
+
# read cache from disk if needed
|
335
|
+
if @file_attr_cache.nil?
|
336
|
+
if File.exists?(file_attr_cache_path)
|
337
|
+
require 'yaml'
|
338
|
+
@file_attr_cache = YAML.load File.read(file_attr_cache_path)
|
339
|
+
else
|
340
|
+
@file_attr_cache = {}
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
path_root = (@file_attr_cache[path] ||= {})
|
345
|
+
attr_info = (path_root[attr_name.to_s] ||= {})
|
346
|
+
attr_mtime = attr_info['mtime'].to_i
|
347
|
+
path_mtime = File.exists?(path) ? File.mtime(path).to_i : 0
|
348
|
+
if attr_mtime.nil? || (path_mtime != attr_mtime)
|
349
|
+
SC.logger.debug "MISS file_attr_cache:#{attr_name}: #{File.basename(path)} path_mtime=#{path_mtime} attr_mtime=#{attr_mtime}"
|
350
|
+
|
351
|
+
value = attr_info['value'] = yield
|
352
|
+
attr_info['mtime'] = path_mtime
|
353
|
+
_write_file_attr_cache
|
354
|
+
|
355
|
+
else
|
356
|
+
value = attr_info['value']
|
357
|
+
end
|
358
|
+
|
359
|
+
return value
|
360
|
+
end
|
361
|
+
|
289
362
|
# Computes a unique build number for this target. The build number is
|
290
363
|
# gauranteed to change anytime the contents of any source file changes
|
291
364
|
# or anytime the build number of a required target changes. Although
|
@@ -321,11 +394,16 @@ module SC
|
|
321
394
|
# files. It is not as fast as using an mtime, but it will remain
|
322
395
|
# constant from one machine to the next so it can be used when
|
323
396
|
# deploying across multiple build machines, etc.
|
397
|
+
begin_attr_changes
|
324
398
|
digests = Dir.glob(File.join(source_root, '**', '*')).map do |path|
|
325
|
-
|
326
|
-
|
327
|
-
|
399
|
+
file_attr(:digest, path) do
|
400
|
+
allowed = File.exists?(path) && !File.directory?(path)
|
401
|
+
allowed = allowed && !target_directory?(path)
|
402
|
+
allowed ? Digest::SHA1.hexdigest(File.read(path)) : nil
|
403
|
+
end
|
328
404
|
end
|
405
|
+
end_attr_changes
|
406
|
+
|
329
407
|
digests.compact!
|
330
408
|
|
331
409
|
# Get all required targets and add in their build number.
|
@@ -69,7 +69,9 @@ module SC
|
|
69
69
|
response = http.send(http_method, http_path, headers)
|
70
70
|
else
|
71
71
|
http_body = env['rack.input']
|
72
|
-
some_request = Net::HTTPGenericRequest.new
|
72
|
+
some_request = Net::HTTPGenericRequest.new http_method.upcase,
|
73
|
+
true, true, http_path, headers
|
74
|
+
|
73
75
|
some_request.body_stream = http_body
|
74
76
|
response = http.request(some_request)
|
75
77
|
end
|
data/lib/sproutcore/tools.rb
CHANGED
@@ -138,6 +138,11 @@ module SC
|
|
138
138
|
@project = a_project
|
139
139
|
end
|
140
140
|
|
141
|
+
def set_test_project(a_project)
|
142
|
+
@project = a_project
|
143
|
+
@discovered_project = true
|
144
|
+
end
|
145
|
+
|
141
146
|
# The current project. This is discovered based on the passed --project
|
142
147
|
# option or based on the current working directory. If no project can
|
143
148
|
# be found, this method will always return null.
|
@@ -50,7 +50,7 @@ describe SC::Target, 'compute_build_number' do
|
|
50
50
|
describe "accurate method to compute build number" do
|
51
51
|
|
52
52
|
before do
|
53
|
-
@target = @project.target_for(:sproutcore)
|
53
|
+
@target = @project.target_for(:sproutcore).prepare!
|
54
54
|
@target.config.build_numbers = nil #precondition
|
55
55
|
@target.config.build_number = nil #precondition
|
56
56
|
end
|
@@ -72,10 +72,10 @@ describe SC::Target, 'compute_build_number' do
|
|
72
72
|
end
|
73
73
|
|
74
74
|
it "changes generated build number if build number for a required target changes" do
|
75
|
-
target = @project.target_for(:sproutcore)
|
75
|
+
target = @project.target_for(:sproutcore).prepare!
|
76
76
|
target.should_not be_nil
|
77
77
|
|
78
|
-
required = target.target_for(:desktop)
|
78
|
+
required = target.target_for(:desktop).prepare!
|
79
79
|
required.should_not be_nil
|
80
80
|
required.config.build_numbers = nil #precondition
|
81
81
|
required.config.build_number = nil #precondition
|
@@ -95,10 +95,10 @@ describe SC::Target, 'compute_build_number' do
|
|
95
95
|
end
|
96
96
|
|
97
97
|
it "does not change generated build number if a nested target that is not required by target changes" do
|
98
|
-
target = @project.target_for(:sproutcore)
|
98
|
+
target = @project.target_for(:sproutcore).prepare!
|
99
99
|
target.should_not be_nil
|
100
100
|
|
101
|
-
not_required = target.target_for(:mobile)
|
101
|
+
not_required = target.target_for(:mobile).prepare!
|
102
102
|
not_required.should_not be_nil
|
103
103
|
|
104
104
|
#precondition
|
@@ -5,8 +5,15 @@ describe SC::Target, 'required_targets' do
|
|
5
5
|
include SC::SpecHelpers
|
6
6
|
|
7
7
|
before do
|
8
|
+
@env = SC.build_mode # force debug mode
|
9
|
+
SC.build_mode = :debug
|
10
|
+
|
8
11
|
@project = fixture_project(:real_world)
|
9
12
|
end
|
13
|
+
|
14
|
+
after do
|
15
|
+
SC.build_mode = @env
|
16
|
+
end
|
10
17
|
|
11
18
|
it "should resolve references to child targets" do
|
12
19
|
target = @project.target_for :sproutcore
|
@@ -66,15 +73,18 @@ describe SC::Target, 'required_targets' do
|
|
66
73
|
end
|
67
74
|
|
68
75
|
it "should log a warning if a required test or debug target could not be found" do
|
76
|
+
|
69
77
|
target = @project.target_for :sproutcore
|
70
78
|
target.config.test_required = 'imaginary_foo'
|
71
79
|
target.config.debug_required = 'imaginary_bar'
|
72
80
|
|
73
81
|
capture('stderr') { target.required_targets(:test => true) }.size.should_not == 0
|
74
82
|
capture('stderr') { target.required_targets(:debug => true) }.size.should_not == 0
|
83
|
+
|
75
84
|
end
|
76
85
|
|
77
86
|
it "should include any CONFIG.theme if passed :theme => true && target_type == :app" do
|
87
|
+
|
78
88
|
expected = @project.target_for 'sproutcore/standard_theme'
|
79
89
|
|
80
90
|
target = @project.target_for :contacts
|
@@ -5,9 +5,15 @@ describe SC::Tools, 'build-number' do
|
|
5
5
|
include SC::SpecHelpers
|
6
6
|
|
7
7
|
before do
|
8
|
+
save_env
|
9
|
+
SC.build_mode = :production
|
8
10
|
@tool = SC::Tools.new('build_number')
|
9
11
|
end
|
10
12
|
|
13
|
+
after do
|
14
|
+
restore_env
|
15
|
+
end
|
16
|
+
|
11
17
|
it "should raise error if no target is passed" do
|
12
18
|
lambda { @tool.build_number }.should raise_error
|
13
19
|
end
|
@@ -17,11 +23,12 @@ describe SC::Tools, 'build-number' do
|
|
17
23
|
end
|
18
24
|
|
19
25
|
it "should write build number when passed target" do
|
20
|
-
@tool.project = fixture_project(:real_world) # req...
|
21
|
-
bn = capture('stdout') { @tool.build_number('sproutcore') }
|
22
|
-
|
23
26
|
expected_target = fixture_project(:real_world).target_for(:sproutcore)
|
24
27
|
expected = expected_target.prepare!.compute_build_number
|
28
|
+
|
29
|
+
@tool.set_test_project fixture_project(:real_world) # req...
|
30
|
+
bn = capture('stdout') { @tool.build_number('sproutcore') }
|
31
|
+
|
25
32
|
bn.should eql(expected)
|
26
33
|
end
|
27
34
|
|
@@ -13,6 +13,14 @@ describe SC::Tools do
|
|
13
13
|
|
14
14
|
describe "logger options" do
|
15
15
|
|
16
|
+
before do
|
17
|
+
save_env
|
18
|
+
end
|
19
|
+
|
20
|
+
after do
|
21
|
+
restore_env
|
22
|
+
end
|
23
|
+
|
16
24
|
it "should default to warn log level" do
|
17
25
|
SC::Tools.start %w(dummy)
|
18
26
|
SC.env.log_level.should == :warn
|
@@ -54,6 +62,14 @@ describe SC::Tools do
|
|
54
62
|
|
55
63
|
describe "build mode options" do
|
56
64
|
|
65
|
+
before do
|
66
|
+
save_env
|
67
|
+
end
|
68
|
+
|
69
|
+
after do
|
70
|
+
restore_env
|
71
|
+
end
|
72
|
+
|
57
73
|
it "should default to :production build mode" do
|
58
74
|
SC::Tools.start %w(dummy)
|
59
75
|
SC.build_mode.should eql(:production)
|
data/spec/spec_helper.rb
CHANGED
@@ -48,6 +48,18 @@ module SC
|
|
48
48
|
|
49
49
|
module SpecHelpers
|
50
50
|
|
51
|
+
# env doesn't automatically reset
|
52
|
+
def save_env
|
53
|
+
@env ||= []
|
54
|
+
@env << { :env => SC.env.dup, :build_mode => SC.build_mode }
|
55
|
+
end
|
56
|
+
|
57
|
+
def restore_env
|
58
|
+
e = (@env || []).pop
|
59
|
+
SC.env = e[:env]
|
60
|
+
SC.build_mode = e[:build_mode]
|
61
|
+
end
|
62
|
+
|
51
63
|
def fixture_path(*path_items)
|
52
64
|
(path_items = path_items.flatten).unshift 'fixtures'
|
53
65
|
path_items.map! { |pi| pi.to_s }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sproutcore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1035
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sprout Systems, Inc. Apple Inc. and contributors
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-19 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|