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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ecdc58b1c28dcdbd33d92cfab008eb4252df0fb8
4
- data.tar.gz: 7e0f277198bb44695818fc849a4f11480767d5b1
3
+ metadata.gz: 92c4c5434dfa27aea21de62e797f79e5634aee95
4
+ data.tar.gz: 332c6ce3352491289eaf6c3199f599e9216395b8
5
5
  SHA512:
6
- metadata.gz: 3aa239b18db10c9c8573b7b6116f5da84f6647ee595a8a08a9950c01d7b7e36e91d0cb729f4d9713a3c2cde9921dcdeec5d6ab87f394cc177810205e3c4732e1
7
- data.tar.gz: 552fdfb5179d368fe5ba55a4c905da3ed728b659621a3c5ac9fcebabf6e00bd722154c89b4640b9124430ba94997001555ed2532af3f1800f42a6f3a7674f184
6
+ metadata.gz: d574b77ff7efdb07ba7821823fc1c96152459812a9c0f4ef111bc9ffa1b1c9eb5d6c0b6a342220f05a82824d51a0390f4346cf4a12a4e5e179f07d33cf23cdf1
7
+ data.tar.gz: 98d3806a19b602d463d44cbe8652194664b84923bf0b1220ab3378837230131ceea14e7dac30645547730e294237db04a2201950960f400ccf34c45a2656cc09
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Explorer
2
2
 
3
- TODO: Write a gem description
3
+ Explorer is a replacement for Pow! written in Ruby.
4
+
5
+ [![Dependency Status](https://gemnasium.com/Darksecond/explorer.svg)](https://gemnasium.com/Darksecond/explorer)
4
6
 
5
7
  ## Installation
6
8
 
data/bin/explore CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  require 'explorer'
4
4
 
5
- Explorer::CLI.start(ARGV)
5
+ Explorer::CLI::CLI.start(ARGV)
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
- class CLI < Thor
5
- desc "version", "Print version of explorer"
6
- def version
7
- puts Explorer::VERSION
8
- end
9
- map %w(-v --version) => :version
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
- puts "-------------------------------------------------------"
28
- end
13
+ map %w(-v --version) => :version
29
14
 
30
- desc 'map-add DOMAIN HOST PORT', 'Add to mapping'
31
- def map_add(domain, host, port)
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
- desc 'tail', 'Tail log'
38
- def tail
39
- ipc = IPCClient.new
40
- ipc.tail
41
- end
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
@@ -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
@@ -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
- #TODO $PORT replacement? (or somewhere else, perhaps)
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
@@ -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 'tail'
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
- @servers.process_manager.start(json['label']) #TODO Refactor out?
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
@@ -1,3 +1,3 @@
1
1
  module Explorer
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
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.1
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