explorer 0.0.1 → 0.0.2
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/README.md +3 -1
- data/bin/explore +1 -1
- data/explorer.gemspec +3 -0
- data/lib/explorer/cli.rb +20 -40
- data/lib/explorer/cli/process.rb +89 -0
- data/lib/explorer/cli/proxy.rb +47 -0
- data/lib/explorer/ipc_client.rb +41 -1
- data/lib/explorer/process.rb +3 -3
- data/lib/explorer/process_manager.rb +12 -2
- data/lib/explorer/server/ipc.rb +20 -2
- data/lib/explorer/version.rb +1 -1
- metadata +45 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92c4c5434dfa27aea21de62e797f79e5634aee95
|
4
|
+
data.tar.gz: 332c6ce3352491289eaf6c3199f599e9216395b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d574b77ff7efdb07ba7821823fc1c96152459812a9c0f4ef111bc9ffa1b1c9eb5d6c0b6a342220f05a82824d51a0390f4346cf4a12a4e5e179f07d33cf23cdf1
|
7
|
+
data.tar.gz: 98d3806a19b602d463d44cbe8652194664b84923bf0b1220ab3378837230131ceea14e7dac30645547730e294237db04a2201950960f400ccf34c45a2656cc09
|
data/README.md
CHANGED
data/bin/explore
CHANGED
data/explorer.gemspec
CHANGED
@@ -26,4 +26,7 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_dependency 'thor', '~> 0.19'
|
27
27
|
spec.add_dependency 'celluloid', '~> 0.16'
|
28
28
|
spec.add_dependency 'celluloid-io', '~> 0.16'
|
29
|
+
spec.add_dependency 'dotenv', '~> 1.0'
|
30
|
+
spec.add_dependency 'rainbow', '~> 2.0'
|
31
|
+
spec.add_dependency 'formatador', '~> 0.2'
|
29
32
|
end
|
data/lib/explorer/cli.rb
CHANGED
@@ -1,50 +1,30 @@
|
|
1
1
|
require 'thor'
|
2
|
+
require 'explorer/cli/proxy'
|
3
|
+
require 'explorer/cli/process'
|
2
4
|
|
3
5
|
module Explorer
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
desc "start CONFIG", 'Start explorer'
|
12
|
-
def start(file)
|
13
|
-
servers = Servers.new hostmap: {'test.dev' => {host: 'localhost', port: 8080}}
|
14
|
-
servers.log_watcher.add(STDOUT)
|
15
|
-
servers.run
|
16
|
-
end
|
17
|
-
|
18
|
-
desc 'map-list', 'List hostmapping'
|
19
|
-
def map_list
|
20
|
-
ipc = IPCClient.new
|
21
|
-
map = ipc.hostmap_list
|
22
|
-
puts "-------------------------------------------------------"
|
23
|
-
puts "| MAP | HOST | PORT |"
|
24
|
-
map.each do |k,v|
|
25
|
-
puts "| #{k.rjust(15)} | #{v['host'].rjust(15)} | #{v['port'].to_s.rjust(15)} |"
|
6
|
+
module CLI
|
7
|
+
# TODO: Rename
|
8
|
+
class CLI < Thor
|
9
|
+
desc "version", "Print version of explorer"
|
10
|
+
def version
|
11
|
+
puts Explorer::VERSION
|
26
12
|
end
|
27
|
-
|
28
|
-
end
|
13
|
+
map %w(-v --version) => :version
|
29
14
|
|
30
|
-
|
31
|
-
|
32
|
-
ipc = IPCClient.new
|
33
|
-
ipc.hostmap_add(domain, host, port)
|
34
|
-
puts "Added #{domain} to hostmap"
|
35
|
-
end
|
15
|
+
desc 'proxy SUBCOMMAND ...ARGS', 'manage proxy'
|
16
|
+
subcommand 'proxy', Proxy
|
36
17
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
18
|
+
desc 'process SUBCOMMAND ...ARGS', 'manage processes'
|
19
|
+
subcommand 'process', Process
|
20
|
+
|
21
|
+
desc "boot [CONFIG]", 'Start explorer'
|
22
|
+
def boot(config=nil)
|
23
|
+
servers = Servers.new hostmap: {'test.dev' => {host: 'localhost', port: 8080}}
|
24
|
+
servers.log_watcher.add(STDOUT)
|
25
|
+
servers.run
|
26
|
+
end
|
42
27
|
|
43
|
-
desc 'cmd-add LABEL CMD', 'Add command'
|
44
|
-
option :dir
|
45
|
-
def cmd_add(label, cmd)
|
46
|
-
ipc = IPCClient.new
|
47
|
-
ipc.cmd_add(label, cmd, options[:dir])
|
48
28
|
end
|
49
29
|
end
|
50
30
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'rainbow'
|
2
|
+
require 'formatador'
|
3
|
+
|
4
|
+
module Explorer
|
5
|
+
module CLI
|
6
|
+
class Process < Thor
|
7
|
+
desc 'tail', 'Tail log'
|
8
|
+
def tail
|
9
|
+
Celluloid.logger = nil # Silence celluloid
|
10
|
+
|
11
|
+
ipc = IPCClient.new
|
12
|
+
ipc.tail
|
13
|
+
rescue Errno::ENOENT
|
14
|
+
puts Rainbow('Explore is not running').color(:red).bright
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'add LABEL CMD (--dir=DIR)', 'Add command'
|
18
|
+
option :dir
|
19
|
+
def add(label, cmd)
|
20
|
+
Celluloid.logger = nil # Silence celluloid
|
21
|
+
|
22
|
+
ipc = IPCClient.new
|
23
|
+
ipc.cmd_add(label, cmd, options[:dir])
|
24
|
+
puts Rainbow("Added #{label}").color(:green).bright
|
25
|
+
rescue Errno::ENOENT
|
26
|
+
puts Rainbow('Explore is not running').color(:red).bright
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'start LABEL', 'Start process'
|
30
|
+
def start(label)
|
31
|
+
Celluloid.logger = nil # Silence celluloid
|
32
|
+
|
33
|
+
ipc = IPCClient.new
|
34
|
+
ipc.cmd_start(label)
|
35
|
+
puts Rainbow("Started #{label}").color(:green).bright
|
36
|
+
rescue Errno::ENOENT
|
37
|
+
puts Rainbow('Explore is not running').color(:red).bright
|
38
|
+
end
|
39
|
+
|
40
|
+
desc 'stop LABEL', 'Stop process'
|
41
|
+
def stop(label)
|
42
|
+
Celluloid.logger = nil # Silence celluloid
|
43
|
+
|
44
|
+
ipc = IPCClient.new
|
45
|
+
ipc.cmd_stop(label)
|
46
|
+
puts Rainbow("Stopped #{label}").color(:green).bright
|
47
|
+
rescue Errno::ENOENT
|
48
|
+
puts Rainbow('Explore is not running').color(:red).bright
|
49
|
+
end
|
50
|
+
|
51
|
+
desc 'remove LABEL', 'Remove process'
|
52
|
+
def remove(label)
|
53
|
+
Celluloid.logger = nil # Silence celluloid
|
54
|
+
|
55
|
+
ipc = IPCClient.new
|
56
|
+
ipc.cmd_remove(label)
|
57
|
+
puts Rainbow("Removed #{label}").color(:green).bright
|
58
|
+
rescue Errno::ENOENT
|
59
|
+
puts Rainbow('Explore is not running').color(:red).bright
|
60
|
+
end
|
61
|
+
|
62
|
+
desc 'list', 'list processes'
|
63
|
+
def list
|
64
|
+
Celluloid.logger = nil # Silence celluloid
|
65
|
+
|
66
|
+
ipc = IPCClient.new
|
67
|
+
list = ipc.cmd_list
|
68
|
+
data = list.map do |p|
|
69
|
+
color = if p['state'] == 'stopped'
|
70
|
+
'red'
|
71
|
+
else
|
72
|
+
'green'
|
73
|
+
end
|
74
|
+
{
|
75
|
+
label: "[#{color}]#{p['label']}[/]",
|
76
|
+
command: "[#{color}]#{p['cmd']}[/]",
|
77
|
+
'working directory' => "[#{color}]#{p['dir']}[/]",
|
78
|
+
'PID' => "[#{color}]#{p['pid']}[/]",
|
79
|
+
'exit code' => "[#{color}]#{p['status']}[/]",
|
80
|
+
'status' => "[#{color}]#{p['state']}[/]",
|
81
|
+
}
|
82
|
+
end
|
83
|
+
Formatador.display_compact_table(data, [:label, :command, 'PID', 'exit code', 'status', 'working directory'])
|
84
|
+
rescue Errno::ENOENT
|
85
|
+
puts Rainbow('Explore is not running').color(:red).bright
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'rainbow'
|
2
|
+
require 'formatador'
|
3
|
+
|
4
|
+
module Explorer
|
5
|
+
module CLI
|
6
|
+
class Proxy < Thor
|
7
|
+
desc 'list', 'List proxy map'
|
8
|
+
def list
|
9
|
+
Celluloid.logger = nil # Silence celluloid
|
10
|
+
|
11
|
+
ipc = IPCClient.new
|
12
|
+
data = ipc.hostmap_list.map do |k, v|
|
13
|
+
{
|
14
|
+
domain: "[yellow]#{k}[/]",
|
15
|
+
host: "[yellow]#{v['host']}[/]",
|
16
|
+
port: "[yellow]#{v['port']}[/]",
|
17
|
+
}
|
18
|
+
end
|
19
|
+
Formatador.display_compact_table(data, [:domain, :host, :port])
|
20
|
+
rescue Errno::ENOENT
|
21
|
+
puts Rainbow('Explore is not running').color(:red).bright
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'add DOMAIN HOST PORT', 'Add domain to proxy'
|
25
|
+
def add(domain, host, port)
|
26
|
+
Celluloid.logger = nil # Silence celluloid
|
27
|
+
|
28
|
+
ipc = IPCClient.new
|
29
|
+
ipc.hostmap_add(domain, host, port)
|
30
|
+
puts "Added #{domain} to proxy"
|
31
|
+
rescue Errno::ENOENT
|
32
|
+
puts Rainbow('Explore is not running').color(:red).bright
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'remove DOMAIN', 'remove domain from proxy'
|
36
|
+
def remove(domain)
|
37
|
+
Celluloid.logger = nil # Silence celluloid
|
38
|
+
|
39
|
+
ipc = IPCClient.new
|
40
|
+
ipc.hostmap_remove(domain)
|
41
|
+
puts "Removed #{domain} from proxy"
|
42
|
+
rescue Errno::ENOENT
|
43
|
+
puts Rainbow('Explore is not running').color(:red).bright
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/explorer/ipc_client.rb
CHANGED
@@ -29,9 +29,17 @@ module Explorer
|
|
29
29
|
@socket.puts msg.to_json
|
30
30
|
end
|
31
31
|
|
32
|
+
def hostmap_remove domain
|
33
|
+
msg = {
|
34
|
+
command: 'map-remove',
|
35
|
+
map: domain
|
36
|
+
}
|
37
|
+
@socket.puts msg.to_json
|
38
|
+
end
|
39
|
+
|
32
40
|
def tail(io = STDOUT)
|
33
41
|
msg = {
|
34
|
-
command: 'tail'
|
42
|
+
command: 'cmd-tail'
|
35
43
|
}
|
36
44
|
@socket.puts msg.to_json
|
37
45
|
|
@@ -51,6 +59,38 @@ module Explorer
|
|
51
59
|
@socket.puts msg.to_json
|
52
60
|
end
|
53
61
|
|
62
|
+
def cmd_start(label)
|
63
|
+
msg = {
|
64
|
+
command: 'cmd-start',
|
65
|
+
label: label,
|
66
|
+
}
|
67
|
+
@socket.puts msg.to_json
|
68
|
+
end
|
69
|
+
|
70
|
+
def cmd_stop(label)
|
71
|
+
msg = {
|
72
|
+
command: 'cmd-stop',
|
73
|
+
label: label,
|
74
|
+
}
|
75
|
+
@socket.puts msg.to_json
|
76
|
+
end
|
77
|
+
|
78
|
+
def cmd_remove(label)
|
79
|
+
msg = {
|
80
|
+
command: 'cmd-remove',
|
81
|
+
label: label,
|
82
|
+
}
|
83
|
+
@socket.puts msg.to_json
|
84
|
+
end
|
85
|
+
|
86
|
+
def cmd_list
|
87
|
+
msg = {
|
88
|
+
command: 'cmd-list'
|
89
|
+
}
|
90
|
+
@socket.puts msg.to_json
|
91
|
+
JSON.parse @socket.readline
|
92
|
+
end
|
93
|
+
|
54
94
|
def shutdown
|
55
95
|
@socket.close if @socket
|
56
96
|
end
|
data/lib/explorer/process.rb
CHANGED
@@ -5,15 +5,16 @@ module Explorer
|
|
5
5
|
finalizer :shutdown
|
6
6
|
|
7
7
|
attr_reader :label, :command, :working_dir, :state, :status
|
8
|
-
attr_reader :pid, :pgid, :pipe, :log_watcher
|
8
|
+
attr_reader :pid, :pgid, :pipe, :log_watcher, :env
|
9
9
|
|
10
10
|
# Log watcher should implement a 'log' method which accepts a label and a line of text
|
11
11
|
# Log watcher should also be thread-safe or an actor
|
12
|
-
def initialize(label, command, working_dir: ENV['PWD'], log_watcher: nil)
|
12
|
+
def initialize(label, command, working_dir: ENV['PWD'], log_watcher: nil, env: {})
|
13
13
|
@label = label
|
14
14
|
@command = command
|
15
15
|
@working_dir = working_dir
|
16
16
|
@log_watcher = log_watcher
|
17
|
+
@env = env
|
17
18
|
@state = :stopped
|
18
19
|
@status = nil
|
19
20
|
end
|
@@ -95,7 +96,6 @@ module Explorer
|
|
95
96
|
end
|
96
97
|
|
97
98
|
def spawn_process(label, command, working_dir: ENV['PWD'], pipe: :out)
|
98
|
-
env = {}
|
99
99
|
options = {
|
100
100
|
chdir: working_dir,
|
101
101
|
in: :close,
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'dotenv'
|
2
|
+
|
1
3
|
module Explorer
|
2
4
|
class ProcessManager
|
3
5
|
def initialize log_watcher = nil
|
@@ -12,8 +14,8 @@ module Explorer
|
|
12
14
|
end
|
13
15
|
|
14
16
|
def add(label, command, working_dir: ENV['PWD'])
|
15
|
-
|
16
|
-
@processes[label] = Process.new(label, command, working_dir: working_dir, log_watcher: @log_watcher)
|
17
|
+
env = load_env(working_dir)
|
18
|
+
@processes[label] = Process.new(label, command, working_dir: working_dir, log_watcher: @log_watcher, env: env)
|
17
19
|
end
|
18
20
|
|
19
21
|
def remove(label)
|
@@ -53,5 +55,13 @@ module Explorer
|
|
53
55
|
def labels
|
54
56
|
@processes.keys
|
55
57
|
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def load_env(directory = ENV['PWD'])
|
62
|
+
path = File.join(directory, '.env')
|
63
|
+
return {} unless File.exist?(path)
|
64
|
+
Dotenv::Environment.new(path)
|
65
|
+
end
|
56
66
|
end
|
57
67
|
end
|
data/lib/explorer/server/ipc.rb
CHANGED
@@ -34,11 +34,29 @@ module Explorer
|
|
34
34
|
socket.puts @servers.hostmap.to_json
|
35
35
|
when 'map-add'
|
36
36
|
@servers.hostmap[json['map']] = { host: json['host'], port: json['port'].to_i }
|
37
|
-
when '
|
37
|
+
when 'map-remove'
|
38
|
+
@servers.hostmap.delete json['map']
|
39
|
+
when 'cmd-tail'
|
38
40
|
@servers.log_watcher.add(socket)
|
39
41
|
when 'cmd-add'
|
40
42
|
@servers.process_manager.add(json['label'], json['cmd'], working_dir: json['dir'] || ENV['PWD'])
|
41
|
-
|
43
|
+
when 'cmd-start'
|
44
|
+
@servers.process_manager.start(json['label'])
|
45
|
+
when 'cmd-stop'
|
46
|
+
@servers.process_manager.stop(json['label'])
|
47
|
+
when 'cmd-remove'
|
48
|
+
@servers.process_manager.remove(json['label'])
|
49
|
+
when 'cmd-list'
|
50
|
+
socket.puts @servers.process_manager.processes.map { |p|
|
51
|
+
{
|
52
|
+
label: p.label,
|
53
|
+
cmd: p.command,
|
54
|
+
dir: p.working_dir,
|
55
|
+
state: p.state,
|
56
|
+
pid: p.pid,
|
57
|
+
status: p.status.nil? ? nil : p.status.to_i,
|
58
|
+
}
|
59
|
+
}.to_json
|
42
60
|
end
|
43
61
|
end
|
44
62
|
rescue EOFError, JSON::ParserError
|
data/lib/explorer/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: explorer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Peters
|
@@ -108,6 +108,48 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0.16'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: dotenv
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rainbow
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '2.0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '2.0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: formatador
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0.2'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.2'
|
111
153
|
description: A pow! replacement written in ruby.
|
112
154
|
email:
|
113
155
|
- mail@darksecond.nl
|
@@ -128,6 +170,8 @@ files:
|
|
128
170
|
- lib/celluloid/io/pty.rb
|
129
171
|
- lib/explorer.rb
|
130
172
|
- lib/explorer/cli.rb
|
173
|
+
- lib/explorer/cli/process.rb
|
174
|
+
- lib/explorer/cli/proxy.rb
|
131
175
|
- lib/explorer/ipc_client.rb
|
132
176
|
- lib/explorer/log_watcher.rb
|
133
177
|
- lib/explorer/process.rb
|