mybot 0.0.4 → 0.1.0

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.
Files changed (53) hide show
  1. data/Botfile +7 -61
  2. data/CHANGELOG.md +2 -25
  3. data/README.md +72 -189
  4. data/lib/mybot.rb +20 -21
  5. data/lib/mybot/base.rb +6 -2
  6. data/lib/mybot/cli.rb +45 -5
  7. data/lib/mybot/command.rb +37 -28
  8. data/lib/mybot/fmt.rb +143 -52
  9. data/lib/mybot/helpers.rb +24 -0
  10. data/lib/mybot/installer.rb +31 -0
  11. data/lib/mybot/lib.rb +20 -59
  12. data/lib/mybot/libs.rb +31 -28
  13. data/lib/mybot/loader.rb +25 -0
  14. data/lib/mybot/node.rb +100 -47
  15. data/lib/mybot/nodes.rb +16 -0
  16. data/lib/mybot/tasks.rb +47 -11
  17. data/lib/mybot/template.rb +8 -8
  18. data/lib/mybot/templates.rb +15 -0
  19. data/lib/mybot/version.rb +1 -1
  20. data/vendor/lib/{core/.gitkeep → .gitkeep} +0 -0
  21. data/vendor/{recipes → plugins}/.gitkeep +0 -0
  22. data/vendor/{tpl/core → tasks}/.gitkeep +0 -0
  23. data/vendor/tpl/.gitkeep +0 -0
  24. metadata +11 -34
  25. data/lib/mybot/aws.rb +0 -54
  26. data/lib/mybot/commands.rb +0 -108
  27. data/lib/mybot/core-ext/array.rb +0 -9
  28. data/lib/mybot/core-ext/class.rb +0 -53
  29. data/lib/mybot/core-ext/kernel.rb +0 -21
  30. data/lib/mybot/messages.rb +0 -30
  31. data/lib/mybot/recipes.rb +0 -25
  32. data/lib/mybot/result.rb +0 -26
  33. data/lib/mybot/utils.rb +0 -7
  34. data/vendor/lib/core/fs.rb +0 -191
  35. data/vendor/lib/core/osx/git.rb +0 -31
  36. data/vendor/lib/core/osx/rails.rb +0 -31
  37. data/vendor/lib/core/osx/static.rb +0 -31
  38. data/vendor/lib/core/ubuntu/apache.rb +0 -42
  39. data/vendor/lib/core/ubuntu/apt.rb +0 -57
  40. data/vendor/lib/core/ubuntu/git.rb +0 -48
  41. data/vendor/lib/core/ubuntu/mysql.rb +0 -214
  42. data/vendor/lib/core/ubuntu/nginx.rb +0 -43
  43. data/vendor/lib/core/ubuntu/passenger.rb +0 -55
  44. data/vendor/lib/core/ubuntu/php.rb +0 -76
  45. data/vendor/lib/core/ubuntu/rails.rb +0 -105
  46. data/vendor/lib/core/ubuntu/ruby.rb +0 -166
  47. data/vendor/lib/core/ubuntu/service.rb +0 -30
  48. data/vendor/lib/core/ubuntu/static.rb +0 -50
  49. data/vendor/lib/core/ubuntu/users.rb +0 -76
  50. data/vendor/lib/core/ubuntu/vim.rb +0 -31
  51. data/vendor/tpl/core/ubuntu/apache/apache2.conf.erb +0 -80
  52. data/vendor/tpl/core/ubuntu/nginx/nginx.conf.erb +0 -72
  53. data/vendor/tpl/core/ubuntu/php/php.ini.erb +0 -1818
@@ -1,29 +1,28 @@
1
- require "mybot/core-ext/kernel"
2
- require "mybot/core-ext/class"
3
- require "mybot/core-ext/array"
1
+ $USE_COLOR = true
2
+ $SHOW_CMD = true
3
+ $LIVE_STDOUT = false
4
+ $LIVE_STDERR = false
5
+ $LIVE_STDIN = false
4
6
 
5
7
  module Mybot
