consolle 0.2.6 → 0.2.7

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
  SHA256:
3
- metadata.gz: 3fdeb782267d3cb951cd1e8fece86486dc48eaf1c2e686e782b256e0dc60745e
4
- data.tar.gz: d078d1aad3ca4bc063aa5ef15d67f0c66273e30a64ea822dd4a4122c173938f7
3
+ metadata.gz: 7b0fccfa081563dfbdbb310a8822ccca827150906aac1208e3b72fa754eb8ab6
4
+ data.tar.gz: 05ab3780cce3a62638540641146dae880f7cdbe75d5ede45ce71ba32433af2ec
5
5
  SHA512:
6
- metadata.gz: 4afbcd6b93ea353b556000ef601acefcfd0bd0e4f76fc89053c2a20c3b72ccddd4a95ee5073f61420a310011fc2cd6df44ccbb17ee319d777645f5d97fb673e6
7
- data.tar.gz: '069a0849b85439b2b9314c2e165ddba1486f86db8b30f13b4346bd137b5607799978c81a78182e6a7f1b956c061763b075a12068fd626445772f9524a6705a4a'
6
+ metadata.gz: 45c5bff6c8b43e6029fb1e4d0f12cc83ce2f5925f0882c8b628394868b52f119c92e4fcc6dccaae7190e72ebdf30cc71cc1b7aeb021f6c9fbaff127fd67b9524
7
+ data.tar.gz: e96701a1acea38c2c90c51e4c5df56ff9e038e48551b5d34c3d17d74b4c6ad0044a8123553e1ebf2000415654da192a5f60890924b08ab904d9ad13ee8728512
data/.version CHANGED
@@ -1 +1 @@
1
- 0.2.6
1
+ 0.2.7
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
5
  # Ruby 3.4.0+ requires base64 as a gem
6
- gem "base64", "~> 0.2"
6
+ gem 'base64', '~> 0.2'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- consolle (0.2.6)
4
+ consolle (0.2.7)
5
5
  logger (~> 1.0)
6
6
  thor (~> 1.0)
7
7
 
data/bin/cone CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require_relative "../lib/consolle"
4
+ require_relative '../lib/consolle'
5
5
 
6
- Consolle::CLI.start(ARGV)
6
+ Consolle::CLI.start(ARGV)
data/bin/consolle CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require_relative "../lib/consolle"
4
+ require_relative '../lib/consolle'
5
5
 
6
- Consolle::CLI.start(ARGV)
6
+ Consolle::CLI.start(ARGV)
data/consolle.gemspec CHANGED
@@ -1,25 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "lib/consolle/version"
3
+ require_relative 'lib/consolle/version'
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = "consolle"
6
+ spec.name = 'consolle'
7
7
  spec.version = Consolle::VERSION
8
- spec.authors = ["nacyot"]
9
- spec.email = ["propellerheaven@gmail.com"]
8
+ spec.authors = ['nacyot']
9
+ spec.email = ['propellerheaven@gmail.com']
10
10
 
11
- spec.summary = "PTY-based Rails console management library"
12
- spec.description = "Consolle is a library that manages Rails console through PTY (Pseudo-Terminal). Moving away from the traditional eval-based execution method, it manages the actual Rails console process as a subprocess to provide a more stable and secure execution environment."
13
- spec.homepage = "https://github.com/nacyot/consolle"
14
- spec.required_ruby_version = ">= 3.1.0"
15
- spec.license = "MIT"
11
+ spec.summary = 'PTY-based Rails console management library'
12
+ spec.description = 'Consolle is a library that manages Rails console through PTY (Pseudo-Terminal). Moving away from the traditional eval-based execution method, it manages the actual Rails console process as a subprocess to provide a more stable and secure execution environment.'
13
+ spec.homepage = 'https://github.com/nacyot/consolle'
14
+ spec.required_ruby_version = '>= 3.1.0'
15
+ spec.license = 'MIT'
16
16
 
17
17
  spec.metadata = {
18
- "homepage_uri" => spec.homepage,
19
- "source_code_uri" => "https://github.com/nacyot/consolle",
20
- "changelog_uri" => "https://github.com/nacyot/consolle/blob/main/CHANGELOG.md",
21
- "bug_tracker_uri" => "https://github.com/nacyot/consolle/issues",
22
- "rubygems_mfa_required" => "true"
18
+ 'homepage_uri' => spec.homepage,
19
+ 'source_code_uri' => 'https://github.com/nacyot/consolle',
20
+ 'changelog_uri' => 'https://github.com/nacyot/consolle/blob/main/CHANGELOG.md',
21
+ 'bug_tracker_uri' => 'https://github.com/nacyot/consolle/issues',
22
+ 'rubygems_mfa_required' => 'true'
23
23
  }
