prize 0.2.1 → 0.3.0

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: 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