6
- autoload :Aws, "mybot/aws"
7
- autoload :Base, "mybot/base"
8
- autoload :Cli, "mybot/cli"
9
- autoload :Command, "mybot/command"
10
- autoload :Commands, "mybot/commands"
11
- autoload :Fmt, "mybot/fmt"
12
- autoload :Lib, "mybot/lib"
13
- autoload :Libs, "mybot/libs"
14
- autoload :Messages, "mybot/messages"
15
- autoload :Node, "mybot/node"
16
- autoload :Recipes, "mybot/recipes"
17
- autoload :Result, "mybot/result"
18
- autoload :Tasks, "mybot/tasks"
19
- autoload :Template, "mybot/template"
20
- autoload :Utils, "mybot/utils"
21
- autoload :VERSION, "mybot/version"
8
+ autoload :Base, "mybot/base"
9
+ autoload :Cli, "mybot/cli"
10
+ autoload :Command, "mybot/command"
11
+ autoload :Fmt, "mybot/fmt"
12
+ autoload :Helpers, "mybot/helpers"
13
+ autoload :Installer, "mybot/installer"
14
+ autoload :Lib, "mybot/lib"
15
+ autoload :Libs, "mybot/libs"
16
+ autoload :Loader, "mybot/loader"
17
+ autoload :Node, "mybot/node"
18
+ autoload :Nodes, "mybot/nodes"
19
+ autoload :Tasks, "mybot/tasks"
20
+ autoload :Template, "mybot/template"
21
+ autoload :Templates, "mybot/templates"
22
+ autoload :VERSION, "mybot/version"
22
23
 
23
24
  GEM_PATH = File.dirname(File.dirname(__FILE__))
24
25
  VENDOR_PATH = File.join(GEM_PATH, "vendor", ".")
25
26
  HOME_PATH = File.expand_path "~"
26
27
  MYBOT_PATH = File.join HOME_PATH, ".mybot"
27
- LIB_PATH = File.join MYBOT_PATH, "lib"
28
- TPL_PATH = File.join MYBOT_PATH, "tpl"
29
28
  end
@@ -1,8 +1,12 @@
1
1
  module Mybot
2
2
  module Base
3
- include Commands
4
- include Recipes
3
+ include Fmt
4
+ include Helpers
5
+ include Libs
6
+ include Loader
7
+ include Nodes
5
8
  include Tasks
9
+ include Templates
6
10
  extend self
7
11
  end
8
12
  end
@@ -1,15 +1,55 @@
1
1
  module Mybot
2
2
  module Cli
3
- include Messages
3
+ include Fmt
4
+ include Installer
4
5
  extend self
5
6
 
6
7
  def start(args)
7
- unless args[0]
8
- error "usage: bot <task>"
8
+ cmd = args.shift
9
+ options = parse(args)
10
+
11
+ error "usage: bot [install|uninstall|<task>] <options>" unless cmd
12
+
13
+ case cmd
14
+ when /(install|uninstall)/
15
+ self.send($1, options)
16
+ else
17
+ Base.load_files
18
+ Base.run_task cmd, options
9
19
  end
20
+ end
21
+
22
+ def parse(args)
23
+ options = {}
10
24
 
11
- Base.load_recipes
12
- Base.run_task args[0]
25
+ args.each_with_index do |arg, i|
26
+ case arg # --foo=bar, -foo=bar
27
+ when /\=/
28
+ key, value = *arg.split("=")
29
+ options[key.sub(/^-{1,2}/,"").to_sym] = value
30
+ when /^-{1,2}no-(.+)/ # --no-foo
31
+ options[$1.to_sym] = false
32
+ when /^-{1,2}(.+)/ # --foo bar, --foo, -foo
33
+ key = $1.to_sym
34
+ value = true
35
+ if args[i+1] && args[i+1] !~ /^-{1,2}/
36
+ value = args.delete_at(i+1)
37
+ end
38
+ options[key] = value
39
+ when Hash
40
+ options.merge!(arg)
41
+ end
42
+ end
43
+
44
+ options.each do |k, v|
45
+ case v
46
+ when /^true$/i then options[k] = true
47
+ when /^false$/i then options[k] = false
48
+ when /^\d+$/ then options[k] = v.to_i
49
+ when /^[\d\.]+$/ then options[k] = v.to_f
50
+ when /,/ then options[k] = v.split(",").map(&:strip)
51
+ end
52
+ end
13
53
  end
