hmx_client 0.0.5 → 0.0.6
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/bin/hmx +15 -23
- data/lib/hmx/client.rb +106 -17
- data/lib/hmx/command/base.rb +194 -0
- data/lib/hmx/command/bootstrap.rb +18 -0
- data/lib/hmx/command/clone.rb +77 -0
- data/lib/hmx/command/config.rb +67 -0
- data/lib/hmx/command/dump.rb +67 -0
- data/lib/hmx/command/fn.rb +43 -0
- data/lib/hmx/command/fountain.rb +46 -0
- data/lib/hmx/command/get.rb +20 -0
- data/lib/hmx/command/getContent.rb +20 -0
- data/lib/hmx/command/help.rb +114 -0
- data/lib/hmx/command/query.rb +22 -0
- data/lib/hmx/command/session.rb +35 -0
- data/lib/hmx/command/task.rb +32 -0
- data/lib/hmx/command/type.rb +45 -0
- data/lib/hmx/command/user.rb +68 -0
- data/lib/hmx/command/view.rb +155 -0
- data/lib/hmx/command.rb +140 -0
- data/lib/hmx/helpers.rb +61 -0
- data/lib/hmx/hmx.rb +125 -16
- data/lib/hmx/version.rb +1 -1
- data/lib/hmx_client.rb +1 -1
- metadata +24 -6
@@ -0,0 +1,46 @@
|
|
1
|
+
require "hmx/command/base"
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module HmxClient::Command
|
5
|
+
|
6
|
+
# Manipulate hmx fountains (auto id generators)
|
7
|
+
#
|
8
|
+
class Fountain < Base
|
9
|
+
|
10
|
+
# fountain
|
11
|
+
#
|
12
|
+
# Lists all of the fountains and their values
|
13
|
+
def index
|
14
|
+
fountainState = hmx.getFountainState([])
|
15
|
+
# fountainState is a map of fountainName => value
|
16
|
+
# Flip this into an array of "name" => name, "value" => value
|
17
|
+
objs = []
|
18
|
+
fountainState.each_pair do | key, value |
|
19
|
+
objs << { "name" => key, "value" => value }
|
20
|
+
end
|
21
|
+
cols = [ 'name', 'value' ]
|
22
|
+
headers = [ 'Fountain', 'Value' ]
|
23
|
+
display_table(objs, cols, headers)
|
24
|
+
end
|
25
|
+
|
26
|
+
# fountain:set
|
27
|
+
#
|
28
|
+
# Sets the new id for the fountain
|
29
|
+
#
|
30
|
+
def set
|
31
|
+
unless args.size > 1
|
32
|
+
raise CommandFailed, "Usage: hmx fountain:set <fountainId> <newValue>"
|
33
|
+
end
|
34
|
+
hmx.setFountainId(args)
|
35
|
+
end
|
36
|
+
# fountain:get
|
37
|
+
#
|
38
|
+
# Increments and returns a fountain value
|
39
|
+
def get
|
40
|
+
unless args.size > 0
|
41
|
+
raise CommandFailed, "Usage: hmx fountain:get <fountainId>"
|
42
|
+
end
|
43
|
+
display hmx.getFountain(args)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "hmx/command/base"
|
2
|
+
|
3
|
+
module HmxClient::Command
|
4
|
+
|
5
|
+
# Get full document from hmx
|
6
|
+
#
|
7
|
+
class Get < Base
|
8
|
+
|
9
|
+
# get
|
10
|
+
#
|
11
|
+
# get a document from hmx, given its display name
|
12
|
+
#
|
13
|
+
def index
|
14
|
+
unless args.size > 0
|
15
|
+
raise CommandFailed, "Usage: hmx get displayname"
|
16
|
+
end
|
17
|
+
dout JSON.pretty_generate(hmx.getData(args))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "hmx/command/base"
|
2
|
+
|
3
|
+
module HmxClient::Command
|
4
|
+
|
5
|
+
# Get document content from hmx
|
6
|
+
#
|
7
|
+
class GetContent < Base
|
8
|
+
|
9
|
+
# getContent
|
10
|
+
#
|
11
|
+
# get the data part of a document from hmx, given its display name
|
12
|
+
#
|
13
|
+
def index
|
14
|
+
unless args.size > 0
|
15
|
+
raise CommandFailed, "Usage: hmx getContent displayname"
|
16
|
+
end
|
17
|
+
dout hmx.getContent(args)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require "hmx/command/base"
|
2
|
+
|
3
|
+
# list commands and display help
|
4
|
+
#
|
5
|
+
class HmxClient::Command::Help < HmxClient::Command::Base
|
6
|
+
|
7
|
+
PRIMARY_NAMESPACES = %w( config query get view)
|
8
|
+
|
9
|
+
# help [COMMAND]
|
10
|
+
#
|
11
|
+
# list available commands or display help for a specific command
|
12
|
+
#
|
13
|
+
def index
|
14
|
+
if command = args.shift
|
15
|
+
help_for_command(command)
|
16
|
+
else
|
17
|
+
help_for_root
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
alias_command "-h", "help"
|
22
|
+
alias_command "--help", "help"
|
23
|
+
|
24
|
+
def self.usage_for_command(command)
|
25
|
+
command = new.send(:commands)[command]
|
26
|
+
"Usage: hmx #{command[:banner]}" if command
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def commands_for_namespace(name)
|
32
|
+
HmxClient::Command.commands.values.select do |command|
|
33
|
+
command[:namespace] == name && command[:command] != name
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def namespaces
|
38
|
+
namespaces = HmxClient::Command.namespaces
|
39
|
+
namespaces
|
40
|
+
end
|
41
|
+
|
42
|
+
def commands
|
43
|
+
commands = HmxClient::Command.commands
|
44
|
+
HmxClient::Command.command_aliases.each do |new, old|
|
45
|
+
commands[new] = commands[old].dup
|
46
|
+
commands[new][:banner] = "#{new} #{commands[new][:banner].split(" ", 2)[1]}"
|
47
|
+
commands[new][:command] = new
|
48
|
+
commands[new][:namespace] = nil
|
49
|
+
end
|
50
|
+
commands
|
51
|
+
end
|
52
|
+
|
53
|
+
def primary_namespaces
|
54
|
+
PRIMARY_NAMESPACES.map { |name| namespaces[name] }.compact
|
55
|
+
end
|
56
|
+
|
57
|
+
def additional_namespaces
|
58
|
+
(namespaces.values - primary_namespaces).sort_by { |n| n[:name] }
|
59
|
+
end
|
60
|
+
|
61
|
+
def summary_for_namespaces(namespaces)
|
62
|
+
size = longest(namespaces.map { |n| n[:name] })
|
63
|
+
namespaces.each do |namespace|
|
64
|
+
name = namespace[:name]
|
65
|
+
namespace[:description] ||= legacy_help_for_namespace(name)
|
66
|
+
puts " %-#{size}s # %s" % [ name, namespace[:description] ]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def help_for_root
|
71
|
+
puts "Usage: hmx COMMAND [command-specific-options]"
|
72
|
+
puts
|
73
|
+
puts "Primary help topics, type \"hmx help TOPIC\" for more details:"
|
74
|
+
puts
|
75
|
+
summary_for_namespaces(primary_namespaces)
|
76
|
+
puts
|
77
|
+
puts "Additional topics:"
|
78
|
+
puts
|
79
|
+
summary_for_namespaces(additional_namespaces)
|
80
|
+
puts
|
81
|
+
end
|
82
|
+
|
83
|
+
def help_for_namespace(name)
|
84
|
+
namespace_commands = commands_for_namespace(name)
|
85
|
+
|
86
|
+
unless namespace_commands.empty?
|
87
|
+
size = longest(namespace_commands.map { |c| c[:banner] })
|
88
|
+
namespace_commands.sort_by { |c| c[:banner].to_s }.each do |command|
|
89
|
+
next if command[:help] =~ /DEPRECATED/
|
90
|
+
command[:summary] ||= legacy_help_for_command(command[:command])
|
91
|
+
puts " %-#{size}s # %s" % [ command[:banner], command[:summary] ]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def help_for_command(name)
|
97
|
+
command = commands[name]
|
98
|
+
|
99
|
+
if command
|
100
|
+
if command[:help].strip.length > 0
|
101
|
+
puts "Usage: hmx #{command[:banner]}"
|
102
|
+
puts command[:help].split("\n")[1..-1].join("\n")
|
103
|
+
puts
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
unless commands_for_namespace(name).empty?
|
108
|
+
puts "Additional commands, type \"hmx help COMMAND\" for more details:"
|
109
|
+
puts
|
110
|
+
help_for_namespace(name)
|
111
|
+
puts
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "hmx/command/base"
|
2
|
+
|
3
|
+
module HmxClient::Command
|
4
|
+
|
5
|
+
# Perform queries against data in hmx
|
6
|
+
#
|
7
|
+
class Query < Base
|
8
|
+
|
9
|
+
# query
|
10
|
+
#
|
11
|
+
# query for documents in a type
|
12
|
+
#
|
13
|
+
# TYPENAME
|
14
|
+
#
|
15
|
+
def index
|
16
|
+
unless args.size > 0
|
17
|
+
raise CommandFailed, "Usage: hmx query <typeName> [<key>=<value>, [<key2>=<value2>...]]"
|
18
|
+
end
|
19
|
+
display hmx.query(args.shift, nil)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "hmx/command/base"
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module HmxClient::Command
|
5
|
+
|
6
|
+
# Display and manage session information for hmx
|
7
|
+
#
|
8
|
+
class Session < Base
|
9
|
+
|
10
|
+
# session
|
11
|
+
#
|
12
|
+
# List the sessions and their status on hmx
|
13
|
+
def index
|
14
|
+
displayNames = hmx.query('sys.session', nil)
|
15
|
+
objs = []
|
16
|
+
displayNames.each do | name |
|
17
|
+
data = hmx.getContent([name])
|
18
|
+
dval = JSON.parse(data)
|
19
|
+
dval["MXSession"]["validUntil"] = Time.at(dval["MXSession"]["validUntil"] / 1000).to_datetime.strftime
|
20
|
+
objs << dval["MXSession"]
|
21
|
+
end
|
22
|
+
cols = [ 'sessionId', 'userId', 'authenticated','validUntil' ]
|
23
|
+
headers = [ 'Session', 'Username', 'Authenticated', 'ValidUntil' ]
|
24
|
+
display_table(objs, cols, headers)
|
25
|
+
end
|
26
|
+
|
27
|
+
# session:expire
|
28
|
+
#
|
29
|
+
# Forces the expiry of any old sessions
|
30
|
+
#
|
31
|
+
def expire
|
32
|
+
display hmx.expireSessions([])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "hmx/command/base"
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module HmxClient::Command
|
5
|
+
|
6
|
+
# Display and manage tasks in hmx
|
7
|
+
#
|
8
|
+
class Task < Base
|
9
|
+
|
10
|
+
# task
|
11
|
+
#
|
12
|
+
# List all of the tasks
|
13
|
+
def index
|
14
|
+
tasks = hmx.getAllTasks([])
|
15
|
+
objs = []
|
16
|
+
tasks.each do | t |
|
17
|
+
task = hmx.getTask([t])
|
18
|
+
objs << task
|
19
|
+
end
|
20
|
+
headers = [ "TaskId", "TaskType", "TaskState", "GroupId" ]
|
21
|
+
cols = [ "taskId", "taskType", "taskState", "group" ]
|
22
|
+
display_table(objs, cols, headers)
|
23
|
+
end
|
24
|
+
# task:purge
|
25
|
+
#
|
26
|
+
# Purge completed tasks
|
27
|
+
def purge
|
28
|
+
hmx.purgeTasks([])
|
29
|
+
display "Purge complete"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "hmx/command/base"
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module HmxClient::Command
|
5
|
+
|
6
|
+
# Display and manage type information in hmx
|
7
|
+
#
|
8
|
+
class Type < Base
|
9
|
+
|
10
|
+
# type
|
11
|
+
#
|
12
|
+
# Display information about a HMX type
|
13
|
+
def index
|
14
|
+
puts JSON.pretty_generate(hmx.getType(args.shift))
|
15
|
+
end
|
16
|
+
|
17
|
+
# type:create
|
18
|
+
#
|
19
|
+
# Create a type with default settings - no triggers, no entitlements
|
20
|
+
def create
|
21
|
+
typeInfo = { "name" => args.shift, "triggers" => [], "typeNature" => "CONTENT", "typeIndexScript" => "", "typeAspect" => "JSONDOCUMENT" }
|
22
|
+
hmx.updateType(typeInfo)
|
23
|
+
puts "Done..."
|
24
|
+
end
|
25
|
+
|
26
|
+
# type:clone-ent
|
27
|
+
#
|
28
|
+
# Clone the entitlements from one type to another
|
29
|
+
#
|
30
|
+
# <srcType> <targType>
|
31
|
+
def clone
|
32
|
+
# We basically load the documents for sys.ent/type/[source]/query and sys.ent/type/[source]/query and copy them to the target
|
33
|
+
sourceType = args.shift
|
34
|
+
targetType = args.shift
|
35
|
+
arr = JSON.parse(hmx.getContent(["sys.ent/type/#{ sourceType }/get"]))
|
36
|
+
arr["MXEntitlement"]["entitlementPath"] = "type/#{ targetType }/get"
|
37
|
+
hmx.putSimpleData([ "sys.ent/type/#{ targetType}/get", JSON.generate(arr)])
|
38
|
+
|
39
|
+
arr = JSON.parse(hmx.getContent(["sys.ent/type/#{ sourceType }/query"]))
|
40
|
+
arr["MXEntitlement"]["entitlementPath"] = "type/#{ targetType }/query"
|
41
|
+
hmx.putSimpleData([ "sys.ent/type/#{ targetType}/query", JSON.generate(arr)])
|
42
|
+
puts "Done..."
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "hmx/command/base"
|
2
|
+
|
3
|
+
module HmxClient::Command
|
4
|
+
|
5
|
+
# Manipulate user entities in hmx
|
6
|
+
#
|
7
|
+
class User < Base
|
8
|
+
|
9
|
+
# user
|
10
|
+
#
|
11
|
+
# manipulate user enties in hMX
|
12
|
+
#
|
13
|
+
#
|
14
|
+
def index
|
15
|
+
unless args.size > 0
|
16
|
+
raise CommandFailed, "Usage: hmx user <userId>"
|
17
|
+
end
|
18
|
+
userName = args.shift
|
19
|
+
dout JSON.pretty_generate(hmx.getData(["sys.user/#{userName}"]))
|
20
|
+
end
|
21
|
+
|
22
|
+
# user:list
|
23
|
+
#
|
24
|
+
# Lists all of the users in the system
|
25
|
+
|
26
|
+
def list
|
27
|
+
views = hmx.query("sys.user", nil)
|
28
|
+
views.each { | v |
|
29
|
+
display v.rpartition('/')[2]
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
# user:get
|
34
|
+
#
|
35
|
+
# Retrieves the definition of a user
|
36
|
+
#
|
37
|
+
def get
|
38
|
+
index
|
39
|
+
end
|
40
|
+
|
41
|
+
# user:password
|
42
|
+
#
|
43
|
+
# Sets the password for a user
|
44
|
+
#
|
45
|
+
def password
|
46
|
+
unless args.size > 1
|
47
|
+
raise CommandFailed, "Usage: hmx user:password <userId> <newPassword>"
|
48
|
+
end
|
49
|
+
user = args.shift
|
50
|
+
userName = "sys.user/#{user}"
|
51
|
+
password = Digest::MD5.hexdigest(args.shift)
|
52
|
+
dataDocument = hmx.getData([userName])
|
53
|
+
dataDocument['document']['MXUser']['hashPassword'] = password
|
54
|
+
display hmx.putData([JSON.generate(dataDocument)])
|
55
|
+
end
|
56
|
+
|
57
|
+
# user:delete
|
58
|
+
#
|
59
|
+
# Removes a user
|
60
|
+
#
|
61
|
+
def delete
|
62
|
+
# We also need to remove the user reference from any groups they belong to (sys.entgroup)
|
63
|
+
# We should be clever and use a custom view for that purpose
|
64
|
+
# something like
|
65
|
+
# (fn[param] (fn[x] (contains (param "user" (.get x '(:document :MXEntitlementGroup :users ))))))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require "hmx/command/base"
|
2
|
+
|
3
|
+
module HmxClient::Command
|
4
|
+
|
5
|
+
# Display the results of a view and list all views
|
6
|
+
#
|
7
|
+
class View < Base
|
8
|
+
|
9
|
+
# view
|
10
|
+
#
|
11
|
+
# run a view in hmx, passing in a view name and an input to the filter function
|
12
|
+
#
|
13
|
+
#
|
14
|
+
def index
|
15
|
+
unless args.size > 0
|
16
|
+
raise CommandFailed, "Usage: hmx view <viewName> <filterContext>"
|
17
|
+
end
|
18
|
+
viewData = hmx.runView(args.shift, JSON.parse(args.shift))
|
19
|
+
resp = ''
|
20
|
+
viewData.each { | line |
|
21
|
+
line.each { | cell | resp = resp + "%20.20s\t" % cell }
|
22
|
+
resp = resp + "\n"
|
23
|
+
}
|
24
|
+
dout resp
|
25
|
+
end
|
26
|
+
|
27
|
+
# view:list
|
28
|
+
#
|
29
|
+
# Lists all of the views in the system
|
30
|
+
|
31
|
+
def list
|
32
|
+
views = hmx.query("sys.view", nil)
|
33
|
+
views.each { | v |
|
34
|
+
display v.rpartition('/')[2]
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
# view:get
|
39
|
+
#
|
40
|
+
# Retrieves the definition of a view
|
41
|
+
#
|
42
|
+
def get
|
43
|
+
unless args.size > 0
|
44
|
+
raise CommandFailed, "Usage: hmx view:get <viewName>"
|
45
|
+
end
|
46
|
+
typeName = "sys.view/#{args.shift}"
|
47
|
+
display "Retrieving #{ typeName }"
|
48
|
+
dout JSON.pretty_generate(hmx.getData([typeName]))
|
49
|
+
end
|
50
|
+
|
51
|
+
# view:create
|
52
|
+
#
|
53
|
+
# Create a new (initially blank) view.
|
54
|
+
# You will then need to call update to set the filter function, map function, query params and
|
55
|
+
# result columns.
|
56
|
+
#
|
57
|
+
# Views are based on types, for create define a name and the type
|
58
|
+
def create
|
59
|
+
unless args.size > 1
|
60
|
+
raise CommanFailed, "Usage: hmx view:create <viewName> <typeName>"
|
61
|
+
end
|
62
|
+
view = args.shift
|
63
|
+
viewName = "sys.view/#{view}"
|
64
|
+
typeName = args.shift
|
65
|
+
|
66
|
+
dataDocument = {
|
67
|
+
"MXView" => {
|
68
|
+
:typeName => typeName,
|
69
|
+
:parameterNames => [],
|
70
|
+
:filterFn => "",
|
71
|
+
:mappingFn => "",
|
72
|
+
:resultColumns => [],
|
73
|
+
:viewName => view
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
dout JSON.pretty_generate(hmx.putSimpleData([viewName, JSON.generate(dataDocument)]))
|
78
|
+
end
|
79
|
+
|
80
|
+
# view:updateFilter
|
81
|
+
#
|
82
|
+
# Set the filter function for a view
|
83
|
+
#
|
84
|
+
def updateFilter
|
85
|
+
unless args.size > 1
|
86
|
+
raise CommandFailed, "Usage: hmx view:updateFilter <viewName> <filterFn>"
|
87
|
+
end
|
88
|
+
view = args.shift
|
89
|
+
viewName = "sys.view/#{view}"
|
90
|
+
filterFn = args.shift
|
91
|
+
|
92
|
+
dataDocument = hmx.getData([viewName])
|
93
|
+
puts dataDocument
|
94
|
+
dataDocument['document']['MXView']['filterFn'] = filterFn
|
95
|
+
display hmx.putData([JSON.generate(dataDocument)])
|
96
|
+
end
|
97
|
+
# view:updateMap
|
98
|
+
#
|
99
|
+
# Set the map function for a view
|
100
|
+
#
|
101
|
+
def updateMap
|
102
|
+
unless args.size > 1
|
103
|
+
raise CommandFailed, "Usage: hmx view:updateMap <viewName> <filterFn>"
|
104
|
+
end
|
105
|
+
view = args.shift
|
106
|
+
viewName = "sys.view/#{view}"
|
107
|
+
mapFn = args.shift
|
108
|
+
dataDocument = hmx.getData([viewName])
|
109
|
+
dataDocument['document']['MXView']['mappingFn'] = mapFn
|
110
|
+
display hmx.putData([JSON.generate(dataDocument)])
|
111
|
+
end
|
112
|
+
# view:updateParam
|
113
|
+
#
|
114
|
+
# Set the parameter names for a view
|
115
|
+
#
|
116
|
+
def updateParam
|
117
|
+
unless args.size > 1
|
118
|
+
raise CommandFailed, "Usage: hmx view:updateParam <viewName> <param> [<param2> ...]"
|
119
|
+
end
|
120
|
+
view = args.shift
|
121
|
+
viewName = "sys.view/#{view}"
|
122
|
+
dataDocument = hmx.getData([viewName])
|
123
|
+
dataDocument['document']['MXView']['parameterNames'] = args
|
124
|
+
display hmx.putData([JSON.generate(dataDocument)])
|
125
|
+
end
|
126
|
+
# view:updateResult
|
127
|
+
#
|
128
|
+
# Set the result names for a view
|
129
|
+
#
|
130
|
+
def updateResult
|
131
|
+
unless args.size > 1
|
132
|
+
raise CommandFailed, "Usage: hmx view:updateResult <viewName> <param> [<param2> ...]"
|
133
|
+
end
|
134
|
+
view = args.shift
|
135
|
+
viewName = "sys.view/#{view}"
|
136
|
+
|
137
|
+
dataDocument = hmx.getData([viewName])
|
138
|
+
dataDocument['document']['MXView']['resultColumns'] = args
|
139
|
+
display hmx.putData([JSON.generate(dataDocument)])
|
140
|
+
end
|
141
|
+
# view:delete
|
142
|
+
#
|
143
|
+
# Delete a view definition
|
144
|
+
#
|
145
|
+
def delete
|
146
|
+
unless args.size >0
|
147
|
+
raise CommandFailed, "Usage: hmx view:delete <viewName>"
|
148
|
+
end
|
149
|
+
view = args.shift
|
150
|
+
viewName = "sys.view/#{view}"
|
151
|
+
display hmx.deleteData(viewName)
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
end
|
data/lib/hmx/command.rb
ADDED
@@ -0,0 +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
|
+
|