monk-shake 1.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +59 -0
- data/bin/monk +23 -0
- data/lib/monk.rb +313 -0
- data/lib/monk/config.rb +27 -0
- data/lib/monk/helpers.rb +129 -0
- data/lib/monk/init_helpers.rb +34 -0
- data/test/add_test.rb +48 -0
- data/test/help_test.rb +39 -0
- data/test/init_test.rb +63 -0
- data/test/mock.rb +36 -0
- data/test/test_helper.rb +48 -0
- metadata +77 -0
data/README.md
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
Monk
|
2
|
+
====
|
3
|
+
|
4
|
+
A feature-complete rewrite of Monk that uses Shake instead of Thor.
|
5
|
+
It is modeled after Monk 1.0 beta.
|
6
|
+
|
7
|
+
See more info in [monkrb.com](http://www.morkrb.com).
|
8
|
+
|
9
|
+
**NOTE:** This is NOT an official replacement for Monk, nor is it
|
10
|
+
supported or endorsed by Citrusbyte.
|
11
|
+
|
12
|
+
### What is it?
|
13
|
+
|
14
|
+
* Monk lets you start a Sinatra project painlessly with everything set
|
15
|
+
up for you.
|
16
|
+
|
17
|
+
### Get started
|
18
|
+
|
19
|
+
You may need to uninstall the original monk gem.
|
20
|
+
|
21
|
+
$ rvm @global # TIP: Recommended for RVM users
|
22
|
+
$ gem uninstall monk
|
23
|
+
$ gem install monk-shake --pre
|
24
|
+
$ monk
|
25
|
+
|
26
|
+
### Differences from the real Monk in general
|
27
|
+
|
28
|
+
* *No more Thor!* The new Monkfile has deprecated the old Thorfile.
|
29
|
+
This version uses Shake instead.
|
30
|
+
|
31
|
+
* *Faster* as a result of above.
|
32
|
+
|
33
|
+
* New help screens. They are actually very helpful.
|
34
|
+
|
35
|
+
* This stores your config in a new format (YAML) in `~/.monk.conf`.
|
36
|
+
|
37
|
+
* The default skeleton is [github.com/rstacruz/monk-plus](https://github.com/rstacruz/monk-plus),
|
38
|
+
the mere reason being it's the only one that takes advantage of new
|
39
|
+
features at the moment.
|
40
|
+
|
41
|
+
### Changes from Monk 0.x
|
42
|
+
|
43
|
+
* This doesn't rely on the `dependencies` gem.
|
44
|
+
|
45
|
+
* `monk init` will cache skeleton files so it'll run faster next time.
|
46
|
+
|
47
|
+
* New `monk install` command installs gems from the `.gems` manifest file.
|
48
|
+
|
49
|
+
* The command `monk unpack` now uses the more reliable RVM.
|
50
|
+
|
51
|
+
* New `monk lock` command generates a `.gems` file for you.
|
52
|
+
|
53
|
+
### Differences from Monk 1.0 beta
|
54
|
+
|
55
|
+
* This does not require RVM.
|
56
|
+
|
57
|
+
* `monk install` will first check if a gem is installed. It will not
|
58
|
+
try to reinstall gems you already have.
|
59
|
+
|
data/bin/monk
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems' if RUBY_VERSION <= "1.9"
|
3
|
+
require File.expand_path('../../vendor/shake/lib/shake', __FILE__)
|
4
|
+
|
5
|
+
# Legacy Monk compatibility.
|
6
|
+
# If there is a Thorfile (but no Monkfile), assume it's a Monk <1.0 project.
|
7
|
+
# Defer to Thor for processing of that file.
|
8
|
+
thor = Shake.find_in_project('Thorfile')
|
9
|
+
if thor
|
10
|
+
monk = Shake.find_in_project('Monkfile')
|
11
|
+
if !monk
|
12
|
+
Dir.chdir File.dirname(thor)
|
13
|
+
require 'thor'
|
14
|
+
load 'Thorfile'
|
15
|
+
Monk.start
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
require File.expand_path('../../lib/monk', __FILE__)
|
21
|
+
|
22
|
+
Monk.load_monkfile
|
23
|
+
Monk.run!
|
data/lib/monk.rb
ADDED
@@ -0,0 +1,313 @@
|
|
1
|
+
$:.push *Dir[File.expand_path('../../vendor/*/lib', __FILE__)]
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'shake'
|
5
|
+
|
6
|
+
class Monk < Shake
|
7
|
+
VERSION = "1.0.0.pre1"
|
8
|
+
PREFIX = File.expand_path('../monk', __FILE__)
|
9
|
+
|
10
|
+
autoload :Helpers, "#{PREFIX}/helpers"
|
11
|
+
autoload :InitHelpers, "#{PREFIX}/init_helpers"
|
12
|
+
autoload :Config, "#{PREFIX}/config"
|
13
|
+
|
14
|
+
extend Helpers
|
15
|
+
extend InitHelpers
|
16
|
+
|
17
|
+
task(:init) do
|
18
|
+
name = params.extract('-s') || 'default'
|
19
|
+
wrong_usage if params.size != 1
|
20
|
+
|
21
|
+
target = params.shift
|
22
|
+
|
23
|
+
unless config.skeletons[name]
|
24
|
+
pass "No such skeleton: #{name}\n" +
|
25
|
+
"Type `#{executable} list` for a list of known skeletons."
|
26
|
+
end
|
27
|
+
|
28
|
+
if File.exists?(target)
|
29
|
+
pass "Error: the target directory already exists."
|
30
|
+
end
|
31
|
+
|
32
|
+
skeleton_files = cache_skeleton(name)
|
33
|
+
pass "Error: can't retrieve the skeleton files." unless skeleton_files
|
34
|
+
cp_r skeleton_files, target
|
35
|
+
|
36
|
+
in_path (target) {
|
37
|
+
rm_rf '.git'
|
38
|
+
touch 'Monkfile'
|
39
|
+
system_q "rvm #{RUBY_VERSION}@#{target} --rvmrc --create" if rvm?
|
40
|
+
system_q "rvm rvmrc trust" if rvm?
|
41
|
+
}
|
42
|
+
|
43
|
+
puts
|
44
|
+
puts "Success! You've created a new project."
|
45
|
+
puts "Get started now:"
|
46
|
+
puts
|
47
|
+
puts " $ cd #{target}"
|
48
|
+
puts " $ #{executable} start"
|
49
|
+
puts
|
50
|
+
|
51
|
+
if rvm?
|
52
|
+
puts "An RVM gemset @#{target} has been created for you."
|
53
|
+
puts
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
task(:install) do
|
58
|
+
manifest = '.gems'
|
59
|
+
|
60
|
+
pass "This project does not have a .gems manifest." unless File.exists?(manifest)
|
61
|
+
|
62
|
+
gems = File.read(manifest).split("\n")
|
63
|
+
|
64
|
+
gems.reject! { |name| name =~ /^\s*(#|$)/ }
|
65
|
+
pass "The .gems manifest is empty." unless gems.any?
|
66
|
+
|
67
|
+
gems.reject! { |name| has_gem? name }
|
68
|
+
pass "All good! You have all needed gems installed." unless gems.any?
|
69
|
+
|
70
|
+
unless rvm?
|
71
|
+
err "Tip: RVM is a great way to manage gems across multiple projects."
|
72
|
+
err "See http://rvm.beginrescueend.com for more info."
|
73
|
+
err
|
74
|
+
end
|
75
|
+
|
76
|
+
gems.each { |name| system "gem install #{name}" }
|
77
|
+
end
|
78
|
+
|
79
|
+
task(:unpack) do
|
80
|
+
ensure_rvm or pass
|
81
|
+
system "rvm rvmrc load"
|
82
|
+
system "rvm gemset unpack vendor"
|
83
|
+
end
|
84
|
+
|
85
|
+
task(:lock) do
|
86
|
+
ensure_rvm or pass
|
87
|
+
system "rvm rvmrc load"
|
88
|
+
system "rvm gemset export .gems"
|
89
|
+
end
|
90
|
+
|
91
|
+
task(:add) do
|
92
|
+
wrong_usage unless params.size == 2
|
93
|
+
name, repo = params
|
94
|
+
|
95
|
+
existed = !!config.skeletons[name]
|
96
|
+
|
97
|
+
config.skeletons[name] = repo
|
98
|
+
config.save!
|
99
|
+
|
100
|
+
if existed
|
101
|
+
err "Updated skeleton #{name}."
|
102
|
+
else
|
103
|
+
err "Added skeleton #{name}."
|
104
|
+
end
|
105
|
+
err "Create a new project from this skeleton by typing: #{executable} init NAME -s #{name}"
|
106
|
+
end
|
107
|
+
|
108
|
+
task (:rm) do
|
109
|
+
wrong_usage if params.size != 1
|
110
|
+
name = params.first
|
111
|
+
|
112
|
+
if name == 'default'
|
113
|
+
pass "You can't delete the default skeleton."
|
114
|
+
elsif config.skeletons[name]
|
115
|
+
config.skeletons.delete name.to_s
|
116
|
+
config.save!
|
117
|
+
|
118
|
+
err "Removed #{name}."
|
119
|
+
else
|
120
|
+
err "No such skeleton."
|
121
|
+
err "See `#{executable} list` for a list of skeletons."
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
task(:purge) do
|
126
|
+
rm_rf cache_path if File.directory?(cache_path)
|
127
|
+
err "Monk cache clear."
|
128
|
+
end
|
129
|
+
|
130
|
+
task(:list) do
|
131
|
+
wrong_usage if params.any?
|
132
|
+
|
133
|
+
puts "Available skeletons:"
|
134
|
+
puts
|
135
|
+
config.skeletons.each do |name, repo|
|
136
|
+
puts " %-20s %s" % [ name, repo ]
|
137
|
+
end
|
138
|
+
puts
|
139
|
+
puts "Create a new project by typing `#{executable} init NAME -s SKELETON`."
|
140
|
+
end
|
141
|
+
|
142
|
+
task(:help) do
|
143
|
+
show_help_for(params.first) and pass if params.any?
|
144
|
+
|
145
|
+
show_task = Proc.new { |name, t| err " %-20s %s" % [ t.usage || name, t.description ] }
|
146
|
+
|
147
|
+
err "Usage: #{executable} <command>"
|
148
|
+
err
|
149
|
+
|
150
|
+
if project?
|
151
|
+
err "Dependency commands:"
|
152
|
+
tasks_for(:dependency).each &show_task
|
153
|
+
err
|
154
|
+
if other_tasks.any?
|
155
|
+
err "Project commands:"
|
156
|
+
other_tasks.each &show_task
|
157
|
+
err
|
158
|
+
end
|
159
|
+
else
|
160
|
+
err "Commands:"
|
161
|
+
tasks_for(:init).each &show_task
|
162
|
+
err
|
163
|
+
err "Skeleton commands:"
|
164
|
+
tasks_for(:skeleton).each &show_task
|
165
|
+
err
|
166
|
+
end
|
167
|
+
|
168
|
+
err "Other commands:"
|
169
|
+
tasks_for(:help).each &show_task
|
170
|
+
|
171
|
+
unless project?
|
172
|
+
err
|
173
|
+
err "Get started by typing:"
|
174
|
+
err " $ #{executable} init my_project"
|
175
|
+
err
|
176
|
+
err "Type `#{executable} help COMMAND` for additional help on a command."
|
177
|
+
err "See http://www.monkrb.com for more information."
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
task(:version) do
|
182
|
+
puts "Monk-shake version #{VERSION}"
|
183
|
+
end
|
184
|
+
|
185
|
+
invalid do
|
186
|
+
task = task(command)
|
187
|
+
if task
|
188
|
+
err "Invalid usage."
|
189
|
+
err "Try: #{executable} #{task.usage}"
|
190
|
+
err
|
191
|
+
err "Type `#{executable} help` for more info."
|
192
|
+
else
|
193
|
+
err "Invalid command: #{command}"
|
194
|
+
err "Type `#{executable} help` for more info."
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# Task metadata
|
199
|
+
default :help
|
200
|
+
|
201
|
+
task(:init).tap do |t|
|
202
|
+
t.category = :init
|
203
|
+
t.usage = "init NAME"
|
204
|
+
t.description = "Starts a Monk project"
|
205
|
+
t.help = %{
|
206
|
+
Usage:
|
207
|
+
|
208
|
+
#{executable} init NAME [-s SKELETON]
|
209
|
+
|
210
|
+
Initializes a Monk application of a given name.
|
211
|
+
|
212
|
+
You may use a different skeleton by specifying `-s SKELETON` where
|
213
|
+
SKELETON refers to the name or URL of the skeleton. If this isn't specified,
|
214
|
+
the default skeleton is used.
|
215
|
+
|
216
|
+
Examples
|
217
|
+
--------
|
218
|
+
|
219
|
+
This creates a new Monk/Sinatra application in the directory `myapp`.
|
220
|
+
|
221
|
+
#{executable} init myapp
|
222
|
+
|
223
|
+
This creates a new application based on the skeleton in the given Git repo.
|
224
|
+
|
225
|
+
#{executable} add myskeleton https://github.com/rstacruz/myskeleton.git
|
226
|
+
#{executable} init myapp -s myskeleton
|
227
|
+
}.gsub(/^ {6}/,'').strip.split("\n")
|
228
|
+
end
|
229
|
+
|
230
|
+
task(:add).tap do |t|
|
231
|
+
t.category = :skeleton
|
232
|
+
t.usage = "add NAME URL"
|
233
|
+
t.description = "Adds a skeleton"
|
234
|
+
end
|
235
|
+
|
236
|
+
task(:rm).tap do |t|
|
237
|
+
t.category = :skeleton
|
238
|
+
t.usage = "rm NAME"
|
239
|
+
t.description = "Removes a skeleton"
|
240
|
+
end
|
241
|
+
|
242
|
+
task(:list).tap do |t|
|
243
|
+
t.category = :skeleton
|
244
|
+
t.description = "Lists known skeletons"
|
245
|
+
end
|
246
|
+
|
247
|
+
task(:purge).tap do |t|
|
248
|
+
t.category = :skeleton
|
249
|
+
t.description = "Clears the skeleton cache"
|
250
|
+
end
|
251
|
+
|
252
|
+
task(:help).tap do |t|
|
253
|
+
t.category = :help
|
254
|
+
t.description = "Shows a list of commands"
|
255
|
+
end
|
256
|
+
|
257
|
+
task(:version).tap do |t|
|
258
|
+
t.category = :help
|
259
|
+
t.description = "Shows the Monk version"
|
260
|
+
end
|
261
|
+
|
262
|
+
task(:install).tap do |t|
|
263
|
+
t.category = :dependency
|
264
|
+
t.description = "Install gems in the .gems manifest file"
|
265
|
+
t.help = %{
|
266
|
+
Usage:
|
267
|
+
|
268
|
+
#{executable} install
|
269
|
+
|
270
|
+
Loads the given gemset name of your project, and installs the gems
|
271
|
+
needed by your project.
|
272
|
+
|
273
|
+
Gems are specified in the `.gems` file. This is created using
|
274
|
+
`#{executable} lock`.
|
275
|
+
|
276
|
+
The gemset name is then specified in `.rvmrc`, which is created upon
|
277
|
+
creating your project with `#{executable} init`.
|
278
|
+
}.gsub(/^ {6}/,'').strip.split("\n")
|
279
|
+
end
|
280
|
+
|
281
|
+
task(:unpack).tap do |t|
|
282
|
+
t.category = :dependency
|
283
|
+
t.description = "Freeze gem dependencies into vendor/"
|
284
|
+
t.help = %{
|
285
|
+
Usage:
|
286
|
+
|
287
|
+
#{executable} unpack
|
288
|
+
|
289
|
+
Freezes the current gem dependencies of your project into the `vendor/`
|
290
|
+
path of your project.
|
291
|
+
|
292
|
+
This allows you to commit the gem contents into your project's repository.
|
293
|
+
This way, deploying your project elsewhere would not need `monk install`
|
294
|
+
or `gem install` to set up the dependencies.
|
295
|
+
}.gsub(/^ {6}/,'').strip.split("\n")
|
296
|
+
end
|
297
|
+
|
298
|
+
task(:lock).tap do |t|
|
299
|
+
t.category = :dependency
|
300
|
+
t.description = "Lock gem dependencies into a .gems manifest file"
|
301
|
+
t.help = %{
|
302
|
+
Usage:
|
303
|
+
|
304
|
+
#{executable} lock
|
305
|
+
|
306
|
+
Locks the current gem version dependencies of your project into the gem
|
307
|
+
manifest file.
|
308
|
+
|
309
|
+
This creates the `.gems` file for your project, which is then used by
|
310
|
+
`#{executable} install`.
|
311
|
+
}.gsub(/^ {6}/,'').strip.split("\n")
|
312
|
+
end
|
313
|
+
end
|
data/lib/monk/config.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
class Monk::Config < OpenStruct
|
5
|
+
def self.filename
|
6
|
+
File.expand_path(File.join(%w(~ .monk.conf)))
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.load
|
10
|
+
if File.file?(filename)
|
11
|
+
self.new YAML::load_file(filename)
|
12
|
+
else
|
13
|
+
self.new
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(*a)
|
18
|
+
super
|
19
|
+
self.skeletons ||= Hash.new
|
20
|
+
# At the time of writing, this is the only monk-shake compatible skeleton
|
21
|
+
self.skeletons['default'] ||= 'git://github.com/rstacruz/monk-plus.git'
|
22
|
+
end
|
23
|
+
|
24
|
+
def save!
|
25
|
+
File.open(self.class.filename, 'w') { |f| f.write YAML::dump(@table) }
|
26
|
+
end
|
27
|
+
end
|
data/lib/monk/helpers.rb
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
# All these functions are available as Monk.xxxx.
|
2
|
+
# (eg, Monk.tasks_for)
|
3
|
+
#
|
4
|
+
module Monk::Helpers
|
5
|
+
def config
|
6
|
+
@config ||= Monk::Config.load
|
7
|
+
end
|
8
|
+
|
9
|
+
def tasks_for(category)
|
10
|
+
tasks.select { |name, t| t.category == category }
|
11
|
+
end
|
12
|
+
|
13
|
+
def other_tasks
|
14
|
+
tasks.select { |name, t| t.category.nil? }
|
15
|
+
end
|
16
|
+
|
17
|
+
def rvm?
|
18
|
+
@has_rvm = (!! `rvm` rescue false) if @has_rvm.nil?
|
19
|
+
@has_rvm
|
20
|
+
end
|
21
|
+
|
22
|
+
def ensure_rvm
|
23
|
+
return true if rvm?
|
24
|
+
err "You need RVM installed for this command."
|
25
|
+
err "See http://rvm.beginrescueend.com for more info."
|
26
|
+
end
|
27
|
+
|
28
|
+
# Checks if a certain gem is installed.
|
29
|
+
# The format is the same as that found in the .gems file.
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# has_gem?('nest -v1.1.0')
|
33
|
+
#
|
34
|
+
def has_gem?(str)
|
35
|
+
_, name, version = str.match(/^([A-Za-z_\-]+) -v(.*)$/).to_a
|
36
|
+
name ||= str
|
37
|
+
version ||= ">=0"
|
38
|
+
|
39
|
+
begin
|
40
|
+
gem(name, version)
|
41
|
+
true
|
42
|
+
rescue Gem::LoadError
|
43
|
+
false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Performs a given block in the given path.
|
48
|
+
def in_path(path, &blk)
|
49
|
+
old = Dir.pwd
|
50
|
+
Dir.chdir path
|
51
|
+
say_status :cd, path
|
52
|
+
yield
|
53
|
+
Dir.chdir old
|
54
|
+
end
|
55
|
+
|
56
|
+
# Loads the monkfile. Used by bin/monk.
|
57
|
+
def load_monkfile
|
58
|
+
file = find_in_project("Monkfile")
|
59
|
+
|
60
|
+
if file
|
61
|
+
load file
|
62
|
+
@project = File.dirname(file)
|
63
|
+
Dir.chdir @project
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def show_help_for(task)
|
68
|
+
name = params.first
|
69
|
+
task = task(name)
|
70
|
+
pass "No such command. Try: #{executable} help" unless task
|
71
|
+
|
72
|
+
help = task.help
|
73
|
+
if help
|
74
|
+
help.each { |line| err line }
|
75
|
+
err
|
76
|
+
else
|
77
|
+
err "Usage: #{executable} #{task.usage || name}"
|
78
|
+
err "#{task.description}." if task.description
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Checks if there is a loaded project or not.
|
83
|
+
def project?
|
84
|
+
! @project.nil?
|
85
|
+
end
|
86
|
+
|
87
|
+
# File expand: fx('~/.cache/monk')
|
88
|
+
def fx(*paths)
|
89
|
+
File.expand_path File.join(*paths.join('/').split('/'))
|
90
|
+
end
|
91
|
+
|
92
|
+
def system(cmd)
|
93
|
+
say_status :run, cmd
|
94
|
+
super
|
95
|
+
end
|
96
|
+
|
97
|
+
def system_q(cmd)
|
98
|
+
say_status :run, cmd
|
99
|
+
`#{cmd}`
|
100
|
+
end
|
101
|
+
|
102
|
+
def say_status(what, cmd)
|
103
|
+
c1 = "\033[0;33m"
|
104
|
+
c0 = "\033[0;m"
|
105
|
+
puts "#{c1}%10s#{c0} %s" % [ what, cmd ]
|
106
|
+
end
|
107
|
+
|
108
|
+
# File helpers
|
109
|
+
def touch(target)
|
110
|
+
say_status :touch, target
|
111
|
+
FileUtils.touch target
|
112
|
+
end
|
113
|
+
|
114
|
+
def mkdir_p(target)
|
115
|
+
return if File.directory?(target)
|
116
|
+
say_status :mkdir, target
|
117
|
+
FileUtils.mkdir_p target
|
118
|
+
end
|
119
|
+
|
120
|
+
def cp_r(from, target)
|
121
|
+
say_status :copy, "#{from} -> #{target}"
|
122
|
+
FileUtils.cp_r from, target
|
123
|
+
end
|
124
|
+
|
125
|
+
def rm_rf(target)
|
126
|
+
say_status :delete, target
|
127
|
+
FileUtils.rm_rf target
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Monk::InitHelpers
|
2
|
+
def cache_path(name=nil)
|
3
|
+
fx "~/.cache/monk", name
|
4
|
+
end
|
5
|
+
|
6
|
+
def directory_with_files?(path)
|
7
|
+
File.directory?(path) and Dir[File.join(path, '{.*,*}')].any?
|
8
|
+
end
|
9
|
+
|
10
|
+
# Cache skeleton files into ~/.cache/monk/default
|
11
|
+
def cache_skeleton(name)
|
12
|
+
repo = config.skeletons[name] or return
|
13
|
+
|
14
|
+
path = cache_path(name)
|
15
|
+
return path if directory_with_files?(path)
|
16
|
+
|
17
|
+
mkdir_p fx(path, '..')
|
18
|
+
|
19
|
+
git_clone repo, path
|
20
|
+
|
21
|
+
if $?.to_i != 0
|
22
|
+
rm_rf path
|
23
|
+
return nil
|
24
|
+
end
|
25
|
+
|
26
|
+
rm_rf File.join(path, '.git')
|
27
|
+
|
28
|
+
path
|
29
|
+
end
|
30
|
+
|
31
|
+
def git_clone(repo, path)
|
32
|
+
system "git clone --depth 1 #{repo} #{path}"
|
33
|
+
end
|
34
|
+
end
|
data/test/add_test.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
scope do
|
4
|
+
test 'add fail' do
|
5
|
+
monk 'add'
|
6
|
+
assert_invalid
|
7
|
+
end
|
8
|
+
|
9
|
+
test 'add fail 2' do
|
10
|
+
monk 'add x y z'
|
11
|
+
assert_invalid
|
12
|
+
end
|
13
|
+
|
14
|
+
test 'add success' do
|
15
|
+
monk 'add foobar git://github.com/y'
|
16
|
+
assert cerr.include?('Added skeleton')
|
17
|
+
|
18
|
+
monk 'list'
|
19
|
+
assert cout =~ /foobar +git:\/\/github.com\/y/
|
20
|
+
end
|
21
|
+
|
22
|
+
test 'update' do
|
23
|
+
monk 'add foobar git://github.com/y'
|
24
|
+
assert cerr.include?('Added skeleton')
|
25
|
+
|
26
|
+
monk 'add foobar git://github.com/z'
|
27
|
+
assert cerr.include?('Updated skeleton')
|
28
|
+
|
29
|
+
monk 'list'
|
30
|
+
assert cout =~ /foobar +git:\/\/github.com\/z/
|
31
|
+
end
|
32
|
+
|
33
|
+
test 'add remove add' do
|
34
|
+
monk 'add foobar git://github.com/y'
|
35
|
+
assert cerr.include?('Added skeleton')
|
36
|
+
|
37
|
+
monk 'rm foobar'
|
38
|
+
assert cerr.include?('Removed')
|
39
|
+
|
40
|
+
monk 'add foobar git://github.com/y'
|
41
|
+
assert cerr.include?('Added skeleton')
|
42
|
+
end
|
43
|
+
|
44
|
+
test 'remove' do
|
45
|
+
monk 'rm foobar'
|
46
|
+
assert cerr.include?('No such skeleton')
|
47
|
+
end
|
48
|
+
end
|
data/test/help_test.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
scope do
|
4
|
+
test 'invalid command' do
|
5
|
+
monk 'shivers'
|
6
|
+
assert cout.empty?
|
7
|
+
assert cerr.include?('Invalid command')
|
8
|
+
end
|
9
|
+
|
10
|
+
test 'monk no args' do
|
11
|
+
monk 'help'
|
12
|
+
err = cerr
|
13
|
+
|
14
|
+
monk ''
|
15
|
+
assert err == cerr
|
16
|
+
end
|
17
|
+
|
18
|
+
test 'help' do
|
19
|
+
monk 'help'
|
20
|
+
|
21
|
+
assert cerr.include?('Usage:')
|
22
|
+
assert cerr.include?('www.monkrb.com')
|
23
|
+
|
24
|
+
%w(help version).each { |c| assert cerr.match(/^ #{c}/) }
|
25
|
+
%w(init add rm purge list).each { |c| assert cerr.match(/^ #{c}/) }
|
26
|
+
%w(unpack lock install).each { |c| assert !cerr.match(/^ #{c}/) }
|
27
|
+
end
|
28
|
+
|
29
|
+
test 'help in project' do
|
30
|
+
FileUtils.touch 'Monkfile'
|
31
|
+
monk 'help'
|
32
|
+
|
33
|
+
assert cerr.include?('Usage:')
|
34
|
+
|
35
|
+
%w(help version).each { |c| assert cerr.match(/^ #{c}/) }
|
36
|
+
%w(init add rm purge list).each { |c| assert !cerr.match(/^ #{c}/) }
|
37
|
+
%w(unpack lock install).each { |c| assert cerr.match(/^ #{c}/) }
|
38
|
+
end
|
39
|
+
end
|
data/test/init_test.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require File.expand_path('../test_helper', __FILE__)
|
2
|
+
|
3
|
+
scope do
|
4
|
+
def mock_cache(name)
|
5
|
+
path = File.join(Monk.cache_path, name)
|
6
|
+
Monk.git_clone 'git://github.com/x/y', path
|
7
|
+
end
|
8
|
+
|
9
|
+
setup do
|
10
|
+
Dir[File.join(Monk.cache_path, '*')].each { |path| FileUtils.rm_rf path }
|
11
|
+
end
|
12
|
+
|
13
|
+
test 'init fail' do
|
14
|
+
monk 'init'
|
15
|
+
assert_invalid
|
16
|
+
end
|
17
|
+
|
18
|
+
test 'init fail 2' do
|
19
|
+
monk 'init x y z'
|
20
|
+
assert_invalid
|
21
|
+
end
|
22
|
+
|
23
|
+
test 'init git' do
|
24
|
+
monk 'init x'
|
25
|
+
assert_successful_init 'x'
|
26
|
+
end
|
27
|
+
|
28
|
+
test 'init cached' do
|
29
|
+
mock_cache 'default'
|
30
|
+
|
31
|
+
monk 'init x'
|
32
|
+
assert_successful_init 'x'
|
33
|
+
|
34
|
+
monk 'init x'
|
35
|
+
assert cerr.include?('exists')
|
36
|
+
end
|
37
|
+
|
38
|
+
test 'init caching' do
|
39
|
+
monk 'init x'
|
40
|
+
assert_successful_init 'x'
|
41
|
+
assert cout.include?('git clone')
|
42
|
+
|
43
|
+
assert File.directory?(Monk.cache_path('default'))
|
44
|
+
|
45
|
+
monk 'init x'
|
46
|
+
assert !cout.include?('git clone')
|
47
|
+
end
|
48
|
+
|
49
|
+
test 'custom skeleton' do
|
50
|
+
monk 'add shivers git://github.com/a/b'
|
51
|
+
monk 'init x -s shivers'
|
52
|
+
|
53
|
+
assert_successful_init 'x'
|
54
|
+
assert cout.include?('git://github.com/a/b')
|
55
|
+
end
|
56
|
+
|
57
|
+
test 'invalid skeleton' do
|
58
|
+
monk 'init x -s scabs'
|
59
|
+
assert cerr.include?('No such skeleton')
|
60
|
+
end
|
61
|
+
|
62
|
+
# TODO: git fail test
|
63
|
+
end
|
data/test/mock.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# Silly mocking
|
2
|
+
|
3
|
+
# Capture output and input
|
4
|
+
class << Monk
|
5
|
+
def puts(what=nil)
|
6
|
+
$out << "#{what}\n"
|
7
|
+
end
|
8
|
+
|
9
|
+
def err(what=nil)
|
10
|
+
$err << "#{what}\n"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Caching will always happen in a temp folder
|
15
|
+
module Monk::InitHelpers
|
16
|
+
def cache_path(name=nil)
|
17
|
+
File.expand_path("../tmp/#{name}", __FILE__)
|
18
|
+
end
|
19
|
+
|
20
|
+
def git_clone(repo, path)
|
21
|
+
FileUtils.mkdir_p path
|
22
|
+
FileUtils.touch File.join(path, 'Monkfile')
|
23
|
+
FileUtils.touch File.join(path, 'init.rb')
|
24
|
+
say_status :run, "git clone --depth 1 #{repo} #{path}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Config will never load the config file
|
29
|
+
class Monk::Config
|
30
|
+
def self.load
|
31
|
+
self.new
|
32
|
+
end
|
33
|
+
|
34
|
+
def save!
|
35
|
+
end
|
36
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
$:.push *Dir[File.expand_path('../../lib', __FILE__)]
|
2
|
+
|
3
|
+
require 'cutest'
|
4
|
+
require 'shellwords'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'monk'
|
7
|
+
|
8
|
+
require File.expand_path('../mock', __FILE__)
|
9
|
+
|
10
|
+
def monk(cmd)
|
11
|
+
$out = ''
|
12
|
+
$err = ''
|
13
|
+
|
14
|
+
Monk.load_monkfile
|
15
|
+
Monk.run *Shellwords.shellsplit(cmd)
|
16
|
+
end
|
17
|
+
|
18
|
+
def cout
|
19
|
+
$out
|
20
|
+
end
|
21
|
+
|
22
|
+
def cerr
|
23
|
+
$err
|
24
|
+
end
|
25
|
+
|
26
|
+
def assert_invalid
|
27
|
+
assert cout.empty?
|
28
|
+
assert cerr.include?('Invalid usage')
|
29
|
+
end
|
30
|
+
|
31
|
+
def assert_successful_init(path)
|
32
|
+
assert cout.include?("Success! You've created a new project")
|
33
|
+
assert cerr.empty?
|
34
|
+
assert File.directory?(path)
|
35
|
+
assert File.file?(File.join(path, 'Monkfile'))
|
36
|
+
assert File.file?(File.join(path, 'init.rb'))
|
37
|
+
assert !File.exists?(File.join(path, '.git'))
|
38
|
+
end
|
39
|
+
|
40
|
+
tmp_path = File.expand_path('../tmp', __FILE__)
|
41
|
+
FileUtils.mkdir_p tmp_path
|
42
|
+
|
43
|
+
prepare do
|
44
|
+
# Clear config
|
45
|
+
Dir.chdir tmp_path
|
46
|
+
Monk.instance_variable_set :@config, nil
|
47
|
+
FileUtils.rm_rf 'Monkfile'
|
48
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: monk-shake
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: 6
|
5
|
+
version: 1.0.0.pre1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Rico Sta. Cruz
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-02-15 00:00:00 +08:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: shake
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ~>
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.1.1
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
description: Monk lets you build Sinatra applications quickly and painlessly by letting it set up the directory structure for you. Monk-shake is a rewritten version of Monk that uses the Shake gem.
|
28
|
+
email:
|
29
|
+
- rico@sinefunc.com
|
30
|
+
executables:
|
31
|
+
- monk
|
32
|
+
extensions: []
|
33
|
+
|
34
|
+
extra_rdoc_files: []
|
35
|
+
|
36
|
+
files:
|
37
|
+
- bin/monk
|
38
|
+
- lib/monk/config.rb
|
39
|
+
- lib/monk/helpers.rb
|
40
|
+
- lib/monk/init_helpers.rb
|
41
|
+
- lib/monk.rb
|
42
|
+
- test/add_test.rb
|
43
|
+
- test/help_test.rb
|
44
|
+
- test/init_test.rb
|
45
|
+
- test/mock.rb
|
46
|
+
- test/test_helper.rb
|
47
|
+
- README.md
|
48
|
+
has_rdoc: true
|
49
|
+
homepage: http://www.github.com/rstacruz/monk-shake
|
50
|
+
licenses: []
|
51
|
+
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.3.1
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project:
|
72
|
+
rubygems_version: 1.5.0
|
73
|
+
signing_key:
|
74
|
+
specification_version: 3
|
75
|
+
summary: Monk the Sinatra glue framework -- reloaded
|
76
|
+
test_files: []
|
77
|
+
|