hmx_client 0.0.7 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,140 +1,140 @@
1
- require "optparse"
2
- require "hmx/helpers"
3
-
4
- module HmxClient
5
- module Command
6
- class InvalidCommand < RuntimeError; end
7
- class CommandFailed < RuntimeError; end
8
-
9
- extend HmxClient::Helpers
10
-
11
- def self.load
12
- Dir[File.join(File.dirname(__FILE__), "command", "*.rb")].each do | file |
13
- require file
14
- end
15
- end
16
-
17
- def self.commands
18
- @@command ||= {}
19
- end
20
-
21
- def self.command_aliases
22
- @@command_aliases ||= {}
23
- end
24
-
25
- def self.namespaces
26
- @@namespaces ||= {}
27
- end
28
-
29
- def self.register_command(command)
30
- commands[command[:command]] = command
31
- end
32
-
33
- def self.register_namespace(namespace)
34
- namespaces[namespace[:name]] = namespace
35
- end
36
-
37
- def self.current_command
38
- @current_command
39
- end
40
-
41
- def self.current_args
42
- @current_args
43
- end
44
-
45
- def self.current_options
46
- @current_options
47
- end
48
-
49
- def self.global_options
50
- @global_options ||= []
51
- end
52
-
53
- def self.global_option(name, *args)
54
- global_options << { :name => name, :args => args }
55
- end
56
-
57
- global_option :debug, "--debug", "-d"
58
- global_option :fileIn, "--file-in FILE", "-i"
59
- global_option :fileOut, "--file-out FILE", "-o"
60
-
61
- def self.prepare_run(cmd, args=[])
62
- command = parse(cmd)
63
-
64
- unless command
65
- error " ! #{cmd} is not a hmx command. See 'hmx help'."
66
- return
67
- end
68
-
69
- @current_command = cmd
70
- opts = {}
71
- invalid_options = []
72
-
73
- parser = OptionParser.new do | parser |
74
- global_options.each do | global_option |
75
- parser.on(*global_option[:args]) do | value |
76
- opts[global_option[:name]] = value
77
- end
78
- end
79
- command[:options].each do | name, option |
80
- parser.on("-#{option[:short]}", "--#{option[:long]}", option[:desc]) do | value |
81
- opts[name.gsub("-","_").to_sym] = value
82
- end
83
- end
84
- end
85
-
86
- begin
87
- parser.order!(args) do |nonopt|
88
- invalid_options << nonopt
89
- end
90
- rescue OptionParser::InvalidOption => ex
91
- invalid_options << ex.args.first
92
- retry
93
- end
94
-
95
- raise OptionParser::ParseError if opts[:help]
96
-
97
- args.concat(invalid_options)
98
-
99
- @current_args = args
100
- @current_options = opts
101
-
102
- [ command[:klass].new(args.dup, opts.dup), command[:method] ]
103
- end
104
-
105
- def self.debug?
106
- @current_options.has_key?(:debug)
107
- end
108
-
109
- def self.fileIn
110
- @current_options[:fileIn]
111
- end
112
-
113
- def self.fileOut
114
- @current_options[:fileOut]
115
- end
116
-
117
- def self.run(cmd, arguments=[])
118
- object, method = prepare_run(cmd, arguments.dup)
119
- object.send(method)
120
- rescue InvalidCommand
121
- error "Unknown command. Run 'hmx help' for usage information."
122
- rescue CommandFailed => e
123
- error e.message
124
- rescue OptionParser::ParseError => ex
125
- commands[cmd] ? run("help", [cmd]) : run("help")
126
- rescue Interrupt => e
127
- error "\n[cancelled]"
128
- end
129
-
130
- def self.parse(cmd)
131
- commands[cmd] || commands[command_aliases[cmd]]
132
- end
133
-
134
- def self.extract_error(body, options={})
135
- default_error = block_given ? yield : "Internal server error"
136
- end
137
- end
138
- end
139
-
140
-
1
+ require "optparse"
2
+ require "hmx/helpers"
3
+
4
+ module HmxClient
5
+ module Command
6
+ class InvalidCommand < RuntimeError; end
7
+ class CommandFailed < RuntimeError; end
8
+
9
+ extend HmxClient::Helpers
10
+
11
+ def self.load
12
+ Dir[File.join(File.dirname(__FILE__), "command", "*.rb")].each do | file |
13
+ require file
14
+ end
15
+ end
16
+
17
+ def self.commands
18
+ @@command ||= {}
19
+ end
20
+
21
+ def self.command_aliases
22
+ @@command_aliases ||= {}
23
+ end
24
+
25
+ def self.namespaces
26
+ @@namespaces ||= {}
27
+ end
28
+
29
+ def self.register_command(command)
30
+ commands[command[:command]] = command
31
+ end
32
+
33
+ def self.register_namespace(namespace)
34
+ namespaces[namespace[:name]] = namespace
35
+ end
36
+
37
+ def self.current_command
38
+ @current_command
39
+ end
40
+
41
+ def self.current_args
42
+ @current_args
43
+ end
44
+
45
+ def self.current_options
46
+ @current_options
47
+ end
48
+
49
+ def self.global_options
50
+ @global_options ||= []
51
+ end
52
+
53
+ def self.global_option(name, *args)
54
+ global_options << { :name => name, :args => args }
55
+ end
56
+
57
+ global_option :debug, "--debug", "-d"
58
+ global_option :fileIn, "--file-in FILE", "-i"
59
+ global_option :fileOut, "--file-out FILE", "-o"
60
+
61
+ def self.prepare_run(cmd, args=[])
62
+ command = parse(cmd)
63
+
64
+ unless command
65
+ error " ! #{cmd} is not a hmx command. See 'hmx help'."
66
+ return
67
+ end
68
+
69
+ @current_command = cmd
70
+ opts = {}
71
+ invalid_options = []
72
+
73
+ parser = OptionParser.new do | parser |
74
+ global_options.each do | global_option |
75
+ parser.on(*global_option[:args]) do | value |
76
+ opts[global_option[:name]] = value
77
+ end
78
+ end
79
+ command[:options].each do | name, option |
80
+ parser.on("-#{option[:short]}", "--#{option[:long]}", option[:desc]) do | value |
81
+ opts[name.gsub("-","_").to_sym] = value
82
+ end
83
+ end
84
+ end
85
+
86
+ begin
87
+ parser.order!(args) do |nonopt|
88
+ invalid_options << nonopt
89
+ end
90
+ rescue OptionParser::InvalidOption => ex
91
+ invalid_options << ex.args.first
92
+ retry
93
+ end
94
+
95
+ raise OptionParser::ParseError if opts[:help]
96
+
97
+ args.concat(invalid_options)
98
+
99
+ @current_args = args
100
+ @current_options = opts
101
+
102
+ [ command[:klass].new(args.dup, opts.dup), command[:method] ]
103
+ end
104
+
105
+ def self.debug?
106
+ @current_options.has_key?(:debug)
107
+ end
108
+
109
+ def self.fileIn
110
+ @current_options[:fileIn]
111
+ end
112
+
113
+ def self.fileOut
114
+ @current_options[:fileOut]
115
+ end
116
+
117
+ def self.run(cmd, arguments=[])
118
+ object, method = prepare_run(cmd, arguments.dup)
119
+ object.send(method)
120
+ rescue InvalidCommand
121
+ error "Unknown command. Run 'hmx help' for usage information."
122
+ rescue CommandFailed => e
123
+ error e.message
124
+ rescue OptionParser::ParseError => ex
125
+ commands[cmd] ? run("help", [cmd]) : run("help")
126
+ rescue Interrupt => e
127
+ error "\n[cancelled]"
128
+ end
129
+
130
+ def self.parse(cmd)
131
+ commands[cmd] || commands[command_aliases[cmd]]
132
+ end
133
+
134
+ def self.extract_error(body, options={})
135
+ default_error = block_given ? yield : "Internal server error"
136
+ end
137
+ end
138
+ end
139
+
140
+
@@ -1,194 +1,195 @@
1
- require "fileutils"
2
- require "hmx/command"
3
- require 'cli-colorize'
4
- require 'hmx/helpers'
5
-
6
- class HmxClient::Command::Base
7
- include HmxClient::Helpers
8
- include CLIColorize
9
-
10
- def self.namespace
11
- self.to_s.split("::").last.downcase
12
- end
13
-
14
- attr_reader :args
15
- attr_reader :options
16
-
17
- FILE = File.expand_path("~/.hmxConfig")
18
-
19
- def initialize(args=[], options={})
20
- @args = args
21
- @options = options
22
- loadConfig!
23
- end
24
-
25
- def loadConfig!
26
- # Load the config from the save file
27
- @config = if File.exist?(FILE)
28
- File.open(FILE) { |file| Marshal.load(file) }
29
- else
30
- {}
31
- end
32
- RestClient.proxy = @config[:proxy] if @config.has_key?(:proxy)
33
- end
34
- def storeConfig(keyName, keyValue)
35
- # Update the config hashMap and persist it
36
- if (keyName == :password)
37
- keyValue = Digest::MD5.hexdigest(keyValue)
38
- end
39
- @config[keyName] = keyValue
40
- writeConfig
41
- end
42
- def removeConfig(keyName)
43
- @config.delete keyName
44
- writeConfig
45
- end
46
- def writeConfig
47
- File.open(FILE, 'w+') { |f| Marshal.dump(@config, f) }
48
- end
49
- def hmx
50
- if @hmx.nil?
51
- @hmx = Hmx.new
52
- @hmx.login(@config)
53
- writeConfig
54
- end
55
- @hmx
56
- end
57
-
58
- protected
59
-
60
- def self.inherited(klass)
61
- help = extract_help_from_caller(caller.first)
62
- HmxClient::Command.register_namespace(
63
- :name => klass.namespace,
64
- :description => help.split("\n").first
65
- )
66
- end
67
-
68
- def self.method_added(method)
69
- return if self == HmxClient::Command::Base
70
- return if private_method_defined?(method)
71
- return if protected_method_defined?(method)
72
-
73
- help = extract_help_from_caller(caller.first)
74
- resolved_method = (method.to_s == "index") ? nil : method.to_s
75
- default_command = [ self.namespace, resolved_method ].compact.join(":")
76
- command = extract_command(help) || default_command
77
- banner = extract_banner(help) || command
78
- permute = !banner.index("*")
79
- banner.gsub!("*", "")
80
-
81
- HmxClient::Command.register_command(
82
- :klass => self,
83
- :method => method,
84
- :namespace => self.namespace,
85
- :command => command,
86
- :banner => banner,
87
- :help => help,
88
- :summary => extract_summary(help),
89
- :description => extract_description(help),
90
- :options => extract_options(help),
91
- :permute => permute
92
- )
93
- end
94
-
95
- def self.alias_command(new, old)
96
- raise "no such command: #{old}" unless HmxClient::Command.commands[old]
97
- HmxClient::Command.command_aliases[new] = old
98
- end
99
-
100
- #
101
- # Parse the caller format and identify the file and line number as identified
102
- # in : http://www.ruby-doc.org/core/classes/Kernel.html#M001397. This will
103
- # look for a colon followed by a digit as the delimiter. The biggest
104
- # complication is windows paths, which have a color after the drive letter.
105
- # This regex will match paths as anything from the beginning to a colon
106
- # directly followed by a number (the line number).
107
- #
108
- # Examples of the caller format :
109
- # * c:/Ruby192/lib/.../lib/heroku/command/addons.rb:8:in `<module:Command>'
110
- # * c:/Ruby192/lib/.../heroku-2.0.1/lib/heroku/command/pg.rb:96:in `<class:Pg>'
111
- # * /Users/ph7/...../xray-1.1/lib/xray/thread_dump_signal_handler.rb:9
112
- #
113
- def self.extract_help_from_caller(line)
114
- # pull out of the caller the information for the file path and line number
115
- if line =~ /^(.+?):(\d+)/
116
- return extract_help($1, $2)
117
- end
118
- raise "unable to extract help from caller: #{line}"
119
- end
120
-
121
- def self.extract_help(file, line)
122
- buffer = []
123
- lines = File.read(file).split("\n")
124
-
125
- catch(:done) do
126
- (line.to_i-2).downto(0) do |i|
127
- case lines[i].strip[0..0]
128
- when "", "#" then buffer << lines[i]
129
- else throw(:done)
130
- end
131
- end
132
- end
133
-
134
- buffer.map! do |line|
135
- line.strip.gsub(/^#/, "")
136
- end
137
-
138
- buffer.reverse.join("\n").strip
139
- end
140
-
141
- def self.extract_command(help)
142
- extract_banner(help).to_s.split(" ").first
143
- end
144
-
145
- def self.extract_banner(help)
146
- help.split("\n").first
147
- end
148
-
149
- def self.extract_summary(help)
150
- extract_description(help).split("\n").first
151
- end
152
-
153
- def self.extract_description(help)
154
- lines = help.split("\n").map { |l| l.strip }
155
- lines.shift
156
- lines.reject do |line|
157
- line =~ /^-(.+)#(.+)/
158
- end.join("\n").strip
159
- end
160
-
161
- def self.extract_options(help)
162
- help.split("\n").map { |l| l.strip }.select do |line|
163
- line =~ /^-(.+)#(.+)/
164
- end.inject({}) do |hash, line|
165
- description = line.split("#", 2).last.strip
166
- long = line.match(/--([A-Za-z\- ]+)/)[1].strip
167
- short = line.match(/-([A-Za-z ])/)[1].strip
168
- hash.update(long.split(" ").first => { :desc => description, :short => short, :long => long })
169
- end
170
- end
171
-
172
- def extract_option(name, default=true)
173
- key = name.gsub("--", "").to_sym
174
- return unless options[key]
175
- value = options[key] || default
176
- block_given? ? yield(value) : value
177
- end
178
-
179
- def confirm_mismatch?
180
- options[:confirm] && (options[:confirm] != options[:app])
181
- end
182
-
183
- def dout(msg)
184
- if (!HmxClient::Command.fileOut.nil?)
185
- realFile = File.expand_path(HmxClient::Command.fileOut)
186
- File.open(realFile, 'w') { | f |
187
- display("Writing to #{ realFile }")
188
- f.write(msg) }
189
- end
190
- puts colorize(msg, :yellow)
191
- #display(green(msg))
192
- end
193
- end
194
-
1
+ require "fileutils"
2
+ require "hmx/command"
3
+ require 'cli-colorize'
4
+ require 'hmx/helpers'
5
+
6
+ class HmxClient::Command::Base
7
+ include HmxClient::Helpers
8
+ include CLIColorize
9
+
10
+ def self.namespace
11
+ self.to_s.split("::").last.downcase
12
+ end
13
+
14
+ attr_reader :args
15
+ attr_reader :options
16
+
17
+ FILE = File.expand_path("~/.hmxConfig")
18
+
19
+ def initialize(args=[], options={})
20
+ @args = args
21
+ @options = options
22
+ loadConfig!
23
+ end
24
+
25
+ def loadConfig!
26
+ # Load the config from the save file
27
+ @config = if File.exist?(FILE)
28
+ File.open(FILE) { |file| Marshal.load(file) }
29
+ else
30
+ {}
31
+ end
32
+ RestClient.proxy = @config[:proxy] if @config.has_key?(:proxy)
33
+ end
34
+ def storeConfig(keyName, keyValue)
35
+ # Update the config hashMap and persist it
36
+ if (keyName == :password)
37
+ keyValue = Digest::MD5.hexdigest(keyValue)
38
+ end
39
+ @config[keyName] = keyValue
40
+ # Remove any saved session config
41
+ removeConfig("context".to_sym); # Also saves config
42
+ end
43
+ def removeConfig(keyName)
44
+ @config.delete keyName
45
+ writeConfig
46
+ end
47
+ def writeConfig
48
+ File.open(FILE, 'w+') { |f| Marshal.dump(@config, f) }
49
+ end
50
+ def hmx
51
+ if @hmx.nil?
52
+ @hmx = Hmx.new
53
+ @hmx.login(@config)
54
+ writeConfig
55
+ end
56
+ @hmx
57
+ end
58
+
59
+ protected
60
+
61
+ def self.inherited(klass)
62
+ help = extract_help_from_caller(caller.first)
63
+ HmxClient::Command.register_namespace(
64
+ :name => klass.namespace,
65
+ :description => help.split("\n").first
66
+ )
67
+ end
68
+
69
+ def self.method_added(method)
70
+ return if self == HmxClient::Command::Base
71
+ return if private_method_defined?(method)
72
+ return if protected_method_defined?(method)
73
+
74
+ help = extract_help_from_caller(caller.first)
75
+ resolved_method = (method.to_s == "index") ? nil : method.to_s
76
+ default_command = [ self.namespace, resolved_method ].compact.join(":")
77
+ command = extract_command(help) || default_command
78
+ banner = extract_banner(help) || command
79
+ permute = !banner.index("*")
80
+ banner.gsub!("*", "")
81
+
82
+ HmxClient::Command.register_command(
83
+ :klass => self,
84
+ :method => method,
85
+ :namespace => self.namespace,
86
+ :command => command,
87
+ :banner => banner,
88
+ :help => help,
89
+ :summary => extract_summary(help),
90
+ :description => extract_description(help),
91
+ :options => extract_options(help),
92
+ :permute => permute
93
+ )
94
+ end
95
+
96
+ def self.alias_command(new, old)
97
+ raise "no such command: #{old}" unless HmxClient::Command.commands[old]
98
+ HmxClient::Command.command_aliases[new] = old
99
+ end
100
+
101
+ #
102
+ # Parse the caller format and identify the file and line number as identified
103
+ # in : http://www.ruby-doc.org/core/classes/Kernel.html#M001397. This will
104
+ # look for a colon followed by a digit as the delimiter. The biggest
105
+ # complication is windows paths, which have a color after the drive letter.
106
+ # This regex will match paths as anything from the beginning to a colon
107
+ # directly followed by a number (the line number).
108
+ #
109
+ # Examples of the caller format :
110
+ # * c:/Ruby192/lib/.../lib/heroku/command/addons.rb:8:in `<module:Command>'
111
+ # * c:/Ruby192/lib/.../heroku-2.0.1/lib/heroku/command/pg.rb:96:in `<class:Pg>'
112
+ # * /Users/ph7/...../xray-1.1/lib/xray/thread_dump_signal_handler.rb:9
113
+ #
114
+ def self.extract_help_from_caller(line)
115
+ # pull out of the caller the information for the file path and line number
116
+ if line =~ /^(.+?):(\d+)/
117
+ return extract_help($1, $2)
118
+ end
119
+ raise "unable to extract help from caller: #{line}"
120
+ end
121
+
122
+ def self.extract_help(file, line)
123
+ buffer = []
124
+ lines = File.read(file).split("\n")
125
+
126
+ catch(:done) do
127
+ (line.to_i-2).downto(0) do |i|
128
+ case lines[i].strip[0..0]
129
+ when "", "#" then buffer << lines[i]
130
+ else throw(:done)
131
+ end
132
+ end
133
+ end
134
+
135
+ buffer.map! do |line|
136
+ line.strip.gsub(/^#/, "")
137
+ end
138
+
139
+ buffer.reverse.join("\n").strip
140
+ end
141
+
142
+ def self.extract_command(help)
143
+ extract_banner(help).to_s.split(" ").first
144
+ end
145
+
146
+ def self.extract_banner(help)
147
+ help.split("\n").first
148
+ end
149
+
150
+ def self.extract_summary(help)
151
+ extract_description(help).split("\n").first
152
+ end
153
+
154
+ def self.extract_description(help)
155
+ lines = help.split("\n").map { |l| l.strip }
156
+ lines.shift
157
+ lines.reject do |line|
158
+ line =~ /^-(.+)#(.+)/
159
+ end.join("\n").strip
160
+ end
161
+
162
+ def self.extract_options(help)
163
+ help.split("\n").map { |l| l.strip }.select do |line|
164
+ line =~ /^-(.+)#(.+)/
165
+ end.inject({}) do |hash, line|
166
+ description = line.split("#", 2).last.strip
167
+ long = line.match(/--([A-Za-z\- ]+)/)[1].strip
168
+ short = line.match(/-([A-Za-z ])/)[1].strip
169
+ hash.update(long.split(" ").first => { :desc => description, :short => short, :long => long })
170
+ end
171
+ end
172
+
173
+ def extract_option(name, default=true)
174
+ key = name.gsub("--", "").to_sym
175
+ return unless options[key]
176
+ value = options[key] || default
177
+ block_given? ? yield(value) : value
178
+ end
179
+
180
+ def confirm_mismatch?
181
+ options[:confirm] && (options[:confirm] != options[:app])
182
+ end
183
+
184
+ def dout(msg)
185
+ if (!HmxClient::Command.fileOut.nil?)
186
+ realFile = File.expand_path(HmxClient::Command.fileOut)
187
+ File.open(realFile, 'w') { | f |
188
+ display("Writing to #{ realFile }")
189
+ f.write(msg) }
190
+ end
191
+ puts colorize(msg, :yellow)
192
+ #display(green(msg))
193
+ end
194
+ end
195
+