atd 0.0.0.TEST.GITLAB1 → 0.1.0.TEST.GITLAB1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +5 -0
- data/CHANGELOG +8 -0
- data/LICENSE +21 -0
- data/README.md +129 -13
- data/atd.gemspec +1 -0
- data/lib/atd/builtin_class_modifications.rb +6 -0
- data/lib/atd/routes.rb +41 -20
- data/lib/atd/version.rb +1 -1
- data/lib/atd.rb +60 -25
- data/lib/extensions/precompilers.rb +9 -0
- metadata +19 -4
- data/.travis.yml +0 -5
- data/lib/atd/middleware.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7632cff0dea940480d94ff9edf270c40cb867d84
|
4
|
+
data.tar.gz: 51bb58c9651e635c8ed24d15a5f1ae1f7af3915f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b47eb2b7b87ba4fa7b62f73a32da06c2e239b0aed06f63812fed6d3c94596a093a483be6b8594f236ef1d33059bcbf22916cf20e095d747b6a73f0b16feb3b82
|
7
|
+
data.tar.gz: 42c78f99c567e0b102b0b2138696a9de72291ac15295fd400ef49533535a73c7c1ceb69dffe332ae3dafc482235eb21695da1929ac90a84c960d2e641346a4bc
|
data/.gitlab-ci.yml
CHANGED
@@ -13,6 +13,7 @@ test:
|
|
13
13
|
pages:
|
14
14
|
only:
|
15
15
|
- master
|
16
|
+
- gitlab-pages-yard-coverage
|
16
17
|
script:
|
17
18
|
- gem install yard
|
18
19
|
- bundle exec yard
|
@@ -20,6 +21,10 @@ pages:
|
|
20
21
|
- mkdir public
|
21
22
|
- mv /builds/izwick-schachter/atd/coverage public/coverage
|
22
23
|
- mv /builds/izwick-schachter/atd/doc public/YARD
|
24
|
+
- mkdir public/YARD/coverage
|
25
|
+
- touch public/YARD/coverage/index.html
|
26
|
+
- yard stats --list-undoc >> public/YARD/coverage/index.html
|
27
|
+
- ruby -ne 'puts "<span>#{$_}</span><br>#{"<br>" if $_.delete("\n")[-1, 1] == ":"}"' -i public/YARD/coverage/index.html
|
23
28
|
- ls -R -a --ignore .git
|
24
29
|
artifacts:
|
25
30
|
paths:
|
data/CHANGELOG
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Isaiah Zwick-Schachter
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
[![build status][build status badge]][build status link] [![coverage report][coverage report badge]][coverage report link] [![gem version][gem version badge]][gem version link] [![documentation coverage][documentation coverage badge]][documentation coverage link]
|
2
|
+
|
3
|
+
[documentation coverage badge]: https://img.shields.io/badge/YARD%20coverage-77.50%-yellow.svg?style=flat-square
|
4
|
+
[documentation coverage link]: http://izwick-schachter.gitlab.io/atd/YARD/coverage
|
5
|
+
|
6
|
+
[build status badge]: https://gitlab.com/izwick-schachter/atd/badges/master/build.svg?style=flat-square
|
7
|
+
[build status link]: https://gitlab.com/izwick-schachter/atd/commits/master
|
8
|
+
|
9
|
+
[coverage report badge]: http://gitlab.com/izwick-schachter/atd/badges/master/coverage.svg?style=flat-square
|
10
|
+
[coverage report link]: http://izwick-schachter.gitlab.io/atd/coverage
|
11
|
+
|
12
|
+
[gem version badge]: https://img.shields.io/gem/v/atd.svg?style=flat-square
|
13
|
+
[gem version link]: https://rubygems.org/gems/atd
|
14
|
+
|
1
15
|
# ATD
|
2
16
|
|
3
17
|
ATD is a new web development backend framework for Ruby. It is built on top of rack, and is meant to be small easy and light. That is why it provides a very minimalist way of writing your backend. It treats a request as a request, without splitting it based on the HTTP method.
|
@@ -7,7 +21,13 @@ ATD is a new web development backend framework for Ruby. It is built on top of r
|
|
7
21
|
Add this line to your application's Gemfile:
|
8
22
|
|
9
23
|
```ruby
|
10
|
-
gem 'atd',
|
24
|
+
gem 'atd', :git => 'https://gitlab.com/izwick-schachter/atd.git'
|
25
|
+
```
|
26
|
+
|
27
|
+
Or, (not recommended) you can use only the rubygems version, which you can use with:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
gem 'atd'
|
11
31
|
```
|
12
32
|
|
13
33
|
And then execute:
|
@@ -30,34 +50,80 @@ Setup is as easy as `require "atd"` at the top of whatever file you need it in
|
|
30
50
|
|
31
51
|
#### Basic Routing
|
32
52
|
|
33
|
-
On the lowest level it can be used serve files or any strings when a path is requested (and optionally when a specific HTTP method is used). Here is a basic route that will serve `Hello World` when `/` is sent
|
53
|
+
On the lowest level it can be used serve files or any strings when a path is requested (and optionally when a specific HTTP method is used). Here is a basic route that will serve `Hello World` when `/` is sent any HTTP request (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`):
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
request "/", "Hello World"
|
57
|
+
```
|
58
|
+
|
59
|
+
The `request` method is also aliased to `req` and `r` for better code readability if you prefer. Here are 3 equivalent routes:
|
34
60
|
|
35
61
|
```ruby
|
36
62
|
request "/", "Hello World"
|
63
|
+
req "/", "Hello World"
|
64
|
+
r "/", "Hello World"
|
65
|
+
```
|
66
|
+
|
67
|
+
For the purposes of this README, we will only use the `request` syntax, for improved readability, but anywhere in the code these are interchangeable, because they all return an `ATD::Route` object.
|
68
|
+
|
69
|
+
You could use the same basic routing syntax to return `Hello World` for a HTTP `GET` request to `/`:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
request.get "/", "Hello World"
|
73
|
+
```
|
74
|
+
|
75
|
+
Or you could use a simpler (but equivalent) syntax:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
get "/", "Hello World"
|
79
|
+
```
|
80
|
+
|
81
|
+
For the purposes of this README we will only use `request.get` and not `get` because we believe it adds clarity.
|
82
|
+
|
83
|
+
You can also have route respond to more than one HTTP verb with `get.post.put.patch`:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
request.get.post.put.patch "/", "Hello World"
|
37
87
|
```
|
38
88
|
|
39
|
-
|
89
|
+
This will respond to `GET`, `POST`, `PUT`, and `PATCH` with `Hello World`, but will repond to `DELETE` with a `404` status code.
|
90
|
+
|
91
|
+
The `get.post.put.patch` is not recommended for readability. Instead use the following syntax:
|
40
92
|
|
41
93
|
```ruby
|
42
|
-
|
94
|
+
request "/", "Hello World", respond_to: [:get, :post, :put, :patch]
|
43
95
|
```
|
44
96
|
|
45
|
-
|
97
|
+
Or, a simpler way would be with `:ignore`:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
request "/", "Hello World", ignore: :delete
|
101
|
+
```
|
46
102
|
|
47
103
|
#### Advanced Routing
|
48
104
|
|
49
105
|
You can also add blocks to the basic routing methods to execute code when they are reached, and customize the response to the incoming request. Here is an example that will return the HTTP method used to request `/`:
|
50
106
|
|
51
107
|
```ruby
|
52
|
-
|
108
|
+
request "/" do
|
53
109
|
@http[:output] = @http[:method]
|
54
110
|
end
|
55
111
|
```
|
56
112
|
|
57
|
-
This example uses the `@http` variable which is provided to the route when called.
|
113
|
+
This example uses the `@http` variable which is provided to the route when called. `@http[:method]` is the http verb used by the request, and `@http[:output]` is what the route will return. If you have already defined a return value, `@http[:output]` will already be set to it. For example:
|
58
114
|
|
59
115
|
```ruby
|
60
|
-
|
116
|
+
request "/", "The HTTP Verb is: " do
|
117
|
+
@http[:output] += @http[:method]
|
118
|
+
end
|
119
|
+
```
|
120
|
+
|
121
|
+
Will return `The HTTP Verb is: get/post/put/patch/delete`, depending on the http verb used in the request. It will also pre-parse a file. So if you have added an HTML file with `request "/", "file.html"`, `@http[:output]` will be set to the contents of that file.
|
122
|
+
|
123
|
+
You could also run some complex method created outside the route. This route is called in the same scope as any block you were to declare. Here is an example:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
request "/", "I'm computing a complex function" do
|
61
127
|
complex_function
|
62
128
|
end
|
63
129
|
```
|
@@ -74,21 +140,48 @@ The `@http` instance variable can be used to work with the http request the the
|
|
74
140
|
@http[:request] # The associated Rack::Request for the request.
|
75
141
|
```
|
76
142
|
|
143
|
+
While you can use `@http[:status_code]` to change the status code, you can also set a status code with `r "/", status_code: 200`. That status code must be >= 100, as per the Rack Specification.
|
144
|
+
|
77
145
|
### Apps
|
78
146
|
|
79
147
|
ATD also allows you to use different "apps". Each app is independent of the others and lives is a class with the same name as the app. A file can have any number of apps, each of which can have it's own settings, files, and routes. By default, adding routes to `main` will make them a part of the app `DefaultApp`, which will work fine if you only need one app.
|
80
148
|
|
81
149
|
#### App Creation
|
82
150
|
|
83
|
-
To create
|
151
|
+
To create an app you can use `ATD.new("AppName")`. It is important to note that *ATD.new is not a constructor, although I will refer to it as one*. It simply behaves like one because you can use it to "construct" a new app. The app creation process creates a new class which you can open anywhere in your app file, with the name you pass. The name must `#respond_to?(:to_sym)`, and must be a valid class name. You must call the constructor before you begin adding routes to the class, or open the class at all.
|
152
|
+
|
153
|
+
You can also use the more intuitive way to create an app, which would be by declaring a class which extends `ATD::App`, like so:
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
class MyAppClass < ATD::App
|
157
|
+
# All of my routes, code, etc.
|
158
|
+
end
|
159
|
+
```
|
160
|
+
|
161
|
+
#### Starting the App
|
162
|
+
|
163
|
+
There are two basic ways to start the app. You can start it by calling `AppName.new.start` or more simply `AppName.start` which will create an instance and call start on it, or you can use the more common syntax. For `DefaultApp` that would be:
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
request "/", "Hello World!"
|
167
|
+
start
|
168
|
+
```
|
169
|
+
|
170
|
+
And for `MyApp` that would be:
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
class MyApp
|
174
|
+
request "/", "Hello World!"
|
175
|
+
start
|
176
|
+
end
|
177
|
+
```
|
84
178
|
|
85
179
|
#### App Routing
|
86
180
|
|
87
181
|
To add routes to an app, you simply must call the standard routing method inside the app class. For example, to create and add routes to an app called `Name` I would use the following code:
|
88
182
|
|
89
183
|
```ruby
|
90
|
-
ATD
|
91
|
-
class Name
|
184
|
+
class Name < ATD::App
|
92
185
|
request "/", "Hello World"
|
93
186
|
end
|
94
187
|
```
|
@@ -97,9 +190,32 @@ end
|
|
97
190
|
|
98
191
|
Currently there is no specified logging interface. Just use `puts` or `p` to log to `STDOUT`.
|
99
192
|
|
100
|
-
###
|
193
|
+
### Compilation
|
194
|
+
|
195
|
+
`ATD` will take your views and compress them for you so that your information can be transmitted more quickly. There are two different types of compilation, precompilation which occurs when the server is started, and compilation, which will live compile your code. While there are a few compilers and precompilers which will come with `ATD` most are user defined. To define compiler and precompiler methods simply add them like so:
|
196
|
+
|
197
|
+
```ruby
|
198
|
+
module ATD::Compilation::Precomiler
|
199
|
+
def extension(file, *opts) # This will work with any file that has .extension
|
200
|
+
# File is the contents of the file being compiled
|
201
|
+
# Whatever you return is what the file will be compiled to
|
202
|
+
file
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
module ATD::Compilation::Compiler
|
207
|
+
# Same thing here
|
208
|
+
def extension(file, *opts) # This will work with any file that has .extension
|
209
|
+
file
|
210
|
+
end
|
211
|
+
end
|
212
|
+
```
|
213
|
+
|
214
|
+
The compilation works by going through the file extensions from last to first and running the compilations for each extension in that order. For example `file.html.erb` will first be compiled by the ERB compiler, then the output of the ERB compiler will be compiled by the HTML compiler.
|
215
|
+
|
216
|
+
## Documentation
|
101
217
|
|
102
|
-
|
218
|
+
You can find the YARD docs at http://izwick-schachter.gitlab.io/atd/YARD/.
|
103
219
|
|
104
220
|
## Development
|
105
221
|
|
data/atd.gemspec
CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.require_paths = ["lib"]
|
25
25
|
|
26
26
|
spec.add_runtime_dependency "rack", "~> 2.0"
|
27
|
+
spec.add_runtime_dependency "webrick", "~> 1.3"
|
27
28
|
|
28
29
|
spec.add_development_dependency "bundler", "~> 1.12"
|
29
30
|
spec.add_development_dependency "rake", "~> 10.0"
|
@@ -15,6 +15,12 @@ class Hash
|
|
15
15
|
end
|
16
16
|
merge(second.to_h, &merger)
|
17
17
|
end
|
18
|
+
|
19
|
+
def include_in_key?(search)
|
20
|
+
each do |key, val|
|
21
|
+
return val if key.is_a?(Array) && key.include?(search)
|
22
|
+
end
|
23
|
+
end
|
18
24
|
end
|
19
25
|
|
20
26
|
# This method only exists for the test suite, specifically {ATDTest#test_route_creation}.
|
data/lib/atd/routes.rb
CHANGED
@@ -1,41 +1,62 @@
|
|
1
1
|
|
2
2
|
module ATD
|
3
3
|
module Compilation
|
4
|
-
|
4
|
+
module Precompiler
|
5
|
+
extend self
|
6
|
+
def filetypes
|
7
|
+
instance_methods(true) - [:filetypes]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
module Compiler
|
11
|
+
extend self
|
12
|
+
def filetypes
|
13
|
+
instance_methods(true) - [:filetypes]
|
14
|
+
end
|
5
15
|
end
|
6
16
|
|
7
|
-
def self.
|
17
|
+
def self.compile(name, contents)
|
18
|
+
return contents if name.nil?
|
19
|
+
name = name.split(".")
|
20
|
+
extensions = name - [name.first]
|
21
|
+
extensions.each do |extension|
|
22
|
+
contents = Compiler.send(extension, contents) if Compiler.filetypes.include? extension.to_sym
|
23
|
+
end
|
24
|
+
contents
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.pre_parse(route)
|
8
28
|
output = route.output
|
9
29
|
name = output
|
10
30
|
return nil if output.nil?
|
11
31
|
if output.include?(".") || output.is_a?(File)
|
12
|
-
file =
|
13
|
-
file = File.read(output) if output.is_a? File
|
32
|
+
file = read_file(output)
|
14
33
|
return nil if file.nil?
|
15
|
-
|
16
|
-
|
17
|
-
name = output.shift
|
18
|
-
output.each do |extension|
|
19
|
-
file = Precompiler.send(extension, file)
|
20
|
-
end
|
21
|
-
end
|
34
|
+
name = (output.is_a?(File) ? File.basename(output) : output)
|
35
|
+
file = precompile(name, file)
|
22
36
|
route.output = file
|
23
37
|
end
|
24
38
|
name
|
25
39
|
end
|
26
40
|
|
27
|
-
|
28
|
-
|
41
|
+
class << self
|
42
|
+
private
|
29
43
|
|
30
|
-
def
|
31
|
-
|
44
|
+
def read_file(output)
|
45
|
+
return File.read(File.join("assets/#{output}")) if output.is_a?(String) && File.exist?("assets/#{output}")
|
46
|
+
return File.read(output) if output.is_a? File
|
32
47
|
end
|
33
|
-
end
|
34
48
|
|
35
|
-
|
36
|
-
|
49
|
+
def precompile(name, contents)
|
50
|
+
name = name.split(".")
|
51
|
+
extensions = name - [name.first]
|
52
|
+
extensions.each do |extension|
|
53
|
+
if Precompiler.filetypes.include? extension.to_sym
|
54
|
+
contents = Precompiler.send(extension, contents)
|
55
|
+
extensions -= [extension]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
contents
|
59
|
+
end
|
37
60
|
end
|
38
61
|
end
|
39
62
|
end
|
40
|
-
|
41
|
-
ATD::Middleware.register(ATD::Compilation)
|
data/lib/atd/version.rb
CHANGED
data/lib/atd.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
require_relative "atd/version"
|
2
2
|
require "rack"
|
3
|
+
require "webrick"
|
3
4
|
require_relative "atd/builtin_class_modifications"
|
4
|
-
require_relative "atd/middleware"
|
5
5
|
require_relative "atd/routes"
|
6
|
+
# Extension packs
|
7
|
+
require_relative "extensions/precompilers"
|
6
8
|
|
7
9
|
# The assistant technical director of your website. It does the dirty work so you can see the big picture.
|
8
10
|
module ATD
|
@@ -16,19 +18,17 @@ module ATD
|
|
16
18
|
end
|
17
19
|
|
18
20
|
# So called because each instance stores a route, and will be called if that route is reached.
|
19
|
-
# A route for the purposes of {ATD} is a parser that
|
21
|
+
# A route for the purposes of {ATD} is a parser that will be fed env in {ATD::App#call the rack app}.
|
20
22
|
class Route
|
21
23
|
attr_accessor :args, :method, :block, :path, :output, :app
|
22
24
|
|
23
|
-
# The first two arguments must me the path and the output.
|
25
|
+
# The first two arguments must me the path and the output.
|
24
26
|
def initialize(*args, &block)
|
25
27
|
args -= [nil]
|
26
|
-
args.reject!(
|
27
|
-
@
|
28
|
-
@path = args.shift
|
29
|
-
@output = args.shift
|
30
|
-
@args = args
|
28
|
+
args.reject! { |arg| arg.is_a?(File) ? false : arg.empty? } # File doesn't respond to empty
|
29
|
+
@method = (args.last.is_a?(Hash) && !args.last[:methods].nil? ? args.last[:methods] : [:get, :post, :put, :patch, :delete])
|
31
30
|
@app = :DefaultApp
|
31
|
+
parse_args(*args, &block)
|
32
32
|
end
|
33
33
|
|
34
34
|
# This works differently from a standard setter because is makes sure that a {Route} can belong to only one {App}.
|
@@ -66,13 +66,12 @@ module ATD
|
|
66
66
|
# Sets route to receive a delete request to path and execute the block provided (if one is provided)
|
67
67
|
|
68
68
|
[:get, :post, :put, :delete, :patch].each do |method|
|
69
|
-
define_method(method) do
|
70
|
-
@
|
71
|
-
@method
|
72
|
-
@
|
73
|
-
@
|
74
|
-
|
75
|
-
self
|
69
|
+
define_method(method) do |*args, &block|
|
70
|
+
@method = [method] if @method.length == 5
|
71
|
+
@method += [method]
|
72
|
+
@method += args.last[:methods] if args.last.is_a?(Hash) && !args.last[:methods].nil?
|
73
|
+
@method.uniq!
|
74
|
+
parse_args(*args, &block)
|
76
75
|
end
|
77
76
|
end
|
78
77
|
|
@@ -91,6 +90,17 @@ module ATD
|
|
91
90
|
}
|
92
91
|
routes
|
93
92
|
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
# This should also manage @message at some point
|
97
|
+
def parse_args(*args, &block)
|
98
|
+
@block = block
|
99
|
+
@path = args.shift if @path.nil?
|
100
|
+
@output = args.shift if @output.nil?
|
101
|
+
@args = Array(@args).concat(args) - [nil] unless args.nil?
|
102
|
+
self
|
103
|
+
end
|
94
104
|
end
|
95
105
|
|
96
106
|
# A template {App} that all Apps extend. When a new App is created with {ATD.new ATD.new} it extends this class.
|
@@ -108,6 +118,19 @@ module ATD
|
|
108
118
|
end
|
109
119
|
alias req request
|
110
120
|
alias r request
|
121
|
+
|
122
|
+
[:get, :post, :put, :patch, :delete].each do |i|
|
123
|
+
define_method(i) do |*args, &block|
|
124
|
+
request.send(i, *args, &block)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Starts the rack server
|
129
|
+
# @param [Class] server The server that you would like to use.
|
130
|
+
# @param [Fixnum] port The port you would like the server to run on.
|
131
|
+
def start(server = WEBrick, port = 3150)
|
132
|
+
Rack::Server.start(app: self.new, server: server, Port: port)
|
133
|
+
end
|
111
134
|
end
|
112
135
|
|
113
136
|
# Sets up the @routes instance variable from the {.routes} class instance variable.
|
@@ -129,15 +152,13 @@ module ATD
|
|
129
152
|
# }
|
130
153
|
# @param [Array] routes An array of instances of {ATD::Route}.
|
131
154
|
def initialize(routes = [])
|
132
|
-
Middleware.setup(ATD::Route)
|
133
|
-
routes.each do |route|
|
134
|
-
Middleware.run(route)
|
135
|
-
end
|
136
155
|
routes += self.class.routes
|
137
156
|
@routes = {}
|
138
157
|
routes.each do |route|
|
139
|
-
|
140
|
-
|
158
|
+
filename = ATD::Compilation.pre_parse(route)
|
159
|
+
route_hash = route.to_h
|
160
|
+
route_hash[route.path][route.method][:filename] = filename
|
161
|
+
@routes = @routes.to_h.deep_merge(route_hash)
|
141
162
|
end
|
142
163
|
end
|
143
164
|
|
@@ -154,6 +175,7 @@ module ATD
|
|
154
175
|
def call(env)
|
155
176
|
route = route(env)
|
156
177
|
return error(404) if route.nil?
|
178
|
+
route[:output] = ATD::Compilation.compile(route[:filename], route[:output])
|
157
179
|
return [route[:status_code].to_i, Hash(route[:headers]), Array(route[:output])] if route[:block].nil?
|
158
180
|
http output: route[:output], request: Rack::Request.new(env), method: env["REQUEST_METHOD"]
|
159
181
|
run_block(route[:block])
|
@@ -163,13 +185,12 @@ module ATD
|
|
163
185
|
|
164
186
|
def route(env)
|
165
187
|
return nil if @routes[env["PATH_INFO"]].nil?
|
166
|
-
return @routes[env["PATH_INFO"]][
|
167
|
-
@routes[env["PATH_INFO"]]
|
188
|
+
# return @routes[env["PATH_INFO"]][[]] unless @routes[env["PATH_INFO"]][[]].nil?
|
189
|
+
@routes[env["PATH_INFO"]].include_in_key?(env["REQUEST_METHOD"].downcase.to_sym)
|
168
190
|
end
|
169
191
|
|
170
192
|
def run_block(block)
|
171
193
|
block.call
|
172
|
-
Middleware.run(self)
|
173
194
|
[self.class.http[:status_code].to_i, Hash(self.class.http[:headers]), Array(self.class.http[:output])]
|
174
195
|
end
|
175
196
|
|
@@ -191,4 +212,18 @@ end
|
|
191
212
|
alias req request
|
192
213
|
alias r request
|
193
214
|
|
194
|
-
|
215
|
+
# Starts the rack server
|
216
|
+
# @param [Class] app The app you would like to start
|
217
|
+
# @param [Class] server The server that you would like to use.
|
218
|
+
# @param [Fixnum] port The port you would like the server to run on.
|
219
|
+
def start(app = DefaultApp, server = WEBrick, port = 3150)
|
220
|
+
Rack::Server.start(app: app.new, server: server, Port: port)
|
221
|
+
end
|
222
|
+
|
223
|
+
[:get, :post, :put, :patch, :delete].each do |i|
|
224
|
+
define_method(i) do |*args, &block|
|
225
|
+
request.send(i, *args, &block)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
Object.const_set(:DefaultApp, Class.new(ATD::App)) # Create DefaultApp
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: atd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.0.TEST.GITLAB1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ACecretMaster
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: webrick
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,9 +160,10 @@ files:
|
|
146
160
|
- ".gitignore"
|
147
161
|
- ".gitlab-ci.yml"
|
148
162
|
- ".rubocop.yml"
|
149
|
-
-
|
163
|
+
- CHANGELOG
|
150
164
|
- CODE_OF_CONDUCT.md
|
151
165
|
- Gemfile
|
166
|
+
- LICENSE
|
152
167
|
- README.md
|
153
168
|
- Rakefile
|
154
169
|
- atd.gemspec
|
@@ -156,9 +171,9 @@ files:
|
|
156
171
|
- bin/setup
|
157
172
|
- lib/atd.rb
|
158
173
|
- lib/atd/builtin_class_modifications.rb
|
159
|
-
- lib/atd/middleware.rb
|
160
174
|
- lib/atd/routes.rb
|
161
175
|
- lib/atd/version.rb
|
176
|
+
- lib/extensions/precompilers.rb
|
162
177
|
homepage: https://rubygems.org/gems/atd
|
163
178
|
licenses:
|
164
179
|
- MIT
|
data/.travis.yml
DELETED
data/lib/atd/middleware.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
# All middleware must respond_to?("setup")
|
2
|
-
# To register middleware, after the class call ATD::Middleware.register(Your::Middleware)
|
3
|
-
module ATD
|
4
|
-
module Middleware
|
5
|
-
@middleware = {}
|
6
|
-
@sources = []
|
7
|
-
|
8
|
-
def self.register(source)
|
9
|
-
@sources.push source
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.run(target = nil)
|
13
|
-
return nil if @middleware[target.class].nil?
|
14
|
-
@middleware[target.class].each do |action|
|
15
|
-
action.call(target)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.create(source, target)
|
20
|
-
@middleware[target] = [] if @middleware[target].nil?
|
21
|
-
@middleware[target].push(source)
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.setup(target)
|
25
|
-
# At some point, target should be used so that middleware are only setup on one target.
|
26
|
-
@sources.each(&:setup)
|
27
|
-
target
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|