forked from sproutit/sproutcore-abbot
/
Rakefile
351 lines (272 loc) · 9.85 KB
/
Rakefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
# ===========================================================================
# Project: Abbot - SproutCore Build Tools
# Copyright: ©2009 Apple Inc.
# portions copyright @2006-2009 Sprout Systems, Inc.
# and contributors
# ===========================================================================
# Rakefile used to build the SproutCore Gem. Requires Jeweler to function.
ROOT_PATH = File.dirname(__FILE__)
# files to ignore changes in
IGNORE_CHANGES = %w[.gitignore .gitmodules .DS_Store .gemspec VERSION.yml ^pkg ^tmp ^coverage]
# Get the DISTRIBUTION info
require 'yaml'
DIST = YAML.load File.read(File.expand_path(File.join(ROOT_PATH, 'DISTRIBUTION.yml')))
# Make empty to not use sudo
SUDO = 'sudo'
################################################
## LOAD DEPENDENCIES
##
begin
require 'rubygems'
require 'jeweler'
require 'extlib'
require 'fileutils'
require 'spec/rake/spectask'
$:.unshift(ROOT_PATH / 'lib')
require 'sproutcore'
rescue LoadError => e
$stderr.puts "WARN: some required gems are not installed (try rake init to setup)"
$stderr.puts e
end
################################################
## PROJECT DESCRIPTION
##
Jeweler::Tasks.new do |gemspec|
gemspec.name = 'sproutcore'
gemspec.authors = 'Sprout Systems, Inc. Apple Inc. and contributors'
gemspec.email = 'contact@sproutcore.com'
gemspec.homepage = 'http://www.sproutcore.com'
gemspec.summary = "SproutCore is a platform for building native look-and-feel applications on the web"
gemspec.add_dependency 'rack', '>= 0.9.1'
gemspec.add_dependency 'json_pure', ">= 1.1.0"
gemspec.add_dependency 'extlib', ">= 0.9.9"
gemspec.add_dependency 'erubis', ">= 2.6.2"
gemspec.add_dependency 'thor', '>= 0.11.7'
gemspec.add_development_dependency 'gemcutter', ">= 0.1.0"
gemspec.add_development_dependency 'jeweler', ">= 1.0.0"
gemspec.add_development_dependency 'rspec', ">= 1.2.0"
gemspec.rubyforge_project = "sproutcore"
gemspec.extra_rdoc_files.include *%w[History.txt README.txt]
gemspec.files.include *%w[.htaccess frameworks/sproutcore/**/*]
gemspec.files.exclude *%w[^coverage/ .gitignore .gitmodules .DS_Store tmp .hashinfo .svn .git]
gemspec.description = File.read(ROOT_PATH / 'README.txt')
end
Jeweler::RubyforgeTasks.new do |rubyforge|
rubyforge.doc_task = 'rdoc'
end
Jeweler::GemcutterTasks.new
def git(path, cmd, log=true)
$stdout.puts("#{path.sub(ROOT_PATH, '')}: git #{cmd}") if log
git_path = path / '.git'
git_index = git_path / 'index'
# The env can become polluted; breaking git. This will avoid that.
%x[GIT_DIR=#{git_path}; GIT_WORK_TREE=#{path}; GIT_INDEX_FILE=#{git_index}; git #{cmd}]
end
################################################
## CORE TASKS
##
desc "performs an initial setup on the tools. Installs gems, checkout"
task :init => [:install_gems, 'dist:init', 'dist:update']
task :install_gems do
$stdout.puts "Installing gems (may ask for password)"
system %[#{SUDO} gem install rack json json_pure extlib erubis thor]
system %[#{SUDO} gem install jeweler gemcutter rspec] # dev req
end
namespace :dist do
desc "checkout any frameworks in the distribution"
task :init do
$stdout.puts "Setup distribution"
DIST.each do |rel_path, opts|
path = ROOT_PATH / rel_path
repo_url = opts['repo']
if !File.exists?(path / ".git")
$stdout.puts " Creating repo for #{rel_path}"
FileUtils.mkdir_p File.dirname(path)
$stdout.puts "\n> git clone #{repo_url} #{path}"
system %[git clone #{repo_url} #{path}]
else
$stdout.puts "Found #{rel_path}"
end
end
end
desc "make the version of each distribution item match the one in VERSION"
task :update => 'dist:init' do
$stdout.puts "Setup distribution"
# Use this to get the commit hash
version_file = ROOT_PATH / 'VERSION.yml'
if File.exist?(version_file)
versions = YAML.load File.read(version_file)
versions = (versions['dist'] || versions[:dist]) if versions
versions ||= {}
end
DIST.each do |rel_path, opts|
path = ROOT_PATH / rel_path
if File.exists?(path / ".git") && versions[rel_path]
sha = versions[rel_path]
$stdout.puts "\n> git fetch"
$stdout.puts git(path, 'fetch')
$stdout.puts "\n> git checkout #{sha}"
$stdout.puts git(path, 'checkout #{sha}')
else
$stdout.puts "WARN: cannot fix version for #{rel_path}"
end
end
end
end
namespace :release do
desc "tags the current repository and any distribution repositories. if you can push to distribution, then push tag as well"
task :tag => :update_version do
tag_name = "REL-#{RELEASE_VERSION}"
DIST.keys.push('abbot').each do |rel_path|
full_path = rel_path=='abbot' ? ROOT_PATH : (ROOT_PATH / rel_path)
git(full_path, "tag -f #{tag_name}")
end
end
task :push_tags => :tag do
tag_name = "REL-#{RELEASE_VERSION}"
DIST.keys.push('abbot').each do |rel_path|
full_path = rel_path=='abbot' ? ROOT_PATH : (ROOT_PATH / rel_path)
git(full_path, "push origin #{tag_name}")
end
end
desc "prepare release. verify clean, update version, tag"
task :prepare => ['git:verify_clean', :update_version, :tag, :push_tags]
desc "release to rubyforge for old skool folks"
task :rubyforge => [:prepare, 'rubyforge:release']
desc "release to gemcutter for new skool kids"
task :gemcutter => [:prepare, 'gemcutter:release']
desc "one release to rule them all"
task :all => [:prepare, 'release:gemcutter', 'release:rubyforge']
end
desc "computes the current hash of the code. used to autodetect build changes"
task :hash_content do
require 'yaml'
require 'digest/md5'
ignore = IGNORE_CHANGES.map do |x|
if x =~ /^\^/
/^#{Regexp.escape(ROOT_PATH / x[1..-1])}/
else
/#{Regexp.escape(x)}/
end
end
# First, get the hashinfo if it exists. use this to decide if we need to
# rehash
hashinfo_path = ROOT_PATH / '.hashinfo.yml'
hash_date = 0
hash_digest = nil
if File.exist?(hashinfo_path)
yaml = YAML.load_file(hashinfo_path)
hash_date = yaml['date'] || yaml[:date] || hash_date
hash_digest = yaml['digest'] || yaml[:digest] || hash_digest
end
# paths to search
paths = Dir.glob(File.join(ROOT_PATH, '**', '*')).reject do |path|
File.directory?(path) || (ignore.find { |i| path =~ i })
end
cur_date = 0
paths.each do |path|
mtime = File.mtime(path)
mtime = mtime.nil? ? 0 : mtime.to_i
$stdout.puts "detected file change: #{path.gsub(ROOT_PATH,'')}" if mtime > hash_date
cur_date = mtime if mtime > cur_date
end
if hash_digest.nil? || (cur_date != hash_date)
digests = paths.map do |path|
Digest::SHA1.hexdigest(File.read(path))
end
digests.compact!
hash_digest = Digest::SHA1.hexdigest(digests.join)
end
hash_date = cur_date
# write cache
File.open(hashinfo_path, 'w+') do |f|
YAML.dump({ :date => hash_date, :digest => hash_digest }, f)
end
# finally set the hash
CONTENT_HASH = hash_digest
$stdout.puts "CONTENT_HASH = #{CONTENT_HASH}"
end
desc "updates the VERSION file, bumbing the build rev if the current commit has changed"
task :update_version => 'hash_content' do
path = ROOT_PATH / 'VERSION.yml'
require 'yaml'
# first, load the current yaml if possible
major = 1
minor = 0
build = 99
rev = '-0-'
dist = {}
if File.exist?(path)
yaml = YAML.load_file(path)
major = yaml['major'] || yaml[:major] || major
minor = yaml['minor'] || yaml[:minor] || minor
build = yaml['patch'] || yaml[:patch] || build
rev = yaml['digest'] || yaml[:digest] || rev
end
build += 1 if rev != CONTENT_HASH #increment if needed
rev = CONTENT_HASH
# Update distribution versions
DIST.each do |rel_path, ignored|
dist_path = ROOT_PATH / rel_path
if File.exists?(dist_path)
dist_rev = git(dist_path, "log HEAD^..HEAD")
dist_rev = dist_rev.split("\n").first.scan(/commit ([^\s]+)/)
dist_rev = ((dist_rev || []).first || []).first
if dist_rev.nil?
$stdout.puts " WARN: cannot find revision for #{rel_path}"
else
dist[rel_path] = dist_rev
end
end
end
$stdout.puts "write version #{[major, minor, build].join('.')} => #{path}"
File.open(path, 'w+') do |f|
YAML.dump({
:major => major,
:minor => minor,
:patch => build,
:digest => rev,
:dist => dist
}, f)
end
RELEASE_VERSION = "#{major}.#{minor}.#{build}"
end
desc "cleanup the pkg dir"
task :clean do
path = ROOT_PATH / 'pkg'
FileUtils.rm_r(path) if File.directory?(path)
`rm #{ROOT_PATH / '*.gem'}`
end
namespace :git do
desc "verifies there are no pending changes to commit to git"
task :verify_clean do
DIST.keys.push('abbot').each do |repo_name|
full_path = repo_name=='abbot' ? ROOT_PATH : (ROOT_PATH / repo_name)
result = git(full_path, 'status')
if !(result =~ /nothing to commit \(working directory clean\)/)
if (repo_name != 'abbot') ||
(!(result =~ /#\n#\tmodified: VERSION.yml\n#\n/))
$stderr.puts "\nFATAL: Cannot complete task: changes are still pending in the '#{repo_name}' repository."
$stderr.puts " Commit your changes to git to continue.\n\n"
exit(1)
end
end
end
end
desc "Collects the current SHA1 commit hash into COMMIT_ID"
task :collect_commit do
log = `git log HEAD^..HEAD`
COMMIT_ID = log.split("\n").first.match(/commit ([\w]+)/).to_a[1]
if COMMIT_ID.empty?
$stderr.puts "\nFATAL: Cannot discover current commit id"
exit(1)
else
$stdout.puts "COMMIT_ID = #{COMMIT_ID}"
end
end
end
# Write a new version everytime we generate
task 'gemspec:generate' => :update_version
task 'rubyforge:setup' => :update_version
Spec::Rake::SpecTask.new
# EOF