24
24
 
25
25
  # Specify which files should be added to the gem when it is released.
@@ -27,14 +27,14 @@ Gem::Specification.new do |spec|
27
27
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
28
28
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
29
29
  end
30
- spec.bindir = "bin"
30
+ spec.bindir = 'bin'
31
31
  spec.executables = spec.files.grep(%r{\Abin/}) { |f| File.basename(f) }
32
- spec.require_paths = ["lib"]
32
+ spec.require_paths = ['lib']
33
33
 
34
34
  # Runtime dependencies
35
- spec.add_dependency "thor", "~> 1.0"
36
- spec.add_dependency "logger", "~> 1.0"
35
+ spec.add_dependency 'logger', '~> 1.0'
36
+ spec.add_dependency 'thor', '~> 1.0'
37
37
 
38
38
  # Development dependencies
39
- spec.add_development_dependency "rspec", "~> 3.0"
40
- end
39
+ spec.add_development_dependency 'rspec', '~> 3.0'
40
+ end
@@ -1,24 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "socket"
4
- require "json"
5
- require "timeout"
6
- require "securerandom"
7
- require "fileutils"
3
+ require 'socket'
4
+ require 'json'
5
+ require 'timeout'
6
+ require 'securerandom'
7
+ require 'fileutils'
8
8
 
9
9
  module Consolle
10
10
  module Adapters
11
11
  class RailsConsole
12
12
  attr_reader :socket_path, :process_pid, :pid_path, :log_path
13
13
 
14
- def initialize(socket_path: nil, pid_path: nil, log_path: nil, rails_root: nil, rails_env: nil, verbose: false, command: nil)
14
+ def initialize(socket_path: nil, pid_path: nil, log_path: nil, rails_root: nil, rails_env: nil, verbose: false,
15
+ command: nil)
15
16
  @socket_path = socket_path || default_socket_path
16
17
  @pid_path = pid_path || default_pid_path
17
18
  @log_path = log_path || default_log_path
18
19
  @rails_root = rails_root || Dir.pwd
19
- @rails_env = rails_env || "development"
20
+ @rails_env = rails_env || 'development'
20
21
  @verbose = verbose
21
- @command = command || "bin/rails console"
22
+ @command = command || 'bin/rails console'
22
23
  @server_pid = nil
23
24
  end
24
25
 
@@ -27,14 +28,14 @@ module Consolle
27
28
 
28
29
  # Start socket server daemon
29
30
  start_server_daemon
30
-
31
+
31
32
  # Wait for server to be ready
32
33
  wait_for_server(timeout: 10)
33
-
34
+
34
35
  # Get server status
35
36
  status = get_status
36
- @server_pid = status["pid"] if status && status["success"]
37
-
37
+ @server_pid = status['pid'] if status && status['success']
38
+
38
39
  true
39
40
  rescue StandardError => e
40
41
  stop_server_daemon
@@ -57,10 +58,10 @@ module Consolle
57
58
 
58
59
  def running?
59
60
  return false unless File.exist?(@socket_path)
60
-
61
+
61
62
  # Check if socket is responsive
62
63
  status = get_status
63
- status && status["success"] && status["running"]
64
+ status && status['success'] && status['running']
64
65
  rescue StandardError
65
66
  false
66
67
  end
@@ -69,50 +70,48 @@ module Consolle
69
70
  # Return the server daemon PID from pid file
70
71
  pid_file = @pid_path
71
72
  return nil unless File.exist?(pid_file)
72
-
73
+
73
74
  File.read(pid_file).strip.to_i
74
75
  rescue StandardError
75
76
  nil
76
77
  end
77
78
 
78
79
  def send_code(code, timeout: 15)
79
- unless running?
80
- raise RuntimeError, "Console is not running"
81
- end
80
+ raise 'Console is not running' unless running?
82
81
 
