parklife 0.6.1 → 0.8.0.beta1
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/.github/workflows/examples.yml +2 -17
- data/.github/workflows/tests.yml +33 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -0
- data/Appraisals +13 -0
- data/CHANGELOG.md +17 -0
- data/Gemfile +1 -1
- data/README.md +1 -1
- data/gemfiles/sinatra_3.x.gemfile +12 -0
- data/gemfiles/sinatra_4.0.gemfile +12 -0
- data/gemfiles/sinatra_4.1.gemfile +12 -0
- data/lib/parklife/application.rb +23 -2
- data/lib/parklife/browser.rb +4 -0
- data/lib/parklife/cli.rb +1 -0
- data/lib/parklife/crawler.rb +6 -0
- data/lib/parklife/errors.rb +6 -0
- data/lib/parklife/sinatra.rb +19 -0
- data/lib/parklife/templates/Parkfile.erb +7 -2
- data/lib/parklife/templates/github_pages.yml +4 -4
- data/lib/parklife/templates/static_build.erb +5 -2
- data/lib/parklife/utils.rb +1 -1
- data/lib/parklife/version.rb +1 -1
- metadata +8 -8
- data/lib/parklife/rails.rb +0 -52
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5fee28b7e4a5dd221a56dc23db922173062e06b22888b2daf3a8bc05136525e2
|
4
|
+
data.tar.gz: '02408d7f687ea75db42814178c9ae168595f43d16e287ce30e558baa0abb5d9a'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c6d913ec8bb296a0ad792b75dd4460a65cb94bf07a47d02db3f0db5c4ec5070de63033a8c4333eda08dfa1655c743f67bc615eef89ee5804d08502df75524ddb
|
7
|
+
data.tar.gz: 10fd0665002537622e0229dd0c366cd3ff32ad6234f18a0da80a8fda4cfc64c296d106346193e3ec1ef4aad1c0bd66eff17373a0a402dcffa33842a19d459ec5
|
@@ -18,21 +18,6 @@ jobs:
|
|
18
18
|
- run: test -f build/index.html
|
19
19
|
working-directory: examples/rack
|
20
20
|
|
21
|
-
rails:
|
22
|
-
runs-on: ubuntu-latest
|
23
|
-
name: Rails example
|
24
|
-
steps:
|
25
|
-
- uses: actions/checkout@v3
|
26
|
-
- uses: ruby/setup-ruby@v1
|
27
|
-
with:
|
28
|
-
bundler-cache: true
|
29
|
-
ruby-version: '3.2'
|
30
|
-
working-directory: examples/rails
|
31
|
-
- run: bin/static-build
|
32
|
-
working-directory: examples/rails
|
33
|
-
- run: test -f build/index.html
|
34
|
-
working-directory: examples/rails
|
35
|
-
|
36
21
|
roda:
|
37
22
|
runs-on: ubuntu-latest
|
38
23
|
name: Roda example
|
@@ -56,9 +41,9 @@ jobs:
|
|
56
41
|
- uses: ruby/setup-ruby@v1
|
57
42
|
with:
|
58
43
|
bundler-cache: true
|
59
|
-
ruby-version: '
|
44
|
+
ruby-version: '3.4'
|
60
45
|
working-directory: examples/sinatra
|
61
|
-
- run:
|
46
|
+
- run: bin/static-build
|
62
47
|
working-directory: examples/sinatra
|
63
48
|
- run: test -f build/index.html
|
64
49
|
working-directory: examples/sinatra
|
data/.github/workflows/tests.yml
CHANGED
@@ -6,6 +6,7 @@ jobs:
|
|
6
6
|
rspec:
|
7
7
|
runs-on: ubuntu-latest
|
8
8
|
strategy:
|
9
|
+
fail-fast: false
|
9
10
|
matrix:
|
10
11
|
ruby:
|
11
12
|
- '2.7'
|
@@ -13,22 +14,50 @@ jobs:
|
|
13
14
|
- '3.1'
|
14
15
|
- '3.2'
|
15
16
|
- '3.3'
|
16
|
-
|
17
|
+
- '3.4'
|
18
|
+
name: RSpec (Ruby ${{ matrix.ruby }})
|
17
19
|
steps:
|
18
|
-
- uses: actions/checkout@
|
20
|
+
- uses: actions/checkout@v4
|
19
21
|
- uses: ruby/setup-ruby@v1
|
20
22
|
with:
|
21
23
|
bundler-cache: true
|
22
24
|
ruby-version: ${{ matrix.ruby }}
|
23
|
-
- run: bundle exec rspec
|
25
|
+
- run: bundle exec rspec --exclude-pattern "spec/**/*sinatra*"
|
24
26
|
|
25
27
|
rubocop:
|
26
28
|
runs-on: ubuntu-latest
|
27
29
|
name: RuboCop
|
28
30
|
steps:
|
29
|
-
- uses: actions/checkout@
|
31
|
+
- uses: actions/checkout@v4
|
30
32
|
- uses: ruby/setup-ruby@v1
|
31
33
|
with:
|
32
34
|
bundler-cache: true
|
33
35
|
ruby-version: '3.2'
|
34
36
|
- run: bundle exec rubocop
|
37
|
+
|
38
|
+
sinatra:
|
39
|
+
runs-on: ubuntu-latest
|
40
|
+
strategy:
|
41
|
+
fail-fast: false
|
42
|
+
matrix:
|
43
|
+
ruby:
|
44
|
+
- '2.7'
|
45
|
+
- '3.0'
|
46
|
+
- '3.1'
|
47
|
+
- '3.2'
|
48
|
+
- '3.3'
|
49
|
+
- '3.4'
|
50
|
+
sinatra:
|
51
|
+
- '3.x'
|
52
|
+
- '4.0'
|
53
|
+
- '4.1'
|
54
|
+
env:
|
55
|
+
BUNDLE_GEMFILE: gemfiles/sinatra_${{ matrix.sinatra }}.gemfile
|
56
|
+
name: Ruby ${{ matrix.ruby }} / Sinatra ${{ matrix.sinatra }}
|
57
|
+
steps:
|
58
|
+
- uses: actions/checkout@v4
|
59
|
+
- uses: ruby/setup-ruby@v1
|
60
|
+
with:
|
61
|
+
bundler-cache: true
|
62
|
+
ruby-version: ${{ matrix.ruby }}
|
63
|
+
- run: bundle exec rspec --pattern "spec/**/*sinatra*"
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/Appraisals
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
## Unreleased
|
2
|
+
|
3
|
+
## Version 0.8.0.beta1 - 2025-08-10
|
4
|
+
|
5
|
+
- Remove out-of-the-box Rails integration in preparation for a separate gem. <https://github.com/benpickles/parklife/pull/131>
|
6
|
+
- Include the port when automatically assigning the base from Rails `default_url_options`. <https://github.com/benpickles/parklife/pull/130>
|
7
|
+
- Improve the HTTP redirect error message to include the request's full URL and redirect location. <https://github.com/benpickles/parklife/pull/129>
|
8
|
+
- Empty the build directory instead of deleting it. <https://github.com/benpickles/parklife/pull/125>
|
9
|
+
- Resurrect build callbacks (`before_build`/`after_build`). <https://github.com/benpickles/parklife/pull/124>
|
10
|
+
|
11
|
+
## Version 0.7.0 - 2025-02-03
|
12
|
+
|
13
|
+
- Add support for Rails 8 and add test infrastructure to ensure future compatibility with Rails 7.0, 7.1, and 8.0. <https://github.com/benpickles/parklife/pull/115>, <https://github.com/benpickles/parklife/pull/117>, <https://github.com/benpickles/parklife/pull/121>
|
14
|
+
- Improve out-of-the-box compatibility with Rails by reading `default_url_options`, `relative_url_root`, and `force_ssl` settings on boot and applying them to Parklife's `config.base` (`force_ssl` has been set to `true` in `production.rb` since Rails 7.1). <https://github.com/benpickles/parklife/pull/118>
|
15
|
+
- Improve out-of-the-box compatibility with Sinatra 4.1 which has host authorisation middleware enabled by default in development mode and would otherwise respond to Parklife requests with a 403 status. Additionally the generated Sinatra production build script now sets the environment variable `APP_ENV=production` to enable production mode. <https://github.com/benpickles/parklife/pull/123>, <https://github.com/benpickles/parklife/pull/122>
|
16
|
+
- When discovering HTML links ignore `<a>` elements without an `href`. <https://github.com/benpickles/parklife/pull/107>
|
17
|
+
|
1
18
|
## Version 0.6.1 - 2024-08-23
|
2
19
|
|
3
20
|
- Don't error when the public directory doesn't exist <https://github.com/benpickles/parklife/pull/105>
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -110,7 +110,7 @@ Parklife.application.config.nested_index = false
|
|
110
110
|
|
111
111
|
### Changing the build output directory
|
112
112
|
|
113
|
-
The build directory
|
113
|
+
The build directory's contents are removed before each build. Defaults to `build`.
|
114
114
|
|
115
115
|
```ruby
|
116
116
|
Parklife.application.config.build_dir = 'my/build/dir'
|
data/lib/parklife/application.rb
CHANGED
@@ -13,16 +13,37 @@ module Parklife
|
|
13
13
|
def initialize
|
14
14
|
@config = Config.new
|
15
15
|
@route_set = RouteSet.new
|
16
|
+
@after_build_callbacks = []
|
17
|
+
@before_build_callbacks = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def after_build(&block)
|
21
|
+
@after_build_callbacks << block
|
22
|
+
end
|
23
|
+
|
24
|
+
def before_build(&block)
|
25
|
+
@before_build_callbacks << block
|
16
26
|
end
|
17
27
|
|
18
28
|
def build
|
19
29
|
raise BuildDirNotDefinedError if config.build_dir.nil?
|
20
30
|
raise RackAppNotDefinedError if config.app.nil?
|
21
31
|
|
22
|
-
|
23
|
-
|
32
|
+
if Dir.exist?(config.build_dir)
|
33
|
+
FileUtils.rm_rf(Pathname.new(config.build_dir).children)
|
34
|
+
else
|
35
|
+
Dir.mkdir(config.build_dir)
|
36
|
+
end
|
37
|
+
|
38
|
+
@before_build_callbacks.each do |callback|
|
39
|
+
callback.call(self)
|
40
|
+
end
|
24
41
|
|
25
42
|
crawler.start
|
43
|
+
|
44
|
+
@after_build_callbacks.each do |callback|
|
45
|
+
callback.call(self)
|
46
|
+
end
|
26
47
|
end
|
27
48
|
|
28
49
|
def configure
|
data/lib/parklife/browser.rb
CHANGED
data/lib/parklife/cli.rb
CHANGED
@@ -26,6 +26,7 @@ module Parklife
|
|
26
26
|
['nested_index', application.config.nested_index],
|
27
27
|
['on_404', application.config.on_404.inspect],
|
28
28
|
['parklife/rails', defined?(::Parklife::Railtie) ? 'enabled' : '-'],
|
29
|
+
['parklife/sinatra', defined?(::Parklife::Sinatra) ? 'enabled' : '-'],
|
29
30
|
['reporter', reporter == $stdout ? '$stdout' : reporter],
|
30
31
|
])
|
31
32
|
end
|
data/lib/parklife/crawler.rb
CHANGED
@@ -51,6 +51,12 @@ module Parklife
|
|
51
51
|
case response.status
|
52
52
|
when 200
|
53
53
|
# Continue processing the route.
|
54
|
+
when 301, 302
|
55
|
+
raise HTTPRedirectError.new(
|
56
|
+
response.status,
|
57
|
+
browser.uri_for(route.path),
|
58
|
+
response.headers['location']
|
59
|
+
)
|
54
60
|
when 404
|
55
61
|
case config.on_404
|
56
62
|
when :warn
|
data/lib/parklife/errors.rb
CHANGED
@@ -11,6 +11,12 @@ module Parklife
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
class HTTPRedirectError < Error
|
15
|
+
def initialize(status, from, to)
|
16
|
+
super %Q(#{status} redirect from "#{from}" to "#{to}")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
14
20
|
class ParkfileLoadError < Error
|
15
21
|
def initialize(path)
|
16
22
|
super %Q(Cannot load Parkfile "#{path}")
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sinatra/base'
|
4
|
+
|
5
|
+
module Parklife
|
6
|
+
module Sinatra
|
7
|
+
def self.registered(app)
|
8
|
+
# Disable Rack::Protection::HostAuthorization middleware so that fetching
|
9
|
+
# a page with Parklife works in development. It's safe to do here because
|
10
|
+
# it will only be executed when this file is explicitly required in a
|
11
|
+
# Parkfile and not in general when the app is running in a web server.
|
12
|
+
if app.settings.respond_to?(:host_authorization)
|
13
|
+
app.set(:host_authorization, permitted_hosts: [])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Sinatra.register Parklife::Sinatra
|
@@ -2,7 +2,11 @@
|
|
2
2
|
require 'parklife/rails'
|
3
3
|
require_relative 'config/environment'
|
4
4
|
<% else -%>
|
5
|
-
|
5
|
+
<% if options[:sinatra] -%>
|
6
|
+
require 'parklife/sinatra'
|
7
|
+
|
8
|
+
<% end -%>
|
9
|
+
# Assuming your <%= options[:sinatra] ? 'Sinatra' : 'Rack' %> app lives in ./app.rb:
|
6
10
|
require_relative 'app'
|
7
11
|
<% end -%>
|
8
12
|
|
@@ -11,8 +15,9 @@ Parklife.application.configure do |config|
|
|
11
15
|
# For a Sinatra "classic" app:
|
12
16
|
config.app = Sinatra::Application
|
13
17
|
#
|
14
|
-
#
|
18
|
+
# For a modular-style Sinatra app the Parklife extension must be explicitly registered:
|
15
19
|
# config.app = App
|
20
|
+
# App.register Parklife::Sinatra
|
16
21
|
|
17
22
|
<% elsif !options[:rails] -%>
|
18
23
|
config.app = App
|
@@ -15,11 +15,11 @@ jobs:
|
|
15
15
|
build:
|
16
16
|
runs-on: ubuntu-latest
|
17
17
|
steps:
|
18
|
-
- uses: actions/checkout@
|
18
|
+
- uses: actions/checkout@v4
|
19
19
|
- uses: ruby/setup-ruby@v1
|
20
20
|
with:
|
21
21
|
bundler-cache: true
|
22
|
-
- uses: actions/configure-pages@
|
22
|
+
- uses: actions/configure-pages@v5
|
23
23
|
id: pages
|
24
24
|
|
25
25
|
# Build with Parklife and use its GitHub Pages URL (either its custom
|
@@ -27,7 +27,7 @@ jobs:
|
|
27
27
|
- run: bin/static-build --base "${{ steps.pages.outputs.base_url }}"
|
28
28
|
|
29
29
|
- name: Upload artifact
|
30
|
-
uses: actions/upload-pages-artifact@
|
30
|
+
uses: actions/upload-pages-artifact@v3
|
31
31
|
if: github.ref == 'refs/heads/main' # Only upload on main branch.
|
32
32
|
with:
|
33
33
|
path: build/
|
@@ -45,4 +45,4 @@ jobs:
|
|
45
45
|
steps:
|
46
46
|
- name: Deploy to GitHub Pages
|
47
47
|
id: deployment
|
48
|
-
uses: actions/deploy-pages@
|
48
|
+
uses: actions/deploy-pages@v4
|
@@ -3,8 +3,7 @@
|
|
3
3
|
set -eu
|
4
4
|
|
5
5
|
<% if options[:rails] -%>
|
6
|
-
#
|
7
|
-
# asset URLs are referenced.
|
6
|
+
# Run the app in production mode to ensure correct asset URLs are generated etc.
|
8
7
|
export RAILS_ENV=production
|
9
8
|
export SECRET_KEY_BASE=dummy
|
10
9
|
|
@@ -17,6 +16,10 @@ export SECRET_KEY_BASE=dummy
|
|
17
16
|
# missing assets in production.
|
18
17
|
bundle exec rails assets:precompile
|
19
18
|
|
19
|
+
<% elsif options[:sinatra] -%>
|
20
|
+
# Run the app in production mode.
|
21
|
+
export APP_ENV=production
|
22
|
+
|
20
23
|
<% end -%>
|
21
24
|
# Build with Parklife - and forward arguments sent to this script.
|
22
25
|
bundle exec parklife build "$@"
|
data/lib/parklife/utils.rb
CHANGED
data/lib/parklife/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parklife
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Pickles
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: nokogiri
|
@@ -52,7 +51,6 @@ dependencies:
|
|
52
51
|
- - ">="
|
53
52
|
- !ruby/object:Gem::Version
|
54
53
|
version: '0'
|
55
|
-
description:
|
56
54
|
email:
|
57
55
|
- spideryoung@gmail.com
|
58
56
|
executables:
|
@@ -65,6 +63,7 @@ files:
|
|
65
63
|
- ".gitignore"
|
66
64
|
- ".rspec"
|
67
65
|
- ".rubocop.yml"
|
66
|
+
- Appraisals
|
68
67
|
- CHANGELOG.md
|
69
68
|
- CODE_OF_CONDUCT.md
|
70
69
|
- Gemfile
|
@@ -74,6 +73,9 @@ files:
|
|
74
73
|
- bin/console
|
75
74
|
- bin/setup
|
76
75
|
- exe/parklife
|
76
|
+
- gemfiles/sinatra_3.x.gemfile
|
77
|
+
- gemfiles/sinatra_4.0.gemfile
|
78
|
+
- gemfiles/sinatra_4.1.gemfile
|
77
79
|
- lib/parklife.rb
|
78
80
|
- lib/parklife/application.rb
|
79
81
|
- lib/parklife/browser.rb
|
@@ -81,9 +83,9 @@ files:
|
|
81
83
|
- lib/parklife/config.rb
|
82
84
|
- lib/parklife/crawler.rb
|
83
85
|
- lib/parklife/errors.rb
|
84
|
-
- lib/parklife/rails.rb
|
85
86
|
- lib/parklife/route.rb
|
86
87
|
- lib/parklife/route_set.rb
|
88
|
+
- lib/parklife/sinatra.rb
|
87
89
|
- lib/parklife/templates/Parkfile.erb
|
88
90
|
- lib/parklife/templates/github_pages.yml
|
89
91
|
- lib/parklife/templates/static_build.erb
|
@@ -98,7 +100,6 @@ metadata:
|
|
98
100
|
homepage_uri: https://parklife.dev
|
99
101
|
rubygems_mfa_required: 'true'
|
100
102
|
source_code_uri: https://github.com/benpickles/parklife
|
101
|
-
post_install_message:
|
102
103
|
rdoc_options: []
|
103
104
|
require_paths:
|
104
105
|
- lib
|
@@ -113,8 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
114
|
- !ruby/object:Gem::Version
|
114
115
|
version: '0'
|
115
116
|
requirements: []
|
116
|
-
rubygems_version: 3.
|
117
|
-
signing_key:
|
117
|
+
rubygems_version: 3.7.1
|
118
118
|
specification_version: 4
|
119
119
|
summary: Convert a Rack app into a static HTML site.
|
120
120
|
test_files: []
|
data/lib/parklife/rails.rb
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rails'
|
4
|
-
|
5
|
-
module Parklife
|
6
|
-
module RailsConfigRefinements
|
7
|
-
# When setting Parklife's base also configure the Rails app's
|
8
|
-
# default_url_options and relative_url_root to match.
|
9
|
-
def base=(value)
|
10
|
-
super.tap { |uri|
|
11
|
-
Rails.application.default_url_options = {
|
12
|
-
host: Utils.host_with_port(uri),
|
13
|
-
protocol: uri.scheme,
|
14
|
-
}
|
15
|
-
|
16
|
-
base_path = !uri.path.empty? && uri.path != '/' ? uri.path : nil
|
17
|
-
ActionController::Base.relative_url_root = base_path
|
18
|
-
}
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
class Railtie < Rails::Railtie
|
23
|
-
initializer 'parklife.disable_host_authorization' do |app|
|
24
|
-
# The offending middleware is included in Rails (6+) development mode and
|
25
|
-
# rejects a request with a 403 response if its host isn't present in the
|
26
|
-
# allowlist (a security feature). This prevents Parklife from working in
|
27
|
-
# a Rails app out of the box unless you manually add the expected
|
28
|
-
# Parklife base to the hosts allowlist or set it to nil to disable it -
|
29
|
-
# both of which aren't great because they disable the security feature
|
30
|
-
# whenever the development server is booted.
|
31
|
-
#
|
32
|
-
# https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization
|
33
|
-
#
|
34
|
-
# However it's safe to remove the middleware at this point because it
|
35
|
-
# won't be executed in the normal Rails development flow, only via a
|
36
|
-
# Parkfile when parklife/rails is required.
|
37
|
-
if defined?(ActionDispatch::HostAuthorization)
|
38
|
-
app.middleware.delete(ActionDispatch::HostAuthorization)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
config.after_initialize do
|
43
|
-
Parklife.application.config.app = Rails.application
|
44
|
-
|
45
|
-
# Allow use of the Rails application's route helpers when defining
|
46
|
-
# Parklife routes in the block form.
|
47
|
-
Parklife.application.routes.singleton_class.include(Rails.application.routes.url_helpers)
|
48
|
-
|
49
|
-
Parklife.application.config.extend(RailsConfigRefinements)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|