14
54
  end
15
55
  end
@@ -1,12 +1,14 @@
1
1
  module Mybot
2
2
  class Command
3
- attr_accessor :channel, :out, :result
3
+ include Fmt
4
4
 
5
- def initialize(node)
6
- @node = node
7
- @out = ""
5
+ attr_accessor :channel, :exit_status, :time
6
+
7
+ def initialize
8
+ @out = @stdout = @stderr = ""
8
9
  @handlers = {}
9
- @result = Result.new
10
+ @exit_status = -1
11
+ @time = 0
10
12
  end
11
13
 
12
14
  def on(s, &block)
@@ -15,44 +17,51 @@ module Mybot
15
17
 
16
18
  def handle_stdout(data)
17
19
  @out = data
18
- @result.stdout += data
19
- @node.fmt.stdout data
20
+ @stdout += data
21
+ stdout_live(data)
20
22
  @handlers.each do |s, proc|
21
- proc.call if @out.include? s
23
+ if @out.include? s
24
+ handle_info s, :type => :stdout
25
+ proc.call
26
+ end
22
27
  end
23
28
  end
24
29
 
25
30
  def handle_stderr(data)
26
31
  @out = data
27
- @result.stderr += data
28
- @node.fmt.stderr data
32
+ @stderr += data
33
+ stderr_live(data)
29
34
  @handlers.each do |s, proc|
30
- proc.call if @out.include? s
35
+ if @out.include? s
36
+ handle_info s, :type => :stderr
37
+ proc.call
38
+ end
31
39
  end
32
40
  end
33
41
 
34
- def handle_sudo
35
- on "[sudo] password" do
36
- write @node.options[:password], :shadow => true
37
- end
42
+ def handle_close
43
+ status_info result
44
+ error "command exited with error" unless result[:exit_status] == 0
45
+ end
38
46
 
39
- on "Password:" do
40
- write @node.options[:password], :shadow => true
41
- end
47
+ def write(data, options = {})
48
+ write_info data, options
49
+ @channel.send_data "#{data}\n"
50
+ end
42
51
 
43
- on "Sorry, try again." do
44
- @node.fmt.error "cannot handle sudo automatically, try manually"
45
- end
52
+ def result
53
+ {
54
+ :stdout => filter(@stdout),
55
+ :stderr => filter(@stderr),
56
+ :exit_status => @exit_status,
57
+ :time => @time
58
+ }
46
59
  end
47
60
 
48
- def write(data, options = {})
49
- if options[:shadow]
50
- @node.fmt.write "***"
51
- else
52
- @node.fmt.write data
53
- end
61
+ private
54
62
 
55
- @channel.send_data "#{data}\n"
63
+ def filter(data)
64
+ data.gsub(/\[sudo\]\ password\ for\ [a-zA-Z0-9_].+\:/, "")
56
65
  end
57
66
  end
58
67
  end
@@ -1,84 +1,175 @@
1
1
  require "colored"
2
2
 
3
3
  module Mybot
4
- class Fmt
5
- cattr_accessor :use_color, :show_cmd, :show_cmd,
6
- :show_stdout, :show_stderr, :show_stdin
4
+ module Fmt
5
+ def info(msg)
6
+ info_format = "INFO"
7
+ info_format = info_format.blue.bold if $USE_COLOR
8
+ puts "#{info_format} #{msg}"
9
+ end
7
10
 
8
- @@use_color = true
9
- @@show_cmd = true
10
- @@show_stdout = true
11
- @@show_stderr = true
12
- @@show_stdin = true
11
+ def warning(msg)
12
+ warning_format = "WARNING"
13
+ warning_format = warning_format.magenta.bold if $USE_COLOR
14
+ puts "#{warning_format} #{msg}"
15
+ end
13
16
 
