greenhouse 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/greenhouse +9 -0
- data/lib/greenhouse/cli.rb +88 -0
- data/lib/greenhouse/commands/add.rb +32 -0
- data/lib/greenhouse/commands/command.rb +88 -0
- data/lib/greenhouse/commands/configure.rb +9 -0
- data/lib/greenhouse/commands/help.rb +45 -0
- data/lib/greenhouse/commands/init.rb +93 -0
- data/lib/greenhouse/commands/launch.rb +113 -0
- data/lib/greenhouse/commands/new.rb +42 -0
- data/lib/greenhouse/commands/pull.rb +45 -0
- data/lib/greenhouse/commands/purge.rb +91 -0
- data/lib/greenhouse/commands/push.rb +45 -0
- data/lib/greenhouse/commands/remove.rb +32 -0
- data/lib/greenhouse/commands/start.rb +21 -0
- data/lib/greenhouse/commands/status.rb +50 -0
- data/lib/greenhouse/commands/sync.rb +42 -0
- data/lib/greenhouse/commands.rb +32 -0
- data/lib/greenhouse/projects/application.rb +19 -0
- data/lib/greenhouse/projects/collection.rb +23 -0
- data/lib/greenhouse/projects/engine.rb +6 -0
- data/lib/greenhouse/projects/gem.rb +6 -0
- data/lib/greenhouse/projects/project.rb +77 -0
- data/lib/greenhouse/projects/repository.rb +197 -0
- data/lib/greenhouse/projects.rb +86 -0
- data/lib/greenhouse/resources/dotenv_file.rb +69 -0
- data/lib/greenhouse/resources/file_resource.rb +50 -0
- data/lib/greenhouse/resources/ignore_file.rb +115 -0
- data/lib/greenhouse/resources/procfile.rb +144 -0
- data/lib/greenhouse/resources/projects_file.rb +44 -0
- data/lib/greenhouse/resources.rb +10 -0
- data/lib/greenhouse/scripts/argument.rb +36 -0
- data/lib/greenhouse/scripts/arguments.rb +28 -0
- data/lib/greenhouse/scripts/invalid_argument.rb +6 -0
- data/lib/greenhouse/scripts/script.rb +109 -0
- data/lib/greenhouse/scripts.rb +4 -0
- data/lib/greenhouse/tasks/add_project.rb +57 -0
- data/lib/greenhouse/tasks/generate_procfile.rb +22 -0
- data/lib/greenhouse/tasks/project_status.rb +37 -0
- data/lib/greenhouse/tasks/project_task.rb +363 -0
- data/lib/greenhouse/tasks/pull_project.rb +14 -0
- data/lib/greenhouse/tasks/purge_project.rb +13 -0
- data/lib/greenhouse/tasks/push_project.rb +14 -0
- data/lib/greenhouse/tasks/remove_greenhouse_files.rb +58 -0
- data/lib/greenhouse/tasks/remove_project.rb +15 -0
- data/lib/greenhouse/tasks/sync_project.rb +19 -0
- data/lib/greenhouse/tasks/task.rb +25 -0
- data/lib/greenhouse/tasks.rb +20 -0
- data/lib/greenhouse/version.rb +20 -0
- data/lib/greenhouse.rb +12 -0
- metadata +165 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
module Greenhouse
|
2
|
+
module Tasks
|
3
|
+
class ProjectStatus
|
4
|
+
include Task
|
5
|
+
include ProjectTask
|
6
|
+
|
7
|
+
def perform(project, verbose=false)
|
8
|
+
@project = project
|
9
|
+
|
10
|
+
@project.repository.fetch if @project.exists?
|
11
|
+
|
12
|
+
puts " \e[36m#{@project.title}\e[0m (#{@project.type.capitalize})"
|
13
|
+
puts " #{@project.repository.remote}"
|
14
|
+
puts " #{@project.exists? ? "\e[32mInitialized" : "\e[33mNot Initialized"}\e[0m"
|
15
|
+
puts " #{@project.configured? ? "\e[32mConfigured" : "\e[33mNot Configured"}\e[0m" if @project.exists? && @project.is_a?(::Greenhouse::Projects::Application)
|
16
|
+
|
17
|
+
if @project.exists?
|
18
|
+
if !verbose
|
19
|
+
puts " \e[33mUncommitted Changes\e[0m" if @project.repository.changes?
|
20
|
+
puts " \e[33mUnpushed Branches\e[0m" if @project.repository.ahead?
|
21
|
+
puts " \e[33mUnpulled Branches\e[0m" if @project.repository.behind?
|
22
|
+
puts " \e[33mDiverged Branches\e[0m" if @project.repository.diverged?
|
23
|
+
end
|
24
|
+
|
25
|
+
if !@project.repository.changes? && !@project.repository.ahead? && @project.repository.up_to_date?
|
26
|
+
puts " \e[32mUp-to-date\e[0m"
|
27
|
+
elsif verbose
|
28
|
+
print_local_changes(4) if @project.repository.changes?
|
29
|
+
print_unpushed_branches(4) if @project.repository.ahead?
|
30
|
+
print_out_of_sync_branches(4) if @project.repository.out_of_sync?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,363 @@
|
|
1
|
+
module Greenhouse
|
2
|
+
module Tasks
|
3
|
+
module ProjectTask
|
4
|
+
def self.included(base)
|
5
|
+
base.send :extend, ClassMethods
|
6
|
+
base.send :include, InstanceMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
module InstanceMethods
|
13
|
+
def self.included(base)
|
14
|
+
base.send :alias_method, :klone, :clone
|
15
|
+
end
|
16
|
+
|
17
|
+
def bundle
|
18
|
+
puts "Running Bundler for \e[36m#{@project.title}\e[0m..."
|
19
|
+
@project.bundle
|
20
|
+
true
|
21
|
+
rescue Exception => e
|
22
|
+
puts "\e[31mError running Bundler for #{@project.title}\e[0m"
|
23
|
+
puts "#{e.class.name}: #{e.message}"
|
24
|
+
puts e.backtrace
|
25
|
+
# TODO? prompt to continue?
|
26
|
+
false
|
27
|
+
end
|
28
|
+
|
29
|
+
def clone
|
30
|
+
puts "Cloning \e[36m#{@project.title}\e[0m (#{@project.repository.remote}) into #{@project.path}..."
|
31
|
+
@project.repository.clone
|
32
|
+
|
33
|
+
# Ignore the project's ignored files
|
34
|
+
Bundler.with_clean_env do
|
35
|
+
@project.chdir do
|
36
|
+
@project.ignored.each { |file| `git update-index --assume-unchanged #{file.to_s} 2>&1` if File.exists?(file.to_s) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
true
|
40
|
+
rescue Exception => e
|
41
|
+
puts "\e[31mCould not clone #{@project.title}\e[0m"
|
42
|
+
puts "#{e.class.name}: #{e.message}"
|
43
|
+
puts e.backtrace
|
44
|
+
# TODO? prompt to continue?
|
45
|
+
false
|
46
|
+
end
|
47
|
+
|
48
|
+
def pull
|
49
|
+
print "Checking \e[36m#{@project.title}\e[0m git remotes for upstream commits... "
|
50
|
+
|
51
|
+
@project.repository.fetch # fetch the latest from remotes
|
52
|
+
if @project.repository.out_of_sync?
|
53
|
+
puts
|
54
|
+
print_out_of_sync_branches
|
55
|
+
|
56
|
+
# Un-ignore the project's ignored files before attempting any pulls/merges
|
57
|
+
Bundler.with_clean_env do
|
58
|
+
@project.chdir do
|
59
|
+
@project.ignored.each { |file| `git update-index --no-assume-unchanged #{file.to_s} 2>&1` if File.exists?(file.to_s) }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
merge = nil
|
64
|
+
stashed = false
|
65
|
+
if @project.repository.changes?(false)
|
66
|
+
puts "\e[33mYou have uncommitted local changes in #{@project.path} on branch #{@project.repository.git.branch.name}\e[0m"
|
67
|
+
while !['y','yes','n','no'].include?(merge) do
|
68
|
+
print "Would you like to stash your changes and merge the latest commits from upstream? ([y]es/[n]o): "
|
69
|
+
merge = STDIN.gets.chomp.downcase
|
70
|
+
end
|
71
|
+
|
72
|
+
if ['y','yes'].include?(merge)
|
73
|
+
puts "Stashing local changes..."
|
74
|
+
stashed = @project.repository.git.branch.name
|
75
|
+
@project.repository.stash
|
76
|
+
end
|
77
|
+
else
|
78
|
+
while !['y','yes','n','no'].include?(merge) do
|
79
|
+
print "Would you like to attempt to merge the latest commits from upstream? ([y]es/[n]o): "
|
80
|
+
merge = STDIN.gets.chomp.downcase
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
if ['y','yes'].include?(merge)
|
85
|
+
@project.repository.out_of_sync.each do |branch|
|
86
|
+
print "Attempting to merge #{branch[1].name}/#{branch[0].name} into #{branch[0].name}..."
|
87
|
+
@project.repository.git.checkout(branch[0].name)
|
88
|
+
@project.repository.git.merge("#{branch[1].name}/#{branch[0].name}")
|
89
|
+
puts "Success."
|
90
|
+
end
|
91
|
+
|
92
|
+
if stashed != false
|
93
|
+
puts "Popping local stash..."
|
94
|
+
@project.repository.git.checkout(stashed)
|
95
|
+
@project.repository.pop_stash
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
# Ignore the project's ignored files
|
101
|
+
Bundler.with_clean_env do
|
102
|
+
@project.chdir do
|
103
|
+
@project.ignored.each { |file| `git update-index --assume-unchanged #{file.to_s} 2>&1` if File.exists?(file.to_s) }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
return true if ['y','yes'].include?(merge)
|
108
|
+
else
|
109
|
+
puts "Already up-to-date."
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def push
|
114
|
+
if @project.repository.ahead? || @project.repository.diverged?
|
115
|
+
print_unpushed_branches
|
116
|
+
|
117
|
+
print "Would you like to push these branches now? ([P]ush/[s]kip): "
|
118
|
+
push = STDIN.gets.chomp.downcase
|
119
|
+
|
120
|
+
if %w(s skip).include?(push)
|
121
|
+
puts "Skipped #{@project.title}"
|
122
|
+
return
|
123
|
+
else
|
124
|
+
begin
|
125
|
+
raise "Cound not push local branches" unless push_branches
|
126
|
+
rescue
|
127
|
+
puts "\e[33mThere was a problem pushing local branches for #{@project.title}\e[0m"
|
128
|
+
puts "You may manually resolve conflicts in #{@project.path} and try again."
|
129
|
+
puts "\e[33mSkipping #{@project.title}...\e[0m"
|
130
|
+
return
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
return true
|
135
|
+
else
|
136
|
+
puts "Nothing to push for \e[36m#{@project.title}\e[0m."
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# TODO move this to a logger class
|
141
|
+
def indent_spaces(indent=0)
|
142
|
+
indent.times.map {" "}.join
|
143
|
+
end
|
144
|
+
|
145
|
+
def print_local_changes(indent=0)
|
146
|
+
puts "#{indent_spaces indent}\e[33mYou have uncommitted changes in #{@project.title}!\e[0m"
|
147
|
+
puts "#{indent_spaces indent}The following files have uncommitted local modifications:"
|
148
|
+
puts
|
149
|
+
@project.repository.changes.each do |name,file|
|
150
|
+
print "#{indent_spaces indent}#{file.untracked ? "U" : file.type}"
|
151
|
+
puts " #{@project.path}/#{name}"
|
152
|
+
end
|
153
|
+
puts
|
154
|
+
end
|
155
|
+
|
156
|
+
def print_unpushed_branches(indent=0)
|
157
|
+
puts "#{indent_spaces indent}\e[33mYou have branches in #{@project.title} that haven't been pushed!\e[0m"
|
158
|
+
puts
|
159
|
+
@project.repository.ahead.each do |branch|
|
160
|
+
puts "#{indent_spaces indent} branch #{branch[0].name} is ahead of #{branch[1].name}/#{branch[0].name}"
|
161
|
+
end
|
162
|
+
@project.repository.diverged.each do |branch|
|
163
|
+
puts "#{indent_spaces indent} branch #{branch[0].name} and #{branch[1].name}/#{branch[0].name} have diverged"
|
164
|
+
end
|
165
|
+
puts
|
166
|
+
end
|
167
|
+
|
168
|
+
def print_out_of_sync_branches(indent=0)
|
169
|
+
puts "#{indent_spaces indent}\e[33mYou have out of sync branches in #{@project.title}\e[0m"
|
170
|
+
puts
|
171
|
+
@project.repository.behind.each do |branch|
|
172
|
+
puts "#{indent_spaces indent} \e[37mbranch\e[0m #{branch[0].name} \e[37mis behind\e[0m #{branch[1].name}/#{branch[0].name}"
|
173
|
+
end
|
174
|
+
|
175
|
+
@project.repository.diverged.each do |branch|
|
176
|
+
puts "#{indent_spaces indent} \e[37mbranch\e[0m #{branch[0].name} \e[37mand\e[0m #{branch[1].name}/#{branch[0].name} \e[37mhave diverged\e[0m"
|
177
|
+
end
|
178
|
+
puts
|
179
|
+
end
|
180
|
+
|
181
|
+
def commit_changes
|
182
|
+
add_untracked = nil
|
183
|
+
if @project.repository.untracked?
|
184
|
+
while !%w(a add p prompt s skip).include?(add_untracked) do
|
185
|
+
puts
|
186
|
+
puts "You have untracked files in your project:"
|
187
|
+
puts
|
188
|
+
@project.repository.untracked.each do |name,file|
|
189
|
+
puts "U #{@project.path}/#{name}"
|
190
|
+
end
|
191
|
+
puts
|
192
|
+
print "Would you like to add them all, be prompted for each or skip them? ([a]dd/[p]rompt/[s]kip): "
|
193
|
+
add_untracked = STDIN.gets.chomp.downcase
|
194
|
+
end
|
195
|
+
|
196
|
+
if %w(a add).include?(add_untracked)
|
197
|
+
@project.repository.untracked.each do |name,file|
|
198
|
+
@project.repository.add(name)
|
199
|
+
end
|
200
|
+
elsif %w(p prompt).include?(add_untracked)
|
201
|
+
@project.repository.untracked.each do |name,file|
|
202
|
+
puts
|
203
|
+
addfile = nil
|
204
|
+
while !%w(a add s skip).include?(addfile) do
|
205
|
+
print "Do you want to add #{name} to your commit? ([a]dd/[s]kip): "
|
206
|
+
addfile = STDIN.gets.chomp.downcase
|
207
|
+
end
|
208
|
+
if %w(a add).include?(addfile)
|
209
|
+
@project.repository.add(name)
|
210
|
+
puts "Added #{name}."
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
add_modified = nil
|
217
|
+
if @project.repository.unstaged?
|
218
|
+
while !%w(a add p prompt s skip).include?(add_modified) do
|
219
|
+
puts
|
220
|
+
puts "You have modified files in your project:"
|
221
|
+
puts
|
222
|
+
@project.repository.unstaged.each do |name,file|
|
223
|
+
puts "#{file.type} #{@project.path}/#{name}"
|
224
|
+
puts file.sha_index
|
225
|
+
end
|
226
|
+
puts
|
227
|
+
print "Would you like to add them all, be prompted for each or skip them? ([a]dd/[p]rompt/[s]kip): "
|
228
|
+
add_modified = STDIN.gets.chomp.downcase
|
229
|
+
end
|
230
|
+
|
231
|
+
if %w(a add).include?(add_modified)
|
232
|
+
@project.repository.unstaged.each do |name,file|
|
233
|
+
@project.repository.add(name)
|
234
|
+
end
|
235
|
+
elsif %w(p prompt).include?(add_modified)
|
236
|
+
@project.repository.unstaged.each do |name,file|
|
237
|
+
puts
|
238
|
+
addfile = nil
|
239
|
+
while !%w(a add s skip).include?(addfile) do
|
240
|
+
print "Do you want to add #{name} to your commit? ([a]dd/[s]kip): "
|
241
|
+
addfile = STDIN.gets.chomp.downcase
|
242
|
+
end
|
243
|
+
if %w(a add).include?(addfile)
|
244
|
+
@project.repository.add(name)
|
245
|
+
puts "Added #{name}."
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
if ![nil,'s','skip'].include?(add_untracked) || ![nil,'s','skip'].include?(add_modified)
|
252
|
+
puts
|
253
|
+
puts "Changes to be committed:"
|
254
|
+
puts
|
255
|
+
@project.repository.staged.each do |name,file|
|
256
|
+
print file.untracked ? "U" : file.type
|
257
|
+
puts " #{@project.path}/#{name}"
|
258
|
+
puts file.sha_index
|
259
|
+
end
|
260
|
+
puts
|
261
|
+
end
|
262
|
+
|
263
|
+
puts "Enter a commit message (leave blank to skip): "
|
264
|
+
message = STDIN.gets.chomp
|
265
|
+
return if message.empty?
|
266
|
+
|
267
|
+
@project.repository.commit(message)
|
268
|
+
return true
|
269
|
+
end
|
270
|
+
|
271
|
+
def push_branches
|
272
|
+
@project.repository.out_of_sync.each do |branch|
|
273
|
+
begin
|
274
|
+
print "Attempting to merge #{branch[1].name}/#{branch[0].name} into #{branch[0].name} before pushing..."
|
275
|
+
@project.repository.git.checkout(branch[0].name)
|
276
|
+
@project.repository.git.merge("#{branch[1].name}/#{branch[0].name}")
|
277
|
+
puts "\e[32mSuccess.\e[0m"
|
278
|
+
rescue
|
279
|
+
# TODO detect unmerged files, allow to resolve inline?
|
280
|
+
puts "\e[31mFailed! Unresolved conflicts.\e[0m"
|
281
|
+
return false
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
print "Pushing local branches..."
|
286
|
+
@project.repository.push
|
287
|
+
puts "\e[32mSuccess.\e[0m"
|
288
|
+
return true
|
289
|
+
end
|
290
|
+
|
291
|
+
def purge(force=false)
|
292
|
+
return unless @project.exists?
|
293
|
+
|
294
|
+
@project.repository.fetch # fetch the latest from remotes
|
295
|
+
if @project.repository.changes? || @project.repository.ahead? || @project.repository.diverged?
|
296
|
+
|
297
|
+
# Prompt to take action if there are local changes
|
298
|
+
if @project.repository.changes?
|
299
|
+
print_local_changes
|
300
|
+
|
301
|
+
puts "You can skip this project, commit your changes now or remove the project (and lose your changes)."
|
302
|
+
commit = nil
|
303
|
+
while !%w(c commit s skip r remove).include?(commit) do
|
304
|
+
print "What would you like to do? ([c]ommit/[s]kip/[r]emove): "
|
305
|
+
commit = STDIN.gets.chomp.downcase
|
306
|
+
end
|
307
|
+
|
308
|
+
if %w(s skip).include?(commit)
|
309
|
+
puts "\e[33mSkipping #{@project.title}...\e[0m"
|
310
|
+
return
|
311
|
+
elsif %w(c commit).include?(commit)
|
312
|
+
begin
|
313
|
+
raise "Could not commit local changes" unless commit_changes
|
314
|
+
rescue
|
315
|
+
puts "\e[33mThere was a problem committing local changes to #{@project.title}\e[0m"
|
316
|
+
puts "\e[33mSkipping #{@project.title}...\e[0m"
|
317
|
+
return
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
# Prompt to take action if there are unpushed branches
|
323
|
+
if @project.repository.ahead? || @project.repository.diverged?
|
324
|
+
print_unpushed_branches
|
325
|
+
|
326
|
+
puts "You can skip this project, push your branches now or remove the project (and lose your changes)."
|
327
|
+
push = nil
|
328
|
+
while !%w(p push s skip r remove).include?(push) do
|
329
|
+
print "What would you like to do? ([p]ush/[s]kip/[r]emove): "
|
330
|
+
push = STDIN.gets.chomp.downcase
|
331
|
+
end
|
332
|
+
|
333
|
+
if %w(s skip).include?(push)
|
334
|
+
puts "\e[33mSkipping #{@project.title}...\e[0m"
|
335
|
+
return
|
336
|
+
elsif %w(p push).include?(push)
|
337
|
+
begin
|
338
|
+
raise "Cound not push local branches" unless push_branches
|
339
|
+
rescue
|
340
|
+
puts "\e[33mThere was a problem pushing local branches for #{@project.title}\e[0m"
|
341
|
+
puts "You may manually resolve conflicts in #{@project.path} and try again."
|
342
|
+
puts "\e[33mSkipping #{@project.title}...\e[0m"
|
343
|
+
return
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
end
|
349
|
+
|
350
|
+
puts "\e[33mRemoving #{@project.title} project directory...\e[0m"
|
351
|
+
|
352
|
+
Projects::procfile.processes.delete_if do |key,process|
|
353
|
+
# this is sort of generic, just checks for the project name in the key/cmd
|
354
|
+
key.match(/\A.*#{@project.name}.*\Z/) || process.command.match(/\A.*#{@project.name}.*\Z/)
|
355
|
+
end
|
356
|
+
Projects::procfile.write
|
357
|
+
|
358
|
+
@project.destroy
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Greenhouse
|
2
|
+
module Tasks
|
3
|
+
class RemoveGreenhouseFiles
|
4
|
+
include Task
|
5
|
+
|
6
|
+
# TODO maybe DRY this up, and/or break into individual tasks
|
7
|
+
def perform(force=false)
|
8
|
+
if Projects::dotenv.exists?
|
9
|
+
if !force
|
10
|
+
print "Would you like to remove your default configuration file? ([K]eep/[r]emove): "
|
11
|
+
remove = STDIN.gets.chomp.downcase
|
12
|
+
end
|
13
|
+
|
14
|
+
if ['r','remove'].include?(remove) || force
|
15
|
+
puts "\e[33mRemoving default config file...\e[0m"
|
16
|
+
Projects::dotenv.unlink
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
if Projects::projects_file.exists?
|
21
|
+
if !force
|
22
|
+
print "Would you like to remove your .projects file? ([k]eep/[r]emove): "
|
23
|
+
remove = STDIN.gets.chomp.downcase
|
24
|
+
end
|
25
|
+
|
26
|
+
if ['r','remove'].include?(remove) || force
|
27
|
+
puts "\e[33mRemoving .projects file...\e[0m"
|
28
|
+
Projects::projects_file.unlink
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
if Projects::ignore_file.exists?
|
33
|
+
if !force
|
34
|
+
print "Would you like to remove your .ignore file? ([k]eep/[r]emove): "
|
35
|
+
remove = STDIN.gets.chomp.downcase
|
36
|
+
end
|
37
|
+
|
38
|
+
if ['r','remove'].include?(remove) || force
|
39
|
+
puts "\e[33mRemoving .ignore file...\e[0m"
|
40
|
+
Projects::ignore_file.unlink
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
if Projects::procfile.exists?
|
45
|
+
if !force
|
46
|
+
print "Would you like to remove your Procfile? ([k]eep/[r]emove): "
|
47
|
+
remove = STDIN.gets.chomp.downcase
|
48
|
+
end
|
49
|
+
|
50
|
+
if ['r','remove'].include?(remove) || force
|
51
|
+
puts "\e[33mRemoving Procfile...\e[0m"
|
52
|
+
Projects::procfile.unlink
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Greenhouse
|
2
|
+
module Tasks
|
3
|
+
class RemoveProject
|
4
|
+
include Task
|
5
|
+
include ProjectTask
|
6
|
+
|
7
|
+
def perform(project)
|
8
|
+
@project = project
|
9
|
+
puts "\e[33mRemoving #{@project.title} from your .projects file...\e[0m"
|
10
|
+
Projects::projects_file.projects.delete_if { |name,project| name == @project.name }
|
11
|
+
Projects::projects_file.write
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Greenhouse
|
2
|
+
module Tasks
|
3
|
+
class SyncProject
|
4
|
+
include Task
|
5
|
+
include ProjectTask
|
6
|
+
|
7
|
+
def perform(project)
|
8
|
+
@project = project
|
9
|
+
|
10
|
+
if @project.exists?
|
11
|
+
pull && bundle
|
12
|
+
push
|
13
|
+
else
|
14
|
+
clone && bundle
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Greenhouse
|
2
|
+
module Tasks
|
3
|
+
module Task
|
4
|
+
def self.included(base)
|
5
|
+
Tasks::tasks << base # Keep track of all tasks
|
6
|
+
|
7
|
+
base.send :extend, ClassMethods
|
8
|
+
base.send :include, InstanceMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
def perform(*args)
|
13
|
+
@task = new
|
14
|
+
@task.before(*args) if @task.respond_to?(:before)
|
15
|
+
@task.perform(*args)
|
16
|
+
@task.after(*args) if @task.respond_to?(:after)
|
17
|
+
@task
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module InstanceMethods
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Greenhouse
|
2
|
+
module Tasks
|
3
|
+
def self.tasks
|
4
|
+
@tasks ||= []
|
5
|
+
@tasks
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'greenhouse/tasks/task'
|
11
|
+
require 'greenhouse/tasks/project_task'
|
12
|
+
require 'greenhouse/tasks/project_status'
|
13
|
+
require 'greenhouse/tasks/add_project'
|
14
|
+
require 'greenhouse/tasks/push_project'
|
15
|
+
require 'greenhouse/tasks/pull_project'
|
16
|
+
require 'greenhouse/tasks/sync_project'
|
17
|
+
require 'greenhouse/tasks/purge_project'
|
18
|
+
require 'greenhouse/tasks/remove_project'
|
19
|
+
require 'greenhouse/tasks/generate_procfile'
|
20
|
+
require 'greenhouse/tasks/remove_greenhouse_files'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Greenhouse
|
2
|
+
VERSION = "0.0.3"
|
3
|
+
end
|
4
|
+
|
5
|
+
__END__
|
6
|
+
0.0.3:
|
7
|
+
* Ability to set the CLI binary name
|
8
|
+
* Broke out Forth Rail specific stuff into it's own binary `forthrail`
|
9
|
+
|
10
|
+
0.0.2:
|
11
|
+
* Improved command arguments (multiple keys, summaries, etc.)
|
12
|
+
* Separated project arguments from standard arguments
|
13
|
+
* Allow passing a project to commands like push, pull, sync, purge, status, etc.
|
14
|
+
* Added -v/--verbose flag for status command to output repository details (uncommitted files, out of sync branches, etc.)
|
15
|
+
* Improved resource file handling for Procfiles and .ignore files
|
16
|
+
* Added -a/--all flag for purge command to control whether to purge the entire ecosystem or just the project directories
|
17
|
+
|
18
|
+
0.0.1:
|
19
|
+
* Refactoring, improving and gemming Greenhouse
|
20
|
+
* Started pulling out Forth Rail specific functionality into a abstracted monkeypatches and mixins
|
data/lib/greenhouse.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'rake'
|
3
|
+
require 'active_support/inflector'
|
4
|
+
require 'greenhouse/resources'
|
5
|
+
require 'greenhouse/projects'
|
6
|
+
require 'greenhouse/scripts'
|
7
|
+
require 'greenhouse/tasks'
|
8
|
+
require 'greenhouse/commands'
|
9
|
+
require 'greenhouse/cli'
|
10
|
+
|
11
|
+
module Greenhouse
|
12
|
+
end
|