whatup 0.2.3 → 0.2.4
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/.gitignore +1 -1
- data/.rubocop.yml +22 -0
- data/README.md +2 -0
- data/Rakefile +1 -1
- data/docs/hw/framework.pdf +0 -0
- data/lib/whatup/cli/commands/interactive/interactive.rb +115 -0
- data/lib/whatup/cli/commands/interactive/setup.rb +24 -0
- data/lib/whatup/client/client.rb +10 -4
- data/lib/whatup/server/client.rb +35 -3
- data/lib/whatup/server/room.rb +28 -0
- data/lib/whatup/server/server.rb +128 -12
- data/lib/whatup/version.rb +1 -1
- data/whatup.gemspec +3 -1
- metadata +34 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 391ddb29c708ee7cf37769dc7aa3723d65e420fe08a268862bff6ec7ff5e659f
|
4
|
+
data.tar.gz: b7e349838c88b72f3fbb04258afa114b124f460af40b99d64654bb5b941c04f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f8458ee475df4aa40d81cd3c126cea7d0153ba3ab2c3d56ec7ff92e130ae1b2765b5594a7a780584498a74d2808779d7024e412d724acad919665b8b339acf3
|
7
|
+
data.tar.gz: e84e5379f28eec45311b4ab0aeea6ec67b45dadea2240f06f3c7dcc33a4094784ad081e6fc1bffa8e57d0c4cbc30248c7a55e663923d95e73b1de89698355316
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -3,10 +3,32 @@
|
|
3
3
|
AllCops:
|
4
4
|
TargetRubyVersion: 2.4 # Modern Ruby
|
5
5
|
|
6
|
+
# attr_reader *%i[a b c]
|
7
|
+
Lint/UnneededSplatExpansion:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
# Needed for the server pid
|
11
|
+
Style/GlobalVars:
|
12
|
+
Exclude:
|
13
|
+
- 'spec/system_spec.rb'
|
14
|
+
|
15
|
+
# Aruba uses modifiable strings
|
16
|
+
Style/FrozenStringLiteralComment:
|
17
|
+
Exclude:
|
18
|
+
- 'spec/system_spec.rb'
|
19
|
+
|
6
20
|
# The default is a bit restrictive
|
7
21
|
Metrics/AbcSize:
|
8
22
|
Max: 30
|
9
23
|
|
24
|
+
# The default is a bit restrictive
|
25
|
+
Metrics/ClassLength:
|
26
|
+
Max: 145
|
27
|
+
|
28
|
+
# <<~OUTPUT.gsub /^\s+/, ''
|
29
|
+
Lint/AmbiguousRegexpLiteral:
|
30
|
+
Enabled: false
|
31
|
+
|
10
32
|
Metrics/BlockLength:
|
11
33
|
Exclude:
|
12
34
|
- 'whatup.gemspec'
|
data/README.md
CHANGED
@@ -6,6 +6,8 @@ whatup is a simple server-based instant messaging application
|
|
6
6
|
|
7
7
|
Check it out on [rubygems.org](https://rubygems.org/gems/whatup).
|
8
8
|
|
9
|
+
[](https://travis-ci.com/jethrodaniel/whatup)
|
10
|
+
|
9
11
|
## Installation
|
10
12
|
|
11
13
|
Assuming you have Ruby 2.4 or greater installed,
|
data/Rakefile
CHANGED
Binary file
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
require 'whatup/client/client'
|
6
|
+
|
7
|
+
module Whatup
|
8
|
+
module CLI
|
9
|
+
# Any methods of class `Whatup::CLI::Interactive` that rely on instance
|
10
|
+
# variables should be included here
|
11
|
+
COMMANDS = %i[room list exit].freeze
|
12
|
+
|
13
|
+
require 'whatup/cli/commands/interactive/setup'
|
14
|
+
|
15
|
+
# Interactive client commands that are available after connecting
|
16
|
+
#
|
17
|
+
# This class is run on the server
|
18
|
+
class Interactive < Thor
|
19
|
+
prepend InteractiveSetup
|
20
|
+
|
21
|
+
attr_accessor *%i[server current_user]
|
22
|
+
|
23
|
+
no_commands do
|
24
|
+
# Checks whether a given input string is a valid command
|
25
|
+
def self.command? msg
|
26
|
+
cmds, opts = parse_input(msg)
|
27
|
+
parsed_args = new(cmds, opts).args
|
28
|
+
commands.key?(parsed_args.first) || parsed_args.first == 'help'
|
29
|
+
end
|
30
|
+
|
31
|
+
# Parses a client's input into a format suitable for Thor commands
|
32
|
+
#
|
33
|
+
# @param [String] msg - the client's message
|
34
|
+
def self.parse_input msg
|
35
|
+
# Split user input at the first "option"
|
36
|
+
cmds, opts = msg&.split /-|--/, 2
|
37
|
+
|
38
|
+
# Then split each by whitespace
|
39
|
+
cmds = cmds&.split(/\s+/)
|
40
|
+
opts = opts&.split(/\s+/)
|
41
|
+
|
42
|
+
# `Whatup::CLI::Interactive.new(cmds, opts)` expects arrays, and
|
43
|
+
# a final options hash
|
44
|
+
cmds = [] if cmds.nil?
|
45
|
+
opts = [] if opts.nil?
|
46
|
+
|
47
|
+
[cmds, opts]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Don't show app name in command help, i.e, instead of
|
52
|
+
# `app command desc`, use `command desc`
|
53
|
+
def self.banner task, _namespace = false, subcommand = false
|
54
|
+
task.formatted_usage(self, false, subcommand).to_s
|
55
|
+
end
|
56
|
+
|
57
|
+
desc 'list', 'Show all connected clients'
|
58
|
+
def list
|
59
|
+
say 'All connected clients:'
|
60
|
+
@server.clients.each { |c| say c.status }
|
61
|
+
end
|
62
|
+
|
63
|
+
desc 'room [NAME]', 'Create and enter chatroom [NAME]'
|
64
|
+
def room name
|
65
|
+
if room = @server.rooms.select { |r| r.name == name }&.first
|
66
|
+
@current_user.puts <<~MSG
|
67
|
+
Entering #{room.name}... enjoy your stay!
|
68
|
+
|
69
|
+
Type `.exit` to exit this chat room.
|
70
|
+
|
71
|
+
Currently in this room:
|
72
|
+
#{room.clients.map do |client|
|
73
|
+
"- #{client.name}\n"
|
74
|
+
end.join}
|
75
|
+
MSG
|
76
|
+
@current_user.room = room
|
77
|
+
|
78
|
+
room.broadcast except: @current_user do
|
79
|
+
<<~MSG
|
80
|
+
#{@current_user.name} has arrived! Play nice, kids.
|
81
|
+
MSG
|
82
|
+
end
|
83
|
+
|
84
|
+
room.clients << @current_user
|
85
|
+
return
|
86
|
+
end
|
87
|
+
|
88
|
+
room = @server.new_room! name: name, clients: [@current_user]
|
89
|
+
|
90
|
+
@current_user.puts <<~MSG
|
91
|
+
Created and entered #{room.name}... invite some people or something!
|
92
|
+
|
93
|
+
Type `.exit` to exit this chat room.
|
94
|
+
MSG
|
95
|
+
end
|
96
|
+
|
97
|
+
# desc 'dm [NAME]', 'Send a direct message to [NAME]'
|
98
|
+
# def dm name
|
99
|
+
# client = @server.find_client_by name: name
|
100
|
+
|
101
|
+
# if client.nil?
|
102
|
+
# @current_user.puts "No client named `#{name}` found!"
|
103
|
+
# return
|
104
|
+
# end
|
105
|
+
|
106
|
+
# client.send_message
|
107
|
+
# end
|
108
|
+
|
109
|
+
desc 'exit', 'Closes your connection with the server'
|
110
|
+
def exit
|
111
|
+
@current_user.exit!
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Whatup
|
4
|
+
module CLI
|
5
|
+
# Implements a `before` hook to set the correct instance variables
|
6
|
+
# before any command methods.
|
7
|
+
#
|
8
|
+
# This is needed, since Thor creates another cli class instance when it is
|
9
|
+
# called with `invoke`, and we need to reassign any variables to the new
|
10
|
+
# cli instance.
|
11
|
+
#
|
12
|
+
# TODO: grab commands dynamically
|
13
|
+
module InteractiveSetup
|
14
|
+
Whatup::CLI::COMMANDS.each do |cmd|
|
15
|
+
define_method cmd do |*args|
|
16
|
+
cli = instance_variable_get(:@_initializer).last[:shell].base
|
17
|
+
@server = cli.server
|
18
|
+
@current_user = cli.current_user
|
19
|
+
super *args
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/whatup/client/client.rb
CHANGED
@@ -20,6 +20,7 @@ module Whatup
|
|
20
20
|
|
21
21
|
@socket = TCPSocket.open @dest[:ip], @dest[:port]
|
22
22
|
|
23
|
+
puts 'Please enter your username to establish a connection...'
|
23
24
|
@request = request!
|
24
25
|
@response = listen!
|
25
26
|
|
@@ -29,12 +30,13 @@ module Whatup
|
|
29
30
|
exit
|
30
31
|
end
|
31
32
|
|
33
|
+
private
|
34
|
+
|
35
|
+
# Loop and send all input to the server
|
32
36
|
def request!
|
33
|
-
puts 'Please enter your username to establish a connection...'
|
34
37
|
Thread.new do
|
35
38
|
loop do
|
36
|
-
|
37
|
-
input = $stdin.gets&.chomp
|
39
|
+
input = Readline.readline '~> ', true
|
38
40
|
exit if input.nil?
|
39
41
|
@socket.puts input
|
40
42
|
end
|
@@ -44,11 +46,15 @@ module Whatup
|
|
44
46
|
@socket.close
|
45
47
|
end
|
46
48
|
|
49
|
+
# Continually listen to the server, and print anything received
|
47
50
|
def listen!
|
48
51
|
Thread.new do
|
49
52
|
loop do
|
50
53
|
response = @socket.gets&.chomp
|
51
|
-
|
54
|
+
|
55
|
+
exit if response == 'END'
|
56
|
+
|
57
|
+
puts response # unless response.nil?
|
52
58
|
end
|
53
59
|
end
|
54
60
|
rescue IOError => e
|
data/lib/whatup/server/client.rb
CHANGED
@@ -4,20 +4,52 @@ module Whatup
|
|
4
4
|
module Server
|
5
5
|
class Client
|
6
6
|
attr_reader :id, :name
|
7
|
-
attr_accessor
|
7
|
+
attr_accessor *%i[socket room]
|
8
8
|
|
9
9
|
def initialize id:, name:, socket:
|
10
10
|
@id = id
|
11
11
|
@name = name
|
12
12
|
@socket = socket
|
13
|
+
@room = nil
|
13
14
|
end
|
14
15
|
|
15
16
|
def puts msg
|
16
|
-
|
17
|
+
socket.puts msg
|
17
18
|
end
|
18
19
|
|
19
20
|
def gets
|
20
|
-
|
21
|
+
socket.gets
|
22
|
+
end
|
23
|
+
|
24
|
+
def input!
|
25
|
+
loop while (msg = gets).blank?
|
26
|
+
msg.chomp
|
27
|
+
end
|
28
|
+
|
29
|
+
def room?
|
30
|
+
!room.nil?
|
31
|
+
end
|
32
|
+
alias chatting? room?
|
33
|
+
|
34
|
+
def status
|
35
|
+
"#{name}" \
|
36
|
+
"#{chatting? ? " (#{@room.name})" : ''}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def broadcast msg
|
40
|
+
@room.clients.reject { |c| c == self }
|
41
|
+
.each { |c| c.puts "#{name}> #{msg}" }
|
42
|
+
end
|
43
|
+
|
44
|
+
def leave_room!
|
45
|
+
broadcast 'LEFT'
|
46
|
+
room.drop_client! self
|
47
|
+
@room = nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def exit!
|
51
|
+
puts "END\n"
|
52
|
+
Thread.kill Thread.current
|
21
53
|
end
|
22
54
|
end
|
23
55
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Whatup
|
4
|
+
module Server
|
5
|
+
class Room
|
6
|
+
attr_accessor *%i[name clients]
|
7
|
+
|
8
|
+
def initialize name:, clients:
|
9
|
+
@name = name
|
10
|
+
@clients = clients
|
11
|
+
|
12
|
+
@clients.each { |c| c.room = self }
|
13
|
+
end
|
14
|
+
|
15
|
+
def drop_client! client
|
16
|
+
@clients = @clients.reject { |c| c == client }
|
17
|
+
end
|
18
|
+
|
19
|
+
def broadcast except: nil
|
20
|
+
clients = except \
|
21
|
+
? @clients.reject { |c| c == except }
|
22
|
+
: @clients
|
23
|
+
|
24
|
+
clients.each { |c| c.puts yield }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/whatup/server/server.rb
CHANGED
@@ -2,8 +2,13 @@
|
|
2
2
|
|
3
3
|
require 'socket'
|
4
4
|
require 'fileutils'
|
5
|
+
require 'securerandom'
|
6
|
+
|
7
|
+
require 'active_support/core_ext/object/blank'
|
5
8
|
|
6
9
|
require 'whatup/server/client'
|
10
|
+
require 'whatup/server/room'
|
11
|
+
require 'whatup/cli/commands/interactive/interactive'
|
7
12
|
|
8
13
|
module Whatup
|
9
14
|
module Server
|
@@ -12,18 +17,26 @@ module Whatup
|
|
12
17
|
|
13
18
|
Client = Whatup::Server::Client
|
14
19
|
|
20
|
+
# Used by the interactive client cli
|
21
|
+
attr_reader *%i[ip port address clients max_id pid pid_file rooms]
|
22
|
+
|
15
23
|
def initialize port:
|
16
24
|
@ip = 'localhost'
|
17
25
|
@port = port
|
18
26
|
@address = "#{@ip}:#{@port}"
|
19
27
|
|
20
28
|
@clients = []
|
29
|
+
@rooms = []
|
21
30
|
@max_id = 1
|
22
31
|
|
23
32
|
@pid = Process.pid
|
24
33
|
@pid_file = "#{Dir.home}/.whatup.pid"
|
25
34
|
end
|
26
35
|
|
36
|
+
# Starts the server.
|
37
|
+
#
|
38
|
+
# The server continuously loops, and handle each new client in a separate
|
39
|
+
# thread.
|
27
40
|
def start
|
28
41
|
say "Starting a server with PID:#{@pid} @ #{@address} ... \n", :green
|
29
42
|
|
@@ -33,34 +46,136 @@ module Whatup
|
|
33
46
|
|
34
47
|
# Listen for connections, then accept each in a separate thread
|
35
48
|
loop do
|
36
|
-
Thread.new
|
37
|
-
handle_client client
|
49
|
+
Thread.new(@socket.accept) do |client|
|
50
|
+
case handle_client client
|
51
|
+
when :exit
|
52
|
+
client.puts 'bye!'
|
53
|
+
Thread.kill Thread.current
|
54
|
+
end
|
38
55
|
end
|
39
56
|
end
|
40
|
-
rescue SignalException
|
57
|
+
rescue SignalException # In case of ^c
|
41
58
|
kill
|
42
59
|
end
|
43
60
|
|
61
|
+
def find_client_by name:
|
62
|
+
@clients.select { |c| c.name == name }&.first
|
63
|
+
end
|
64
|
+
|
65
|
+
def new_room! clients: [], name:
|
66
|
+
room = Room.new name: name, clients: clients
|
67
|
+
@rooms << room
|
68
|
+
room
|
69
|
+
end
|
70
|
+
|
44
71
|
private
|
45
72
|
|
73
|
+
# Receives a new client, then continuously gets input from that client
|
74
|
+
#
|
75
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
46
76
|
def handle_client client
|
77
|
+
client = create_new_client_if_not_existing! client
|
78
|
+
|
79
|
+
# Loop forever to maintain the connection
|
80
|
+
loop do
|
81
|
+
handle_chatting(client) if client.chatting?
|
82
|
+
|
83
|
+
# Wait until we get a valid command. This takes as long as the client
|
84
|
+
# takes.
|
85
|
+
msg = client.input! unless Whatup::CLI::Interactive.command?(msg)
|
86
|
+
|
87
|
+
puts "#{client.name}> #{msg}"
|
88
|
+
|
89
|
+
# Initialize a new cli class using the initial command and options,
|
90
|
+
# and then set any instance variables, since Thor will create a new
|
91
|
+
# class instance when it's invoked.
|
92
|
+
cmds, opts = Whatup::CLI::Interactive.parse_input msg
|
93
|
+
cli = Whatup::CLI::Interactive.new(cmds, opts).tap do |c|
|
94
|
+
c.server = self
|
95
|
+
c.current_user = client
|
96
|
+
end
|
97
|
+
|
98
|
+
begin
|
99
|
+
# Send the output to the client
|
100
|
+
redirect stdin: client.socket, stdout: client.socket do
|
101
|
+
# Invoke the cli using the provided commands and options.
|
102
|
+
|
103
|
+
# This _should_ achieve the same effect as
|
104
|
+
# `Whatup::CLI::Interactive.start(args)`, but allows us to set
|
105
|
+
# instance variables on the cli class.
|
106
|
+
cli.invoke cli.args.first, cli.args[1..cli.args.size - 1]
|
107
|
+
end
|
108
|
+
rescue RuntimeError,
|
109
|
+
Thor::InvocationError,
|
110
|
+
Thor::UndefinedCommandError => e
|
111
|
+
puts e.message
|
112
|
+
client.puts 'Invalid input or unknown command'
|
113
|
+
rescue ArgumentError => e
|
114
|
+
puts e.message
|
115
|
+
client.puts e.message
|
116
|
+
end
|
117
|
+
msg = nil # rubocop:disable Lint/UselessAssignment
|
118
|
+
end
|
119
|
+
end
|
120
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
121
|
+
|
122
|
+
def handle_chatting client
|
123
|
+
loop do
|
124
|
+
input = client.input!
|
125
|
+
room = client.room
|
126
|
+
puts "#{client.name}> #{input}"
|
127
|
+
if input == '.exit'
|
128
|
+
client.leave_room!
|
129
|
+
break
|
130
|
+
end
|
131
|
+
room.broadcast except: client do
|
132
|
+
"#{client.name}> #{input}"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Receives a username from a client, then creates a new client unless a
|
138
|
+
# client with that username already exists.
|
139
|
+
#
|
140
|
+
# If no username is provided (i.e, blank), it assigns a random, anonymous
|
141
|
+
# username in the format `ANON-xxx`, where `xxx` is a random number upto
|
142
|
+
# 100, left-padded with zeros.
|
143
|
+
def create_new_client_if_not_existing! client
|
144
|
+
name = client.gets.chomp
|
145
|
+
rand_num = SecureRandom.random_number(100).to_s.rjust 3, '0'
|
146
|
+
name = name == '' ? "ANON-#{rand_num}" : name
|
147
|
+
|
148
|
+
if @clients.any? { |c| c.name == name }
|
149
|
+
client.puts 'That name is taken! Goodbye.'
|
150
|
+
client.exit!
|
151
|
+
end
|
152
|
+
|
47
153
|
@clients << client = Client.new(
|
48
|
-
id:
|
49
|
-
name:
|
154
|
+
id: new_client_id,
|
155
|
+
name: name,
|
50
156
|
socket: client
|
51
157
|
)
|
52
158
|
|
53
159
|
puts "#{client.name} just showed up!"
|
54
160
|
client.puts "Hello, #{client.name}!"
|
161
|
+
client
|
162
|
+
end
|
55
163
|
|
56
|
-
|
57
|
-
|
58
|
-
|
164
|
+
# @return A new, unique client identification number
|
165
|
+
def new_client_id
|
166
|
+
@max_id += 1
|
167
|
+
end
|
59
168
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
169
|
+
# Reroutes stdin and stdout inside a block
|
170
|
+
def redirect stdin: $stdin, stdout: $stdout
|
171
|
+
original_stdin = $stdin
|
172
|
+
original_stdout = $stdout
|
173
|
+
$stdin = stdin
|
174
|
+
$stdout = stdout
|
175
|
+
yield
|
176
|
+
ensure
|
177
|
+
$stdin = original_stdin
|
178
|
+
$stdout = original_stdout
|
64
179
|
end
|
65
180
|
|
66
181
|
def exit_if_pid_exists!
|
@@ -92,6 +207,7 @@ module Whatup
|
|
92
207
|
def kill
|
93
208
|
say "Killing the server with PID:#{Process.pid} ...", :red
|
94
209
|
FileUtils.rm_rf @pid_file
|
210
|
+
exit
|
95
211
|
end
|
96
212
|
end
|
97
213
|
end
|
data/lib/whatup/version.rb
CHANGED
data/whatup.gemspec
CHANGED
@@ -56,7 +56,9 @@ Gem::Specification.new do |spec|
|
|
56
56
|
'rake' => '~> 12.3.2',
|
57
57
|
'rspec' => '~> 3.8',
|
58
58
|
'yard' => '~> 0.9.18',
|
59
|
-
'rubocop' => '~> 0.65.0'
|
59
|
+
'rubocop' => '~> 0.65.0',
|
60
|
+
'aruba' => '~> 0.14.9',
|
61
|
+
'activesupport' => '~> 5.2'
|
60
62
|
}.each do |gem, version|
|
61
63
|
spec.add_development_dependency gem, version
|
62
64
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: whatup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Delk
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|
@@ -108,6 +108,34 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: 0.65.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: aruba
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.14.9
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.14.9
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: activesupport
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '5.2'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '5.2'
|
111
139
|
- !ruby/object:Gem::Dependency
|
112
140
|
name: thor
|
113
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -151,15 +179,19 @@ files:
|
|
151
179
|
- bin/console
|
152
180
|
- bin/setup
|
153
181
|
- docs/hw/assignment.pdf
|
182
|
+
- docs/hw/framework.pdf
|
154
183
|
- docs/hw/inital_design.md
|
155
184
|
- docs/installing_ruby.md
|
156
185
|
- exe/whatup
|
157
186
|
- lib/whatup.rb
|
158
187
|
- lib/whatup/cli/cli.rb
|
159
188
|
- lib/whatup/cli/commands/client.rb
|
189
|
+
- lib/whatup/cli/commands/interactive/interactive.rb
|
190
|
+
- lib/whatup/cli/commands/interactive/setup.rb
|
160
191
|
- lib/whatup/cli/commands/server.rb
|
161
192
|
- lib/whatup/client/client.rb
|
162
193
|
- lib/whatup/server/client.rb
|
194
|
+
- lib/whatup/server/room.rb
|
163
195
|
- lib/whatup/server/server.rb
|
164
196
|
- lib/whatup/version.rb
|
165
197
|
- whatup.gemspec
|