prize 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8825741790fa325286bf8200af6a202eee1e68b91201a616b7be6d19ee7a5486
4
- data.tar.gz: ef8344fa03f490af6c0e3e7c145e61c0d829724f9932dc6a6963c0623c4f4106
3
+ metadata.gz: e5d5d94d02356ee18c3dad96ac30d013a3cc20e26d0aa64614bf11935c927524
4
+ data.tar.gz: abccbe946f44b040a02c85df0b5a1c9decceabed42455f6953bba5d5304afbf7
5
5
  SHA512:
6
- metadata.gz: 7e492f6fd67cc30f17b63a88306e0ca1b0fa4b5f694cd9b2135c95a5c2faff43985583bf628439769443126eeddd4aba554f8ad171ae6b6d4302ea0679e9ee1c
7
- data.tar.gz: f676378486137ce96877fbfc2a5bb34b8528eb4038fe5601df28d83f5746b376da7bd72c7ccebc9084e9f5fb57af624a6929976c5637cfe840e800ef55530d6d
6
+ metadata.gz: 0d4dc34770bec250fa5fbf281ca6c6512585b2a7dc938e63a495e9ca6724a2bfdd8c6db5cda05f677add58255319d25c7aadc9536fe491b1f4ed261696dbc073
7
+ data.tar.gz: 81d5e92ae7c568501f31e8f7ffb62d0110252e1b8a6c5e37ef51141509be3d527b692130f0a7d22089af6ecc7ff9fd1fed92bc07dc0fc0ebd4c5cb2e43d82f3e
data/.gitignore CHANGED
@@ -6,6 +6,3 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
-
10
- # rspec failure tracking
11
- .rspec_status
@@ -68,7 +68,7 @@ members of the project's leadership.
68
68
  ## Attribution
69
69
 
70
70
  This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