14
- def initialize(host, user)
15
- @host, @user = host, user
17
+ def error(msg)
18
+ error_format = "ERROR"
19
+ error_format = error_format.red.bold if $USE_COLOR
20
+ puts "#{error_format} #{msg}"
21
+ abort
16
22
  end
17
23
 
18
- def run(cmd)
19
- run_format = "RUN"
20
- run_format = run_format.blue.bold if @@use_color
21
- $stdout.print "#{prompt} #{run_format} #{cmd}\n" if @@show_cmd
24
+ def task_info(task)
25
+ task_format = "TASK"
26
+ task_format = task_format.green.bold if $USE_COLOR
27
+ puts "#{task_format} #{task}"
22
28
  end
23
29
 
24
- def stdout(data)
25
- data = data.green if @@use_color
26
- $stdout.print(data) if @@show_stdout
30
+ def run_info(cmd, options = {})
31
+ return unless $SHOW_CMD
32
+
33
+ primary_cmd "RUN", cmd, options
34
+ secondary_cmd "SUDO" if options[:sudo]
35
+ secondary_cmd "CWD", options[:cwd] if options[:cwd] != ""
36
+
37
+ unless options[:env].empty?
38
+ secondary_cmd "ENV"
39
+ kv_cmd options[:env]
40
+ end
27
41
  end
28
42
 
29
- def stderr(data)
30
- data = data.red if @@use_color
31
- $stdout.print(data) if @@show_stderr
43
+ def handle_info(s, options = {})
44
+ if $USE_COLOR
45
+ s = s.green if options[:type] == :stdout
46
+ s = s.red if options[:type] == :stderr
47
+ end
48
+
49
+ secondary_cmd "HANDLE", s
32
50
  end
33
51
 
34
- def write(data)
35
- write_format = "WRITE"
36
- write_format = write_format.blue.bold if @@use_color
52
+ def write_info(data, options = {})
53
+ return unless $SHOW_CMD
54
+
37
55
  lf_format = "<LF>"
38
- lf_format = lf_format.red.bold if @@use_color
39
- if @@show_stdin
40
- $stdout.print "\n#{prompt} #{write_format} #{data}#{lf_format}\n"
56
+ lf_format = lf_format.bold if $USE_COLOR
57
+
58
+ if options[:shadow]
59
+ data = "*" * data.size
41
60
  end
61
+
62
+ secondary_cmd "WRITE", "#{data}#{lf_format}"
42
63
  end
43
64
 
44
- def upload(from, to)
45
- upload_format = "UPLOAD"
46
- upload_format = upload_format.blue.bold if @@use_color
65
+ def status_info(result)
66
+ return unless $SHOW_CMD
67
+
68
+ value_format = "#{result[:exit_status]}"
47
69
 
48
- if @@show_cmd
49
- $stdout.print "#{prompt} #{upload_format} #{from} -> #{to}\n"
70
+ if $USE_COLOR
71
+ if result[:exit_status] == 0
72
+ value_format = value_format.green.bold
73
+ else
74
+ value_format = value_format.red.bold
75
+ end
50
76
  end
51
- end
52
77
 
53
- def download(from, to)
54
- download_format = "DOWNLOAD"
55
- download_format = download_format.blue.bold if @@use_color
56
-
57
-
58
- if @@show_cmd
59
- $stdout.print "#{prompt} #{download_format} #{from} -> #{to}\n"
78
+ secondary_cmd "EXIT", value_format
79
+ time_info result[:time]
80
+
81
+ if result[:exit_status] != 0
82
+ stdout(result[:stdout])
83
+ stderr(result[:stderr])
60
84
  end
61
85
  end
62
86
 
