greenhouse 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/bin/greenhouse +9 -0
  3. data/lib/greenhouse/cli.rb +88 -0
  4. data/lib/greenhouse/commands/add.rb +32 -0
  5. data/lib/greenhouse/commands/command.rb +88 -0
  6. data/lib/greenhouse/commands/configure.rb +9 -0
  7. data/lib/greenhouse/commands/help.rb +45 -0
  8. data/lib/greenhouse/commands/init.rb +93 -0
  9. data/lib/greenhouse/commands/launch.rb +113 -0
  10. data/lib/greenhouse/commands/new.rb +42 -0
  11. data/lib/greenhouse/commands/pull.rb +45 -0
  12. data/lib/greenhouse/commands/purge.rb +91 -0
  13. data/lib/greenhouse/commands/push.rb +45 -0
  14. data/lib/greenhouse/commands/remove.rb +32 -0
  15. data/lib/greenhouse/commands/start.rb +21 -0
  16. data/lib/greenhouse/commands/status.rb +50 -0
  17. data/lib/greenhouse/commands/sync.rb +42 -0
  18. data/lib/greenhouse/commands.rb +32 -0
  19. data/lib/greenhouse/projects/application.rb +19 -0
  20. data/lib/greenhouse/projects/collection.rb +23 -0
  21. data/lib/greenhouse/projects/engine.rb +6 -0
  22. data/lib/greenhouse/projects/gem.rb +6 -0
  23. data/lib/greenhouse/projects/project.rb +77 -0
  24. data/lib/greenhouse/projects/repository.rb +197 -0
  25. data/lib/greenhouse/projects.rb +86 -0
  26. data/lib/greenhouse/resources/dotenv_file.rb +69 -0
  27. data/lib/greenhouse/resources/file_resource.rb +50 -0
  28. data/lib/greenhouse/resources/ignore_file.rb +115 -0
  29. data/lib/greenhouse/resources/procfile.rb +144 -0
  30. data/lib/greenhouse/resources/projects_file.rb +44 -0
  31. data/lib/greenhouse/resources.rb +10 -0
  32. data/lib/greenhouse/scripts/argument.rb +36 -0
  33. data/lib/greenhouse/scripts/arguments.rb +28 -0
  34. data/lib/greenhouse/scripts/invalid_argument.rb +6 -0
  35. data/lib/greenhouse/scripts/script.rb +109 -0
  36. data/lib/greenhouse/scripts.rb +4 -0
  37. data/lib/greenhouse/tasks/add_project.rb +57 -0
  38. data/lib/greenhouse/tasks/generate_procfile.rb +22 -0
  39. data/lib/greenhouse/tasks/project_status.rb +37 -0
  40. data/lib/greenhouse/tasks/project_task.rb +363 -0
  41. data/lib/greenhouse/tasks/pull_project.rb +14 -0
  42. data/lib/greenhouse/tasks/purge_project.rb +13 -0
  43. data/lib/greenhouse/tasks/push_project.rb +14 -0
  44. data/lib/greenhouse/tasks/remove_greenhouse_files.rb +58 -0
  45. data/lib/greenhouse/tasks/remove_project.rb +15 -0
  46. data/lib/greenhouse/tasks/sync_project.rb +19 -0
  47. data/lib/greenhouse/tasks/task.rb +25 -0
  48. data/lib/greenhouse/tasks.rb +20 -0
  49. data/lib/greenhouse/version.rb +20 -0
  50. data/lib/greenhouse.rb +12 -0
  51. 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,14 @@
1
+ module Greenhouse
2
+ module Tasks
3
+ class PullProject
4
+ include Task
5
+ include ProjectTask
6
+
7
+ def perform(project)
8
+ @project = project
9
+
10
+ pull && bundle
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ module Greenhouse
2
+ module Tasks
3
+ class PurgeProject
4
+ include Task
5
+ include ProjectTask
6
+
7
+ def perform(project, force=false)
8
+ @project = project
9
+ purge(force)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module Greenhouse
2
+ module Tasks
3
+ class PushProject
4
+ include Task
5
+ include ProjectTask
6
+
7
+ def perform(project)
8
+ @project = project
9
+
10
+ push
11
+ end
12
+ end
13
+ end
14
+ 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