- available at [http://contributor-covenant.org/version/1/4][version]
71
+ available at [https://contributor-covenant.org/version/1/4][version]
72
72
 
73
- [homepage]: http://contributor-covenant.org
74
- [version]: http://contributor-covenant.org/version/1/4/
73
+ [homepage]: https://contributor-covenant.org
74
+ [version]: https://contributor-covenant.org/version/1/4/
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in arql.gemspec
3
+ # Specify your gem's dependencies in prize.gemspec
4
4
  gemspec
5
5
 
6
6
  gem "rake", "~> 12.0"
@@ -1,10 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- prize (0.2.1)
4
+ prize (0.3.0)
5
5
  activesupport (~> 6.0.3)
6
6
  hiredis (~> 0.6.0)
7
+ net-ssh-gateway (~> 2.0.0)
7
8
  pry (~> 0.13.1)
9
+ pry-byebug (~> 3.9.0)
10
+ pry-doc (~> 1.1.0)
8
11
  rainbow (~> 3.0.0)
9
12
  redis (~> 4.0.0)
10
13
  thor (~> 0.20.0)
@@ -18,6 +21,7 @@ GEM
18
21
  minitest (~> 5.1)
19
22
  tzinfo (~> 1.1)
20
23
  zeitwerk (~> 2.2, >= 2.2.2)
24
+ byebug (11.1.3)
21
25
  coderay (1.1.3)
22
26
  concurrent-ruby (1.1.7)
23
27
  hiredis (0.6.3)
@@ -25,9 +29,18 @@ GEM
25
29
  concurrent-ruby (~> 1.0)
26
30
  method_source (1.0.0)
27
31
  minitest (5.14.1)
32
+ net-ssh (6.1.0)
33
+ net-ssh-gateway (2.0.0)
34
+ net-ssh (>= 4.0.0)
28
35
  pry (0.13.1)
29
36
  coderay (~> 1.1)
30
37
  method_source (~> 1.0)
38
+ pry-byebug (3.9.0)
39
+ byebug (~> 11.0)
40
+ pry (~> 0.13.0)
41
+ pry-doc (1.1.0)
42
+ pry (~> 0.11)
43
+ yard (~> 0.9.11)
31
44
  rainbow (3.0.0)
32
45
  rake (12.3.3)
33
46
  redis (4.0.3)
@@ -35,6 +48,7 @@ GEM
35
48
  thread_safe (0.3.6)
36
49
  tzinfo (1.2.7)
37
50
  thread_safe (~> 0.1)
51
+ yard (0.9.25)
38
52
  zeitwerk (2.4.0)
39
53
 
40
54
  PLATFORMS
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2019 Liu Xiang
3
+ Copyright (c) 2020 Liu Xiang
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/exe/prize CHANGED
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'prize'
3
+ PrizeSetsidWrrapper = File.dirname(File.absolute_path(__FILE__)) + '/prize_setsid_wrapper'
4
+
5
+ require "prize"
4
6
 
5
7
  Prize::Cli.start
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ Process.setsid
4
+
5
+ exec(*ARGV)
@@ -1,2 +1,10 @@
1
1
  require "prize/version"
2
+ require 'prize/id'
3
+ require 'prize/ext'
4
+ require "prize/repl"
5
+ require "prize/ssh_proxy"
6
+ require "prize/app"
2
7
  require "prize/cli"
8
+
9
+ module Prize
10
+ end
@@ -0,0 +1,72 @@
1
+ require 'net/ssh/gateway'
2
+ require 'redis'
3
+
4
+ module Prize
5
+ class App
6
+
7
+ class << self
8
+ attr_accessor :options, :redis, :redis_client
9
+ end
10
+
11
+ def initialize(options)
12
+ require 'active_support/all'
13
+ @options = options
14
+ load_initializer!
15
+ @redis = Redis.new(connect_options)
16
+ App.options = @options
17
+ App.redis = @redis
18
+ App.redis_client = @redis.instance_variable_get('@client')
19
+ end
20
+
21
+ def connect_options
22
+ opts = @options.to_h.slice(:url, :host, :port, :path, :db, :password, :timeout,
23
+ :connect_timeout, :replica, :cluster)
24
+ if @options.ssh_host
25
+ proxy = start_ssh_proxy!
26
+ opts.merge!(proxy)
27
+ end
28
+ opts
29
+ end
30
+
31
+ def load_initializer!
32
+ if File.exists?(File.expand_path('~/.prizerc'))
33
+ load(File.expand_path('~/.prizerc'))
34
+ end
35
+ end
36
+
37
+ def start_ssh_proxy!
38
+ ssh_config = {
39
+ host: @options.ssh_host,
40
+ forward_host: @options.host || '127.0.0.1',
41
+ forward_port: @options.port || 6379
42
+ }
43
+ @options.ssh_user.try { |e| ssh_config.merge!(user: e) }
44
+ @options.ssh_port.try { |e| ssh_config.merge!(port: e) }
45
+ @options.ssh_password.try { |e| ssh_config.merge!(password: e) }
46
+ @options.ssh_local_port.try { |e| ssh_config.merge!(local_port: e) }
47
+ local_ssh_proxy_port = Prize::SSHProxy.connect(ssh_config)
48
+ {
49
+ host: '127.0.0.1',
50
+ port: local_ssh_proxy_port
51
+ }
52
+ end
53
+
54
+ def run!
55
+ if @options.code.present?
56
+ @redis.instance_eval(@options.code)
57
+ elsif @options.args.present?
58
+ @options.args.each do |rb|
59
+ @redis.instance_eval(IO.read(rb))
60
+ end
61
+ elsif STDIN.isatty
62
+ run_repl!
63
+ else
64
+ @redis.instance_eval(STDIN.read)
65
+ end
66
+ end
67
+
68
+ def run_repl!
69
+ Repl.new
70
+ end
71
+ end
72
+ end
@@ -1,52 +1,100 @@
1
- require 'thor'
2
- require 'redis'
3
- require 'hiredis'
4
- require 'pry'
5
- require 'rainbow'
1
+ require 'optparse'
2
+ require 'ostruct'
6
3
 
7
4
  module Prize
8
- class Cli < ::Thor
9
-
10
- default_command :main
11
-
12
- desc '', 'Simple Redis CLI client with Pry loaded'
13
- class_option :url, type: :string, aliases: ['-u'], required: false, desc: 'Server URL, for a TCP connection: `redis://:[password]@[hostname]:[port]/[db]` (password, port and database are optional), for a unix socket connection: `unix://[path to Redis socket]`. This overrides all other options.'
14
- class_option :host, type: :string, aliases: ['-H'], required: false, desc: 'Server hostname (default: 127.0.0.1)'
15
- class_option :port, type: :numeric, aliases: ['-p'], required: false, desc: 'Server port (default: 6379)'
16
- class_option :path, type: :string, aliases: ['-s', '--socket'], required: false, desc: 'Server socket (overrides hostname and port)'
17
- class_option :timeout, type: :numeric, required: false, desc: 'Timeout in seconds (default: 5.0)'
18
- class_option :connect_timeout, type: :numeric, required: false, desc: 'Timeout for initial connect in seconds (default: same as timeout)'
19
- class_option :password, type: :string, aliases: ['-a'], required: false, desc: 'Password to authenticate against server'
20
- class_option :db, type: :numeric, aliases: ['-n'], required: false, desc: 'Database number (default: 0)'
21
- class_option :replica, type: :boolean, required: false, desc: 'Whether to use readonly replica nodes in Redis Cluster or not'
22
- class_option :cluster, type: :string, required: false, desc: 'List of cluster nodes to contact, format: URL1,URL2,URL3...'
23
- def main
24
- @redis = Redis.new(build_options)
25
- Pry.config.prompt = Pry::Prompt.new("", "", prompt)
26
- if File.exists?(File.expand_path('~/.prizerc'))
27
- Pry.load_file_at_toplevel(File.expand_path('~/.prizerc'))
5
+ class Cli
6
+ class << self
7
+ def start
8
+ parse_options!
9
+ App.new(@options).run!
28
10
  end
29
- Pry.start(@redis)
30
- end
31
11
 
32
- no_commands do
33
- def build_options
34
- opts = options.to_h.merge(driver: :hiredis)
35
- opts['cluster'] = opts['cluster'].split(',') if opts['cluster']
36
- opts
37
- end
12
+ def parse_options!
13
+ @options = OpenStruct.new
14
+
15
+
16
+ OptionParser.new do |opts|
17
+ opts.banner = <<~EOF
18
+ Usage: prize [options]
19
+ EOF
20
+
21
+ opts.on('-uURL', '--url=URL', 'Server URL, for a TCP connection: `redis://:[password]@[hostname]:[port]/[db]` (password, port and database are optional), for a unix socket connection: `unix://[path to Redis socket]`. This overrides all other options.') do |url|
22
+ @options.url = url
23
+ end
24
+
25
+ opts.on('-hHOST', '--host=HOST', 'Server hostname (default: 127.0.0.1)') do |host|
26
+ @options.host = host
27
+ end
28
+
29
+ opts.on('-pPORT', '--port=PORT', 'Server port (default: 6379)') do |port|
30
+ @options.port = port.to_i
31
+ end
32
+
33
+ opts.on('-sPATH', '--sock=PATH', 'Server socket (overrides hostname and port)') do |path|
34
+ @options.path = path
35
+ end
36
+
37
+ opts.on('-dDB', '--db=DB', 'Specify database') do |db|
38
+ @options.db = db
39
+ end
40
+
41
+ opts.on('-PPASSWORD', '--password=PASSWORD', 'Specify password') do |password|
42
+ @options.password = password
43
+ end
44
+
45
+ opts.on('', '--timeout=TIMEOUT', 'Timeout in seconds (default: 5.0)') do |timeout|
46
+ @options.timeout = timeout.to_i
47
+ end
48
+
49
+ opts.on('', '--connect-timeout=TIMEOUT', 'Timeout for initial connect in seconds (default: same as timeout)') do |timeout|
50
+ @options.connect_timeout = timeout.to_i
51
+ end
52
+
53
+ opts.on('', '--replica', 'Whether to use readonly replica nodes in Redis Cluster or not') do
54
+ @options.replica = true
55
+ end
56
+
57
+ opts.on('', '--cluster=CLUSTER_URL', 'List of cluster nodes to contact, format: URL1,URL2,URL3...') do |cluster|
58
+ @options.cluster = cluster.split(',')
59
+ end
60
+
61
+ opts.on('-HSSH_HOST', '--ssh-host=SSH_HOST', 'Specify SSH host') do |ssh_host|
62
+ @options.ssh_host = ssh_host
63
+ end
64
+
65
+ opts.on('-OSSH_PORT', '--ssh-port=SSH_PORT', 'Specify SSH port') do |ssh_port|
66
+ @options.ssh_port = ssh_port.to_i
67
+ end
68
+
69
+ opts.on('-USSH_USER', '--ssh-user=SSH_USER', 'Specify SSH user') do |ssh_user|
70
+ @options.ssh_user = ssh_user
71
+ end
72
+
73
+ opts.on('-WSSH_PASSWORD', '--ssh-password=SSH_PASSWORD', 'Specify SSH password') do |ssh_password|
74
+ @options.ssh_password = ssh_password
75
+ end
76
+
77
+ opts.on('-LSSH_LOCAL_PORT', '--ssh-local-port=SSH_LOCAL_PORT', 'Specify local SSH proxy port') do |local_port|
78
+ @options.ssh_local_port = local_port.to_i
79
+ end
80
+
81
+ opts.on('-ECODE', '--eval=CODE', 'evaluate CODE') do |code|
82
+ @options.code = code
83
+ end
84
+
85
+ opts.on('-V', '--version', 'Prints version') do
86
+ puts "PRIZE #{Prize::VERSION}"
87
+ exit
88
+ end
89
+
90
+ opts.on('', '--help', 'Prints this help') do
91
+ puts opts
92
+ exit
93
+ end
94
+
95
+ end.parse!
38
96
 
39
- def prompt
40
- opts = @redis.instance_variable_get('@client').options
41
- host = opts[:url] || opts[:path] || "#{opts[:host]}:#{opts[:port]}/#{opts[:db]}"
42
- [proc do |obj, nest_level, _|
43
- if obj == @redis && nest_level == 0
44
- nest_level_prompt = ''
45
- else
46
- nest_level_prompt = "(#{obj}:#{nest_level})"
47
- end
48
- "%s#{Rainbow('@').green}%s#{nest_level_prompt} %s " % [Rainbow('PRIZE').red, Rainbow(host).yellow, Rainbow('❯').green]
49
- end]
97
+ @options.args = ARGV
50
98
  end
51
99
  end
52
100
  end
@@ -0,0 +1,5 @@
1
+ require 'prize/commands/info'
2
+ require 'prize/commands/reconnect'
3
+
4
+ module Prize::Commands
5
+ end
@@ -0,0 +1,48 @@
1
+ require 'rainbow'
2
+
3
+ module Prize::Commands
4
+ module Info
5
+ class << self
6
+ def db_info
7
+ <<~EOF
8
+
9
+ Redis Connection Information:
10
+
11
+ Active: #{color_boolean(Prize::App.redis_client.connected?)}
12
+ Host: #{Prize::App.options.host || '127.0.0.1'}
13
+ Port: #{Prize::App.options.port || 6379}
14
+ Password: #{(Prize::App.options.password || '').gsub(/./, '*')}
15
+ Database: #{Prize::App.options.db || 0}
16
+ EOF
17
+ end
18
+
19
+ def ssh_info
20
+ <<~EOF
21
+
22
+ SSH Connection Information:
23
+
24
+ Active: #{color_boolean(Prize::SSHProxy.active?)}
25
+ Host: #{Prize::App.options.ssh_host}
26
+ Port: #{Prize::App.options.ssh_port || ''}
27
+ Username: #{Prize::App.options.ssh_user}
28
+ Password: #{(Prize::App.options.ssh_password || '').gsub(/./, '*')}
29
+ Local Port: #{Prize::SSHProxy.local_ssh_proxy_port}
30
+ EOF
31
+ end
32
+
33
+ private
34
+ def color_boolean(bool)
35
+ if bool
36
+ Rainbow('TRUE').green
37
+ else
38
+ Rainbow('FALSE').red
39
+ end
40
+ end
41
+ end
42
+
43
+ Pry.commands.block_command 'inf' do
44
+ puts Info::db_info
45
+ puts Info::ssh_info if Prize::App.options.ssh_host.present?
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,23 @@
1
+ module Prize::Commands
2
+ module Reconnect
3
+ class << self
4
+ def reconnect
5
+ Prize::SSHProxy.reconnect if Prize::App.options.ssh_host.present?
6
+ Prize::App.redis_client.reconnect unless Prize::App.redis_client.connected?
7
+ end
8
+
9
+ def reconnect!
10
+ Prize::SSHProxy.reconnect! if Prize::App.options.ssh_host.present?
11
+ Prize::App.redis_client.reconnect
12
+ end
13
+ end
14
+
15
+ Pry.commands.block_command 'reconnect' do
16
+ Reconnect.reconnect
17
+ end
18
+
19
+ Pry.commands.block_command 'reconnect!' do
20
+ Reconnect.reconnect!
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ require 'prize/ext/object'
2
+ require 'prize/ext/time'
3
+ require 'prize/ext/string'
@@ -0,0 +1,18 @@
1
+ class Object
2
+
3
+ def j
4
+ to_json
5
+ end
6
+
7
+ def jj
8
+ JSON.pretty_generate(JSON.parse(to_json))
9
+ end
10
+
11
+ def jp
12
+ puts j
13
+ end
14
+
15
+ def jjp
16
+ puts jj
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ class String
2
+ def p
3
+ puts self
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ require 'active_support/core_ext/time/conversions'
2
+ require 'active_support/core_ext/object/json'
3
+
4
+ class Time
5
+ DATE_FORMATS ||= {}
6
+ DATE_FORMATS[:default] = '%Y-%m-%d %H:%M:%S'
7
+
8
+ def inspect
9
+ to_s
10
+ end
11
+
12
+ def as_json(*args)
13
+ to_s
14
+ end
15
+ end
@@ -0,0 +1,59 @@
1
+ module Prize
2
+ class ID
3
+ @worker_id_bits = 5
4
+ @data_center_id_bits = 5
5
+ @max_worker_id = -1 ^ (-1 << @worker_id_bits)
6
+ @max_data_center_id = -1 ^ (-1 << @data_center_id_bits)
7
+
8
+ @sequence_bits = 12
9
+ @worker_id_shift = @sequence_bits
10
+ @data_center_id_shift = @sequence_bits + @worker_id_shift
11
+ @timestamp_left_shift = @sequence_bits + @worker_id_bits + @data_center_id_bits
12
+ @sequence_mask = -1 ^ (-1 << @sequence_bits)
13
+
14
+ @id_epoch = (Time.new(2018, 1, 1, 0, 0, 0).to_f * 1000).to_i
15
+ @worker_id = 0
16
+ @data_center_id = 0
17
+ @sequence = 0
18
+
19
+ @last_timestamp = -1
20
+
21
+ class << self
22
+ def long
23
+ ts = (Time.now.to_f * 1000).to_i
24
+ if ts < @last_timestamp
25
+ raise 'Clock moved backwards.'
26
+ end
27
+
28
+ if ts == @last_timestamp
29
+ @sequence = (@sequence + 1) & @sequence_mask
30
+ if (@sequence == 0)
31
+ ts = til_next_millis(@last_timestamp)
32
+ end
33
+ else
34
+ @sequence = 0
35
+ end
36
+ @last_timestamp = ts
37
+
38
+ ((ts - @id_epoch) << @timestamp_left_shift) | (@data_center_id << @data_center_id_shift) | (@worker_id << @worker_id_shift) | @sequence
39
+ end
40
+
41
+ def uuid
42
+ require 'securerandom'
43
+ SecureRandom.uuid.gsub('-', '')
44
+ end
45
+
46
+ private
47
+
48
+ def til_next_millis(last_timestamp)
49
+ ts = (Time.now.to_f * 1000).to_i
50
+ while ts <= last_timestamp
51
+ ts = (Time.now.to_f * 1000).to_i
52
+ end
53
+ ts
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ ::ID = Prize::ID
@@ -0,0 +1,31 @@
1
+ require 'pry'
2
+ require 'pry-byebug'
3
+ require 'prize/commands'
4
+ require 'rainbow'
5
+
6
+ module Prize
7
+ class Repl
8
+ def initialize
9
+ @redis = App.redis
10
+ Pry.config.prompt = Pry::Prompt.new("", "", prompt)
11
+ Pry.start(@redis)
12
+ end
13
+
14
+ def prompt
15
+ opts = @redis.instance_variable_get('@client').options
16
+ if App.options.ssh_host
17
+ host = "#{App.options.ssh_host}:#{App.options.host || '127.0.0.1'}:#{App.options.port || 6379}/#{opts[:db]}"
18
+ else
19
+ host = opts[:url] || opts[:path] || "#{opts[:host]}:#{opts[:port]}/#{opts[:db]}"
20
+ end
21
+ [proc do |obj, nest_level, _|
22
+ if obj == @redis && nest_level == 0
23
+ nest_level_prompt = ''
24
+ else
25
+ nest_level_prompt = "(#{obj}:#{nest_level})"
26
+ end
27
+ "%s#{Rainbow('@').green}%s#{nest_level_prompt} %s " % [Rainbow('PRIZE').red, Rainbow(host).yellow, Rainbow('❯').green]
28
+ end]
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ require 'net/ssh/gateway'
2
+ require 'prize/ssh_proxy_patch'
3
+
4
+ module Prize
5
+ class SSHProxy
6
+ class << self
7
+
8
+ attr_accessor :config, :ssh_gateway, :local_ssh_proxy_port
9
+
10
+ def connect(config)
11
+ @config = config
12
+ @ssh_gateway = Net::SSH::Gateway.new(config[:host], config[:user], config.slice(:port, :password).symbolize_keys.merge(keepalive: true, keepalive_interval: 30, loop_wait: 1))
13
+ @local_ssh_proxy_port = @ssh_gateway.open(config[:forward_host], config[:forward_port], config[:local_port])
14
+ end
15
+
16
+ def reconnect
17
+ reconnect! unless @ssh_gateway.active?
18
+ end
19
+
20
+ def reconnect!
21
+ @ssh_gateway.shutdown!
22
+ @ssh_gateway = Net::SSH::Gateway.new(@config[:host], @config[:user], @config.slice(:port, :password).symbolize_keys)
23
+ @ssh_gateway.open(config[:forward_host], config[:forward_port], @local_ssh_proxy_port)
24
+ end
25
+
26
+ def active?
27
+ @ssh_gateway.active?
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,88 @@
1
+ require 'net/ssh/proxy/command'
2
+
3
+ module Net
4
+ module SSH
5
+ module Proxy
6
+ class Command
7
+
8
+ # Return a new socket connected to the given host and port via the
9
+ # proxy that was requested when the socket factory was instantiated.
10
+ def open(host, port, connection_options = nil)
11
+ command_line = @command_line_template.gsub(/%(.)/) {
12
+ case $1
13
+ when 'h'
14
+ host
15
+ when 'p'
16
+ port.to_s
17
+ when 'r'
18
+ remote_user = connection_options && connection_options[:remote_user]
19
+ if remote_user
20
+ remote_user
21
+ else
22
+ raise ArgumentError, "remote user name not available"
23
+ end
24
+ when '%'
25
+ '%'
26
+ else
27
+ raise ArgumentError, "unknown key: #{$1}"
28
+ end
29
+ }
30
+ command_line = '%s %s' % [PrizeSetsidWrrapper, command_line]
31
+ begin
32
+ io = IO.popen(command_line, "r+")
33
+ begin
34
+ if result = IO.select([io], nil, [io], @timeout)
35
+ if result.last.any? || io.eof?
36
+ raise "command failed"
37
+ end
38
+ else
39
+ raise "command timed out"
40
+ end
41
+ rescue StandardError
42
+ close_on_error(io)
43
+ raise
44
+ end
45
+ rescue StandardError => e
46
+ raise ConnectError, "#{e}: #{command_line}"
47
+ end
48
+ @command_line = command_line
49
+ if Gem.win_platform?
50
+ # read_nonblock and write_nonblock are not available on Windows
51
+ # pipe. Use sysread and syswrite as a replacement works.
52
+ def io.send(data, flag)
53
+ syswrite(data)
54
+ end
55
+
56
+ def io.recv(size)
57
+ sysread(size)
58
+ end
59
+ else
60
+ def io.send(data, flag)
61
+ begin
62
+ result = write_nonblock(data)
63
+ rescue IO::WaitWritable, Errno::EINTR
64
+ IO.select(nil, [self])
65
+ retry
66
+ end
67
+ result
68
+ end
69
+
70
+ def io.recv(size)
71
+ begin
72
+ result = read_nonblock(size)
73
+ rescue IO::WaitReadable, Errno::EINTR
74
+ timeout_in_seconds = 20
75
+ if IO.select([self], nil, [self], timeout_in_seconds) == nil
76
+ raise "Unexpected spurious read wakeup"
77
+ end
78
+ retry
79
+ end
80
+ result
81
+ end
82
+ end
83
+ io
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -1,3 +1,3 @@
1
1
  module Prize
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -1,4 +1,4 @@
1
- require_relative "lib/prize/version"
1
+ require_relative 'lib/prize/version'
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "prize"
@@ -12,7 +12,6 @@ Gem::Specification.new do |spec|
12
12
  spec.license = "MIT"
13
13
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
14
14
 
15
-
16
15
  # Specify which files should be added to the gem when it is released.
17
16
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
18
17
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
@@ -23,9 +22,12 @@ Gem::Specification.new do |spec|
23
22
  spec.require_paths = ["lib"]
24
23
 
25
24
  spec.add_dependency 'activesupport', '~> 6.0.3'
25
+ spec.add_dependency 'net-ssh-gateway', '~> 2.0.0'
26
+ spec.add_dependency 'pry', '~> 0.13.1'
27
+ spec.add_dependency 'pry-byebug', '~> 3.9.0'
28
+ spec.add_dependency 'pry-doc', '~> 1.1.0'
29
+ spec.add_dependency 'rainbow', '~> 3.0.0'
26
30
  spec.add_dependency 'redis', '~> 4.0.0'
27
31
  spec.add_dependency 'hiredis', '~> 0.6.0'
28
32
  spec.add_dependency 'thor', '~> 0.20.0'
29
- spec.add_dependency 'pry', '~> 0.13.1'
30
- spec.add_dependency 'rainbow', '~> 3.0.0'
31
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Liu Xiang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-21 00:00:00.000000000 Z
11
+ date: 2020-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -25,61 +25,61 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 6.0.3
27
27
  - !ruby/object:Gem::Dependency
28
- name: redis
28
+ name: net-ssh-gateway
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 4.0.0
33
+ version: 2.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 4.0.0
40
+ version: 2.0.0
41
41
  - !ruby/object:Gem::Dependency
42
- name: hiredis
42
+ name: pry
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.6.0
47
+ version: 0.13.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.6.0
54
+ version: 0.13.1
55
55
  - !ruby/object:Gem::Dependency
56
- name: thor
56
+ name: pry-byebug
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.20.0
61
+ version: 3.9.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.20.0
68
+ version: 3.9.0
69
69
  - !ruby/object:Gem::Dependency
70
- name: pry
70
+ name: pry-doc
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.13.1
75
+ version: 1.1.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.13.1
82
+ version: 1.1.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rainbow
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -94,17 +94,58 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: 3.0.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: redis
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 4.0.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 4.0.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: hiredis
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.6.0
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.6.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: thor
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 0.20.0
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 0.20.0
97
139
  description: Simple Redis CLI client with pry loaded
98
140
  email:
99
141
  - liuxiang921@gmail.com
100
142
  executables:
101
143
  - prize
144
+ - prize_setsid_wrapper
102
145
  extensions: []
103
146
  extra_rdoc_files: []
104
147
  files:
105
148
  - ".gitignore"
106
- - ".rspec"
107
- - ".travis.yml"
108
149
  - CODE_OF_CONDUCT.md
109
150
  - Gemfile
110
151
  - Gemfile.lock
@@ -114,8 +155,21 @@ files:
114
155
  - bin/console
115
156
  - bin/setup
116
157
  - exe/prize
158
+ - exe/prize_setsid_wrapper
117
159
  - lib/prize.rb
160
+ - lib/prize/app.rb
118
161
  - lib/prize/cli.rb
162
+ - lib/prize/commands.rb
163
+ - lib/prize/commands/info.rb
164
+ - lib/prize/commands/reconnect.rb
165
+ - lib/prize/ext.rb
166
+ - lib/prize/ext/object.rb
167
+ - lib/prize/ext/string.rb
168
+ - lib/prize/ext/time.rb
169
+ - lib/prize/id.rb
170
+ - lib/prize/repl.rb
171
+ - lib/prize/ssh_proxy.rb
172
+ - lib/prize/ssh_proxy_patch.rb
119
173
  - lib/prize/version.rb
120
174
  - prize.gemspec
121
175
  homepage: https://github.com/lululau/prize
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
@@ -1,7 +0,0 @@
1
- ---
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - 2.6.2
7
- before_install: gem install bundler -v 1.17.2