87
+ def stdout(data)
88
+ return if $LIVE_STDOUT || data.empty?
89
+
90
+ stdout_data_format = data.split("\r\n").join("\n")
91
+ stdout_data_format = stdout_data_format.green if $USE_COLOR
92
+
93
+ secondary_cmd "STDOUT"
94
+ puts stdout_data_format
95
+ end
96
+
97
+ def stderr(data)
98
+ return if $LIVE_STDERR || data.empty?
99
+
100
+ stderr_data_format = data
101
+ stderr_data_format = stderr_data_format.red if $USE_COLOR
102
+
103
+ secondary_cmd "STDERR"
104
+ puts stderr_data_format
105
+ end
106
+
107
+ def stdout_live(data)
108
+ return unless $LIVE_STDOUT
109
+
110
+ stdout_data_format = data
111
+ stdout_data_format = stdout_data_format.green if $USE_COLOR
112
+
113
+ $stdout.print stdout_data_format
114
+ end
115
+
116
+ def stderr_live(data)
117
+ return unless $LIVE_STDERR
118
+
119
+ stderr_data_format = data
120
+ stderr_data_format = stderr_data_format.red if $USE_COLOR
121
+
122
+ $stdout.print stderr_data_format
123
+ end
124
+
125
+ def upload_info(options)
126
+ return unless $SHOW_CMD
127
+
128
+ primary_cmd "UPLOAD", options[:file], options
129
+ secondary_cmd "TO", options[:to]
130
+ end
131
+
132
+ def download_info(options)
133
+ return unless $SHOW_CMD
134
+
135
+ primary_cmd "DOWNLOAD", options[:file], options
136
+ secondary_cmd "TO", options[:to]
137
+ end
138
+
139
+ def prompt(user, host)
140
+ prompt_format = "[#{user}@#{host}]"
141
+ prompt_format = prompt_format.white if $USE_COLOR
142
+ end
143
+
63
144
  def progress(n)
64
- if @@show_cmd
65
- $stdout.print "\r#{n}%"
66
- puts if n == 100
67
- end
145
+ return unless $SHOW_CMD
146
+
147
+ progress_format = "PROGRESS"
148
+ progress_format = progress_format.blue.bold if $USE_COLOR
149
+
150
+ $stdout.print "\r #{progress_format} #{n}%"
151
+ puts if n == 100
68
152
  end
69
153
 
70
- def error(msg)
71
- error_format = "ERROR"
72
- error_format = error_format.bold.red if @@use_color
73
- $stdout.print "#{prompt} #{error_format} #{msg}\n"
74
- abort
154
+ def time_info(time)
155
+ secondary_cmd "TIME", "#{time}s"
156
+ end
157
+
158
+ def primary_cmd(name, value, options = {})
159
+ name = name.bold if $USE_COLOR
160
+ prompt_format = prompt(options[:user], options[:host])
161
+ puts "#{prompt_format} #{name} #{value}"
75
162
  end
76
163
 
77
- private
164
+ def secondary_cmd(name, value = "")
165
+ name = name.blue.bold if $USE_COLOR
166
+ puts " #{name} #{value}"
167
+ end
78
168
 
79
- def prompt
80
- p ="[#{@user}@#{@host}]"
81
- p = p.bold if @@use_color
169
+ def kv_cmd(options)
170
+ options.each do |k, v|
171
+ puts " #{k}: #{v}"
172
+ end
82
173
  end
83
174
  end
84
175
  end
@@ -0,0 +1,24 @@
1
+ module Mybot
2
+ module Helpers
3
+ def wait
4
+ $stdout.print "Press any key to continue..."
5
+ $stdin.gets
6
+ end
7
+
8
+ def ask(q = "")
9
+ $stdout.print "#{q}"
10
+ $stdin.gets.chomp
11
+ end
12
+
13
+ def yes?(q = "")
14
+ result = ""
15
+ loop do
16
+ $stdout.print "#{q}"
17
+ result = $stdin.gets.chomp
18
+ break if result =~ /y|yes|Y|YES|Yes|n|no|N|NO|No/
19
+ end
20
+
21
+ result =~ /y|yes|Y|YES|Yes/
22
+ end
23
+ end
24
+ end