haplo 2.5.3-java → 2.5.4-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 +4 -4
- data/haplo.gemspec +2 -2
- data/lib/debuggers.rb +154 -0
- data/lib/notifications.rb +3 -0
- data/lib/plugin_tool.rb +9 -1
- data/lib/version.txt +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 14c1565278be74ecd4daeb39ec0f3336e9ac64f9484c93c389e8fe35de340e7d
|
4
|
+
data.tar.gz: cf5549bef8cb65ea57bba0c132ee6dd1e491d106260edbae25168320c3711cc0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fc234fe95b06d67ae5621cfcac00c507e90ee00a3f7b942b5513bd8809ac2b25b2f0c4e33898fcf2bb789efc35d68cd1c1c44bd7ae0ce32b70f7f910a3fb143
|
7
|
+
data.tar.gz: fc4aa0ab6e8493ed7cf6a6514f8f90cf8bee22d4c329223e72055a2395bbd43761107d171e80c6327d4f684e23eac03c87ae80f19dc77f9247c7dfd89058561f
|
data/haplo.gemspec
CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
|
|
3
3
|
files = Dir.glob("#{root_dir}/**/*.*").map { |x| x[root_dir.length + 1, x.length]}
|
4
4
|
|
5
5
|
s.name = 'haplo'
|
6
|
-
s.version = '2.5.
|
7
|
-
s.date = '2021-07-
|
6
|
+
s.version = '2.5.4'
|
7
|
+
s.date = '2021-07-27'
|
8
8
|
s.summary = "Haplo Plugin Tool"
|
9
9
|
s.description = "Development tools for developing Haplo plugins, see https://haplo.org"
|
10
10
|
s.licenses = ["MPL-2.0"]
|
data/lib/debuggers.rb
CHANGED
@@ -107,3 +107,157 @@ module PluginTool
|
|
107
107
|
|
108
108
|
end
|
109
109
|
|
110
|
+
# -------------------------------------------------------------------------
|
111
|
+
|
112
|
+
module DebugAdapterProtocolTunnel
|
113
|
+
|
114
|
+
@@dap_plugins = nil
|
115
|
+
@@dap_debugger_option = nil
|
116
|
+
@@dap_server = nil
|
117
|
+
@@dap_connection = nil
|
118
|
+
|
119
|
+
def self.prepare(plugins, options)
|
120
|
+
@@dap_plugins = plugins
|
121
|
+
@@dap_debugger_option = options.debugger
|
122
|
+
raise "BAD DEBUGGER OPTION #{@@dap_debugger_option}" unless @@dap_debugger_option =~ /\A(\d+)\z/
|
123
|
+
@@dap_server = TCPServer.new("127.0.0.1", @@dap_debugger_option.to_i)
|
124
|
+
Thread.new do
|
125
|
+
while true
|
126
|
+
connection = @@dap_server.accept
|
127
|
+
if connection
|
128
|
+
if @@dap_connection
|
129
|
+
connection.close
|
130
|
+
else
|
131
|
+
@@dap_connection = DAPConnection.new(connection, @@dap_plugins)
|
132
|
+
Thread.new do
|
133
|
+
@@dap_connection.run
|
134
|
+
_stop_remote_debugger()
|
135
|
+
@@dap_connection = nil
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
rescue => e
|
141
|
+
# ignore
|
142
|
+
end
|
143
|
+
at_exit do
|
144
|
+
@@dap_server.close
|
145
|
+
@@dap_connection.close if @@dap_connection
|
146
|
+
_stop_remote_debugger()
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def self._stop_remote_debugger
|
151
|
+
puts "DEBUGGER: Stopping remote debugger..."
|
152
|
+
result = PluginTool.post("/api/development-plugin-loader/debugger-dap-stop")
|
153
|
+
if result == 'OK'
|
154
|
+
puts "DEBUGGER: Remote debugger stopped."
|
155
|
+
else
|
156
|
+
puts "DEBUGGER: Error stopping remote debugger, application server may be in non-functioning state."
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.log_message_from_server(text)
|
161
|
+
if @@dap_connection
|
162
|
+
@@dap_connection._write({
|
163
|
+
'type' => 'event',
|
164
|
+
'event' => 'output',
|
165
|
+
'body' => {
|
166
|
+
'category' => 'console',
|
167
|
+
'output' => text+"\n"
|
168
|
+
}
|
169
|
+
})
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def self.dap_message_from_server(json)
|
174
|
+
if @@dap_connection
|
175
|
+
@@dap_connection._write(JSON.parse(json))
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
class DAPConnection
|
180
|
+
def initialize(connection, plugins)
|
181
|
+
@connection = connection
|
182
|
+
@plugins = plugins
|
183
|
+
@running = false
|
184
|
+
@next_seq = 1
|
185
|
+
@write_mutex = Mutex.new
|
186
|
+
@_dump_messages = (ENV['HAPLO_DAP_DEBUG'] == '1')
|
187
|
+
end
|
188
|
+
|
189
|
+
def close
|
190
|
+
begin
|
191
|
+
@connection.close
|
192
|
+
rescue => e
|
193
|
+
# ignore any errors
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def run
|
198
|
+
begin
|
199
|
+
run2
|
200
|
+
rescue => e
|
201
|
+
puts "DEBUGGER: Local connection closed"
|
202
|
+
end
|
203
|
+
self.close
|
204
|
+
end
|
205
|
+
|
206
|
+
def run2
|
207
|
+
@running = true
|
208
|
+
have_initialized = false
|
209
|
+
while @running
|
210
|
+
header = @connection.readline
|
211
|
+
blank = @connection.readline
|
212
|
+
if header =~ /\Acontent-length:\s+(\d+)\r\n\z/i && blank == "\r\n"
|
213
|
+
body = @connection.read($1.to_i)
|
214
|
+
message = JSON.parse(body)
|
215
|
+
puts "DAP READ: #{JSON.pretty_generate(message)}\n" if @_dump_messages
|
216
|
+
unless have_initialized
|
217
|
+
if message['type'] == 'request' && message['command'] == 'initialize'
|
218
|
+
puts "DEBUGGER: Local connection from #{message['arguments']['clientName']} (#{message['arguments']['clientID']})\nDEBUGGER: Starting remote debugger..."
|
219
|
+
plugin_locations = {}
|
220
|
+
@plugins.each { |p| plugin_locations[p.name] = p.plugin_dir }
|
221
|
+
start_response = PluginTool.post("/api/development-plugin-loader/debugger-dap-start", {
|
222
|
+
:plugin_locations => JSON.generate(plugin_locations)
|
223
|
+
})
|
224
|
+
unless start_response =~ /\ATOKEN: (.+)\z/
|
225
|
+
raise "Remote debugger failed to start"
|
226
|
+
end
|
227
|
+
@token = $1
|
228
|
+
puts "DEBUGGER: Remote debugger started."
|
229
|
+
have_initialized = true
|
230
|
+
else
|
231
|
+
raise "Expected initialize message after DAP connection"
|
232
|
+
end
|
233
|
+
end
|
234
|
+
# TODO: Send messages in another thread, so that they can be batched together
|
235
|
+
message_response = PluginTool.post_with_json_response("/api/development-plugin-loader/debugger-dap-messages", {
|
236
|
+
:token => @token,
|
237
|
+
:messages => JSON.generate([message])
|
238
|
+
})
|
239
|
+
if message_response['error']
|
240
|
+
puts "DEBUGGER: Server responded with error: #{message_response['error']}"
|
241
|
+
else
|
242
|
+
message_response['messages'].each do |response|
|
243
|
+
_write(response) if response
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def _write(message)
|
251
|
+
@write_mutex.synchronize do
|
252
|
+
m = {'seq' => @next_seq}
|
253
|
+
@next_seq += 1
|
254
|
+
m.merge!(message)
|
255
|
+
puts "DAP WRITE: #{JSON.pretty_generate(m)}\n" if @_dump_messages
|
256
|
+
msg_json = JSON.generate(m)
|
257
|
+
@connection.write("Content-Length: #{msg_json.bytesize}\r\n\r\n")
|
258
|
+
@connection.write(msg_json)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|
data/lib/notifications.rb
CHANGED
@@ -69,6 +69,9 @@ module PluginTool
|
|
69
69
|
when 'log '
|
70
70
|
# Output from console.log()
|
71
71
|
puts "LOG:#{data}"
|
72
|
+
DebugAdapterProtocolTunnel.log_message_from_server(data)
|
73
|
+
when 'DAP1'
|
74
|
+
DebugAdapterProtocolTunnel.dap_message_from_server(data)
|
72
75
|
when 'prof'
|
73
76
|
# Profiler report
|
74
77
|
PluginTool.profiler_handle_report(data)
|
data/lib/plugin_tool.rb
CHANGED
@@ -23,7 +23,7 @@ NO_DEPENDENCY_COMMANDS.delete('list')
|
|
23
23
|
PLUGIN_SEARCH_PATH = ['.']
|
24
24
|
|
25
25
|
# Options for passing to plugin objects
|
26
|
-
options = Struct.new(:output, :minimiser, :no_dependency, :with_dependency, :exclude_with_prefix, :no_console, :show_system_audit, :args, :force, :turbo, :profile, :profile_file, :profile_format, :coverage_file, :coverage_format, :server_substring, :restrict_to_app_id).new
|
26
|
+
options = Struct.new(:output, :minimiser, :no_dependency, :with_dependency, :exclude_with_prefix, :no_console, :show_system_audit, :args, :force, :turbo, :debugger, :profile, :profile_file, :profile_format, :coverage_file, :coverage_format, :server_substring, :restrict_to_app_id).new
|
27
27
|
|
28
28
|
# Parse arguments
|
29
29
|
show_help = false
|
@@ -37,6 +37,7 @@ opts = GetoptLong.new(
|
|
37
37
|
['--server', '-s', GetoptLong::REQUIRED_ARGUMENT],
|
38
38
|
['--force', GetoptLong::NO_ARGUMENT],
|
39
39
|
['--turbo', GetoptLong::NO_ARGUMENT],
|
40
|
+
['--debugger', GetoptLong::REQUIRED_ARGUMENT],
|
40
41
|
['--profile', GetoptLong::REQUIRED_ARGUMENT],
|
41
42
|
['--profile-file', GetoptLong::REQUIRED_ARGUMENT],
|
42
43
|
['--profile-format', GetoptLong::REQUIRED_ARGUMENT],
|
@@ -77,6 +78,8 @@ opts.each do |opt, argument|
|
|
77
78
|
options.force = true
|
78
79
|
when '--turbo'
|
79
80
|
options.turbo = true
|
81
|
+
when '--debugger'
|
82
|
+
options.debugger = argument
|
80
83
|
when '--profile'
|
81
84
|
options.profile = argument.to_f
|
82
85
|
when '--profile-file'
|
@@ -365,6 +368,11 @@ PluginTool.start_syntax_check
|
|
365
368
|
# Notifications support (including console)
|
366
369
|
PluginTool.start_notifications(options) unless options.no_console
|
367
370
|
|
371
|
+
# If the debugger is requested, open the listening socket. Debugger initialised on connection.
|
372
|
+
if options.debugger
|
373
|
+
DebugAdapterProtocolTunnel.prepare(plugins, options)
|
374
|
+
end
|
375
|
+
|
368
376
|
# Open watcher
|
369
377
|
watcher = PluginTool.make_watcher(plugins.map { |p| p.plugin_dir })
|
370
378
|
|
data/lib/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
ccc8c26
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haplo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.5.
|
4
|
+
version: 2.5.4
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Haplo Services
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-07-
|
11
|
+
date: 2021-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Development tools for developing Haplo plugins, see https://haplo.org
|
14
14
|
email: client.services@haplo-services.com
|