hobo-inviqa 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +4 -0
- data/Gemfile.lock +93 -0
- data/Guardfile +14 -0
- data/Hobofile +34 -0
- data/Rakefile +2 -0
- data/bin/hobo +23 -0
- data/features/deps.feature +43 -0
- data/features/hobo/basic.feature +30 -0
- data/features/hobo/help.feature +12 -0
- data/features/hobo/subcommands.feature +16 -0
- data/features/seed/plant.feature +64 -0
- data/features/step_definitions/seed.rb +11 -0
- data/features/support/env.rb +6 -0
- data/features/vm.feature +0 -0
- data/hobo.gemspec +37 -0
- data/lib/hobo.rb +44 -0
- data/lib/hobo/cli.rb +185 -0
- data/lib/hobo/config/file.rb +21 -0
- data/lib/hobo/error_handlers/debug.rb +9 -0
- data/lib/hobo/error_handlers/friendly.rb +52 -0
- data/lib/hobo/errors.rb +60 -0
- data/lib/hobo/help_formatter.rb +111 -0
- data/lib/hobo/helper/file_locator.rb +39 -0
- data/lib/hobo/helper/shell.rb +59 -0
- data/lib/hobo/lib/seed/project.rb +41 -0
- data/lib/hobo/lib/seed/replacer.rb +57 -0
- data/lib/hobo/lib/seed/seed.rb +43 -0
- data/lib/hobo/metadata.rb +28 -0
- data/lib/hobo/patches/rake.rb +56 -0
- data/lib/hobo/patches/slop.rb +22 -0
- data/lib/hobo/paths.rb +49 -0
- data/lib/hobo/tasks/debug.rb +22 -0
- data/lib/hobo/tasks/deps.rb +45 -0
- data/lib/hobo/tasks/seed.rb +43 -0
- data/lib/hobo/tasks/tools.rb +13 -0
- data/lib/hobo/tasks/vm.rb +49 -0
- data/lib/hobo/ui.rb +96 -0
- data/lib/hobo/util.rb +7 -0
- data/lib/hobo/version.rb +3 -0
- data/spec/hobo/cli_spec.rb +135 -0
- data/spec/hobo/config/file_spec.rb +48 -0
- data/spec/hobo/error_handlers/debug_spec.rb +10 -0
- data/spec/hobo/error_handlers/friendly_spec.rb +81 -0
- data/spec/hobo/error_spec.rb +0 -0
- data/spec/hobo/help_formatter_spec.rb +131 -0
- data/spec/hobo/helpers/file_locator_spec.rb +7 -0
- data/spec/hobo/helpers/shell_spec.rb +7 -0
- data/spec/hobo/lib/seed/project_spec.rb +83 -0
- data/spec/hobo/lib/seed/replacer_spec.rb +47 -0
- data/spec/hobo/lib/seed/seed_spec.rb +95 -0
- data/spec/hobo/metadata_spec.rb +46 -0
- data/spec/hobo/patches/rake_spec.rb +0 -0
- data/spec/hobo/paths_spec.rb +77 -0
- data/spec/hobo/ui_spec.rb +64 -0
- data/spec/spec_helper.rb +6 -0
- metadata +355 -0
@@ -0,0 +1,13 @@
|
|
1
|
+
namespace :tools do
|
2
|
+
task :composer do
|
3
|
+
bin_file = File.join(Hobo.project_bin_path, "composer.phar")
|
4
|
+
unless File.exists?(bin_file)
|
5
|
+
Hobo.ui.success "Getting composer.phar"
|
6
|
+
FileUtils.mkdir_p File.dirname(bin_file)
|
7
|
+
Dir.chdir File.dirname(bin_file) do
|
8
|
+
shell "php", "-r", "eval('?>'.file_get_contents('https://getcomposer.org/installer'));", realtime: true, indent: 2
|
9
|
+
end
|
10
|
+
Hobo.ui.separator
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
desc "VM related commands"
|
2
|
+
project_only
|
3
|
+
namespace :vm do
|
4
|
+
def vagrantfile &block
|
5
|
+
locate("*Vagrantfile", missing: "No Vagrantfile found") do
|
6
|
+
yield
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "Start VM"
|
11
|
+
task :start => [ 'deps:gems', 'deps:chef', 'deps:composer', 'vm:up', 'vm:start' ]
|
12
|
+
|
13
|
+
desc "Stop VM"
|
14
|
+
task :stop do
|
15
|
+
vagrantfile do
|
16
|
+
Hobo.ui.title "Stopping VM"
|
17
|
+
bundle_shell "vagrant", "suspend", "--color", realtime: true, indent: 2
|
18
|
+
Hobo.ui.separator
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Rebuild VM"
|
23
|
+
task :rebuild => [ 'vm:destroy', 'vm:start' ]
|
24
|
+
|
25
|
+
desc "Destroy VM"
|
26
|
+
task :destroy do
|
27
|
+
vagrantfile do
|
28
|
+
Hobo.ui.title "Stopping VM"
|
29
|
+
bundle_shell "vagrant", "destroy", "--color", realtime: true, indent: 2
|
30
|
+
Hobo.ui.separator
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
task :up do
|
35
|
+
vagrantfile do
|
36
|
+
Hobo.ui.title "Starting vagrant VM"
|
37
|
+
bundle_shell "vagrant", "up", "--no-provision", "--color", realtime: true, indent: 2
|
38
|
+
Hobo.ui.separator
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
task :provision do
|
43
|
+
vagrantfile do
|
44
|
+
Hobo.ui.title "Provisioning VM"
|
45
|
+
bundle_shell "vagrant", "provision", "--color", realtime: true, indent: 2
|
46
|
+
Hobo.ui.separator
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/hobo/ui.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'highline'
|
2
|
+
|
3
|
+
module Hobo
|
4
|
+
class << self
|
5
|
+
attr_accessor :ui
|
6
|
+
end
|
7
|
+
|
8
|
+
class Ui
|
9
|
+
attr_accessor :interactive
|
10
|
+
|
11
|
+
def initialize out = $stdout, error = $stderr
|
12
|
+
colors = HighLine::ColorScheme.new do |cs|
|
13
|
+
cs[:debug] = [ ]
|
14
|
+
cs[:info] = [ ]
|
15
|
+
cs[:warning] = [ :yellow ]
|
16
|
+
cs[:error] = [ :red ]
|
17
|
+
cs[:success] = [ :green ]
|
18
|
+
cs[:opt] = [ :green ]
|
19
|
+
cs[:command] = [:green ]
|
20
|
+
cs[:special] = [ :blue ]
|
21
|
+
cs[:title] = [ :green ]
|
22
|
+
cs[:help_title] = [ :yellow ]
|
23
|
+
cs[:description] = [ :bold ]
|
24
|
+
end
|
25
|
+
|
26
|
+
HighLine.color_scheme = colors
|
27
|
+
|
28
|
+
@out = ::HighLine.new $stdin, out
|
29
|
+
@error = ::HighLine.new $stdin, error
|
30
|
+
end
|
31
|
+
|
32
|
+
def color_scheme scheme = nil
|
33
|
+
HighLine.color_scheme = scheme if scheme
|
34
|
+
HighLine.color_scheme
|
35
|
+
end
|
36
|
+
|
37
|
+
def ask question, opts = {}
|
38
|
+
unless Hobo.ui.interactive
|
39
|
+
raise Hobo::NonInteractive.new(question) if opts[:default].nil?
|
40
|
+
return opts[:default]
|
41
|
+
end
|
42
|
+
|
43
|
+
question = "#{question} [#{opts[:default]}]" if opts[:default]
|
44
|
+
question += ": "
|
45
|
+
begin
|
46
|
+
answer = @out.ask(question) do |q|
|
47
|
+
q.validate = opts[:validate] if opts[:validate]
|
48
|
+
q.readline
|
49
|
+
end
|
50
|
+
answer.strip.empty? ? opts[:default] : answer.strip
|
51
|
+
rescue EOFError
|
52
|
+
Hobo.ui.info ""
|
53
|
+
""
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def separator
|
58
|
+
info ""
|
59
|
+
end
|
60
|
+
|
61
|
+
def color *args
|
62
|
+
@out.color *args
|
63
|
+
end
|
64
|
+
|
65
|
+
def debug message
|
66
|
+
say @out, message, :debug
|
67
|
+
end
|
68
|
+
|
69
|
+
def info message
|
70
|
+
say @out, message, :info
|
71
|
+
end
|
72
|
+
|
73
|
+
def warning message
|
74
|
+
say @error, message, :warning
|
75
|
+
end
|
76
|
+
|
77
|
+
def error message
|
78
|
+
say @error, message, :error
|
79
|
+
end
|
80
|
+
|
81
|
+
def success message
|
82
|
+
say @out, message, :success
|
83
|
+
end
|
84
|
+
|
85
|
+
def title message
|
86
|
+
say @out, message, :title
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def say channel, message, color
|
92
|
+
return if message.nil?
|
93
|
+
channel.say(color ? channel.color(message, color) : message)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/lib/hobo/util.rb
ADDED
data/lib/hobo/version.rb
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'rake'
|
2
|
+
|
3
|
+
require 'hobo/metadata'
|
4
|
+
require 'hobo/patches/rake'
|
5
|
+
require 'hobo/patches/slop'
|
6
|
+
|
7
|
+
require 'hobo/errors'
|
8
|
+
require 'hobo/cli'
|
9
|
+
|
10
|
+
|
11
|
+
describe Hobo::Cli do
|
12
|
+
cli = nil
|
13
|
+
help = nil
|
14
|
+
|
15
|
+
before do
|
16
|
+
Rake::Task.tasks.each do |task|
|
17
|
+
task.clear
|
18
|
+
end
|
19
|
+
Hobo.ui = double(Hobo::Ui).as_null_object
|
20
|
+
help = double(Hobo::HelpFormatter).as_null_object
|
21
|
+
cli = Hobo::Cli.new help: help
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "hobofile" do
|
25
|
+
it "should load the hobofile if present" do
|
26
|
+
cli.start []
|
27
|
+
Rake::Task["test:non-interactive"].should_not be nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "command mapping" do
|
32
|
+
it "should set command map on help formatter" do
|
33
|
+
help.should_recieve('command_map=')
|
34
|
+
cli.start ["test", "subcommand"]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "metadata" do
|
39
|
+
it "should propagate description metadata" do
|
40
|
+
map = nil
|
41
|
+
allow(help).to receive("command_map=") { |i| map = i }
|
42
|
+
cli.start []
|
43
|
+
map["test:metadata"].description.should match "description"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should propagate long description metadata" do
|
47
|
+
map = nil
|
48
|
+
allow(help).to receive("command_map=") { |i| map = i }
|
49
|
+
cli.start []
|
50
|
+
map["test:metadata"].long_description.should match "long description"
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should propagate arg list metadata" do
|
54
|
+
map = nil
|
55
|
+
allow(help).to receive("command_map=") { |i| map = i }
|
56
|
+
cli.start []
|
57
|
+
expect(map["test:metadata"].arg_list).to eq [ :arg ]
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should propagate option metadata" do
|
61
|
+
map = nil
|
62
|
+
allow(help).to receive("command_map=") { |i| map = i }
|
63
|
+
cli.start []
|
64
|
+
map["test:metadata"].options.length.should be 2
|
65
|
+
expect(map["test:metadata"].options.map(&:short)).to eq [ 'o', 'h' ]
|
66
|
+
expect(map["test:metadata"].options.map(&:long)).to eq [ 'option', 'help' ]
|
67
|
+
expect(map["test:metadata"].options.map(&:description)).to eq [ 'Option description', 'Display help' ]
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should propagate hidden metadata" do
|
71
|
+
map = nil
|
72
|
+
allow(help).to receive("command_map=") { |i| map = i }
|
73
|
+
cli.start []
|
74
|
+
map["test:metadata"].hidden.should be true
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "global options" do
|
79
|
+
it "should set non-interactive mode in ui if --non-interactive" do
|
80
|
+
Hobo.ui.should_receive('interactive=').with(false)
|
81
|
+
cli.start(['--non-interactive'])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "invocation" do
|
86
|
+
it "should show help if no args or opts passed" do
|
87
|
+
help.should_receive(:help)
|
88
|
+
cli.start([])
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should show help for --help" do
|
92
|
+
help.should_receive(:help)
|
93
|
+
cli.start ["--help"]
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should execute a top level command" do
|
97
|
+
Hobo.ui.should_recieve(:info).with("top level")
|
98
|
+
cli.start ["top-level"]
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should execute a subcommand" do
|
102
|
+
Hobo.ui.should_recieve(:info).with("Subcommand test")
|
103
|
+
cli.start ["test", "subcommand"]
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should show help for a namespace" do
|
107
|
+
help.should_receive(:help).with(all: nil, target: "test")
|
108
|
+
cli.start ["test"]
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should show command help for --help" do
|
112
|
+
help.should_receive(:help).with(all: nil, target: "test:subcommand")
|
113
|
+
cli.start ["test", "subcommand", "--help"]
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should propagate --all option to help" do
|
117
|
+
help.should_receive(:help).with(all: true, target: "test")
|
118
|
+
cli.start ["test", "--all"]
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should propagate command opts to command" do
|
122
|
+
Hobo.ui.should_receive(:info).with("1234")
|
123
|
+
cli.start ["test", "option-test", "--testing=1234"]
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should propagate arguments to command" do
|
127
|
+
Hobo.ui.should_receive(:info).with("1234")
|
128
|
+
cli.start ["test", "argument-test", "1234"]
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should raise an exception if not enough arguments were passed" do
|
132
|
+
expect { cli.start(["test", "metadata"]) }.to raise_error Hobo::MissingArgumentsError
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'hobo/paths'
|
3
|
+
require 'hobo/config/file'
|
4
|
+
|
5
|
+
describe Hobo::Config::File do
|
6
|
+
before do
|
7
|
+
Hobo.project_path = nil
|
8
|
+
FakeFS.activate!
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
FakeFS::FileSystem.clear
|
13
|
+
FakeFS.deactivate!
|
14
|
+
end
|
15
|
+
|
16
|
+
def fake_config
|
17
|
+
{
|
18
|
+
:string => "string",
|
19
|
+
:integer => 0,
|
20
|
+
:boolean => true,
|
21
|
+
:hash => { :test => true },
|
22
|
+
:array => [ 1 ]
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "save" do
|
27
|
+
it "should save config hash to specified file" do
|
28
|
+
Hobo::Config::File.save "test.yaml", fake_config
|
29
|
+
File.read("test.yaml").should match /string: string/
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "load" do
|
34
|
+
it "should load config hash from file" do
|
35
|
+
Hobo::Config::File.save "test.yaml", fake_config
|
36
|
+
fake_config().should eq Hobo::Config::File.load("test.yaml")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should return empty hash if file does not exist" do
|
40
|
+
Hobo::Config::File.load("test.yaml").should eq({})
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should raise error if file can't be parsed" do
|
44
|
+
File.write("test.yaml", "##Invalid yaml file")
|
45
|
+
expect { Hobo::Config::File.load("test.yaml") }.to raise_error(RuntimeError, "Invalid hobo configuration (test.yaml)")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'hobo/error_handlers/debug'
|
2
|
+
|
3
|
+
describe Hobo::ErrorHandlers::Debug do
|
4
|
+
describe "handle" do
|
5
|
+
it "should re-raise the error" do
|
6
|
+
exception = Exception.new
|
7
|
+
expect { Hobo::ErrorHandlers::Debug.new.handle(exception) }.to raise_error exception
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'hobo/error_handlers/friendly'
|
2
|
+
require 'hobo/ui'
|
3
|
+
|
4
|
+
describe Hobo::ErrorHandlers::Friendly do
|
5
|
+
before do
|
6
|
+
Hobo.ui = double(Hobo::Ui.new).as_null_object
|
7
|
+
FakeFS.activate!
|
8
|
+
FileUtils.mkdir '/tmp'
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
FakeFS::FileSystem.clear
|
13
|
+
FakeFS.deactivate!
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "handle" do
|
17
|
+
it "should display specialized error for Interrupt" do
|
18
|
+
error = Interrupt.new
|
19
|
+
Hobo.ui.should_receive(:warning).with(/Caught Interrupt/)
|
20
|
+
Hobo::ErrorHandlers::Friendly.new.handle(error)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should display specialized error for an external command error" do
|
24
|
+
File.write("temp_log", "command output")
|
25
|
+
output = Struct.new(:path).new
|
26
|
+
output.path = "temp_log"
|
27
|
+
error = Hobo::ExternalCommandError.new("command", 128, output)
|
28
|
+
Hobo.ui.should_receive(:error).with(/The following external command appears to have failed \(exit status 128\)/)
|
29
|
+
Hobo::ErrorHandlers::Friendly.new.handle(error)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should write command output to /tmp/hobo_error.log for external command error" do
|
33
|
+
File.write("temp_log", "command output")
|
34
|
+
output = Struct.new(:path).new
|
35
|
+
output.path = "temp_log"
|
36
|
+
error = Hobo::ExternalCommandError.new("command", 128, output)
|
37
|
+
Hobo::ErrorHandlers::Friendly.new.handle(error)
|
38
|
+
File.read(File.join(Dir.tmpdir, 'hobo_error.log')).should match "command output"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should display specialized error for invalid command or opt error" do
|
42
|
+
error = Hobo::InvalidCommandOrOpt.new("command")
|
43
|
+
Hobo.ui.should_receive(:error).with(/Invalid command or option specified: 'command'/)
|
44
|
+
Hobo::ErrorHandlers::Friendly.new.handle(error)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should display specialized error for missing argument error" do
|
48
|
+
error = Hobo::MissingArgumentsError.new("command", ["arg1"])
|
49
|
+
Hobo.ui.should_receive(:error).with(/Not enough arguments for command/)
|
50
|
+
Hobo::ErrorHandlers::Friendly.new.handle(error)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should display specialized error for user error" do
|
54
|
+
error = Hobo::UserError.new("user error")
|
55
|
+
Hobo.ui.should_receive(:error).with(/user error/)
|
56
|
+
Hobo::ErrorHandlers::Friendly.new.handle(error)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should display generic error for other exception" do
|
60
|
+
error = nil
|
61
|
+
begin
|
62
|
+
raise Exception.new("general error")
|
63
|
+
rescue Exception => error
|
64
|
+
end
|
65
|
+
|
66
|
+
Hobo.ui.should_receive(:error).with(/An unexpected error has occured/)
|
67
|
+
Hobo::ErrorHandlers::Friendly.new.handle(error)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should write error backtrace to /tmp/hobo_error.log for other exception" do
|
71
|
+
error = nil
|
72
|
+
begin
|
73
|
+
raise Exception.new("general error")
|
74
|
+
rescue Exception => error
|
75
|
+
end
|
76
|
+
|
77
|
+
Hobo::ErrorHandlers::Friendly.new.handle(error)
|
78
|
+
File.read(File.join(Dir.tmpdir, 'hobo_error.log')).should match /\(Exception\) general error/
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|