hmx_client 0.0.7 → 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.
@@ -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
+