lanyon 0.3.4 → 0.4.3
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 +5 -5
- data/History.md +23 -0
- data/LICENSE +1 -1
- data/README.md +17 -3
- data/Rakefile +2 -1
- data/lanyon.gemspec +4 -4
- data/lib/lanyon/application.rb +8 -6
- data/lib/lanyon/backports.rb +2 -0
- data/lib/lanyon/router.rb +14 -2
- data/lib/lanyon/version.rb +4 -2
- data/lib/lanyon.rb +4 -1
- data/test/helper.rb +12 -4
- data/test/test_build.rb +6 -3
- data/test/test_configuration.rb +22 -21
- data/test/test_integration.rb +72 -65
- data/test/test_router.rb +60 -20
- metadata +9 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a2f2ed82be1b1a0e4a4ca74b9ef4bf855fd321fbfdab480711e19b506c29e79e
|
4
|
+
data.tar.gz: e8713bd319fb150aa8763f9b977a6d3407cef1f2fe1edef01e712a8d0c5f09e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4acef77523d343f1dcf1b2c13037cf2ca3aafd9c34613daf52aaae6697811a2b571278e52c2b75db653881fe467ddcb54abdbc991aca7ab8fed87a7cbebf946
|
7
|
+
data.tar.gz: 02b0eb0279f08fde9307f01c5190efc3d2197d5b7f6205aea87383811091582a9d85fd11cddd656f33a7ef5de850dd671e9770cb92a062c4af7530116321c7f4
|
data/History.md
CHANGED
@@ -1,6 +1,29 @@
|
|
1
1
|
Release History
|
2
2
|
===============
|
3
3
|
|
4
|
+
## 0.4.3
|
5
|
+
|
6
|
+
* Use Rack::ContentLength middleware to fix missing
|
7
|
+
Content-Length headers for rack 2.1.0 and later
|
8
|
+
* Update development dependencies
|
9
|
+
|
10
|
+
## 0.4.2
|
11
|
+
|
12
|
+
* Avoid deprecation warnings for minitest expectations
|
13
|
+
* Improve code style
|
14
|
+
|
15
|
+
## 0.4.1
|
16
|
+
|
17
|
+
* Drop pessimistic constraint on Jekyll version
|
18
|
+
* Remove Jekyll cache directory after tests
|
19
|
+
* Let "clean" task remove Jekyll cache directory
|
20
|
+
* Add Jekyll cache directory to .gitignore
|
21
|
+
* Add magic comments for frozen string literals
|
22
|
+
|
23
|
+
## 0.4.0
|
24
|
+
|
25
|
+
* Support .html extension stripping
|
26
|
+
|
4
27
|
## 0.3.4
|
5
28
|
|
6
29
|
* Allow Rack 2
|
data/LICENSE
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2015-
|
3
|
+
Copyright (c) 2015-2022 Marcus Stollsteimer
|
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/README.md
CHANGED
@@ -56,7 +56,7 @@ or as Lanyon initialization options in `config.ru`.
|
|
56
56
|
Example:
|
57
57
|
|
58
58
|
``` ruby
|
59
|
-
run Lanyon.application(:
|
59
|
+
run Lanyon.application(destination: "mysite")
|
60
60
|
```
|
61
61
|
|
62
62
|
This will set a custom destination path, overriding the default (`_site`)
|
@@ -70,7 +70,7 @@ Additional Lanyon initialization options:
|
|
70
70
|
(default: false)
|
71
71
|
|
72
72
|
Note that on read-only filesystems a site build will fail,
|
73
|
-
so you must set
|
73
|
+
so you must set `skip_build: true` in these cases.
|
74
74
|
|
75
75
|
### Custum 404 Page
|
76
76
|
|
@@ -83,6 +83,20 @@ This can also be a file generated by Jekyll from e.g. Markdown sources.
|
|
83
83
|
|
84
84
|
- Gem dependencies (runtime): `jekyll`, `rack`
|
85
85
|
|
86
|
+
## How URLs are resolved
|
87
|
+
|
88
|
+
Lanyon maps URLs to corresponding files as follows:
|
89
|
+
|
90
|
+
1. a `path/` with a trailing slash is changed to `path/index.html`,
|
91
|
+
2. then, Lanyon checks for an exactly corresponding file,
|
92
|
+
3. when `path` does not exist but `path/index.html` does,
|
93
|
+
the response will be a redirect to `path/`,
|
94
|
+
4. when neither 2. nor 3. apply, +path.html+ is tried.
|
95
|
+
|
96
|
+
To avoid confusion, it's probably a good idea to have only one
|
97
|
+
of `resource`, `resource/index.html`, and `resource.html` present
|
98
|
+
as file in your site.
|
99
|
+
|
86
100
|
## Reporting Bugs
|
87
101
|
|
88
102
|
Report bugs on the Lanyon home page: <https://github.com/stomar/lanyon/>
|
@@ -93,7 +107,7 @@ Lanyon was inspired by [rack-jekyll][rack-jekyll] and written as a replacement.
|
|
93
107
|
|
94
108
|
## License
|
95
109
|
|
96
|
-
Copyright © 2015-
|
110
|
+
Copyright © 2015-2022 Marcus Stollsteimer
|
97
111
|
|
98
112
|
Lanyon is licensed under the [MIT License][MIT].
|
99
113
|
See also the included `LICENSE` file for more information.
|
data/Rakefile
CHANGED
@@ -7,7 +7,7 @@ def gemspec_file
|
|
7
7
|
end
|
8
8
|
|
9
9
|
|
10
|
-
task :
|
10
|
+
task default: [:test]
|
11
11
|
|
12
12
|
Rake::TestTask.new do |t|
|
13
13
|
t.pattern = "test/**/test_*.rb"
|
@@ -25,6 +25,7 @@ end
|
|
25
25
|
desc "Remove generated files"
|
26
26
|
task :clean do
|
27
27
|
FileUtils.rm_rf("demo/_site")
|
28
|
+
FileUtils.rm_rf("demo/.jekyll-cache")
|
28
29
|
FileUtils.rm(Dir.glob("*.gem"))
|
29
30
|
end
|
30
31
|
|
data/lanyon.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
|
11
11
|
s.summary = "Lanyon serves your Jekyll site as a Rack application."
|
12
12
|
s.description =
|
13
|
-
"Lanyon is a good friend of Jekyll, the static site generator, "
|
13
|
+
"Lanyon is a good friend of Jekyll, the static site generator, " \
|
14
14
|
"and transforms your website into a Rack application."
|
15
15
|
|
16
16
|
s.authors = ["Marcus Stollsteimer"]
|
@@ -21,11 +21,11 @@ Gem::Specification.new do |s|
|
|
21
21
|
|
22
22
|
s.required_ruby_version = ">= 2.0.0"
|
23
23
|
|
24
|
-
s.add_dependency "jekyll", ">= 2.0"
|
24
|
+
s.add_dependency "jekyll", ">= 2.0"
|
25
25
|
s.add_dependency "rack", ">= 1.6", "< 3.0"
|
26
26
|
|
27
|
-
s.add_development_dependency "rake", "~> 11.2"
|
28
27
|
s.add_development_dependency "minitest", "~> 5.8"
|
28
|
+
s.add_development_dependency "rake", "~> 13.0"
|
29
29
|
|
30
30
|
s.require_paths = ["lib"]
|
31
31
|
|
@@ -40,7 +40,7 @@ Gem::Specification.new do |s|
|
|
40
40
|
] +
|
41
41
|
Dir.glob("lib/**/*") +
|
42
42
|
Dir.glob("test/**/*") +
|
43
|
-
Dir.glob("demo/**/*").reject {|f| f
|
43
|
+
Dir.glob("demo/**/*").reject {|f| f.start_with?("demo/_site/") }
|
44
44
|
|
45
45
|
s.extra_rdoc_files = %w[README.md LICENSE History.md]
|
46
46
|
s.rdoc_options = ["--charset=UTF-8", "--main=README.md"]
|
data/lib/lanyon/application.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "rack/mime"
|
2
4
|
require "rack/request"
|
3
5
|
require "rack/response"
|
@@ -42,7 +44,7 @@ module Lanyon
|
|
42
44
|
|
43
45
|
def response(filename) # :nodoc:
|
44
46
|
response = Rack::Response.new(File.binread(filename))
|
45
|
-
response["Content-Type"]
|
47
|
+
response["Content-Type"] = media_type(filename)
|
46
48
|
|
47
49
|
response.finish
|
48
50
|
end
|
@@ -61,7 +63,7 @@ module Lanyon
|
|
61
63
|
end
|
62
64
|
|
63
65
|
def html_wrap(title, content) # :nodoc:
|
64
|
-
<<-
|
66
|
+
<<-DOCUMENT.gsub(/^ {6}/, "")
|
65
67
|
<!DOCTYPE html>
|
66
68
|
<html lang="en">
|
67
69
|
<head>
|
@@ -71,7 +73,7 @@ module Lanyon
|
|
71
73
|
#{content}
|
72
74
|
</body>
|
73
75
|
</html>
|
74
|
-
|
76
|
+
DOCUMENT
|
75
77
|
end
|
76
78
|
|
77
79
|
def default_404_body # :nodoc:
|
@@ -95,7 +97,7 @@ module Lanyon
|
|
95
97
|
end
|
96
98
|
|
97
99
|
def redirect_body(to_path) # :nodoc:
|
98
|
-
message = %Q
|
100
|
+
message = %Q(<p>Redirecting to <a href="#{to_path}">#{to_path}</a>.</p>)
|
99
101
|
|
100
102
|
html_wrap("Redirection", message)
|
101
103
|
end
|
@@ -108,9 +110,9 @@ module Lanyon
|
|
108
110
|
|
109
111
|
body = redirect_body(location)
|
110
112
|
headers = {
|
111
|
-
"Location"
|
113
|
+
"Location" => location,
|
112
114
|
"Cache-Control" => "max-age=#{cache_time}, must-revalidate",
|
113
|
-
"Expires"
|
115
|
+
"Expires" => (Time.now + cache_time).httpdate
|
114
116
|
}
|
115
117
|
|
116
118
|
html_response(body, 301, headers)
|
data/lib/lanyon/backports.rb
CHANGED
data/lib/lanyon/router.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "rack/utils"
|
2
4
|
|
3
5
|
|
@@ -16,9 +18,17 @@ module Lanyon
|
|
16
18
|
# Returns the full file system path of the file corresponding to
|
17
19
|
# the given URL +path+, or
|
18
20
|
#
|
19
|
-
# - +:
|
20
|
-
# - +:
|
21
|
+
# - +:must_redirect+ if the request must be redirected to +path/+,
|
22
|
+
# - +:not_found+ if no corresponding file exists.
|
23
|
+
#
|
24
|
+
# The return value is found as follows:
|
21
25
|
#
|
26
|
+
# 1. a +path/+ with a trailing slash is changed to +path/index.html+,
|
27
|
+
# 2. then, the method checks for an exactly corresponding file,
|
28
|
+
# 3. when +path+ does not exist but +path/index.html+ does,
|
29
|
+
# a redirect will be indicated,
|
30
|
+
# 4. finally, when no exactly corresponding file or redirect
|
31
|
+
# can be found, +path.html+ is tried.
|
22
32
|
def endpoint(path)
|
23
33
|
normalized = normalize_path_info(path)
|
24
34
|
|
@@ -27,6 +37,8 @@ module Lanyon
|
|
27
37
|
fullpath
|
28
38
|
elsif needs_redirect_to_dir?(fullpath)
|
29
39
|
:must_redirect
|
40
|
+
elsif FileTest.file?(fullpath_html = "#{fullpath}.html")
|
41
|
+
fullpath_html
|
30
42
|
else
|
31
43
|
:not_found
|
32
44
|
end
|
data/lib/lanyon/version.rb
CHANGED
data/lib/lanyon.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# = lanyon.rb
|
2
4
|
#
|
3
5
|
# See Lanyon module for documentation.
|
@@ -49,6 +51,7 @@ module Lanyon
|
|
49
51
|
|
50
52
|
Rack::Builder.new do
|
51
53
|
use Rack::Head
|
54
|
+
use Rack::ContentLength
|
52
55
|
use Rack::ConditionalGet
|
53
56
|
use Rack::ETag, nil, nil
|
54
57
|
|
@@ -68,7 +71,7 @@ module Lanyon
|
|
68
71
|
|
69
72
|
# @private
|
70
73
|
def self.default_options # :nodoc:
|
71
|
-
{ :
|
74
|
+
{ skip_build: false }
|
72
75
|
end
|
73
76
|
|
74
77
|
# @private
|
data/test/helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "minitest/autorun"
|
2
4
|
require "fileutils"
|
3
5
|
require "stringio"
|
@@ -6,7 +8,11 @@ require "rack/mock"
|
|
6
8
|
require "lanyon"
|
7
9
|
|
8
10
|
|
9
|
-
TEST_DIR = File.expand_path(
|
11
|
+
TEST_DIR = File.expand_path(__dir__)
|
12
|
+
|
13
|
+
SOURCE_DIR = File.join(TEST_DIR, "source")
|
14
|
+
CACHE_DIR = File.join(SOURCE_DIR, ".jekyll-cache")
|
15
|
+
|
10
16
|
TEMP_DIR = File.join(TEST_DIR, "tmp")
|
11
17
|
|
12
18
|
|
@@ -24,10 +30,13 @@ def chdir_tempdir
|
|
24
30
|
Dir.chdir(TEMP_DIR)
|
25
31
|
end
|
26
32
|
|
27
|
-
def
|
28
|
-
File.
|
33
|
+
def teardown_cachedir
|
34
|
+
FileUtils.rm_rf(CACHE_DIR) if File.exist?(CACHE_DIR)
|
29
35
|
end
|
30
36
|
|
37
|
+
def sourcedir
|
38
|
+
SOURCE_DIR
|
39
|
+
end
|
31
40
|
|
32
41
|
def silence_output
|
33
42
|
original_stderr, original_stdout = $stderr, $stdout
|
@@ -38,7 +47,6 @@ ensure
|
|
38
47
|
$stderr, $stdout = original_stderr, original_stdout
|
39
48
|
end
|
40
49
|
|
41
|
-
|
42
50
|
def file_must_exist(filename)
|
43
51
|
assert File.exist?(filename),
|
44
52
|
"Expected file `#{filename}' to exist."
|
data/test/test_build.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "helper"
|
2
4
|
|
3
5
|
|
@@ -9,7 +11,7 @@ describe "when creating a Lanyon application" do
|
|
9
11
|
|
10
12
|
destdir = File.join(tempdir, "_site")
|
11
13
|
|
12
|
-
@dir_options = { :
|
14
|
+
@dir_options = { source: sourcedir, destination: destdir }
|
13
15
|
@page = File.join(destdir, "index.html")
|
14
16
|
@no_page = File.join(destdir, "not_a_page.html")
|
15
17
|
|
@@ -21,6 +23,7 @@ describe "when creating a Lanyon application" do
|
|
21
23
|
|
22
24
|
after do
|
23
25
|
teardown_tempdir
|
26
|
+
teardown_cachedir
|
24
27
|
end
|
25
28
|
|
26
29
|
it "builds the site by default, removing old content" do
|
@@ -33,7 +36,7 @@ describe "when creating a Lanyon application" do
|
|
33
36
|
end
|
34
37
|
|
35
38
|
it "does not build the site when :skip_build option is set" do
|
36
|
-
options = {:
|
39
|
+
options = { skip_build: true }.merge(@dir_options)
|
37
40
|
silence_output do
|
38
41
|
Lanyon.application(options)
|
39
42
|
end
|
@@ -43,7 +46,7 @@ describe "when creating a Lanyon application" do
|
|
43
46
|
end
|
44
47
|
|
45
48
|
it "does always build the site with ::build" do
|
46
|
-
options = {:
|
49
|
+
options = { skip_build: true }.merge(@dir_options)
|
47
50
|
silence_output do
|
48
51
|
Lanyon.build(options)
|
49
52
|
end
|
data/test/test_configuration.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "helper"
|
2
4
|
|
3
5
|
|
@@ -23,7 +25,7 @@ describe "when configuring site" do
|
|
23
25
|
|
24
26
|
it "loads the correct default destination" do
|
25
27
|
config = get_jekyll_config
|
26
|
-
config["destination"].must_equal File.join(Dir.pwd, "_site")
|
28
|
+
_(config["destination"]).must_equal File.join(Dir.pwd, "_site")
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
@@ -41,8 +43,8 @@ describe "when configuring site" do
|
|
41
43
|
|
42
44
|
it "loads the configuration from file" do
|
43
45
|
config = get_jekyll_config
|
44
|
-
config.must_include "config_file_opt"
|
45
|
-
config["config_file_opt"].must_equal "ok"
|
46
|
+
_(config).must_include "config_file_opt"
|
47
|
+
_(config["config_file_opt"]).must_equal "ok"
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
@@ -59,28 +61,28 @@ describe "when configuring site" do
|
|
59
61
|
end
|
60
62
|
|
61
63
|
it "loads the configuration from file" do
|
62
|
-
config = get_jekyll_config(:
|
63
|
-
config.must_include "config_file_opt"
|
64
|
-
config["config_file_opt"].must_equal "ok"
|
64
|
+
config = get_jekyll_config(config: "_my_config.yml")
|
65
|
+
_(config).must_include "config_file_opt"
|
66
|
+
_(config["config_file_opt"]).must_equal "ok"
|
65
67
|
end
|
66
68
|
end
|
67
69
|
|
68
70
|
describe "when initialization options are given" do
|
69
71
|
|
70
72
|
it "has the initialization options" do
|
71
|
-
config = get_jekyll_config(:
|
72
|
-
config.must_include "init_opt"
|
73
|
-
config["init_opt"].must_equal "ok"
|
73
|
+
config = get_jekyll_config(init_opt: "ok")
|
74
|
+
_(config).must_include "init_opt"
|
75
|
+
_(config["init_opt"]).must_equal "ok"
|
74
76
|
end
|
75
77
|
|
76
78
|
it "has the correct destination" do
|
77
|
-
config = get_jekyll_config(:
|
78
|
-
config["destination"].must_equal "/project/_site"
|
79
|
+
config = get_jekyll_config(destination: "/project/_site")
|
80
|
+
_(config["destination"]).must_equal "/project/_site"
|
79
81
|
end
|
80
82
|
|
81
83
|
it "does not pass :skip_build on to Jekyll" do
|
82
|
-
config = get_jekyll_config(:
|
83
|
-
config.wont_include "skip_build"
|
84
|
+
config = get_jekyll_config(skip_build: "ok")
|
85
|
+
_(config).wont_include "skip_build"
|
84
86
|
end
|
85
87
|
end
|
86
88
|
|
@@ -99,17 +101,16 @@ describe "when configuring site" do
|
|
99
101
|
end
|
100
102
|
|
101
103
|
it "has all options and initialization options override file options" do
|
102
|
-
config = get_jekyll_config(:
|
103
|
-
|
104
|
-
config.must_include "
|
105
|
-
config.must_include "
|
106
|
-
config.
|
107
|
-
config["common_opt"].must_equal "from init"
|
104
|
+
config = get_jekyll_config(init_opt: "ok", common_opt: "from init")
|
105
|
+
_(config).must_include "init_opt"
|
106
|
+
_(config).must_include "config_file_opt"
|
107
|
+
_(config).must_include "common_opt"
|
108
|
+
_(config["common_opt"]).must_equal "from init"
|
108
109
|
end
|
109
110
|
|
110
111
|
it "has the correct destination" do
|
111
|
-
config = get_jekyll_config(:
|
112
|
-
config["destination"].must_equal "/project/_site_from_init"
|
112
|
+
config = get_jekyll_config(destination: "/project/_site_from_init")
|
113
|
+
_(config["destination"]).must_equal "/project/_site_from_init"
|
113
114
|
end
|
114
115
|
end
|
115
116
|
end
|
data/test/test_integration.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "helper"
|
4
4
|
|
@@ -18,12 +18,13 @@ describe "when handling requests" do
|
|
18
18
|
|
19
19
|
@destdir = File.join(tempdir, "_site")
|
20
20
|
|
21
|
-
app = get_app(:
|
21
|
+
app = get_app(source: sourcedir, destination: @destdir)
|
22
22
|
@request = Rack::MockRequest.new(app)
|
23
23
|
end
|
24
24
|
|
25
25
|
after do
|
26
26
|
teardown_tempdir
|
27
|
+
teardown_cachedir
|
27
28
|
end
|
28
29
|
|
29
30
|
|
@@ -34,23 +35,23 @@ describe "when handling requests" do
|
|
34
35
|
end
|
35
36
|
|
36
37
|
it "returns status 200" do
|
37
|
-
@response.status.must_equal 200
|
38
|
+
_(@response.status).must_equal 200
|
38
39
|
end
|
39
40
|
|
40
41
|
it "returns correct Content-Length header" do
|
41
|
-
@response.original_headers["Content-Length"].must_equal "17"
|
42
|
+
_(@response.original_headers["Content-Length"]).must_equal "17"
|
42
43
|
end
|
43
44
|
|
44
45
|
it "returns correct Content-Type header" do
|
45
|
-
@response.headers["Content-Type"].must_equal "text/html"
|
46
|
+
_(@response.headers["Content-Type"]).must_equal "text/html"
|
46
47
|
end
|
47
48
|
|
48
49
|
it "returns an ETag header" do
|
49
|
-
@response.headers["ETag"].wont_be_nil
|
50
|
+
_(@response.headers["ETag"]).wont_be_nil
|
50
51
|
end
|
51
52
|
|
52
53
|
it "returns correct body" do
|
53
|
-
@response.body.must_match %r{<p>Home Page</p>}
|
54
|
+
_(@response.body).must_match %r{<p>Home Page</p>}
|
54
55
|
end
|
55
56
|
end
|
56
57
|
|
@@ -61,21 +62,21 @@ describe "when handling requests" do
|
|
61
62
|
@response = @request.get("/not/a/page")
|
62
63
|
end
|
63
64
|
|
64
|
-
it "returns status
|
65
|
-
@response.status.must_equal 404
|
65
|
+
it "returns status 404" do
|
66
|
+
_(@response.status).must_equal 404
|
66
67
|
end
|
67
68
|
|
68
69
|
it "returns correct Content-Length header" do
|
69
|
-
@response.original_headers["Content-Length"].must_equal "142"
|
70
|
+
_(@response.original_headers["Content-Length"]).must_equal "142"
|
70
71
|
end
|
71
72
|
|
72
73
|
it "returns correct Content-Type header" do
|
73
|
-
@response.headers["Content-Type"].must_equal "text/html"
|
74
|
+
_(@response.headers["Content-Type"]).must_equal "text/html"
|
74
75
|
end
|
75
76
|
|
76
77
|
it "returns correct body" do
|
77
78
|
expected = %r{<!DOCTYPE html>.*<p>404: Not Found</p>}m
|
78
|
-
@response.body.must_match expected
|
79
|
+
_(@response.body).must_match expected
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
@@ -86,7 +87,7 @@ describe "when handling requests" do
|
|
86
87
|
@custom_404 = File.join(sourcedir, "404.html")
|
87
88
|
File.open(@custom_404, "w") {|f| f.print "Custom 404" }
|
88
89
|
|
89
|
-
app = get_app(:
|
90
|
+
app = get_app(source: sourcedir, destination: @destdir)
|
90
91
|
request = Rack::MockRequest.new(app)
|
91
92
|
@response = request.get("/not/a/page")
|
92
93
|
end
|
@@ -96,15 +97,15 @@ describe "when handling requests" do
|
|
96
97
|
end
|
97
98
|
|
98
99
|
it "returns correct Content-Length header" do
|
99
|
-
@response.original_headers["Content-Length"].must_equal "10"
|
100
|
+
_(@response.original_headers["Content-Length"]).must_equal "10"
|
100
101
|
end
|
101
102
|
|
102
103
|
it "returns correct Content-Type header" do
|
103
|
-
@response.headers["Content-Type"].must_equal "text/html"
|
104
|
+
_(@response.headers["Content-Type"]).must_equal "text/html"
|
104
105
|
end
|
105
106
|
|
106
107
|
it "returns correct body" do
|
107
|
-
@response.body.must_equal "Custom 404"
|
108
|
+
_(@response.body).must_equal "Custom 404"
|
108
109
|
end
|
109
110
|
end
|
110
111
|
|
@@ -116,19 +117,19 @@ describe "when handling requests" do
|
|
116
117
|
end
|
117
118
|
|
118
119
|
it "returns status 200" do
|
119
|
-
@response.status.must_equal 200
|
120
|
+
_(@response.status).must_equal 200
|
120
121
|
end
|
121
122
|
|
122
123
|
it "returns correct Content-Type header" do
|
123
|
-
@response.headers["Content-Type"].must_equal "text/html"
|
124
|
+
_(@response.headers["Content-Type"]).must_equal "text/html"
|
124
125
|
end
|
125
126
|
|
126
127
|
it "returns correct Content-Length header" do
|
127
|
-
@response.original_headers["Content-Length"].must_equal "19"
|
128
|
+
_(@response.original_headers["Content-Length"]).must_equal "19"
|
128
129
|
end
|
129
130
|
|
130
131
|
it "returns correct body" do
|
131
|
-
@response.body.must_match %r{<p>A Blog Post</p>}
|
132
|
+
_(@response.body).must_match %r{<p>A Blog Post</p>}
|
132
133
|
end
|
133
134
|
end
|
134
135
|
|
@@ -140,12 +141,12 @@ describe "when handling requests" do
|
|
140
141
|
end
|
141
142
|
|
142
143
|
it "returns status 200" do
|
143
|
-
@response.status.must_equal 200
|
144
|
+
_(@response.status).must_equal 200
|
144
145
|
end
|
145
146
|
|
146
147
|
it "returns Content-Type 'application/octet-stream'" do
|
147
148
|
type = @response.headers["Content-Type"]
|
148
|
-
type.must_equal "application/octet-stream"
|
149
|
+
_(type).must_equal "application/octet-stream"
|
149
150
|
end
|
150
151
|
end
|
151
152
|
|
@@ -154,12 +155,12 @@ describe "when handling requests" do
|
|
154
155
|
|
155
156
|
it "returns correct Content-Type for *.css" do
|
156
157
|
type = @request.get("/css/test.css").headers["Content-Type"]
|
157
|
-
type.must_equal "text/css"
|
158
|
+
_(type).must_equal "text/css"
|
158
159
|
end
|
159
160
|
|
160
161
|
it "returns correct Content-Type for *.min.js" do
|
161
162
|
type = @request.get("/js/test.min.js").headers["Content-Type"]
|
162
|
-
type.must_equal "application/javascript"
|
163
|
+
_(type).must_equal "application/javascript"
|
163
164
|
end
|
164
165
|
end
|
165
166
|
|
@@ -167,11 +168,11 @@ describe "when handling requests" do
|
|
167
168
|
describe "when asked for partially matching paths" do
|
168
169
|
|
169
170
|
it "returns status 404 for path 1" do
|
170
|
-
@request.get("/2015/10/05/hello").status.must_equal 404
|
171
|
+
_(@request.get("/2015/10/05/hello").status).must_equal 404
|
171
172
|
end
|
172
173
|
|
173
174
|
it "returns status 404 for path 2" do
|
174
|
-
@request.get("/10/05/hello-world.html").status.must_equal 404
|
175
|
+
_(@request.get("/10/05/hello-world.html").status).must_equal 404
|
175
176
|
end
|
176
177
|
end
|
177
178
|
|
@@ -182,8 +183,8 @@ describe "when handling requests" do
|
|
182
183
|
filename = File.join(@destdir, "/../_site/index.html")
|
183
184
|
assert File.exist?(filename)
|
184
185
|
|
185
|
-
|
186
|
-
|
186
|
+
response = @request.get("/../_site/index.html")
|
187
|
+
_(response.status).must_equal 404
|
187
188
|
end
|
188
189
|
end
|
189
190
|
|
@@ -191,23 +192,24 @@ describe "when handling requests" do
|
|
191
192
|
describe "when a directory is requested" do
|
192
193
|
|
193
194
|
it "redirects to 'directory/' for 'directory' with index.html" do
|
194
|
-
@request.get("/dir-with-index").status.must_equal 301
|
195
|
+
_(@request.get("/dir-with-index").status).must_equal 301
|
195
196
|
end
|
196
197
|
|
197
198
|
it "returns status 200 for 'directory/' with index.html" do
|
198
|
-
@request.get("/dir-with-index/").status.must_equal 200
|
199
|
+
_(@request.get("/dir-with-index/").status).must_equal 200
|
199
200
|
end
|
200
201
|
|
201
202
|
it "returns correct body for 'directory/' with index.html" do
|
202
|
-
@request.get("/dir-with-index/").body
|
203
|
+
response_body = @request.get("/dir-with-index/").body
|
204
|
+
_(response_body).must_match %r{<p>Index of dir-with-index/</p>}
|
203
205
|
end
|
204
206
|
|
205
207
|
it "returns status 404 for 'directory' without index.html" do
|
206
|
-
@request.get("/dir-without-index").status.must_equal 404
|
208
|
+
_(@request.get("/dir-without-index").status).must_equal 404
|
207
209
|
end
|
208
210
|
|
209
211
|
it "returns status 404 for 'directory/' without index.html" do
|
210
|
-
@request.get("/dir-without-index/").status.must_equal 404
|
212
|
+
_(@request.get("/dir-without-index/").status).must_equal 404
|
211
213
|
end
|
212
214
|
end
|
213
215
|
|
@@ -219,20 +221,20 @@ describe "when handling requests" do
|
|
219
221
|
end
|
220
222
|
|
221
223
|
it "returns status 301" do
|
222
|
-
@response.status.must_equal 301
|
224
|
+
_(@response.status).must_equal 301
|
223
225
|
end
|
224
226
|
|
225
227
|
it "returns correct Location header" do
|
226
|
-
@response.headers["Location"].must_equal "/dir-with-index/"
|
228
|
+
_(@response.headers["Location"]).must_equal "/dir-with-index/"
|
227
229
|
end
|
228
230
|
|
229
231
|
it "returns a Cache-Control header" do
|
230
|
-
@response.headers["Cache-Control"].wont_be_nil
|
232
|
+
_(@response.headers["Cache-Control"]).wont_be_nil
|
231
233
|
end
|
232
234
|
|
233
235
|
it "returns correct body" do
|
234
236
|
expected = %r{<!DOCTYPE html>.*<a href="/dir-with-index/">}m
|
235
|
-
@request.get("/dir-with-index").body.must_match expected
|
237
|
+
_(@request.get("/dir-with-index").body).must_match expected
|
236
238
|
end
|
237
239
|
end
|
238
240
|
|
@@ -245,11 +247,11 @@ describe "when handling requests" do
|
|
245
247
|
|
246
248
|
it "returns correct body" do
|
247
249
|
response_body = @response.body.force_encoding("UTF-8")
|
248
|
-
response_body.must_match %r{<p>¡Buenos días!</p>}
|
250
|
+
_(response_body).must_match %r{<p>¡Buenos días!</p>}
|
249
251
|
end
|
250
252
|
|
251
253
|
it "returns the bytesize as Content-Length header" do
|
252
|
-
@response.original_headers["Content-Length"].must_equal "23"
|
254
|
+
_(@response.original_headers["Content-Length"]).must_equal "23"
|
253
255
|
end
|
254
256
|
end
|
255
257
|
|
@@ -262,11 +264,11 @@ describe "when handling requests" do
|
|
262
264
|
|
263
265
|
it "returns correct body" do
|
264
266
|
expected = "File\r\nwith\r\nCRLF\r\nnewlines\r\n"
|
265
|
-
@response.body.must_equal expected
|
267
|
+
_(@response.body).must_equal expected
|
266
268
|
end
|
267
269
|
|
268
270
|
it "returns the bytesize as Content-Length header" do
|
269
|
-
@response.original_headers["Content-Length"].must_equal "28"
|
271
|
+
_(@response.original_headers["Content-Length"]).must_equal "28"
|
270
272
|
end
|
271
273
|
end
|
272
274
|
|
@@ -274,18 +276,18 @@ describe "when handling requests" do
|
|
274
276
|
describe "when URL contains special characters" do
|
275
277
|
|
276
278
|
it "returns status 200 for URL with escapes" do
|
277
|
-
|
278
|
-
|
279
|
+
response = @request.get("%2F2015%2F11%2F05%2Fhello-world.html")
|
280
|
+
_(response.status).must_equal 200
|
279
281
|
end
|
280
282
|
|
281
283
|
it "returns status 200 for resource name with blank" do
|
282
|
-
|
283
|
-
|
284
|
+
response = @request.get("with%20blank.html")
|
285
|
+
_(response.status).must_equal 200
|
284
286
|
end
|
285
287
|
|
286
288
|
it "returns status 200 for resource name with plus" do
|
287
|
-
|
288
|
-
|
289
|
+
response = @request.get("with+plus.html")
|
290
|
+
_(response.status).must_equal 200
|
289
291
|
end
|
290
292
|
end
|
291
293
|
|
@@ -303,20 +305,20 @@ describe "when handling requests" do
|
|
303
305
|
end
|
304
306
|
|
305
307
|
it "returns correct status code for unchanged '/'" do
|
306
|
-
@request.get("/", @correct_etag).status.must_equal 304
|
308
|
+
_(@request.get("/", @correct_etag).status).must_equal 304
|
307
309
|
end
|
308
310
|
|
309
311
|
it "does not return a Content-Length header for unchanged '/'" do
|
310
312
|
response = @request.get("/", @correct_etag)
|
311
|
-
response.original_headers["Content-Length"].must_be_nil
|
313
|
+
_(response.original_headers["Content-Length"]).must_be_nil
|
312
314
|
end
|
313
315
|
|
314
316
|
it "returns correct status code for changed '/'" do
|
315
|
-
@request.get("/", @other_etag).status.must_equal 200
|
317
|
+
_(@request.get("/", @other_etag).status).must_equal 200
|
316
318
|
end
|
317
319
|
|
318
320
|
it "returns correct status code for 404" do
|
319
|
-
@request.get("/not/a/page", @other_etag).status.must_equal 404
|
321
|
+
_(@request.get("/not/a/page", @other_etag).status).must_equal 404
|
320
322
|
end
|
321
323
|
end
|
322
324
|
|
@@ -324,15 +326,15 @@ describe "when handling requests" do
|
|
324
326
|
describe "when handling HEAD requests" do
|
325
327
|
|
326
328
|
it "returns status 200 for '/'" do
|
327
|
-
@request.head("/").status.must_equal 200
|
329
|
+
_(@request.head("/").status).must_equal 200
|
328
330
|
end
|
329
331
|
|
330
332
|
it "returns correct Content-Length header for '/'" do
|
331
|
-
@request.head("/").original_headers["Content-Length"].must_equal "17"
|
333
|
+
_(@request.head("/").original_headers["Content-Length"]).must_equal "17"
|
332
334
|
end
|
333
335
|
|
334
336
|
it "does not return a body" do
|
335
|
-
@request.head("/").body.must_equal ""
|
337
|
+
_(@request.head("/").body).must_equal ""
|
336
338
|
end
|
337
339
|
end
|
338
340
|
|
@@ -340,36 +342,41 @@ describe "when handling requests" do
|
|
340
342
|
describe "when handling OPTIONS requests" do
|
341
343
|
|
342
344
|
it "returns status 200" do
|
343
|
-
@request.options("/").status.must_equal 200
|
345
|
+
_(@request.options("/").status).must_equal 200
|
344
346
|
end
|
345
347
|
|
346
348
|
it "returns correct Allow header" do
|
347
|
-
@request.options("/").original_headers["Allow"]
|
349
|
+
response_allow_header = @request.options("/").original_headers["Allow"]
|
350
|
+
_(response_allow_header).must_equal "GET,HEAD,OPTIONS"
|
348
351
|
end
|
349
352
|
|
350
353
|
it "does not return a body" do
|
351
|
-
@request.options("/").body.must_equal ""
|
354
|
+
_(@request.options("/").body).must_equal ""
|
352
355
|
end
|
353
356
|
|
354
357
|
it "returns 404 for nonexistent resource" do
|
355
|
-
@request.options("/not/a/page").status.must_equal 404
|
356
|
-
@request.options("/not/a/page").body.must_match %r{<p>404: Not Found</p>}
|
358
|
+
_(@request.options("/not/a/page").status).must_equal 404
|
359
|
+
_(@request.options("/not/a/page").body).must_match %r{<p>404: Not Found</p>}
|
357
360
|
end
|
358
361
|
end
|
359
362
|
|
360
363
|
|
361
|
-
describe "when handling POST, PUT, DELETE, and other requests" do
|
364
|
+
describe "when handling POST, PUT, DELETE, and other not allowed requests" do
|
362
365
|
|
363
366
|
it "returns status 405" do
|
364
|
-
@request.post("/").status.must_equal 405
|
365
|
-
@request.put("/").status.must_equal 405
|
366
|
-
@request.delete("/").status.must_equal 405
|
367
|
-
@request.request("OTHER", "/").status.must_equal 405
|
367
|
+
_(@request.post("/").status).must_equal 405
|
368
|
+
_(@request.put("/").status).must_equal 405
|
369
|
+
_(@request.delete("/").status).must_equal 405
|
370
|
+
_(@request.request("OTHER", "/").status).must_equal 405
|
368
371
|
end
|
369
372
|
|
370
373
|
it "returns correct body" do
|
371
374
|
expected = %r{<!DOCTYPE html>.*<p>405: Method Not Allowed</p>}m
|
372
|
-
@request.post("/").body.must_match expected
|
375
|
+
_(@request.post("/").body).must_match expected
|
376
|
+
end
|
377
|
+
|
378
|
+
it "returns correct Content-Length header" do
|
379
|
+
_(@request.post("/").original_headers["Content-Length"]).must_equal "151"
|
373
380
|
end
|
374
381
|
end
|
375
382
|
end
|
data/test/test_router.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "helper"
|
2
4
|
|
3
5
|
|
@@ -17,6 +19,10 @@ describe Lanyon::Router do
|
|
17
19
|
dir-with-index/index.html
|
18
20
|
dir-without-index/page.html
|
19
21
|
dir1/dir2/dir3/index.html
|
22
|
+
foo
|
23
|
+
foo.html
|
24
|
+
bar.html
|
25
|
+
bar/index.html
|
20
26
|
]
|
21
27
|
|
22
28
|
files.each do |path|
|
@@ -37,44 +43,78 @@ describe Lanyon::Router do
|
|
37
43
|
|
38
44
|
it "returns path for '/'" do
|
39
45
|
filename = File.join(@sitedir, "index.html")
|
40
|
-
@router.endpoint("/").must_equal filename
|
46
|
+
_(@router.endpoint("/")).must_equal filename
|
41
47
|
end
|
42
48
|
|
43
49
|
it "returns existing path" do
|
44
50
|
filename = File.join(@sitedir, "page.html")
|
45
|
-
@router.endpoint("/page.html").must_equal filename
|
51
|
+
_(@router.endpoint("/page.html")).must_equal filename
|
46
52
|
end
|
47
53
|
|
48
54
|
it "returns existing path for resource without extension" do
|
49
55
|
filename = File.join(@sitedir, "README")
|
50
|
-
@router.endpoint("/README").must_equal filename
|
56
|
+
_(@router.endpoint("/README")).must_equal filename
|
51
57
|
end
|
52
58
|
|
53
59
|
it "returns :not_found for non-existent path" do
|
54
|
-
@router.endpoint("/not-a-page.html").must_equal :not_found
|
60
|
+
_(@router.endpoint("/not-a-page.html")).must_equal :not_found
|
55
61
|
end
|
56
62
|
|
57
63
|
it "returns :not_found for partially matching paths" do
|
58
|
-
@router.endpoint("/dir1/dir2/").must_equal :not_found
|
59
|
-
@router.endpoint("/dir2/dir3").must_equal :not_found
|
60
|
-
@router.endpoint("ir1/di").must_equal :not_found
|
64
|
+
_(@router.endpoint("/dir1/dir2/")).must_equal :not_found
|
65
|
+
_(@router.endpoint("/dir2/dir3")).must_equal :not_found
|
66
|
+
_(@router.endpoint("ir1/di")).must_equal :not_found
|
61
67
|
end
|
62
68
|
|
63
69
|
it "returns path for '/path/to/dir/' with index" do
|
64
70
|
filename = File.join(@sitedir, "dir-with-index/index.html")
|
65
|
-
@router.endpoint("/dir-with-index/").must_equal filename
|
71
|
+
_(@router.endpoint("/dir-with-index/")).must_equal filename
|
66
72
|
end
|
67
73
|
|
68
74
|
it "returns :must_redirect for '/path/to/dir' with index" do
|
69
|
-
@router.endpoint("/dir-with-index").must_equal :must_redirect
|
75
|
+
_(@router.endpoint("/dir-with-index")).must_equal :must_redirect
|
70
76
|
end
|
71
77
|
|
72
78
|
it "returns :not_found for '/path/to/dir/' without index" do
|
73
|
-
@router.endpoint("/dir-without-index/").must_equal :not_found
|
79
|
+
_(@router.endpoint("/dir-without-index/")).must_equal :not_found
|
74
80
|
end
|
75
81
|
|
76
82
|
it "returns :not_found for '/path/to/dir' without index" do
|
77
|
-
@router.endpoint("/dir-without-index").must_equal :not_found
|
83
|
+
_(@router.endpoint("/dir-without-index")).must_equal :not_found
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
describe "when automatically adding .html extension" do
|
89
|
+
|
90
|
+
it "returns existing path" do
|
91
|
+
filename = File.join(@sitedir, "page.html")
|
92
|
+
_(@router.endpoint("/page")).must_equal filename
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "when both `foo' and `foo.html' exist" do
|
96
|
+
|
97
|
+
it "returns `foo' and not `foo.html' when asked for `foo'" do
|
98
|
+
filename = File.join(@sitedir, "foo")
|
99
|
+
_(@router.endpoint("/foo")).must_equal filename
|
100
|
+
end
|
101
|
+
|
102
|
+
it "can also serve `foo.html'" do
|
103
|
+
filename = File.join(@sitedir, "foo.html")
|
104
|
+
_(@router.endpoint("/foo.html")).must_equal filename
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "when both `bar.html' and `bar/index.html' exist" do
|
109
|
+
|
110
|
+
it "returns :must_redirect and not `bar.html' when asked for `bar'" do
|
111
|
+
_(@router.endpoint("/bar")).must_equal :must_redirect
|
112
|
+
end
|
113
|
+
|
114
|
+
it "can also serve `bar.html'" do
|
115
|
+
filename = File.join(@sitedir, "bar.html")
|
116
|
+
_(@router.endpoint("/bar.html")).must_equal filename
|
117
|
+
end
|
78
118
|
end
|
79
119
|
end
|
80
120
|
|
@@ -83,27 +123,27 @@ describe Lanyon::Router do
|
|
83
123
|
|
84
124
|
it "discards leading '..' for existing path" do
|
85
125
|
filename = File.join(@sitedir, "page.html")
|
86
|
-
@router.endpoint("/../../page.html").must_equal filename
|
126
|
+
_(@router.endpoint("/../../page.html")).must_equal filename
|
87
127
|
end
|
88
128
|
|
89
129
|
it "allows safe directory traversal" do
|
90
130
|
filename = File.join(@sitedir, "index.html")
|
91
|
-
@router.endpoint("/dir1/../").must_equal filename
|
131
|
+
_(@router.endpoint("/dir1/../")).must_equal filename
|
92
132
|
end
|
93
133
|
|
94
134
|
it "returns :not_found for unsafe directory traversal 1" do
|
95
135
|
filename = File.join(@sitedir, "/../_site/page.html")
|
96
136
|
assert File.exist?(filename)
|
97
137
|
|
98
|
-
@router.endpoint("/../_site/page.html").must_equal :not_found
|
138
|
+
_(@router.endpoint("/../_site/page.html")).must_equal :not_found
|
99
139
|
end
|
100
140
|
|
101
141
|
it "returns :not_found for unsafe directory traversal 2" do
|
102
|
-
@router.endpoint("/%2E%2E/_site/").must_equal :not_found
|
142
|
+
_(@router.endpoint("/%2E%2E/_site/")).must_equal :not_found
|
103
143
|
end
|
104
144
|
|
105
145
|
it "returns :not_found for unsafe directory traversal 3" do
|
106
|
-
@router.endpoint("/dir1/../dir1/../../_site/").must_equal :not_found
|
146
|
+
_(@router.endpoint("/dir1/../dir1/../../_site/")).must_equal :not_found
|
107
147
|
end
|
108
148
|
end
|
109
149
|
|
@@ -113,7 +153,7 @@ describe Lanyon::Router do
|
|
113
153
|
describe "when 404.html does not exist" do
|
114
154
|
|
115
155
|
it "returns nil" do
|
116
|
-
@router.custom_404_body.must_be_nil
|
156
|
+
_(@router.custom_404_body).must_be_nil
|
117
157
|
end
|
118
158
|
end
|
119
159
|
|
@@ -129,7 +169,7 @@ describe Lanyon::Router do
|
|
129
169
|
end
|
130
170
|
|
131
171
|
it "returns correct body" do
|
132
|
-
@router.custom_404_body.must_equal "Custom 404"
|
172
|
+
_(@router.custom_404_body).must_equal "Custom 404"
|
133
173
|
end
|
134
174
|
end
|
135
175
|
end
|
@@ -139,14 +179,14 @@ describe Lanyon::Router do
|
|
139
179
|
|
140
180
|
it "strips trailing slash from root" do
|
141
181
|
router = Lanyon::Router.new(@sitedir + "/")
|
142
|
-
router.root.must_equal @sitedir
|
182
|
+
_(router.root).must_equal @sitedir
|
143
183
|
end
|
144
184
|
|
145
185
|
it "does not append a trailing slash to root" do
|
146
186
|
assert !@sitedir.end_with?("/")
|
147
187
|
|
148
188
|
router = Lanyon::Router.new(@sitedir)
|
149
|
-
router.root.must_equal @sitedir
|
189
|
+
_(router.root).must_equal @sitedir
|
150
190
|
end
|
151
191
|
end
|
152
192
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lanyon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3
|
4
|
+
version: 0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcus Stollsteimer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
@@ -17,9 +17,6 @@ dependencies:
|
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '2.0'
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '4.0'
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -27,9 +24,6 @@ dependencies:
|
|
27
24
|
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '2.0'
|
30
|
-
- - "<"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '4.0'
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: rack
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -51,33 +45,33 @@ dependencies:
|
|
51
45
|
- !ruby/object:Gem::Version
|
52
46
|
version: '3.0'
|
53
47
|
- !ruby/object:Gem::Dependency
|
54
|
-
name:
|
48
|
+
name: minitest
|
55
49
|
requirement: !ruby/object:Gem::Requirement
|
56
50
|
requirements:
|
57
51
|
- - "~>"
|
58
52
|
- !ruby/object:Gem::Version
|
59
|
-
version: '
|
53
|
+
version: '5.8'
|
60
54
|
type: :development
|
61
55
|
prerelease: false
|
62
56
|
version_requirements: !ruby/object:Gem::Requirement
|
63
57
|
requirements:
|
64
58
|
- - "~>"
|
65
59
|
- !ruby/object:Gem::Version
|
66
|
-
version: '
|
60
|
+
version: '5.8'
|
67
61
|
- !ruby/object:Gem::Dependency
|
68
|
-
name:
|
62
|
+
name: rake
|
69
63
|
requirement: !ruby/object:Gem::Requirement
|
70
64
|
requirements:
|
71
65
|
- - "~>"
|
72
66
|
- !ruby/object:Gem::Version
|
73
|
-
version: '
|
67
|
+
version: '13.0'
|
74
68
|
type: :development
|
75
69
|
prerelease: false
|
76
70
|
version_requirements: !ruby/object:Gem::Requirement
|
77
71
|
requirements:
|
78
72
|
- - "~>"
|
79
73
|
- !ruby/object:Gem::Version
|
80
|
-
version: '
|
74
|
+
version: '13.0'
|
81
75
|
description: Lanyon is a good friend of Jekyll, the static site generator, and transforms
|
82
76
|
your website into a Rack application.
|
83
77
|
email: sto.mar@web.de
|
@@ -146,8 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
140
|
- !ruby/object:Gem::Version
|
147
141
|
version: '0'
|
148
142
|
requirements: []
|
149
|
-
|
150
|
-
rubygems_version: 2.5.1
|
143
|
+
rubygems_version: 3.3.3
|
151
144
|
signing_key:
|
152
145
|
specification_version: 4
|
153
146
|
summary: Lanyon serves your Jekyll site as a Rack application.
|