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
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 275b120e3a88469a7c59a1ef80c34e8e53684599
|
4
|
+
data.tar.gz: 3e5d0d6545c76c9d127252c20616277ccd338c9d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b821db4b17049bc511b15af85f48a7810d22b45b8578aeddb47baf89b30ea54f99f88e4de727875639a322f40640477399cb6e58d107bb22fbf1c852070aca60
|
7
|
+
data.tar.gz: 15da3ce7567ce8ac67789d9f839dd202649bbef426c6d3a29571ebadf4286d4e60d27c02bc7d227e81b7a94d7efd8b490c9621e30cee25dec56ab8881395e05f
|
data/bin/greenhouse
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
module Greenhouse
|
2
|
+
class CLI
|
3
|
+
include Scripts::Script
|
4
|
+
|
5
|
+
valid_arguments("-v")
|
6
|
+
|
7
|
+
def self.verbose
|
8
|
+
@verbose || false
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.verbose?
|
12
|
+
verbose == true
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.verbose=(v)
|
16
|
+
@verbose = v
|
17
|
+
@verbose
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.exec(cmd)
|
21
|
+
if verbose?
|
22
|
+
system cmd
|
23
|
+
else
|
24
|
+
`#{cmd}`
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.arguments(*args)
|
29
|
+
keep = []
|
30
|
+
args.each_with_index do |arg,a|
|
31
|
+
if Commands::exists?(arg)
|
32
|
+
begin
|
33
|
+
@command = Commands::command(arg)
|
34
|
+
@command.arguments(*args.slice(a+1,args.length-a))
|
35
|
+
rescue Scripts::InvalidArgument => e
|
36
|
+
puts e.message
|
37
|
+
Commands::command(arg).usage
|
38
|
+
exit 1
|
39
|
+
end
|
40
|
+
break
|
41
|
+
end
|
42
|
+
keep << arg
|
43
|
+
end
|
44
|
+
super(*keep)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.binary=(bin)
|
48
|
+
@binary = bin
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.binary
|
52
|
+
@binary ||= "greenhouse"
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.command_name
|
56
|
+
binary
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.usage
|
60
|
+
puts <<USAGE
|
61
|
+
usage: #{command_name} #{valid_arguments.to_s} <command> [<args>]
|
62
|
+
|
63
|
+
The available greenhouse commands are:
|
64
|
+
USAGE
|
65
|
+
|
66
|
+
Commands::commands.each do |cmd|
|
67
|
+
print " %-#{Commands::commands.sort { |a,b| a.command_name.length <=> b.command_name.length }.last.command_name.length + 2}s" % cmd.command_name
|
68
|
+
puts cmd.command_summary
|
69
|
+
end
|
70
|
+
|
71
|
+
puts
|
72
|
+
puts "See `#{command_name} help <command>` for more information on a specific command."
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.start
|
76
|
+
arguments(*ARGV)
|
77
|
+
verbose = arguments.map(&:key).include?("-v")
|
78
|
+
|
79
|
+
if @command.nil?
|
80
|
+
usage
|
81
|
+
exit 1
|
82
|
+
end
|
83
|
+
|
84
|
+
@command.run
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Greenhouse
|
2
|
+
module Commands
|
3
|
+
class Add
|
4
|
+
include Command
|
5
|
+
command_summary "Add a project to the ecosystem"
|
6
|
+
|
7
|
+
def add_another?
|
8
|
+
another = nil
|
9
|
+
while !['', 'n','no'].include?(another) do
|
10
|
+
puts "The following projects are configured in your ecosystem: "
|
11
|
+
#Projects::projects.each do |project|
|
12
|
+
# puts
|
13
|
+
# Tasks::ProjectStatus.perform(project)
|
14
|
+
#end
|
15
|
+
Projects.projects.each do |project|
|
16
|
+
puts " \e[36m#{project.title}\e[0m"
|
17
|
+
end
|
18
|
+
puts
|
19
|
+
print "Would you like to add another project? ([y]es/[N]o): "
|
20
|
+
another = STDIN.gets.chomp.downcase
|
21
|
+
Tasks::AddProject.perform if ['y','yes'].include?(another)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def run
|
26
|
+
Tasks::AddProject.perform
|
27
|
+
|
28
|
+
add_another?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Greenhouse
|
2
|
+
module Commands
|
3
|
+
module Command
|
4
|
+
def self.included(base)
|
5
|
+
Commands::commands << base # Keep track of all commands
|
6
|
+
|
7
|
+
base.send :include, Scripts::Script
|
8
|
+
base.send :extend, ClassMethods
|
9
|
+
base.send :include, InstanceMethods
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def command_name(n=nil)
|
14
|
+
@command_name = n unless n.nil?
|
15
|
+
return @command_name unless @command_name.nil?
|
16
|
+
self.name.underscore.split("/").last
|
17
|
+
end
|
18
|
+
|
19
|
+
def command_summary(summary=nil)
|
20
|
+
@command_summary = summary unless summary.nil?
|
21
|
+
@command_summary
|
22
|
+
end
|
23
|
+
|
24
|
+
def usage
|
25
|
+
puts "usage: #{::Greenhouse::CLI.command_name} #{command_name} #{valid_arguments.to_s}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def run
|
29
|
+
begin
|
30
|
+
@command ||= new
|
31
|
+
before_hooks.each { |block| @command.instance_eval(&block) }
|
32
|
+
@command.run
|
33
|
+
after_hooks.each { |block| @command.instance_eval(&block) }
|
34
|
+
rescue Exception => e
|
35
|
+
puts e.message
|
36
|
+
@command.usage if e.is_a?(Scripts::InvalidArgument)
|
37
|
+
exit 1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def append_after_hook(&block)
|
42
|
+
@after_hooks ||= []
|
43
|
+
@after_hooks << block
|
44
|
+
end
|
45
|
+
alias_method :after_hook, :append_after_hook
|
46
|
+
|
47
|
+
def prepend_after_hook(&block)
|
48
|
+
@after_hooks ||= []
|
49
|
+
@after_hooks.unshift block
|
50
|
+
end
|
51
|
+
|
52
|
+
def after_hooks
|
53
|
+
@after_hooks ||= []
|
54
|
+
@after_hooks
|
55
|
+
end
|
56
|
+
|
57
|
+
def append_before_hook(&block)
|
58
|
+
@before_hooks ||= []
|
59
|
+
@before_hooks << block
|
60
|
+
end
|
61
|
+
alias_method :before_hook, :append_before_hook
|
62
|
+
|
63
|
+
def prepend_before_hook(&block)
|
64
|
+
@before_hooks ||= []
|
65
|
+
@before_hooks.unshift block
|
66
|
+
end
|
67
|
+
|
68
|
+
def before_hooks
|
69
|
+
@before_hooks ||= []
|
70
|
+
@before_hooks
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_arg
|
74
|
+
Scripts::Argument.new(command_name, :summary => command_summary)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
module InstanceMethods
|
79
|
+
%w(command_name command_summary usage).each do |method|
|
80
|
+
define_method method do |*args|
|
81
|
+
self.class.send method, *args
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Greenhouse
|
2
|
+
module Commands
|
3
|
+
class Help
|
4
|
+
include Command
|
5
|
+
|
6
|
+
command_summary "Provides help for greenhouse usage"
|
7
|
+
|
8
|
+
valid_arguments *Commands::commands.map(&:to_arg)
|
9
|
+
validate_arguments false
|
10
|
+
|
11
|
+
def self.usage
|
12
|
+
puts <<USAGE
|
13
|
+
usage: #{::Greenhouse::CLI.command_name} #{command_name} <command>
|
14
|
+
|
15
|
+
The available greenhouse commands are:
|
16
|
+
USAGE
|
17
|
+
|
18
|
+
Commands::commands.select { |cmd| cmd != self}.each do |cmd|
|
19
|
+
print " %-#{Commands::commands.sort { |a,b| a.command_name.length <=> b.command_name.length }.last.command_name.length + 2}s" % cmd.command_name
|
20
|
+
puts "# #{cmd.command_summary}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def run
|
25
|
+
if arguments.empty?
|
26
|
+
usage
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
begin
|
31
|
+
cmd = Commands::commands.select { |cmd| cmd.command_name == arguments.first.key.underscore }.first
|
32
|
+
raise if cmd.nil?
|
33
|
+
|
34
|
+
puts cmd.command_summary
|
35
|
+
puts
|
36
|
+
print " "
|
37
|
+
cmd.usage
|
38
|
+
rescue
|
39
|
+
puts "Invalid Command: #{arguments.first.key.underscore}"
|
40
|
+
usage
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'greenhouse/tasks/sync_project'
|
2
|
+
|
3
|
+
module Greenhouse
|
4
|
+
module Commands
|
5
|
+
class Init
|
6
|
+
include Command
|
7
|
+
command_summary "Initialize the current directory as a Greenhouse projects directory"
|
8
|
+
|
9
|
+
# Make sure .ignore defaults are set before init
|
10
|
+
before_hook do
|
11
|
+
unless Projects::ignore_file.exists?
|
12
|
+
Projects::ignore_file.open('w') do |f|
|
13
|
+
f.write <<IGNORE
|
14
|
+
# Add any files here that are checked into your git repository, but are commonly edited
|
15
|
+
# or changed when working in a dev environment.
|
16
|
+
#
|
17
|
+
# Files will be ignored across all projects with `git --assume-unchanged FILE` and all
|
18
|
+
# paths are relative to the project directory.
|
19
|
+
#
|
20
|
+
# If you wish to commit changes to a file, you may run `git --no-assume-unchanged FILE`
|
21
|
+
# to unignore it temporarily, then run `git --assume-unchanged FILE` again when you're
|
22
|
+
# done.
|
23
|
+
#
|
24
|
+
# You may also create a .ignore file within each project directory if you'd like, and
|
25
|
+
# the files listed there will only be ignored for that project. Of course anything
|
26
|
+
# defined in a project .gitignore file is permanently ignored by git and does not
|
27
|
+
# need to be accounted for here.
|
28
|
+
|
29
|
+
# Ignore Gemfile so you can point to local ecosystem paths during development without
|
30
|
+
# worry of inadvertently committing your Gemfile.
|
31
|
+
Gemfile
|
32
|
+
|
33
|
+
# Ignore Gemfile.lock (mainly for applications) so that you don't inadvertently commit
|
34
|
+
# any development/local gems to the bundle.
|
35
|
+
Gemfile.lock
|
36
|
+
|
37
|
+
# Ignore your application database config since different devs may be using different
|
38
|
+
# setups.
|
39
|
+
config/database.yml
|
40
|
+
|
41
|
+
# Ignore tmp dir just in case
|
42
|
+
tmp/
|
43
|
+
IGNORE
|
44
|
+
end
|
45
|
+
Projects::ignore_file.reload
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
after_hook do
|
50
|
+
puts
|
51
|
+
puts "New ecosystem initialized in \e[36m#{Projects::path}\e[0m"
|
52
|
+
end
|
53
|
+
|
54
|
+
class << self
|
55
|
+
def usage
|
56
|
+
puts "usage: #{::Greenhouse::CLI.command_name} #{command_name} #{valid_arguments.to_s}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_another?
|
61
|
+
another = nil
|
62
|
+
while !['', 'n','no'].include?(another) do
|
63
|
+
puts "The following projects will be initialized in your ecosystem:"
|
64
|
+
Projects.projects.each do |project|
|
65
|
+
puts " \e[36m#{project.title}\e[0m"
|
66
|
+
end
|
67
|
+
puts
|
68
|
+
print "Would you like to add another project before initializing? ([y]es/[N]o): "
|
69
|
+
another = STDIN.gets.chomp.downcase
|
70
|
+
Tasks::AddProject.perform if ['y','yes'].include?(another)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def run
|
75
|
+
while Projects.projects.empty? do
|
76
|
+
puts "You must define at least one project for your ecosystem.\n"
|
77
|
+
Tasks::AddProject.perform
|
78
|
+
end
|
79
|
+
|
80
|
+
# Prompt to add another project
|
81
|
+
add_another?
|
82
|
+
|
83
|
+
# Sync all projects
|
84
|
+
Projects.projects.each do |project|
|
85
|
+
Tasks::SyncProject.perform(project)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Create a Procfile that uses `greenhouse launch` to launch the app's processes
|
89
|
+
Tasks::GenerateProcfile.perform
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'greenhouse/tasks/sync_project'
|
2
|
+
|
3
|
+
module Greenhouse
|
4
|
+
module Commands
|
5
|
+
class Launch
|
6
|
+
include Command
|
7
|
+
command_summary "Launch an application's processes using it's Procfile"
|
8
|
+
project_arguments *Projects::applications.map(&:to_arg)
|
9
|
+
valid_arguments *Projects::applications.map { |app| app.procfile.processes.select { |key,process| process.enabled? }.keys }.flatten
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def usage
|
13
|
+
puts <<USAGE
|
14
|
+
usage: #{::Greenhouse::CLI.command_name} #{command_name} <application> [<process> [<process> [...]]]
|
15
|
+
|
16
|
+
Applications:
|
17
|
+
#{project_arguments.to_help}
|
18
|
+
USAGE
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def run
|
23
|
+
if arguments.empty?
|
24
|
+
puts "Please provide the application you'd like to launch."
|
25
|
+
puts
|
26
|
+
usage
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
appname = arguments.slice!(0).key
|
31
|
+
app = Projects.applications.select { |app| app.name == appname }.first
|
32
|
+
|
33
|
+
if app.nil?
|
34
|
+
if Projects.projects.select { |proj| proj.name == appname }.first.nil?
|
35
|
+
puts "The application '#{appname}' does not exist."
|
36
|
+
else
|
37
|
+
puts "The project '#{appname}' is not defined as an application."
|
38
|
+
end
|
39
|
+
puts
|
40
|
+
usage
|
41
|
+
return
|
42
|
+
end
|
43
|
+
|
44
|
+
if !app.exists?
|
45
|
+
puts "The application directory #{app.path} does not exist. Are you sure you've initialized your ecosystem?"
|
46
|
+
puts
|
47
|
+
usage
|
48
|
+
return
|
49
|
+
end
|
50
|
+
|
51
|
+
Signal.trap("HUP") { |signo| quit(signo) }
|
52
|
+
Signal.trap("INT") { |signo| quit(signo) }
|
53
|
+
Signal.trap("KILL") { |signo| quit(signo) }
|
54
|
+
Signal.trap("TERM") { |signo| quit(signo) }
|
55
|
+
|
56
|
+
begin
|
57
|
+
@procs = {}
|
58
|
+
Bundler.with_clean_env do
|
59
|
+
app.chdir do
|
60
|
+
if app.dotenv.exists?
|
61
|
+
begin
|
62
|
+
# We have to unset these because foreman sets them by default, and Dotenv won't override a set value
|
63
|
+
%w(PORT RACK_ENV RAILS_ENV).each { |key| ENV[key] = nil }
|
64
|
+
require 'dotenv'
|
65
|
+
Dotenv.load!
|
66
|
+
rescue
|
67
|
+
puts "\e[31mError parsing .env file for #{app.title}.\e[0m"
|
68
|
+
exit 1
|
69
|
+
end
|
70
|
+
else
|
71
|
+
puts "\e[33mWarning: No .env file found in #{app.title}!\e[0m"
|
72
|
+
puts "Your application may not behave as expected without a .env file."
|
73
|
+
end
|
74
|
+
|
75
|
+
unless app.procfile.exists?
|
76
|
+
puts "\e[31mNo Procfile found for #{app.title}\e[0m"
|
77
|
+
exit 1
|
78
|
+
end
|
79
|
+
|
80
|
+
app.procfile.enabled.each do |key,process|
|
81
|
+
next if arguments.length > 0 && !arguments.map(&:key).include?(key)
|
82
|
+
@procs[key] = process
|
83
|
+
end
|
84
|
+
|
85
|
+
arguments.map(&:key).each { |key| puts "Skipping process not found in Procfile: #{key}" unless @procs.keys.include?(key) }
|
86
|
+
@procs.each do |key,process|
|
87
|
+
@procs[key] = fork do
|
88
|
+
exec process.command
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
Process.wait
|
93
|
+
end
|
94
|
+
end
|
95
|
+
rescue
|
96
|
+
quit 1
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
def quit(signo)
|
102
|
+
@procs.each do |key,pid|
|
103
|
+
begin
|
104
|
+
Process.kill("KILL", pid)
|
105
|
+
rescue # make sure to kill all children
|
106
|
+
end
|
107
|
+
end
|
108
|
+
exit signo
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Greenhouse
|
2
|
+
module Commands
|
3
|
+
class New
|
4
|
+
include Command
|
5
|
+
|
6
|
+
command_summary "Setup a new Greenhouse projects directory"
|
7
|
+
validate_arguments false
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def usage
|
11
|
+
puts "usage: #{::Greenhouse::CLI.command_name} #{command_name} <name> #{valid_arguments.to_s}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
if arguments.length == 0
|
17
|
+
usage
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
|
21
|
+
projects_directory = arguments.first.key
|
22
|
+
if File.exists?(projects_directory)
|
23
|
+
STDERR.puts "Directory already exists: #{projects_directory}"
|
24
|
+
STDERR.puts "You can try running `#{::Greenhouse::CLI.command_name} init` from inside the directory."
|
25
|
+
exit 1
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
FileUtils.mkdir(projects_directory)
|
30
|
+
rescue
|
31
|
+
STDERR.puts "Unable to create projects directory: #{projects_directory}"
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
|
35
|
+
exec "cd #{projects_directory}; greenhouse init"
|
36
|
+
#Dir.chdir(projects_directory) do
|
37
|
+
# Init.run
|
38
|
+
#end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Greenhouse
|
2
|
+
module Commands
|
3
|
+
class Pull
|
4
|
+
include Command
|
5
|
+
command_summary "Pull and merge remote branches for all projects"
|
6
|
+
project_arguments *Projects::projects.map(&:to_arg)
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def usage
|
10
|
+
puts <<USAGE
|
11
|
+
usage: #{::Greenhouse::CLI.command_name} #{command_name} [<project>] #{valid_arguments.to_s}
|
12
|
+
|
13
|
+
Projects:
|
14
|
+
#{project_arguments.to_help}
|
15
|
+
USAGE
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def pull_all
|
20
|
+
if Projects.projects.empty?
|
21
|
+
puts "No projects defined."
|
22
|
+
return
|
23
|
+
end
|
24
|
+
|
25
|
+
Projects.projects.each do |project|
|
26
|
+
Tasks::PullProject.perform(project)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def pull_project(project)
|
31
|
+
unless project.exists?
|
32
|
+
puts "Project \e[36m#{project.title}\e[0m does not exist. Try initializing it with `greenhouse init`"
|
33
|
+
return
|
34
|
+
end
|
35
|
+
|
36
|
+
Tasks::PullProject.perform(project)
|
37
|
+
end
|
38
|
+
|
39
|
+
def run
|
40
|
+
project = Projects::projects.select { |project| arguments.map(&:key).include?(project.name) }.first
|
41
|
+
project.nil? ? pull_all : pull_project(project)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Greenhouse
|
2
|
+
module Commands
|
3
|
+
class Purge
|
4
|
+
include ::Greenhouse::Commands::Command
|
5
|
+
command_summary "Purge project directories from your ecosystem allowing you to start from scratch"
|
6
|
+
valid_argument Scripts::Argument.new("-a --all", :summary => "Remove your ecosystem configuration files in addition to project directories (will NOT prompt when combined with -f)")
|
7
|
+
valid_argument Scripts::Argument.new(["-f", "--force"], :summary => "Force the purge, will still prompt if you have local changes or unpushed local branches")
|
8
|
+
project_arguments *Projects::projects.map(&:to_arg)
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def usage
|
12
|
+
puts <<USAGE
|
13
|
+
usage: #{::Greenhouse::CLI.command_name} #{command_name} [<project>] #{valid_arguments.to_s}
|
14
|
+
|
15
|
+
Arguments:
|
16
|
+
#{valid_arguments.to_help}
|
17
|
+
|
18
|
+
Projects:
|
19
|
+
#{project_arguments.to_help}
|
20
|
+
USAGE
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def clean?
|
25
|
+
return false if Projects::projects_file.exists?
|
26
|
+
return false if Projects::ignore_file.exists?
|
27
|
+
return false if Projects::procfile.exists?
|
28
|
+
return false if Projects::projects.any?(&:exists?)
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def force?
|
33
|
+
arguments.map(&:key).include?("-f")
|
34
|
+
end
|
35
|
+
|
36
|
+
def purge_all?
|
37
|
+
arguments.map(&:key).include?("-a")
|
38
|
+
end
|
39
|
+
|
40
|
+
def run
|
41
|
+
app = Projects::projects.select { |project| arguments.map(&:key).include?(project.name) }.first
|
42
|
+
if app.nil?
|
43
|
+
if clean?
|
44
|
+
puts "Nothing to do."
|
45
|
+
return
|
46
|
+
end
|
47
|
+
#return unless force? || prompt
|
48
|
+
|
49
|
+
purge
|
50
|
+
else
|
51
|
+
Tasks::PurgeProject.perform(app, force?)
|
52
|
+
end
|
53
|
+
|
54
|
+
puts "\e[33mDone\e[0m"
|
55
|
+
return
|
56
|
+
end
|
57
|
+
|
58
|
+
def purge
|
59
|
+
Projects.projects.each do |project|
|
60
|
+
Tasks::PurgeProject.perform(project, force?)
|
61
|
+
end
|
62
|
+
|
63
|
+
Tasks::RemoveGreenhouseFiles.perform(force?) if purge_all?
|
64
|
+
end
|
65
|
+
|
66
|
+
def prompt
|
67
|
+
puts <<PUTS
|
68
|
+
\e[31mThis will completely clean out the ecosystem, removing all projects and
|
69
|
+
optionally dropping the database and wiping configuration files.\e[0m
|
70
|
+
|
71
|
+
PUTS
|
72
|
+
puts <<PUTS
|
73
|
+
You will be prompted if you have any uncommitted local changes or unpushed branches
|
74
|
+
in any of your projects and may choose to either take action or skip that project
|
75
|
+
to avoid losing any work.
|
76
|
+
|
77
|
+
PUTS
|
78
|
+
puts <<PUTS
|
79
|
+
You will be prompted separately to confirm whether you'd like to drop or keep your
|
80
|
+
databases.
|
81
|
+
PUTS
|
82
|
+
|
83
|
+
puts
|
84
|
+
print "Are you sure you want to continue? ([y]es/[N]o): "
|
85
|
+
continue = STDIN.gets.chomp.downcase
|
86
|
+
["y","yes"].include?(continue)
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|