83
82
  request = {
84
- "action" => "eval",
85
- "code" => code,
86
- "timeout" => timeout,
87
- "request_id" => SecureRandom.uuid
83
+ 'action' => 'eval',
84
+ 'code' => code,
85
+ 'timeout' => timeout,
86
+ 'request_id' => SecureRandom.uuid
88
87
  }
89
88
 
90
89
  response = send_request(request, timeout: timeout + 5)
91
-
90
+
92
91
  # Format response for compatibility
93
- if response["success"]
92
+ if response['success']
94
93
  {
95
- "success" => true,
96
- "result" => response["result"],
97
- "execution_time" => response["execution_time"],
98
- "request_id" => response["request_id"]
94
+ 'success' => true,
95
+ 'result' => response['result'],
96
+ 'execution_time' => response['execution_time'],
97
+ 'request_id' => response['request_id']
99
98
  }
100
99
  else
101
100
  {
102
- "success" => false,
103
- "error" => response["error"] || "Unknown",
104
- "message" => response["message"] || "Unknown error",
105
- "request_id" => response["request_id"]
101
+ 'success' => false,
102
+ 'error' => response['error'] || 'Unknown',
103
+ 'message' => response['message'] || 'Unknown error',
104
+ 'request_id' => response['request_id']
106
105
  }
107
106
  end
108
107
  end
109
108
 
110
109
  def get_status
111
110
  request = {
112
- "action" => "status",
113
- "request_id" => SecureRandom.uuid
111
+ 'action' => 'status',
112
+ 'request_id' => SecureRandom.uuid
114
113
  }
115
-
114
+
116
115
  send_request(request, timeout: 5)
117
116
  rescue StandardError
118
117
  nil
@@ -121,30 +120,30 @@ module Consolle
121
120
  private
122
121
 
123
122
  def default_socket_path
124
- File.join(Dir.pwd, "tmp", "cone", "cone.socket")
123
+ File.join(Dir.pwd, 'tmp', 'cone', 'cone.socket')
125
124
  end
126
125
 
127
126
  def default_pid_path
128
- File.join(Dir.pwd, "tmp", "cone", "cone.pid")
127
+ File.join(Dir.pwd, 'tmp', 'cone', 'cone.pid')
129
128
  end
130
129
 
131
130
  def default_log_path
132
- File.join(Dir.pwd, "tmp", "cone", "cone.log")
131
+ File.join(Dir.pwd, 'tmp', 'cone', 'cone.log')
133
132
  end
134
133
 
135
134
  def server_command
136
- consolle_lib_path = File.expand_path("../..", __dir__)
137
-
135
+ consolle_lib_path = File.expand_path('../..', __dir__)
136
+
138
137
  # Build server command
