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.
- data/.gitignore +4 -4
- data/Gemfile +4 -4
- data/Rakefile +1 -1
- data/bin/hmx +33 -33
- data/hmx_client.gemspec +27 -27
- data/lib/hmx/client.rb +167 -167
- data/lib/hmx/command.rb +140 -140
- data/lib/hmx/command/base.rb +195 -194
- data/lib/hmx/command/bootstrap.rb +18 -18
- data/lib/hmx/command/check.rb +170 -0
- data/lib/hmx/command/clone.rb +77 -77
- data/lib/hmx/command/config.rb +67 -67
- data/lib/hmx/command/dump.rb +67 -67
- data/lib/hmx/command/fn.rb +125 -43
- data/lib/hmx/command/fountain.rb +46 -46
- data/lib/hmx/command/get.rb +20 -20
- data/lib/hmx/command/getContent.rb +20 -20
- data/lib/hmx/command/help.rb +114 -114
- data/lib/hmx/command/partition.rb +38 -38
- data/lib/hmx/command/query.rb +22 -22
- data/lib/hmx/command/session.rb +35 -35
- data/lib/hmx/command/task.rb +32 -32
- data/lib/hmx/command/type.rb +45 -45
- data/lib/hmx/command/user.rb +68 -68
- data/lib/hmx/command/view.rb +161 -155
- data/lib/hmx/helpers.rb +76 -61
- data/lib/hmx/hmx.rb +148 -215
- data/lib/hmx/version.rb +3 -3
- data/lib/hmx_client.rb +7 -7
- data/sampleCommands.txt +5 -5
- metadata +12 -11
@@ -1,18 +1,18 @@
|
|
1
|
-
require "hmx/command/base"
|
2
|
-
require 'date'
|
3
|
-
|
4
|
-
module HmxClient::Command
|
5
|
-
|
6
|
-
# Bootstrap a default configuration
|
7
|
-
#
|
8
|
-
class Bootstrap < Base
|
9
|
-
|
10
|
-
# bootstrap
|
11
|
-
#
|
12
|
-
# Bootstrap a default configuration into this partition
|
13
|
-
def index
|
14
|
-
hmx.
|
15
|
-
puts "Done."
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
1
|
+
require "hmx/command/base"
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module HmxClient::Command
|
5
|
+
|
6
|
+
# Bootstrap a default configuration
|
7
|
+
#
|
8
|
+
class Bootstrap < Base
|
9
|
+
|
10
|
+
# bootstrap
|
11
|
+
#
|
12
|
+
# Bootstrap a default configuration into this partition
|
13
|
+
def index
|
14
|
+
hmx.doBootstrap([])
|
15
|
+
puts "Done."
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
require "hmx/command/base"
|
2
|
+
|
3
|
+
module HmxClient::Command
|
4
|
+
|
5
|
+
# Provides the ability to check view functions locally
|
6
|
+
#
|
7
|
+
class Check < Base
|
8
|
+
|
9
|
+
# check
|
10
|
+
#
|
11
|
+
# Download an environment to check
|
12
|
+
# <folderName> <type>
|
13
|
+
#
|
14
|
+
# Creates <folderName>/functions/[function files that are Ruby]
|
15
|
+
# And <folderName>/<typeName>/[files corresponding to the documents in that type]
|
16
|
+
#
|
17
|
+
def index
|
18
|
+
unless args.size > 1
|
19
|
+
raise CommandFailed, "Usage: hmx check <folderName> <typeName>"
|
20
|
+
end
|
21
|
+
rootFolder = args.shift;
|
22
|
+
typeName = args.shift;
|
23
|
+
Dir.mkdir(rootFolder) if !Dir.exist?(rootFolder)
|
24
|
+
fnFolder = rootFolder + '/function/'
|
25
|
+
Dir.mkdir(fnFolder) if !Dir.exist?(fnFolder)
|
26
|
+
displayNames = hmx.doQuery(['sys.fn',nil])
|
27
|
+
displayNames.each { | displayName |
|
28
|
+
fnInfo = hmx.doGetData([displayName])
|
29
|
+
if fnInfo['document']['MXFunction']['fnLang'] == 'RUBY'
|
30
|
+
puts "Writing function - #{ displayName }"
|
31
|
+
outfile = fnFolder + fnInfo['document']['MXFunction']['fnName'] + '.rb'
|
32
|
+
File.open(outfile, 'w') { | f | f.write(fnInfo['document']['MXFunction']['content']) }
|
33
|
+
end
|
34
|
+
}
|
35
|
+
# Now do types
|
36
|
+
typeFolder = rootFolder + '/' + typeName
|
37
|
+
Dir.mkdir(typeFolder) if !Dir.exist?(typeFolder)
|
38
|
+
displayNames = hmx.doQuery([typeName, nil])
|
39
|
+
displayNames.each { | displayName |
|
40
|
+
document = hmx.doGetData([displayName])
|
41
|
+
outfile = rootFolder + '/' + displayName
|
42
|
+
puts "Writing #{ typeName } - #{ displayName }"
|
43
|
+
File.open(outfile, 'w') { | f | f.write(JSON.pretty_generate(document)) }
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# check:save
|
49
|
+
#
|
50
|
+
# Given a check function, runs that function against all documents, outputting the value
|
51
|
+
# If the third parameter is given that is an option, to pick one doc (ONE), just display part
|
52
|
+
# PART, or FULL for everything.
|
53
|
+
#
|
54
|
+
# <folder> <fnName> <typeName> [ONE|PART|FULL]
|
55
|
+
def checkSave
|
56
|
+
unless args.size > 1
|
57
|
+
raise CommandFailed, 'Usage: hmx check:save <folderName> <checkfn> <typeName> <ONE|PART|FULL>'
|
58
|
+
end
|
59
|
+
@rootFolder = args.shift
|
60
|
+
fnName = args.shift
|
61
|
+
typeName = args.shift
|
62
|
+
option = 'FULL'
|
63
|
+
if args.size > 0
|
64
|
+
option = args.shift
|
65
|
+
end
|
66
|
+
|
67
|
+
# What we do here is this
|
68
|
+
# Create an eval string of
|
69
|
+
#
|
70
|
+
content = getFn(fnName)
|
71
|
+
Evaluator.class_eval(content)
|
72
|
+
|
73
|
+
# Now get the data object
|
74
|
+
typeFolder = "#{@rootFolder}/#{typeName}"
|
75
|
+
ev = Evaluator.new(@rootFolder)
|
76
|
+
res = []
|
77
|
+
Dir.foreach(typeFolder) { | f |
|
78
|
+
display "Testing #{f}"
|
79
|
+
fullFile = File.expand_path("#{typeFolder}/#{f}")
|
80
|
+
if (File.file?(fullFile))
|
81
|
+
data = getData(fullFile)
|
82
|
+
res << ev.check(data)
|
83
|
+
end
|
84
|
+
}
|
85
|
+
display_tab(res)
|
86
|
+
end
|
87
|
+
# check:view
|
88
|
+
#
|
89
|
+
# Given a folder, a type, a filter fn and a map fn, and a set of parameters to the view
|
90
|
+
# run the view "locally" in this environment, by evaluating the filter and map against
|
91
|
+
# each document downloaded for the type
|
92
|
+
|
93
|
+
def checkView
|
94
|
+
unless args.size > 3
|
95
|
+
raise CommandFailed, "Usage: hmx check:view <folderName> <typeName> <filter> <map> <paramString>"
|
96
|
+
end
|
97
|
+
@rootFolder = args.shift
|
98
|
+
typeName = args.shift
|
99
|
+
filterFn = args.shift
|
100
|
+
mapFn = args.shift
|
101
|
+
paramString = args.shift
|
102
|
+
paramString = JSON.parse(paramString)
|
103
|
+
|
104
|
+
filterContent = getFn(filterFn)
|
105
|
+
mapContent = getFn(mapFn)
|
106
|
+
Evaluator.class_eval(filterContent)
|
107
|
+
Evaluator.class_eval(mapContent)
|
108
|
+
ev = Evaluator.new(@rootFolder)
|
109
|
+
res = []
|
110
|
+
typeFolder = "#{@rootFolder}/#{typeName}/"
|
111
|
+
Dir.foreach(typeFolder) { | f |
|
112
|
+
fullFile = File.expand_path("#{typeFolder}/#{f}")
|
113
|
+
if (File.file?(fullFile))
|
114
|
+
data = getData(fullFile)
|
115
|
+
val = ev.runView(data, paramString)
|
116
|
+
if (!val.nil?)
|
117
|
+
res << val
|
118
|
+
end
|
119
|
+
end
|
120
|
+
}
|
121
|
+
display_tab res
|
122
|
+
end
|
123
|
+
|
124
|
+
protected
|
125
|
+
|
126
|
+
def getContent(fileName)
|
127
|
+
File.open(fileName) { | h |
|
128
|
+
c = ''
|
129
|
+
while(line = h.gets)
|
130
|
+
c = c + line
|
131
|
+
end
|
132
|
+
c
|
133
|
+
}
|
134
|
+
end
|
135
|
+
|
136
|
+
def getFn(fnName)
|
137
|
+
fnFile = @rootFolder + "/function/#{fnName}.rb"
|
138
|
+
getContent(fnFile)
|
139
|
+
end
|
140
|
+
|
141
|
+
def getData(fileName)
|
142
|
+
JSON.parse(getContent(fileName))
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# This is where we'll put the helper functions ($Helper.doGetData)
|
147
|
+
class ScriptHelper
|
148
|
+
def initialize(rootFolder)
|
149
|
+
@rootFolder = rootFolder
|
150
|
+
end
|
151
|
+
|
152
|
+
def getDataAsMap(displayName)
|
153
|
+
{ "data" => @rootFolder }
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
class Evaluator
|
158
|
+
def initialize(rootFolder)
|
159
|
+
$helper = ScriptHelper.new(rootFolder)
|
160
|
+
end
|
161
|
+
|
162
|
+
def runView(data, params)
|
163
|
+
if (filter(data, params))
|
164
|
+
map(data, params)
|
165
|
+
else
|
166
|
+
nil
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
data/lib/hmx/command/clone.rb
CHANGED
@@ -1,77 +1,77 @@
|
|
1
|
-
require "hmx/command/base"
|
2
|
-
require 'date'
|
3
|
-
|
4
|
-
module HmxClient::Command
|
5
|
-
|
6
|
-
# Clone a partition or setup a partition from a clone
|
7
|
-
#
|
8
|
-
class Clone < Base
|
9
|
-
|
10
|
-
# clone
|
11
|
-
#
|
12
|
-
# Create a clone file for the current partition
|
13
|
-
def index
|
14
|
-
# Clone the type information
|
15
|
-
# Clone these built in types (i.e. the content)
|
16
|
-
# Clone other types as defined by the command line
|
17
|
-
extraTypes = args
|
18
|
-
types = [ 'sys.user', 'sys.config', 'sys.ent', 'sys.egroup', 'sys.trigger', 'sys.view' ]
|
19
|
-
extraTypes.each { | et | types << et }
|
20
|
-
types.each { | t | dumpTypeAndData(t) }
|
21
|
-
end
|
22
|
-
|
23
|
-
# clone:load
|
24
|
-
#
|
25
|
-
# Load a file that was created using hmx clone
|
26
|
-
# The file basically contains a series of types (documents separated by << >>)
|
27
|
-
# and data (separated by [[ ]])
|
28
|
-
def load
|
29
|
-
# We define the file as being the input file on the command line (--file-in)
|
30
|
-
if (HmxClient::Command.fileIn.nil?)
|
31
|
-
raise CommandFailed, "Usage: hmx clone:load --file-in=<filename>"
|
32
|
-
end
|
33
|
-
realFile = File.expand_path(HmxClient::Command.fileIn)
|
34
|
-
File.open(realFile, 'r') { | f |
|
35
|
-
currentDoc = ''
|
36
|
-
isType = false
|
37
|
-
while(line = f.gets)
|
38
|
-
if (line[0] == '#')
|
39
|
-
elsif (line[0] == '<' && line[1] == '<')
|
40
|
-
currentDoc = ''
|
41
|
-
isType = true
|
42
|
-
elsif (line[0] == '>' && line[1] == '>')
|
43
|
-
if isType
|
44
|
-
print '.'
|
45
|
-
hmx.
|
46
|
-
end
|
47
|
-
currentDoc = ''
|
48
|
-
elsif (line[0] == '[' && line[1] == '[')
|
49
|
-
currentDoc = ''
|
50
|
-
isType = false
|
51
|
-
elsif (line[0] == ']' && line[1] == ']')
|
52
|
-
if (!isType)
|
53
|
-
print 'x'
|
54
|
-
hmx.
|
55
|
-
end
|
56
|
-
currentDoc = ''
|
57
|
-
else
|
58
|
-
currentDoc = currentDoc + line
|
59
|
-
end
|
60
|
-
end
|
61
|
-
}
|
62
|
-
puts ""
|
63
|
-
puts "Done"
|
64
|
-
end
|
65
|
-
|
66
|
-
protected
|
67
|
-
def dumpTypeAndData(typeName)
|
68
|
-
puts "####### #{ typeName } "
|
69
|
-
puts "<<"
|
70
|
-
puts JSON.generate(hmx.
|
71
|
-
puts ">>"
|
72
|
-
puts "####### Data for #{ typeName } "
|
73
|
-
displayNames = hmx.
|
74
|
-
displayNames.each { | d | puts("[["); puts JSON.generate(hmx.
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
1
|
+
require "hmx/command/base"
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module HmxClient::Command
|
5
|
+
|
6
|
+
# Clone a partition or setup a partition from a clone
|
7
|
+
#
|
8
|
+
class Clone < Base
|
9
|
+
|
10
|
+
# clone
|
11
|
+
#
|
12
|
+
# Create a clone file for the current partition
|
13
|
+
def index
|
14
|
+
# Clone the type information
|
15
|
+
# Clone these built in types (i.e. the content)
|
16
|
+
# Clone other types as defined by the command line
|
17
|
+
extraTypes = args
|
18
|
+
types = [ 'sys.user', 'sys.config', 'sys.ent', 'sys.egroup', 'sys.trigger', 'sys.view' ]
|
19
|
+
extraTypes.each { | et | types << et }
|
20
|
+
types.each { | t | dumpTypeAndData(t) }
|
21
|
+
end
|
22
|
+
|
23
|
+
# clone:load
|
24
|
+
#
|
25
|
+
# Load a file that was created using hmx clone
|
26
|
+
# The file basically contains a series of types (documents separated by << >>)
|
27
|
+
# and data (separated by [[ ]])
|
28
|
+
def load
|
29
|
+
# We define the file as being the input file on the command line (--file-in)
|
30
|
+
if (HmxClient::Command.fileIn.nil?)
|
31
|
+
raise CommandFailed, "Usage: hmx clone:load --file-in=<filename>"
|
32
|
+
end
|
33
|
+
realFile = File.expand_path(HmxClient::Command.fileIn)
|
34
|
+
File.open(realFile, 'r') { | f |
|
35
|
+
currentDoc = ''
|
36
|
+
isType = false
|
37
|
+
while(line = f.gets)
|
38
|
+
if (line[0] == '#')
|
39
|
+
elsif (line[0] == '<' && line[1] == '<')
|
40
|
+
currentDoc = ''
|
41
|
+
isType = true
|
42
|
+
elsif (line[0] == '>' && line[1] == '>')
|
43
|
+
if isType
|
44
|
+
print '.'
|
45
|
+
hmx.doUpdateType([JSON.parse(currentDoc)])
|
46
|
+
end
|
47
|
+
currentDoc = ''
|
48
|
+
elsif (line[0] == '[' && line[1] == '[')
|
49
|
+
currentDoc = ''
|
50
|
+
isType = false
|
51
|
+
elsif (line[0] == ']' && line[1] == ']')
|
52
|
+
if (!isType)
|
53
|
+
print 'x'
|
54
|
+
hmx.doPutData([currentDoc])
|
55
|
+
end
|
56
|
+
currentDoc = ''
|
57
|
+
else
|
58
|
+
currentDoc = currentDoc + line
|
59
|
+
end
|
60
|
+
end
|
61
|
+
}
|
62
|
+
puts ""
|
63
|
+
puts "Done"
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
def dumpTypeAndData(typeName)
|
68
|
+
puts "####### #{ typeName } "
|
69
|
+
puts "<<"
|
70
|
+
puts JSON.generate(hmx.doGetType([typeName]))
|
71
|
+
puts ">>"
|
72
|
+
puts "####### Data for #{ typeName } "
|
73
|
+
displayNames = hmx.doQuery([typeName, nil])
|
74
|
+
displayNames.each { | d | puts("[["); puts JSON.generate(hmx.doGetData([d])); puts("]]") }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/hmx/command/config.rb
CHANGED
@@ -1,67 +1,67 @@
|
|
1
|
-
require "hmx/command/base"
|
2
|
-
|
3
|
-
module HmxClient::Command
|
4
|
-
|
5
|
-
# Manage app config vars
|
6
|
-
#
|
7
|
-
class Config < Base
|
8
|
-
|
9
|
-
# config
|
10
|
-
#
|
11
|
-
# display the config vars for an app
|
12
|
-
#
|
13
|
-
# -s, --shell # output config vars in shell format
|
14
|
-
#
|
15
|
-
def index
|
16
|
-
display_vars(@config, :long => true, :shell => false)
|
17
|
-
end
|
18
|
-
|
19
|
-
# config:add KEY1=VALUE1 ...
|
20
|
-
#
|
21
|
-
# add one or more config vars
|
22
|
-
#
|
23
|
-
def add
|
24
|
-
unless args.size > 0 and args.all? { |a| a.include?('=') }
|
25
|
-
raise CommandFailed, "Usage: hmx config:add <key>=<value> [<key2>=<value2> ...]"
|
26
|
-
end
|
27
|
-
|
28
|
-
args.inject({}) do |vars, arg|
|
29
|
-
key, value = arg.split('=', 2)
|
30
|
-
storeConfig(key.to_sym,value)
|
31
|
-
end
|
32
|
-
|
33
|
-
display_vars(@config, :indent => 2)
|
34
|
-
end
|
35
|
-
|
36
|
-
# config:remove KEY1 [KEY2 ...]
|
37
|
-
#
|
38
|
-
# remove a config var
|
39
|
-
#
|
40
|
-
def remove
|
41
|
-
raise CommandFailed, "Usage: hmx config:remove KEY1 [KEY2 ...]" if args.empty?
|
42
|
-
|
43
|
-
args.each do |key|
|
44
|
-
removeConfig(key.to_sym)
|
45
|
-
display_vars(@config, :indent => 2)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
protected
|
50
|
-
def display_vars(vars, options={})
|
51
|
-
max_length = vars.map { |v| v[0].to_s.size }.max
|
52
|
-
vars.keys.sort.each do |key|
|
53
|
-
if options[:shell]
|
54
|
-
display "#{key}=#{vars[key]}"
|
55
|
-
else
|
56
|
-
spaces = ' ' * (max_length - key.to_s.size)
|
57
|
-
display "#{' ' * (options[:indent] || 0)}#{key}#{spaces} => #{format(vars[key], options)}"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def format(value, options)
|
63
|
-
return value if options[:long] || value.to_s.size < 36
|
64
|
-
value[0, 16] + '...' + value[-16, 16]
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
1
|
+
require "hmx/command/base"
|
2
|
+
|
3
|
+
module HmxClient::Command
|
4
|
+
|
5
|
+
# Manage app config vars
|
6
|
+
#
|
7
|
+
class Config < Base
|
8
|
+
|
9
|
+
# config
|
10
|
+
#
|
11
|
+
# display the config vars for an app
|
12
|
+
#
|
13
|
+
# -s, --shell # output config vars in shell format
|
14
|
+
#
|
15
|
+
def index
|
16
|
+
display_vars(@config, :long => true, :shell => false)
|
17
|
+
end
|
18
|
+
|
19
|
+
# config:add KEY1=VALUE1 ...
|
20
|
+
#
|
21
|
+
# add one or more config vars
|
22
|
+
#
|
23
|
+
def add
|
24
|
+
unless args.size > 0 and args.all? { |a| a.include?('=') }
|
25
|
+
raise CommandFailed, "Usage: hmx config:add <key>=<value> [<key2>=<value2> ...]"
|
26
|
+
end
|
27
|
+
|
28
|
+
args.inject({}) do |vars, arg|
|
29
|
+
key, value = arg.split('=', 2)
|
30
|
+
storeConfig(key.to_sym,value)
|
31
|
+
end
|
32
|
+
|
33
|
+
display_vars(@config, :indent => 2)
|
34
|
+
end
|
35
|
+
|
36
|
+
# config:remove KEY1 [KEY2 ...]
|
37
|
+
#
|
38
|
+
# remove a config var
|
39
|
+
#
|
40
|
+
def remove
|
41
|
+
raise CommandFailed, "Usage: hmx config:remove KEY1 [KEY2 ...]" if args.empty?
|
42
|
+
|
43
|
+
args.each do |key|
|
44
|
+
removeConfig(key.to_sym)
|
45
|
+
display_vars(@config, :indent => 2)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
protected
|
50
|
+
def display_vars(vars, options={})
|
51
|
+
max_length = vars.map { |v| v[0].to_s.size }.max
|
52
|
+
vars.keys.sort.each do |key|
|
53
|
+
if options[:shell]
|
54
|
+
display "#{key}=#{vars[key]}"
|
55
|
+
else
|
56
|
+
spaces = ' ' * (max_length - key.to_s.size)
|
57
|
+
display "#{' ' * (options[:indent] || 0)}#{key}#{spaces} => #{format(vars[key], options)}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def format(value, options)
|
63
|
+
return value if options[:long] || value.to_s.size < 36
|
64
|
+
value[0, 16] + '...' + value[-16, 16]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|