sprout 0.3.35
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sprout might be problematic. Click here for more details.
- data/MIT-LICENSE.txt +20 -0
- data/Manifest.txt +9 -0
- data/bin/sprout +167 -0
- data/lib/command.rb +29 -0
- data/lib/file_target.rb +8 -0
- data/lib/generate.rb +37 -0
- data/lib/library.rb +18 -0
- data/lib/log.rb +46 -0
- data/lib/platform.rb +110 -0
- data/lib/progress_bar.rb +314 -0
- data/lib/project.rb +10 -0
- data/lib/project_model.rb +59 -0
- data/lib/remote_file_loader.rb +186 -0
- data/lib/remote_file_target.rb +44 -0
- data/lib/sprout.rb +340 -0
- data/lib/sprout/version.rb +9 -0
- data/lib/task.rb +20 -0
- data/lib/template.rb +37 -0
- data/lib/template_resolver.rb +204 -0
- data/lib/tool.rb +18 -0
- data/lib/user.rb +234 -0
- data/rakefile.rb +146 -0
- data/setup.rb +1585 -0
- metadata +105 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
module PatternPark
|
3
|
+
|
4
|
+
class RemoteFileTarget < FileTarget
|
5
|
+
attr_accessor :url,
|
6
|
+
:type,
|
7
|
+
:sprout,
|
8
|
+
:archive_type,
|
9
|
+
:archive_path,
|
10
|
+
:install_path,
|
11
|
+
:project_path,
|
12
|
+
:post_install
|
13
|
+
:mount_path
|
14
|
+
attr_reader :downloaded_path,
|
15
|
+
:file_name,
|
16
|
+
:copy_path
|
17
|
+
|
18
|
+
def resolve
|
19
|
+
# already run once, don't run again in this session
|
20
|
+
if(!file_name.nil?)
|
21
|
+
return
|
22
|
+
end
|
23
|
+
if(url.nil? || url == '')
|
24
|
+
return
|
25
|
+
end
|
26
|
+
@file_name = url.split('/').pop
|
27
|
+
@downloaded_path = File.join(Sprout.cache, type, install_path, file_name)
|
28
|
+
a_type = (archive_type == 'txt') ? nil : archive_type
|
29
|
+
@install_path = File.join(Sprout.cache, type, install_path, a_type)
|
30
|
+
@copy_path = File.join(install_path, archive_path)
|
31
|
+
loader = RemoteFileLoader.new
|
32
|
+
|
33
|
+
if(Sprout.update || !File.exists?(downloaded_path))
|
34
|
+
# retrieve from the network
|
35
|
+
loader.get_remote_file(url, downloaded_path)
|
36
|
+
end
|
37
|
+
|
38
|
+
if(Sprout.update || !File.exists?(install_path))
|
39
|
+
# unpack into install path
|
40
|
+
loader.unpack_downloaded_file(downloaded_path, install_path)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/sprout.rb
ADDED
@@ -0,0 +1,340 @@
|
|
1
|
+
$:.push(File.dirname(__FILE__))
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/tasklib'
|
5
|
+
require 'yaml'
|
6
|
+
require 'log'
|
7
|
+
require 'erb'
|
8
|
+
require 'uri'
|
9
|
+
require 'fileutils'
|
10
|
+
require 'zip/zipfilesystem'
|
11
|
+
require 'archive/tar/minitar'
|
12
|
+
|
13
|
+
module PatternPark
|
14
|
+
class SproutError < StandardError; end
|
15
|
+
class UsageError < SproutError; end
|
16
|
+
|
17
|
+
class Sprout
|
18
|
+
attr_accessor :name,
|
19
|
+
:type,
|
20
|
+
:render,
|
21
|
+
:platform,
|
22
|
+
:base_url,
|
23
|
+
:dependencies,
|
24
|
+
:targets,
|
25
|
+
:config_cache,
|
26
|
+
:config
|
27
|
+
|
28
|
+
@@base_urls = ['http://projectsprouts.googlecode.com/svn/trunk/sprouts/',
|
29
|
+
'http://www.projectsprouts.org/sprout/']
|
30
|
+
@@default_rakefiles = ['rakefile', 'Rakefile', 'rakefile.rb', 'Rakefile.rb'].freeze
|
31
|
+
@@universal = 'universal'
|
32
|
+
@@update = false
|
33
|
+
@@project_name = ''
|
34
|
+
@@config_cache = nil
|
35
|
+
@@home = nil
|
36
|
+
@@cache = nil
|
37
|
+
@@project_path = nil
|
38
|
+
|
39
|
+
##
|
40
|
+
# Given a simple string @name, request that sprout
|
41
|
+
# definition from each location in the location list
|
42
|
+
# until it's found
|
43
|
+
#
|
44
|
+
def Sprout.load(name)
|
45
|
+
local = File.join(Sprout.config_cache, name)
|
46
|
+
if(!Sprout.update && File.exists?(local))
|
47
|
+
return Sprout.load_local(local)
|
48
|
+
else
|
49
|
+
@@base_urls.each do |url|
|
50
|
+
begin
|
51
|
+
loader = RemoteFileLoader.new
|
52
|
+
loader.get_remote_file(url + name, local)
|
53
|
+
sprout = Sprout.load_local(local)
|
54
|
+
if(sprout.post_install)
|
55
|
+
eval(sprout.post_install)
|
56
|
+
end
|
57
|
+
return sprout
|
58
|
+
rescue OpenURI::HTTPError => e
|
59
|
+
Log.puts("[WARNING] Sprout not found at: #{url + name}, trying next location")
|
60
|
+
next
|
61
|
+
end
|
62
|
+
raise SproutError.new("\n[ERROR] Sprout could not find '#{name}' definition at any known locations, please check the sprout name and try again.")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Retrieve and resolve a locally downloaded Sprout
|
69
|
+
def Sprout.load_local(path)
|
70
|
+
data = nil
|
71
|
+
File.open(path, 'r') do |f|
|
72
|
+
data = f.read
|
73
|
+
end
|
74
|
+
data = ERB.new(data, nil, '>').result(binding)
|
75
|
+
begin
|
76
|
+
sprout = YAML.load(data)
|
77
|
+
rescue StandardError => e
|
78
|
+
Log.puts("[ERROR] An invalid sprout definition was encountered at: [#{path}] with:\n\n#{data}\n\nPlease try again...")
|
79
|
+
if(File.exists?(path))
|
80
|
+
File.delete(path)
|
81
|
+
end
|
82
|
+
raise UsageError.new('Invalid Sprout definiton')
|
83
|
+
end
|
84
|
+
sprout.resolve
|
85
|
+
return sprout
|
86
|
+
end
|
87
|
+
|
88
|
+
def Sprout.update=(update)
|
89
|
+
@@update = update
|
90
|
+
end
|
91
|
+
|
92
|
+
def Sprout.update
|
93
|
+
return @@update
|
94
|
+
end
|
95
|
+
|
96
|
+
##
|
97
|
+
# Begin loading and resolving this Sprout instance
|
98
|
+
# and recursively call on dependencies
|
99
|
+
def resolve
|
100
|
+
load_target
|
101
|
+
load_dependencies
|
102
|
+
end
|
103
|
+
|
104
|
+
def execute
|
105
|
+
dependencies.each do |dep|
|
106
|
+
dep.execute
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def post_install
|
111
|
+
if(target.nil?)
|
112
|
+
return nil
|
113
|
+
end
|
114
|
+
return target.post_install
|
115
|
+
end
|
116
|
+
|
117
|
+
##
|
118
|
+
# Load the remote file target associated with this sprout instance
|
119
|
+
def load_target
|
120
|
+
target = get_platform_target
|
121
|
+
if(target)
|
122
|
+
# Forward type name so that RemoteFileTargets can place
|
123
|
+
# downloaded files into the appropriate user home folder
|
124
|
+
target.type = type
|
125
|
+
target.resolve
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
##
|
130
|
+
# Take the array of string dependency names
|
131
|
+
# load each dependency YAML file, and replace
|
132
|
+
# the array with resolved Sprout instances
|
133
|
+
# Tell each dependency to load it's own
|
134
|
+
# dependencies
|
135
|
+
def load_dependencies(loaded_deps=nil)
|
136
|
+
loaded_deps = (loaded_deps.nil?) ? [name] : loaded_deps # Don't reload deps have already been loaded
|
137
|
+
deps = []
|
138
|
+
|
139
|
+
if(dependencies)
|
140
|
+
dependencies.each do |dep|
|
141
|
+
dep.values.each do |name|
|
142
|
+
if(!loaded_deps.index(name))
|
143
|
+
dep = Sprout.load(name)
|
144
|
+
loaded_deps << name
|
145
|
+
deps << dep
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
@dependencies = deps
|
151
|
+
end
|
152
|
+
|
153
|
+
##
|
154
|
+
# Insert search locations (Array) 'base paths' for Sprout.load operations
|
155
|
+
def Sprout.insert_locations(locations)
|
156
|
+
@@base_urls = Sprout.clean_locations(locations) + @@base_urls
|
157
|
+
end
|
158
|
+
|
159
|
+
# TODO: Be smart about added a trailing '/'
|
160
|
+
# Try to ensure that only valid URLs get
|
161
|
+
# added to the list of locations - throw
|
162
|
+
# something informative if needed.
|
163
|
+
def Sprout.clean_locations(locations)
|
164
|
+
return locations
|
165
|
+
end
|
166
|
+
|
167
|
+
##
|
168
|
+
# The system-specific home folder for Sprout application data
|
169
|
+
# e.g., On OS X, /Users/you/Library/Sprouts
|
170
|
+
# e.g., On Win, C:\Documents And Settings\you\Local Settings\Application Data\Sprouts
|
171
|
+
def Sprout.home
|
172
|
+
if(@@home.nil?)
|
173
|
+
@@home = User.new().application_home(:sprouts)
|
174
|
+
end
|
175
|
+
return @@home
|
176
|
+
end
|
177
|
+
|
178
|
+
##
|
179
|
+
# The nearest valid project path or current working directory
|
180
|
+
# if no rakefile was found in parent paths
|
181
|
+
def Sprout.project_path(path=nil)
|
182
|
+
if(@@project_path.nil?)
|
183
|
+
path = (path.nil?) ? Dir.pwd : path;
|
184
|
+
path = Sprout.get_project_path(path)
|
185
|
+
if(path.nil?)
|
186
|
+
path = Dir.pwd
|
187
|
+
end
|
188
|
+
@@project_path = path
|
189
|
+
end
|
190
|
+
return @@project_path
|
191
|
+
end
|
192
|
+
|
193
|
+
def Sprout.project_path=(path)
|
194
|
+
@@project_path = path
|
195
|
+
end
|
196
|
+
|
197
|
+
def Sprout.get_project_path(path)
|
198
|
+
if(path.nil? || path == '/')
|
199
|
+
return nil
|
200
|
+
end
|
201
|
+
@@default_rakefiles.each do |file|
|
202
|
+
if(File.exists?(File.join(path, file)))
|
203
|
+
return path
|
204
|
+
end
|
205
|
+
end
|
206
|
+
return Sprout.get_project_path(File.dirname(path))
|
207
|
+
end
|
208
|
+
|
209
|
+
##
|
210
|
+
# Offline storage location for network entities like
|
211
|
+
# Sprout definitions, tasks and archives
|
212
|
+
def Sprout.cache
|
213
|
+
if(@@cache.nil?)
|
214
|
+
@@cache = File.join(Sprout.home, 'cache')
|
215
|
+
end
|
216
|
+
return @@cache
|
217
|
+
end
|
218
|
+
|
219
|
+
def Sprout.config_cache
|
220
|
+
if(@@config_cache.nil?)
|
221
|
+
@@config_cache = File.join(Sprout.cache, 'sprouts')
|
222
|
+
end
|
223
|
+
return @@config_cache
|
224
|
+
end
|
225
|
+
|
226
|
+
##
|
227
|
+
# List of potential rakefile names for project_path searching
|
228
|
+
def Sprout.default_rakefiles
|
229
|
+
return @@default_rakefiles
|
230
|
+
end
|
231
|
+
|
232
|
+
def Sprout.rakefile
|
233
|
+
@@default_rakefiles.each do |name|
|
234
|
+
file = File.join(Sprout.project_path, name)
|
235
|
+
if(File.exists?(file))
|
236
|
+
return file
|
237
|
+
end
|
238
|
+
end
|
239
|
+
return nil
|
240
|
+
end
|
241
|
+
|
242
|
+
##
|
243
|
+
# Reset static values for test purposes
|
244
|
+
def Sprout.init_values
|
245
|
+
User.init_values
|
246
|
+
@@project_path = nil
|
247
|
+
@@config_cache = nil
|
248
|
+
@@cache = nil
|
249
|
+
@@home = nil
|
250
|
+
end
|
251
|
+
|
252
|
+
##
|
253
|
+
# List of files to ignore when copying project templates
|
254
|
+
# These files will not be copied
|
255
|
+
@@COPY_IGNORE_FILES = ['.', '..', '.svn', '.DS_Store', 'CVS', '.cvs' 'Thumbs.db', '__MACOSX', '.Trashes', 'Desktop DB', 'Desktop DF']
|
256
|
+
# Do not copy files found in the ignore_files list
|
257
|
+
def Sprout.ignore_file? file
|
258
|
+
@@COPY_IGNORE_FILES.each do |name|
|
259
|
+
if(name == file)
|
260
|
+
return true
|
261
|
+
end
|
262
|
+
end
|
263
|
+
return false
|
264
|
+
end
|
265
|
+
|
266
|
+
##
|
267
|
+
# The project name as entered in the sprout shell command
|
268
|
+
def Sprout.project_name=(name)
|
269
|
+
@@project_name = name
|
270
|
+
end
|
271
|
+
|
272
|
+
def Sprout.project_name
|
273
|
+
return @@project_name
|
274
|
+
end
|
275
|
+
|
276
|
+
def get_platform_target
|
277
|
+
usr = User.new
|
278
|
+
@target = nil
|
279
|
+
if(targets)
|
280
|
+
universal_target = nil
|
281
|
+
platform = usr.platform.to_s
|
282
|
+
targets.each do |t|
|
283
|
+
if(t.platform == platform)
|
284
|
+
@target = t
|
285
|
+
elsif(t.platform == @@universal)
|
286
|
+
universal_target = t
|
287
|
+
end
|
288
|
+
end
|
289
|
+
if(target.nil? && universal_target)
|
290
|
+
@target = universal_target
|
291
|
+
end
|
292
|
+
end
|
293
|
+
return @target
|
294
|
+
end
|
295
|
+
|
296
|
+
##
|
297
|
+
# The first FileTarget that is applicable for this
|
298
|
+
# client operating system
|
299
|
+
def target
|
300
|
+
return @target
|
301
|
+
end
|
302
|
+
|
303
|
+
def archive_path
|
304
|
+
return File.join(install_path, target.archive_path)
|
305
|
+
end
|
306
|
+
|
307
|
+
def install_path
|
308
|
+
target.install_path
|
309
|
+
end
|
310
|
+
|
311
|
+
def downloaded_path
|
312
|
+
target.downloaded_path
|
313
|
+
end
|
314
|
+
|
315
|
+
def config_path(name)
|
316
|
+
return Sprout.config_cache + name
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
require 'singleton'
|
321
|
+
require 'progress_bar'
|
322
|
+
require 'template_resolver'
|
323
|
+
require 'platform'
|
324
|
+
require 'user'
|
325
|
+
require 'project'
|
326
|
+
require 'library'
|
327
|
+
require 'template'
|
328
|
+
require 'task'
|
329
|
+
require 'command'
|
330
|
+
require 'tool'
|
331
|
+
require 'remote_file_loader'
|
332
|
+
require 'file_target'
|
333
|
+
require 'remote_file_target'
|
334
|
+
|
335
|
+
require 'project_model'
|
336
|
+
require 'generate'
|
337
|
+
end
|
338
|
+
|
339
|
+
cache = File.join(PatternPark::Sprout.cache)
|
340
|
+
$:.push(cache)
|
data/lib/task.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
module PatternPark
|
3
|
+
|
4
|
+
class Task < Sprout
|
5
|
+
|
6
|
+
def type
|
7
|
+
return 'task'
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute
|
11
|
+
super
|
12
|
+
if(target.project_path != '')
|
13
|
+
from = target.install_path
|
14
|
+
to = File.join(Sprout.project_path, target.project_path)
|
15
|
+
FileUtils.makedirs(to)
|
16
|
+
TemplateResolver.instance.copy_files(from, to, render)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/template.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
module PatternPark
|
3
|
+
require 'find'
|
4
|
+
|
5
|
+
class Template < Sprout
|
6
|
+
|
7
|
+
def type
|
8
|
+
return 'template'
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute
|
12
|
+
if(target)
|
13
|
+
proj_path = File.join(Sprout.project_path, target.project_path)
|
14
|
+
from = target.install_path
|
15
|
+
to = proj_path
|
16
|
+
FileUtils.makedirs(to)
|
17
|
+
TemplateResolver.instance.copy_files(from, to, render)
|
18
|
+
|
19
|
+
# This code will change the Sprout.project path
|
20
|
+
# to the first rakefile found in the template
|
21
|
+
# I'm not convinced this is a good idea -
|
22
|
+
# seems like other utils may need to know about
|
23
|
+
# the structure of a project, but most of them
|
24
|
+
# need to load the nearest rakefile and use
|
25
|
+
# the paths identified in them....
|
26
|
+
Find.find(proj_path) do |path|
|
27
|
+
Sprout.default_rakefiles.each do |rakefile|
|
28
|
+
if(File.basename(path) == rakefile)
|
29
|
+
Sprout.project_path = File.dirname(path)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
super
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|