139
138
  [
140
- "ruby",
141
- "-I", consolle_lib_path,
142
- "-e", server_script,
143
- "--",
139
+ 'ruby',
140
+ '-I', consolle_lib_path,
141
+ '-e', server_script,
142
+ '--',
144
143
  @socket_path,
145
144
  @rails_root,
146
145
  @rails_env,
147
- @verbose ? "debug" : "info",
146
+ @verbose ? 'debug' : 'info',
148
147
  @pid_path,
149
148
  @log_path,
150
149
  @command
@@ -156,31 +155,31 @@ module Consolle
156
155
  begin
157
156
  require 'consolle/server/console_socket_server'
158
157
  require 'logger'
159
-
158
+ #{' '}
160
159
  socket_path, rails_root, rails_env, log_level, pid_path, log_path, command = ARGV
161
-
160
+ #{' '}
162
161
  # Write initial log
163
162
  log_file = log_path || socket_path.sub(/\\.socket$/, '.log')
164
163
  File.open(log_file, 'a') { |f| f.puts "[Server] Starting... PID: \#{Process.pid}" }
165
-
164
+ #{' '}
166
165
  # Daemonize
167
166
  Process.daemon(true, false)
168
-
167
+ #{' '}
169
168
  # Redirect output
170
169
  $stdout.reopen(log_file, 'a')
171
170
  $stderr.reopen(log_file, 'a')
172
171
  $stdout.sync = $stderr.sync = true
173
-
172
+ #{' '}
174
173
  # Write PID file
175
174
  pid_file = pid_path || socket_path.sub(/\\.socket$/, '.pid')
176
175
  File.write(pid_file, Process.pid.to_s)
177
-
176
+ #{' '}
178
177
  puts "[Server] Daemon started, PID: \#{Process.pid}"
179
-
178
+ #{' '}
180
179
  # Create logger with appropriate level
181
180
  logger = Logger.new(log_file)
182
181
  logger.level = (log_level == 'debug') ? Logger::DEBUG : Logger::INFO
183
-
182
+ #{' '}
184
183
  # Start server
185
184
  server = Consolle::Server::ConsoleSocketServer.new(
186
185
  socket_path: socket_path,
@@ -189,12 +188,12 @@ module Consolle
189
188
  logger: logger,
190
189
  command: command
191
190
  )
192
-
191
+ #{' '}
193
192
  puts "[Server] Starting server with log level: \#{log_level}..."
194
193
  server.start
195
-
194
+ #{' '}
196
195
  puts "[Server] Server started, entering sleep..."
197
-
196
+ #{' '}
198
197
  # Keep running
199
198
  sleep
200
199
  rescue => e
@@ -209,7 +208,7 @@ module Consolle
209
208
  # Ensure directory exists
210
209
  socket_dir = File.dirname(@socket_path)
211
210
  FileUtils.mkdir_p(socket_dir) unless Dir.exist?(socket_dir)
212
-
211
+
213
212
  # Start server process
214
213
  log_file = @log_path
215
214
  pid = Process.spawn(
@@ -217,7 +216,7 @@ module Consolle
217
216
  out: log_file,
218
217
  err: log_file
219
218
  )
220
-
219
+
221
220
  Process.detach(pid)
222
221
  end
223
222
 
@@ -225,27 +224,32 @@ module Consolle
225
224
  # Read PID file
226
225
  pid_file = @pid_path
227
226
  return unless File.exist?(pid_file)
228
-
227
+
229
228
  pid = File.read(pid_file).to_i
230
-
229
+
231
230
  # Kill process
232
231
  begin
233
- Process.kill("TERM", pid)
234
-
232
+ Process.kill('TERM', pid)
233
+
235
234
  # Wait for socket to disappear
236
235
  10.times do
237
236
  break unless File.exist?(@socket_path)
237
+
238
238
  sleep 0.1
239
239
  end
240
-
240
+
241
241
  # Force kill if needed
242
242
  if File.exist?(@socket_path)
243
- Process.kill("KILL", pid) rescue nil
243
+ begin
244
+ Process.kill('KILL', pid)
245
+ rescue StandardError
246
+ nil
247
+ end
244
248
  end
245
249
  rescue Errno::ESRCH
246
250
  # Process already dead
247
251
  end
248
-
252
+
249
253
  # Clean up files
250
254
  File.unlink(@socket_path) if File.exist?(@socket_path)
251
255
  File.unlink(pid_file) if File.exist?(pid_file)
@@ -253,43 +257,44 @@ module Consolle
253
257
 
254
258
  def wait_for_server(timeout: 10)
255
259
  deadline = Time.now + timeout
256
-
260
+
257
261
  while Time.now < deadline
258
262
  return true if File.exist?(@socket_path) && get_status
263
+
259
264
  sleep 0.1
260
265
  end
261
-
266
+
262
267
  raise "Server failed to start within #{timeout} seconds"
263
268
  end
264
269
 
265
270
  def send_request(request, timeout: 30)
266
271
  Timeout.timeout(timeout) do
267
272
  socket = UNIXSocket.new(@socket_path)
268
-
273
+
269
274
  # Send request
270
275
  socket.write(JSON.generate(request))
271
276
  socket.write("\n")
272
277
  socket.flush
273
-
278
+
274
279
  # Read response
275
280
  response_data = socket.gets
276
281
  socket.close
277
-
282
+
278
283
  JSON.parse(response_data)
279
284
  end
280
285
  rescue Timeout::Error
281
286
  {
282
- "success" => false,
283
- "error" => "Timeout",
284
- "message" => "Request timed out after #{timeout} seconds"
287
+ 'success' => false,
288
+ 'error' => 'Timeout',
289
+ 'message' => "Request timed out after #{timeout} seconds"
285
290
  }
286
291
  rescue StandardError => e
287
292
  {
288
- "success" => false,
289
- "error" => e.class.name,
290
- "message" => e.message
293
+ 'success' => false,
294
+ 'error' => e.class.name,
295
+ 'message' => e.message
291
296
  }
292
297
  end
293
298
  end
294
299
  end
295
- end
300
+ end