toycol 0.2.2 → 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: 102026f42040d677807fb5fe1cd08797f564951096c15ac2c0150a757cc82926
4
- data.tar.gz: d7b4312381d610821b197f688c871acbe26a6d70146c67441d23cbd52a0ed697
3
+ metadata.gz: a9cd0de8dd5ec5a48e22a49c8198492a96162c9ff922a07c897e3af7cdfe779a
4
+ data.tar.gz: 938b7f68fef82731d61c1937c2ed53753c1bbb301c49434cc6d538edb6f862f9
5
5
  SHA512:
6
- metadata.gz: 11eb3611d926c804f1f0d632f40daf2a37b7f663bdb449c69c2353d608dba87161723f4380d5dedfa78a46f1d264dde625b9bdd30ba6dda6e64eed12964f83cf
7
- data.tar.gz: 9c38815ef3861ad35ac635f713fb2f6b459ee6cbc64cbe9da56ec355381a5f21c30189e28ebe92f961406b99d9349631b52571729fd8c290d94cd61c0eefd4ea
6
+ metadata.gz: 53e62c64e3f418da9e0f7068482531bab41466e6d73d560e8bf74ae900cf2587a61d810365eea15f01f194592c70b563320ffe93f170810e4fa6f443f3a73837
7
+ data.tar.gz: 112910c06cdb28e5f8690fd18373a2d418a466b075cc0ff793816aed2475acb1ccf5657ae8cfb7b3c321cefc1bde44e5a34fd9b9024f3c20d14047938adf6121
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+ title: "[FEATURE]"
5
+ labels: enhancement
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ ## Is your feature request related to a problem? Please describe.
11
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12
+
13
+ ## Describe the solution you'd like
14
+ A clear and concise description of what you want to happen.
15
+
16
+ ## Describe alternatives you've considered
17
+ A clear and concise description of any alternative solutions or features you've considered.
18
+
19
+ ## Additional context
20
+ Add any other context or screenshots about the feature request here.
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "toycol", path: "../../"
@@ -0,0 +1,13 @@
1
+ Toycol::Protocol.define do
2
+ request.path do |message|
3
+ %r{(?<path>\/\w*)}.match(message)[:path]
4
+ end
5
+
6
+ request.query do |message|
7
+ %r{\?(?<query>.+)}.match(message) { |m| m[:query] }
8
+ end
9
+
10
+ request.http_method do |message|
11
+ "GET"
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rack"
4
+ require "toycol"
5
+
6
+ Toycol::Protocol.use
7
+
8
+ class App
9
+ def call(env)
10
+ case env["REQUEST_METHOD"]
11
+ when "GET"
12
+ [
13
+ 200,
14
+ { "Content-Type" => "text/html" },
15
+ ["This app has no protocol name\n"]
16
+ ]
17
+ end
18
+ end
19
+ end
20
+
21
+ run App.new
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  Toycol::Protocol.define(:duck) do
4
2
  custom_status_codes(
5
3
  600 => "I'm afraid you are not a duck..."
@@ -7,11 +5,11 @@ Toycol::Protocol.define(:duck) do
7
5
  additional_request_methods "OTHER"
8
6
 
9
7
  request.path do |message|
10
- %r{(?<path>/\w*)}.match(message)[:path]
8
+ %r{(?<path>\/\w*)}.match(message)[:path]
11
9
  end
12
10
 
13
11
  request.query do |message|
14
- /\?(?<query>.+)/.match(message) { |m| m[:query] }
12
+ %r{\<3(?<query>.+)}.match(message) { |m| m[:query] }
15
13
  end
16
14
 
17
15
  request.http_method do |message|
@@ -2,26 +2,29 @@
2
2
 
3
3
  require "optparse"
4
4
  require_relative "./client"
5
+ require_relative "./template_generator"
5
6
 
6
7
  module Toycol
7
8
  class Command
8
9
  class Options
10
+ @options = {}
11
+
9
12
  class << self
10
13
  def parse!(argv)
11
- options = {}
12
14
  option_parser = create_option_parser
13
15
  sub_command_option_parser = create_sub_command_option_parser
14
16
 
15
17
  begin
16
18
  option_parser.order!(argv)
17
- options[:command] = argv.shift
18
- options[:request_message] = argv.shift if %w[client c].include?(options[:command]) && argv.first != "-h"
19
- sub_command_option_parser[options[:command]].parse!(argv)
19
+ @options[:command] = argv.shift
20
+ @options[:request_message] = argv.shift if request_message?(argv.first)
21
+ @options[:protocol_name] = argv.shift if protocol_name?(argv.first)
22
+ sub_command_option_parser[@options[:command]].parse!(argv)
20
23
  rescue OptionParser::MissingArgument, OptionParser::InvalidOption, ArgumentError => e
21
24
  abort e.message
22
25
  end
23
26
 
24
- options
27
+ @options
25
28
  end
26
29
 
27
30
  def create_option_parser
@@ -45,19 +48,34 @@ module Toycol
45
48
 
46
49
  def create_sub_command_option_parser
47
50
  sub_command_parser = Hash.new { |_k, v| raise ArgumentError, "'#{v}' is not sub command" }
48
- sub_command_parser["client"] = client_option_parser
49
- sub_command_parser["c"] = client_option_parser
50
- sub_command_parser["server"] = server_option_parser
51
- sub_command_parser["s"] = server_option_parser
51
+ sub_command_parser["client"] = client_option_parser
52
+ sub_command_parser["c"] = client_option_parser
53
+ sub_command_parser["server"] = server_option_parser
54
+ sub_command_parser["s"] = server_option_parser
55
+ sub_command_parser["generate"] = generator_option_parser
56
+ sub_command_parser["g"] = generator_option_parser
52
57
  sub_command_parser
53
58
  end
54
59
 
55
60
  private
56
61
 
62
+ def request_message?(arg)
63
+ %w[client c].include?(@options[:command]) \
64
+ && arg != "-p" \
65
+ && arg != "-h"
66
+ end
67
+
68
+ def protocol_name?(arg)
69
+ %w[geberate g].include?(@options[:command]) \
70
+ && arg != "-t" \
71
+ && arg != "-h"
72
+ end
73
+
57
74
  def sub_command_summaries
58
75
  [
59
76
  { name: "client REQUEST_MESSAGE -p PORT", summary: "Send request message to server" },
60
- { name: "server -u SERVER_NAME", summary: "Start proxy and background server" }
77
+ { name: "server -u SERVER_NAME", summary: "Start proxy and background server" },
78
+ { name: "generate NAME -t TYPE", summary: "Generate new protocol or Rack app" }
61
79
  ]
62
80
  end
63
81
 
@@ -89,16 +107,14 @@ module Toycol
89
107
  end
90
108
  end
91
109
 
92
- def client_command_help_messages
93
- [
94
- { name: "client -p=PORT_NUMBER", summary: "Send request to server" }
95
- ]
96
- end
110
+ def generator_option_parser
111
+ OptionParser.new do |opt|
112
+ opt.on("-t TYPE", "--type TYPE", "generate TYPE of template (default: :all)") do |type|
113
+ @options[:template_type] = type
114
+ end
97
115
 
98
- def server_command_help_messages
99
- [
100
- { name: "server -u=SERVER_NAME", summary: "Start proxy & background server" }
101
- ]
116
+ opt.on_head("-h", "--help", "Show this message") { help_command(opt) }
117
+ end
102
118
  end
103
119
 
104
120
  def help_command(parser)
@@ -126,6 +142,9 @@ module Toycol
126
142
  when "server", "s"
127
143
  ARGV.push("-q", "-s", "toycol")
128
144
  Rack::Server.start
145
+ when "generate", "g"
146
+ type = options[:template_type] || "all"
147
+ ::Toycol::TemplateGenerator.generate!(type: type, name: options[:protocol_name])
129
148
  end
130
149
  end
131
150
  end
@@ -17,7 +17,7 @@ module Toycol
17
17
  end
18
18
 
19
19
  # For application which use the protocol
20
- def use(protocol_name)
20
+ def use(protocol_name = nil)
21
21
  @protocol_name = protocol_name
22
22
  end
23
23
 
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Toycol
4
+ class TemplateGenerator
5
+ class << self
6
+ def generate!(type:, name:)
7
+ raise StandardError, "Unknown Type: This type of template can't be generated" unless valid? type
8
+
9
+ if type == "all"
10
+ new(name, "protocol").generate!
11
+ new(name, "app").generate!
12
+ else
13
+ new(name, type).generate!
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def valid?(type)
20
+ %w[all app protocol].include? type
21
+ end
22
+ end
23
+
24
+ def initialize(name, type)
25
+ @name = name
26
+ @type = type
27
+ end
28
+
29
+ def generate!
30
+ raise StandardError, "#{filename} already exists" unless Dir.glob(filename).empty?
31
+
32
+ File.open(filename, "w") { |f| f.print template_text_for_new }
33
+ puts "Generate #{filename} in #{FileUtils.pwd}"
34
+ end
35
+
36
+ private
37
+
38
+ def filename
39
+ @filename ||= case @type
40
+ when "protocol" then "Protocolfile#{@name ? ".#{@name}" : nil}"
41
+ when "app" then "config#{@name ? "_#{@name}" : nil}.ru"
42
+ end
43
+ end
44
+
45
+ def template_text_for_new
46
+ if @name
47
+ template_text.sub(":PROTOCOL_NAME", ":#{@name}")
48
+ else
49
+ template_text.sub("\(:PROTOCOL_NAME\)", "")
50
+ end
51
+ end
52
+
53
+ def template_text
54
+ case @type
55
+ when "protocol" then File.open("lib/toycol/templates/protocol.txt", "r", &:read)
56
+ when "app" then File.open("lib/toycol/templates/application.txt", "r", &:read)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,22 @@
1
+ require "rack"
2
+ require "toycol"
3
+
4
+ # Specify which protocol to use
5
+ Toycol::Protocol.use(:PROTOCOL_NAME)
6
+
7
+ class App
8
+ def call(env)
9
+ # Define your app on request method, request path, request query etc
10
+ # For example:
11
+ # case env['REQUEST_METHOD']
12
+ # when 'GET'
13
+ # [
14
+ # 200,
15
+ # { 'Content-Type' => 'text/html' },
16
+ # ["Hello, This app is running by :#{name} protocol."]
17
+ # ]
18
+ # end
19
+ end
20
+ end
21
+
22
+ run App.new
@@ -0,0 +1,39 @@
1
+ Toycol::Protocol.define(:PROTOCOL_NAME) do
2
+ # For example
3
+ # client would send:
4
+ # quack, quack /posts<3user_id=1
5
+ # server would interpret client message:
6
+ # GET /posts?user_id=1
7
+
8
+
9
+ # [OPTIONAL] You can define your additional request methods:
10
+ # For example:
11
+ # additional_request_methods OTHER
12
+
13
+ # [OPTIONAL] You can define your own response status code:
14
+ # For example:
15
+ # define_status_codes(
16
+ # 600 => "I'm afraid you are not a duck..."
17
+ # )
18
+
19
+ # [REQUIRED] Define how you parse request path from request message
20
+ request.path do |message|
21
+ # For example:
22
+ # %r{(?<path>\/\w*)}.match(message)[:path]
23
+ end
24
+
25
+ # [REQUIRED] Define how you parse query from request message
26
+ request.query do |message|
27
+ # For example:
28
+ # %r{\<3(?<query>.+)}.match(message) { |m| m[:query] }
29
+ end
30
+
31
+ # [REQUIRED] Define how you parse query from request message
32
+ request.http_method do |message|
33
+ # For example:
34
+ # case message.scan(/quack/).size
35
+ # when 2 then "GET"
36
+ # else "OTHER"
37
+ # end
38
+ end
39
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Toycol
4
- VERSION = "0.2.2"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: toycol
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Misaki Shioi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-07-24 00:00:00.000000000 Z
11
+ date: 2021-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -33,6 +33,7 @@ extensions: []
33
33
  extra_rdoc_files: []
34
34
  files:
35
35
  - ".github/ISSUE_TEMPLATE/bug_report.md"
36
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
36
37
  - ".github/dependabot.yml"
37
38
  - ".github/workflows/main.yml"
38
39
  - ".gitignore"
@@ -45,6 +46,9 @@ files:
45
46
  - Rakefile
46
47
  - bin/console
47
48
  - bin/setup
49
+ - examples/anonymous/Gemfile
50
+ - examples/anonymous/Protocolfile
51
+ - examples/anonymous/config.ru
48
52
  - examples/duck/Gemfile
49
53
  - examples/duck/Protocolfile.duck
50
54
  - examples/duck/config_duck.ru
@@ -72,6 +76,9 @@ files:
72
76
  - lib/toycol/protocol.rb
73
77
  - lib/toycol/proxy.rb
74
78
  - lib/toycol/server.rb
79
+ - lib/toycol/template_generator.rb
80
+ - lib/toycol/templates/application.txt
81
+ - lib/toycol/templates/protocol.txt
75
82
  - lib/toycol/version.rb
76
83
  - toycol.gemspec
77
84
  homepage: https://github.com/shioimm/toycol