haplo 2.1.0-java
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.
- checksums.yaml +7 -0
- data/README.txt +17 -0
- data/bin/haplo-plugin +3 -0
- data/haplo.gemspec +18 -0
- data/lib/CertificateBundle.pem +3952 -0
- data/lib/auth.rb +168 -0
- data/lib/check.rb +60 -0
- data/lib/custom.rb +73 -0
- data/lib/haplo-templates.jar +0 -0
- data/lib/hmac.rb +12 -0
- data/lib/js.jar +0 -0
- data/lib/js_min.js +38 -0
- data/lib/js_syntax_test.js +88 -0
- data/lib/jshint.js +4359 -0
- data/lib/local_config.rb +28 -0
- data/lib/manifest.rb +44 -0
- data/lib/minimise.rb +68 -0
- data/lib/misc.rb +8 -0
- data/lib/new_plugin.rb +88 -0
- data/lib/notifications.rb +89 -0
- data/lib/packing.rb +62 -0
- data/lib/plugin.rb +227 -0
- data/lib/plugin_tool.rb +197 -0
- data/lib/run.rb +67 -0
- data/lib/schema_requirements.rb +63 -0
- data/lib/server.rb +143 -0
- data/lib/syntax_checking.rb +120 -0
- data/lib/uglifyjs/parse-js.js +1342 -0
- data/lib/uglifyjs/process.js +2011 -0
- data/lib/uglifyjs/squeeze-more.js +69 -0
- data/lib/usage.txt +81 -0
- data/lib/version.txt +1 -0
- data/lib/watchers.rb +39 -0
- metadata +76 -0
data/lib/plugin_tool.rb
ADDED
@@ -0,0 +1,197 @@
|
|
1
|
+
|
2
|
+
def end_on_error(err)
|
3
|
+
puts err
|
4
|
+
exit 1
|
5
|
+
end
|
6
|
+
|
7
|
+
File.open("#{File.dirname(__FILE__)}/version.txt") do |f|
|
8
|
+
puts "Haplo Plugin Tool (#{f.read.chomp})"
|
9
|
+
end
|
10
|
+
|
11
|
+
PluginTool.try_load_custom
|
12
|
+
|
13
|
+
PluginTool::LocalConfig.load
|
14
|
+
|
15
|
+
# Commands not needing server
|
16
|
+
LOCAL_ONLY_COMMANDS = {"license-key" => true, "pack" => true, "check" => true}
|
17
|
+
|
18
|
+
# Plugin names
|
19
|
+
plugin_names = []
|
20
|
+
|
21
|
+
# Options for passing to plugin objects
|
22
|
+
options = Struct.new(:output, :minimiser, :no_console, :show_system_audit, :args, :force, :server_substring).new
|
23
|
+
|
24
|
+
# Parse arguments
|
25
|
+
show_help = false
|
26
|
+
opts = GetoptLong.new(
|
27
|
+
['--help', '-h', GetoptLong::NO_ARGUMENT],
|
28
|
+
['--plugin', '-p', GetoptLong::OPTIONAL_ARGUMENT],
|
29
|
+
['--server', '-s', GetoptLong::REQUIRED_ARGUMENT],
|
30
|
+
['--force', GetoptLong::NO_ARGUMENT],
|
31
|
+
['--output', GetoptLong::REQUIRED_ARGUMENT],
|
32
|
+
['--no-console', '-n', GetoptLong::NO_ARGUMENT],
|
33
|
+
['--show-system-audit', GetoptLong::NO_ARGUMENT],
|
34
|
+
['--minimise', '--minimize', '-m', GetoptLong::NO_ARGUMENT]
|
35
|
+
)
|
36
|
+
option_output = nil
|
37
|
+
opts.each do |opt, argument|
|
38
|
+
case opt
|
39
|
+
when '--help'
|
40
|
+
show_help = true
|
41
|
+
when '--plugin'
|
42
|
+
plugin_names = argument.split(',').map {|n| n.gsub(/[\/\\]+\z/,'')} # remove trailing dir separators
|
43
|
+
when '--server'
|
44
|
+
options.server_substring = argument
|
45
|
+
when '--output'
|
46
|
+
options.output = argument
|
47
|
+
when '--no-console'
|
48
|
+
options.no_console = true
|
49
|
+
when '--show-system-audit'
|
50
|
+
options.show_system_audit = true
|
51
|
+
when '--minimise', '--minimize'
|
52
|
+
options.minimiser = PluginTool::Minimiser.new
|
53
|
+
when '--force'
|
54
|
+
options.force = true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
# Handle rest of command line -- first arg is the command, the rest are passed on
|
58
|
+
PLUGIN_TOOL_COMMAND = (ARGV.shift || 'develop')
|
59
|
+
options.args = ARGV
|
60
|
+
|
61
|
+
automatic_plugin_exclusion = false
|
62
|
+
|
63
|
+
# Help message?
|
64
|
+
if show_help || PLUGIN_TOOL_COMMAND == 'help'
|
65
|
+
puts File.open("#{File.dirname(__FILE__)}/usage.txt") { |f| f.read }
|
66
|
+
exit 0
|
67
|
+
end
|
68
|
+
|
69
|
+
# Plugin names handling
|
70
|
+
def find_all_plugins()
|
71
|
+
all_plugins = []
|
72
|
+
Dir.glob("**/plugin.json").each do |p|
|
73
|
+
if p =~ /\A([a-zA-Z0-9_]+)\/plugin\.json\z/
|
74
|
+
all_plugins << $1
|
75
|
+
end
|
76
|
+
end
|
77
|
+
all_plugins
|
78
|
+
end
|
79
|
+
|
80
|
+
if plugin_names.length == 1 && plugin_names[0] == 'ALL'
|
81
|
+
plugin_names = find_all_plugins()
|
82
|
+
automatic_plugin_exclusion = true
|
83
|
+
end
|
84
|
+
|
85
|
+
# Some commands don't require a server or plugin to be specified
|
86
|
+
case PLUGIN_TOOL_COMMAND
|
87
|
+
when 'new'
|
88
|
+
end_on_error "Plugin name not specified, use --plugin option." if plugin_names.empty?
|
89
|
+
end_on_error "Only one plugin name should be specified for new command" if plugin_names.length > 1
|
90
|
+
PluginTool.make_new_plugin(plugin_names.first)
|
91
|
+
exit 0
|
92
|
+
when 'auth'
|
93
|
+
PluginTool.cmd_auth options
|
94
|
+
exit 0
|
95
|
+
when 'server'
|
96
|
+
PluginTool.cmd_server options
|
97
|
+
exit 0
|
98
|
+
end
|
99
|
+
|
100
|
+
# Find a plugin if none was specified
|
101
|
+
if plugin_names.empty?
|
102
|
+
all_plugins = find_all_plugins()
|
103
|
+
end_on_error "No plugin found" if all_plugins.length == 0
|
104
|
+
if all_plugins.length > 1
|
105
|
+
puts "Too many plugins in the current directory for automatic selection."
|
106
|
+
puts "Use -p plugin_name to specify. Eg:"
|
107
|
+
all_plugins.each do |name|
|
108
|
+
puts " #{$0} -p #{name}"
|
109
|
+
end
|
110
|
+
exit 1
|
111
|
+
end
|
112
|
+
plugin_names = all_plugins
|
113
|
+
end
|
114
|
+
|
115
|
+
# Make plugin objects, start them, sort by order the server will load them
|
116
|
+
plugins = plugin_names.map do |name|
|
117
|
+
PluginTool::Plugin.new(name, options)
|
118
|
+
end
|
119
|
+
plugins.each { |p| p.start }
|
120
|
+
plugins.sort! do |a,b|
|
121
|
+
pri_a = a.plugin_load_priority
|
122
|
+
pri_b = b.plugin_load_priority
|
123
|
+
(pri_a == pri_b) ? (a.name <=> b.name) : (pri_a <=> pri_b)
|
124
|
+
end
|
125
|
+
plugins.each { |p| p.print_banner }
|
126
|
+
|
127
|
+
# Custom behaviour for this repo?
|
128
|
+
PluginTool.custom_behaviour.start(plugins, PLUGIN_TOOL_COMMAND, options, LOCAL_ONLY_COMMANDS[PLUGIN_TOOL_COMMAND])
|
129
|
+
|
130
|
+
# Special handling for some commands
|
131
|
+
case PLUGIN_TOOL_COMMAND
|
132
|
+
when 'pack'
|
133
|
+
end_on_error "Output directory not specified, use --output option." unless options.output != nil
|
134
|
+
require "#{File.dirname(__FILE__)}/packing.rb"
|
135
|
+
when 'check'
|
136
|
+
PluginTool.check_plugins(plugins)
|
137
|
+
exit 0
|
138
|
+
end
|
139
|
+
|
140
|
+
# Set up server communications
|
141
|
+
unless LOCAL_ONLY_COMMANDS[PLUGIN_TOOL_COMMAND]
|
142
|
+
PluginTool.setup_auth(options)
|
143
|
+
PluginTool.check_for_certificate_file
|
144
|
+
|
145
|
+
PluginTool.custom_behaviour.server_ready(plugins, PLUGIN_TOOL_COMMAND, options)
|
146
|
+
|
147
|
+
if automatic_plugin_exclusion
|
148
|
+
exclusions = PluginTool::LocalConfig.get_list("exclude")
|
149
|
+
plugins = plugins.select do |plugin|
|
150
|
+
if exclusions.include?(plugin.name)
|
151
|
+
puts "NOTICE: Excluded plugin #{plugin.name}"
|
152
|
+
false
|
153
|
+
else
|
154
|
+
true
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
plugins.each { |p| p.setup_for_server }
|
160
|
+
end
|
161
|
+
|
162
|
+
# Run the command
|
163
|
+
plugins.each { |p| p.command(PLUGIN_TOOL_COMMAND) }
|
164
|
+
|
165
|
+
# It this isn't the long-running develop command, stop now
|
166
|
+
if PLUGIN_TOOL_COMMAND != 'develop'
|
167
|
+
exit 0
|
168
|
+
end
|
169
|
+
|
170
|
+
# Syntax checking in the background
|
171
|
+
PluginTool.start_syntax_check
|
172
|
+
|
173
|
+
# Notifications support (including console)
|
174
|
+
PluginTool.start_notifications(options) unless options.no_console
|
175
|
+
|
176
|
+
# Open watcher
|
177
|
+
watcher = PluginTool.make_watcher(plugins.map { |p| p.plugin_dir })
|
178
|
+
|
179
|
+
# Start plugins
|
180
|
+
plugins.each { |p| p.develop_setup }
|
181
|
+
|
182
|
+
# Upload changes
|
183
|
+
first_run = true
|
184
|
+
while(true)
|
185
|
+
puts "Scanning plugin files..."
|
186
|
+
plugins.each { |p| p.develop_scan_and_upload(first_run) }
|
187
|
+
PluginTool::Plugin.do_apply
|
188
|
+
PluginTool.finish_with_connection
|
189
|
+
puts "Waiting for changes..."
|
190
|
+
if first_run
|
191
|
+
puts " Any changes you make to your local copy of the plugin will be automatically"
|
192
|
+
puts " uploaded to the server."
|
193
|
+
end
|
194
|
+
first_run = false
|
195
|
+
watcher.wait(3600)
|
196
|
+
end
|
197
|
+
|
data/lib/run.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
|
2
|
+
# Make sure we use a JRuby which has been tested
|
3
|
+
PLUGIN_TOOL_JRUBY_REQUIREMENT = '9.0.4.0'
|
4
|
+
PLUGIN_TOOL_JAVA_REQUIREMENT = '1.8'
|
5
|
+
PLUGIN_TOOL_JAVA_REQUIREMENT_READABLE = "at least Java 8"
|
6
|
+
|
7
|
+
unless defined? JRUBY_VERSION
|
8
|
+
puts "haplo-plugin can only run under JRuby"
|
9
|
+
exit 1
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'rubygems'
|
13
|
+
|
14
|
+
unless Gem::Dependency.new('', '>= '+PLUGIN_TOOL_JRUBY_REQUIREMENT).match?('', JRUBY_VERSION)
|
15
|
+
puts "haplo-plugin requires JRuby #{PLUGIN_TOOL_JRUBY_REQUIREMENT} or later, you have #{JRUBY_VERSION}"
|
16
|
+
exit 1
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'java'
|
20
|
+
|
21
|
+
unless Gem::Dependency.new('', '>= '+PLUGIN_TOOL_JAVA_REQUIREMENT).match?('', java.lang.System.getProperty("java.version").gsub(/[^0-9\.].+?\z/,''))
|
22
|
+
puts "haplo-plugin requires #{PLUGIN_TOOL_JAVA_REQUIREMENT_READABLE}"
|
23
|
+
exit 1
|
24
|
+
end
|
25
|
+
|
26
|
+
require 'digest/sha1'
|
27
|
+
require 'net/http'
|
28
|
+
require 'net/https'
|
29
|
+
require 'getoptlong'
|
30
|
+
require 'fileutils'
|
31
|
+
require 'thread'
|
32
|
+
|
33
|
+
gem 'json'
|
34
|
+
require 'json'
|
35
|
+
|
36
|
+
PLUGIN_TOOL_ROOT_DIR = File.expand_path(File.dirname(__FILE__)+'/..')
|
37
|
+
|
38
|
+
JS_JAR = "#{PLUGIN_TOOL_ROOT_DIR}/lib/js.jar"
|
39
|
+
unless File.exists? JS_JAR
|
40
|
+
puts "Can't find JavaScript interpreter .jar file"
|
41
|
+
exit 1
|
42
|
+
end
|
43
|
+
require JS_JAR
|
44
|
+
|
45
|
+
TEMPLATES_JAR = "#{PLUGIN_TOOL_ROOT_DIR}/lib/haplo-templates.jar"
|
46
|
+
unless File.exists? TEMPLATES_JAR
|
47
|
+
puts "Can't find Haplo Templates .jar file"
|
48
|
+
exit 1
|
49
|
+
end
|
50
|
+
require TEMPLATES_JAR
|
51
|
+
|
52
|
+
require "#{PLUGIN_TOOL_ROOT_DIR}/lib/hmac.rb"
|
53
|
+
require "#{PLUGIN_TOOL_ROOT_DIR}/lib/local_config.rb"
|
54
|
+
require "#{PLUGIN_TOOL_ROOT_DIR}/lib/manifest.rb"
|
55
|
+
require "#{PLUGIN_TOOL_ROOT_DIR}/lib/auth.rb"
|
56
|
+
require "#{PLUGIN_TOOL_ROOT_DIR}/lib/server.rb"
|
57
|
+
require "#{PLUGIN_TOOL_ROOT_DIR}/lib/schema_requirements.rb"
|
58
|
+
require "#{PLUGIN_TOOL_ROOT_DIR}/lib/syntax_checking.rb"
|
59
|
+
require "#{PLUGIN_TOOL_ROOT_DIR}/lib/notifications.rb"
|
60
|
+
require "#{PLUGIN_TOOL_ROOT_DIR}/lib/plugin.rb"
|
61
|
+
require "#{PLUGIN_TOOL_ROOT_DIR}/lib/new_plugin.rb"
|
62
|
+
require "#{PLUGIN_TOOL_ROOT_DIR}/lib/misc.rb"
|
63
|
+
require "#{PLUGIN_TOOL_ROOT_DIR}/lib/watchers.rb"
|
64
|
+
require "#{PLUGIN_TOOL_ROOT_DIR}/lib/minimise.rb"
|
65
|
+
require "#{PLUGIN_TOOL_ROOT_DIR}/lib/check.rb"
|
66
|
+
require "#{PLUGIN_TOOL_ROOT_DIR}/lib/custom.rb"
|
67
|
+
require "#{PLUGIN_TOOL_ROOT_DIR}/lib/plugin_tool.rb"
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
module PluginTool
|
3
|
+
|
4
|
+
class SchemaRequirements
|
5
|
+
IGNORE_LINE = /\A\s*(\#.+)?\z/m # comment or blank line
|
6
|
+
OBJECT_FORMAT = /\A(OPTIONAL )?(?<kind>\S+)\s+(?<code>[a-zA-Z0-9_:-]+)\s*(as\s+(?<name>[a-zA-Z0-9_]+))?\s*\z/m
|
7
|
+
|
8
|
+
SCHEMA_LOCALS = {
|
9
|
+
"type" => "T",
|
10
|
+
"attribute" => "A",
|
11
|
+
"aliased-attribute" => "AA",
|
12
|
+
"qualifier" => "Q",
|
13
|
+
"label" => "Label",
|
14
|
+
"group" => "Group"
|
15
|
+
}
|
16
|
+
|
17
|
+
def initialize(filename)
|
18
|
+
# Define the special attributes by default
|
19
|
+
@schema_names = {"A" => {
|
20
|
+
"Parent" => true,
|
21
|
+
"Type" => true,
|
22
|
+
"Title" => true
|
23
|
+
}}
|
24
|
+
return unless File.exist?(filename)
|
25
|
+
File.open(filename) do |file|
|
26
|
+
file.each do |line|
|
27
|
+
if (line !~ IGNORE_LINE) && (match = OBJECT_FORMAT.match(line))
|
28
|
+
kind = SCHEMA_LOCALS[match[:kind]] || 'UNUSED'
|
29
|
+
@schema_names[kind] ||= {}
|
30
|
+
name = match[:name]
|
31
|
+
if name && !name.empty?
|
32
|
+
@schema_names[kind][name] = true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
@schema_names.delete('UNUSED')
|
38
|
+
end
|
39
|
+
|
40
|
+
def locals
|
41
|
+
@schema_names.keys.dup
|
42
|
+
end
|
43
|
+
|
44
|
+
FIND_USE_REGEXP = Regexp.new("\\b(#{SCHEMA_LOCALS.values.join('|')})\\.([a-zA-Z0-9]+)\\b")
|
45
|
+
|
46
|
+
def report_usage(js)
|
47
|
+
report = []
|
48
|
+
js.split(/\r?\n/).each_with_index do |line, index|
|
49
|
+
line.scan(FIND_USE_REGEXP) do
|
50
|
+
kind = $1
|
51
|
+
name = $2
|
52
|
+
lookup = @schema_names[kind]
|
53
|
+
unless lookup && lookup.has_key?(name)
|
54
|
+
report << "line #{index+1}: Schema name #{kind}.#{name} isn't declared in requirements.schema\n\n"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
report.empty? ? nil : report.join
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
data/lib/server.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
|
2
|
+
module PluginTool
|
3
|
+
|
4
|
+
def self.set_server(hostname, port, key)
|
5
|
+
@@server_hostname = hostname
|
6
|
+
@@server_port = port
|
7
|
+
@@server_key = key
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.get_server_hostname
|
11
|
+
@@server_hostname
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.check_for_certificate_file
|
15
|
+
@@server_ca = nil
|
16
|
+
hostname_parts = (@@server_hostname || '').split('.')
|
17
|
+
search_list = (0..hostname_parts.length).map do |n|
|
18
|
+
filename = "server"
|
19
|
+
search_parts = hostname_parts[n..hostname_parts.length]
|
20
|
+
filename << '.' unless search_parts.empty?
|
21
|
+
filename << search_parts.join('.')
|
22
|
+
filename << ".crt"
|
23
|
+
end
|
24
|
+
@@server_ca = search_list.find { |f| File.file?(f) }
|
25
|
+
if @@server_ca
|
26
|
+
puts "NOTICE: Using alternative CAs for SSL from #{@@server_ca}"
|
27
|
+
else
|
28
|
+
# Use build in certificate bundle
|
29
|
+
@@server_ca = "#{File.dirname(__FILE__)}/CertificateBundle.pem"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.make_http_connection
|
34
|
+
http = Net::HTTP.new(@@server_hostname, @@server_port)
|
35
|
+
ssl_ca = OpenSSL::X509::Store.new
|
36
|
+
unless ssl_ca.respond_to? :add_file
|
37
|
+
puts
|
38
|
+
puts "jruby-openssl gem is not installed or bouncy castle crypto not available on CLASSPATH."
|
39
|
+
puts "See installation instructions."
|
40
|
+
puts
|
41
|
+
exit 1
|
42
|
+
end
|
43
|
+
ssl_ca.add_file(@@server_ca)
|
44
|
+
http.use_ssl = true
|
45
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
46
|
+
http.cert_store = ssl_ca
|
47
|
+
http.start
|
48
|
+
http
|
49
|
+
end
|
50
|
+
|
51
|
+
@@http = nil
|
52
|
+
def self.get_http
|
53
|
+
@@http ||= make_http_connection
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.finish_with_connection
|
57
|
+
if @@http != nil
|
58
|
+
@@http.finish
|
59
|
+
@@http = nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.setup_request(req)
|
64
|
+
req['User-Agent'] = 'plugin-tool'
|
65
|
+
req['X-ONEIS-Key'] = @@server_key if @@server_key
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.get(path)
|
69
|
+
http = get_http
|
70
|
+
request = Net::HTTP::Get.new(path)
|
71
|
+
setup_request(request)
|
72
|
+
http.request(request).body
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.get_with_json_response(path)
|
76
|
+
report_errors_from_server(JSON.parse(get(path)))
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.post(path, params = nil, files = nil)
|
80
|
+
http = get_http
|
81
|
+
request = Net::HTTP::Post.new(path)
|
82
|
+
setup_request(request)
|
83
|
+
if files == nil
|
84
|
+
request.set_form_data(params) if params != nil
|
85
|
+
else
|
86
|
+
boundary = "----------XnJLe9ZIbbGUYtzPQJ16u1"
|
87
|
+
request["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
|
88
|
+
body = ''
|
89
|
+
if params != nil
|
90
|
+
params.each do |key,value|
|
91
|
+
body << <<-EOF
|
92
|
+
--#{boundary}\r
|
93
|
+
Content-Disposition: form-data; name="#{key}"\r
|
94
|
+
\r
|
95
|
+
#{value}\r
|
96
|
+
EOF
|
97
|
+
end
|
98
|
+
end
|
99
|
+
files.each do |key,info|
|
100
|
+
pathname, data = info
|
101
|
+
body << <<-EOF
|
102
|
+
--#{boundary}\r
|
103
|
+
Content-Disposition: form-data; name="#{key}"; filename="#{pathname}"\r
|
104
|
+
Content-Type: application/octet-stream\r
|
105
|
+
Content-Length: #{data.length}\r
|
106
|
+
\r
|
107
|
+
#{data}\r
|
108
|
+
EOF
|
109
|
+
end
|
110
|
+
body << "--#{boundary}--\r"
|
111
|
+
request.body = body
|
112
|
+
end
|
113
|
+
http.request(request).body
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.post_with_json_response(path, params = nil, files = nil)
|
117
|
+
report_errors_from_server(JSON.parse(post(path, params, files)))
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.report_errors_from_server(r)
|
121
|
+
unless r.kind_of? Hash
|
122
|
+
r = {
|
123
|
+
"result" => 'error',
|
124
|
+
"protocol_error" => true,
|
125
|
+
"message" => "Unknown error. Either the server is not enabled for development, or the credentials in #{SERVER_INFO} are not valid."
|
126
|
+
}
|
127
|
+
end
|
128
|
+
if r["result"] != 'success' && r.has_key?("message")
|
129
|
+
puts "\n\n**************************************************************"
|
130
|
+
puts " ERROR REPORTED BY SERVER"
|
131
|
+
puts "**************************************************************\n\n"
|
132
|
+
puts r["message"]
|
133
|
+
puts "\n**************************************************************\n\n"
|
134
|
+
beep
|
135
|
+
end
|
136
|
+
r
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.get_application_info
|
140
|
+
@@server_application_info ||= JSON.parse(get("/api/development-plugin-loader/application-info"))
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|