parklife 0.2.0

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.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/tests.yml +62 -0
  3. data/.gitignore +10 -0
  4. data/.rspec +2 -0
  5. data/CHANGELOG.md +9 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +6 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +103 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/examples/rack/.gitignore +1 -0
  14. data/examples/rack/Gemfile +4 -0
  15. data/examples/rack/Gemfile.lock +47 -0
  16. data/examples/rack/Parkfile +23 -0
  17. data/examples/rails/.gitignore +26 -0
  18. data/examples/rails/Gemfile +5 -0
  19. data/examples/rails/Gemfile.lock +150 -0
  20. data/examples/rails/Parkfile +6 -0
  21. data/examples/rails/Rakefile +6 -0
  22. data/examples/rails/app/assets/config/manifest.js +2 -0
  23. data/examples/rails/app/assets/stylesheets/application.css +15 -0
  24. data/examples/rails/app/assets/stylesheets/global.css +4 -0
  25. data/examples/rails/app/controllers/application_controller.rb +2 -0
  26. data/examples/rails/app/controllers/posts_controller.rb +9 -0
  27. data/examples/rails/app/helpers/application_helper.rb +2 -0
  28. data/examples/rails/app/jobs/application_job.rb +2 -0
  29. data/examples/rails/app/models/application_record.rb +3 -0
  30. data/examples/rails/app/models/post.rb +5 -0
  31. data/examples/rails/app/views/layouts/application.html.erb +14 -0
  32. data/examples/rails/app/views/posts/index.html.erb +7 -0
  33. data/examples/rails/app/views/posts/show.html.erb +3 -0
  34. data/examples/rails/bin/bundle +3 -0
  35. data/examples/rails/bin/rails +4 -0
  36. data/examples/rails/bin/rake +4 -0
  37. data/examples/rails/bin/setup +33 -0
  38. data/examples/rails/bin/update +28 -0
  39. data/examples/rails/config/application.rb +35 -0
  40. data/examples/rails/config/boot.rb +3 -0
  41. data/examples/rails/config/database.yml +25 -0
  42. data/examples/rails/config/environment.rb +5 -0
  43. data/examples/rails/config/environments/development.rb +53 -0
  44. data/examples/rails/config/environments/production.rb +79 -0
  45. data/examples/rails/config/environments/test.rb +36 -0
  46. data/examples/rails/config/initializers/application_controller_renderer.rb +8 -0
  47. data/examples/rails/config/initializers/assets.rb +12 -0
  48. data/examples/rails/config/initializers/backtrace_silencers.rb +7 -0
  49. data/examples/rails/config/initializers/content_security_policy.rb +25 -0
  50. data/examples/rails/config/initializers/cookies_serializer.rb +5 -0
  51. data/examples/rails/config/initializers/filter_parameter_logging.rb +4 -0
  52. data/examples/rails/config/initializers/inflections.rb +16 -0
  53. data/examples/rails/config/initializers/mime_types.rb +4 -0
  54. data/examples/rails/config/initializers/wrap_parameters.rb +14 -0
  55. data/examples/rails/config/locales/en.yml +33 -0
  56. data/examples/rails/config/routes.rb +5 -0
  57. data/examples/rails/config.ru +5 -0
  58. data/examples/rails/data/1-hello-from-parklife.txt +3 -0
  59. data/examples/rails/data/2-hello-again.txt +3 -0
  60. data/examples/rails/data/3-magic-number.txt +3 -0
  61. data/examples/rails/db/migrate/20190507172823_create_posts.rb +11 -0
  62. data/examples/rails/db/schema.rb +24 -0
  63. data/examples/rails/db/seeds.rb +10 -0
  64. data/examples/rails/parklife-build +24 -0
  65. data/examples/rails/public/404.html +67 -0
  66. data/examples/rails/public/422.html +67 -0
  67. data/examples/rails/public/500.html +66 -0
  68. data/examples/rails/public/apple-touch-icon-precomposed.png +0 -0
  69. data/examples/rails/public/apple-touch-icon.png +0 -0
  70. data/examples/rails/public/favicon.ico +0 -0
  71. data/examples/rails/public/robots.txt +1 -0
  72. data/examples/sinatra/.gitignore +1 -0
  73. data/examples/sinatra/Gemfile +4 -0
  74. data/examples/sinatra/Gemfile.lock +56 -0
  75. data/examples/sinatra/Parkfile +21 -0
  76. data/exe/parklife +3 -0
  77. data/lib/parklife/application.rb +39 -0
  78. data/lib/parklife/cli.rb +36 -0
  79. data/lib/parklife/config.rb +14 -0
  80. data/lib/parklife/crawler.rb +104 -0
  81. data/lib/parklife/errors.rb +25 -0
  82. data/lib/parklife/rails.rb +12 -0
  83. data/lib/parklife/route.rb +23 -0
  84. data/lib/parklife/route_set.rb +36 -0
  85. data/lib/parklife/utils.rb +20 -0
  86. data/lib/parklife/version.rb +3 -0
  87. data/lib/parklife.rb +8 -0
  88. data/parklife.gemspec +38 -0
  89. metadata +217 -0
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The page you were looking for doesn't exist (404)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ .rails-default-error-page {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ .rails-default-error-page div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ .rails-default-error-page div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ .rails-default-error-page h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ .rails-default-error-page div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body class="rails-default-error-page">
58
+ <!-- This file lives in public/404.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>The page you were looking for doesn't exist.</h1>
62
+ <p>You may have mistyped the address or the page may have moved.</p>
63
+ </div>
64
+ <p>If you are the application owner check the logs for more information.</p>
65
+ </div>
66
+ </body>
67
+ </html>
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ .rails-default-error-page {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ .rails-default-error-page div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ .rails-default-error-page div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ .rails-default-error-page h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ .rails-default-error-page div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body class="rails-default-error-page">
58
+ <!-- This file lives in public/422.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>The change you wanted was rejected.</h1>
62
+ <p>Maybe you tried to change something you didn't have access to.</p>
63
+ </div>
64
+ <p>If you are the application owner check the logs for more information.</p>
65
+ </div>
66
+ </body>
67
+ </html>
@@ -0,0 +1,66 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ .rails-default-error-page {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ .rails-default-error-page div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ .rails-default-error-page div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ .rails-default-error-page h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ .rails-default-error-page div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body class="rails-default-error-page">
58
+ <!-- This file lives in public/500.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>We're sorry, but something went wrong.</h1>
62
+ </div>
63
+ <p>If you are the application owner check the logs for more information.</p>
64
+ </div>
65
+ </body>
66
+ </html>
File without changes
File without changes
@@ -0,0 +1 @@
1
+ # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
@@ -0,0 +1 @@
1
+ build
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'parklife', path: '../..'
4
+ gem 'sinatra'
@@ -0,0 +1,56 @@
1
+ PATH
2
+ remote: ../..
3
+ specs:
4
+ parklife (0.1.0)
5
+ capybara
6
+ nokogiri
7
+ thor
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ addressable (2.8.1)
13
+ public_suffix (>= 2.0.2, < 6.0)
14
+ capybara (3.38.0)
15
+ addressable
16
+ matrix
17
+ mini_mime (>= 0.1.3)
18
+ nokogiri (~> 1.8)
19
+ rack (>= 1.6.0)
20
+ rack-test (>= 0.6.3)
21
+ regexp_parser (>= 1.5, < 3.0)
22
+ xpath (~> 3.2)
23
+ matrix (0.4.2)
24
+ mini_mime (1.1.2)
25
+ mini_portile2 (2.8.1)
26
+ mustermann (1.0.3)
27
+ nokogiri (1.14.2)
28
+ mini_portile2 (~> 2.8.0)
29
+ racc (~> 1.4)
30
+ public_suffix (5.0.1)
31
+ racc (1.6.2)
32
+ rack (2.2.3)
33
+ rack-protection (2.0.5)
34
+ rack
35
+ rack-test (2.0.2)
36
+ rack (>= 1.3)
37
+ regexp_parser (2.7.0)
38
+ sinatra (2.0.5)
39
+ mustermann (~> 1.0)
40
+ rack (~> 2.0)
41
+ rack-protection (= 2.0.5)
42
+ tilt (~> 2.0)
43
+ thor (1.2.1)
44
+ tilt (2.0.9)
45
+ xpath (3.2.0)
46
+ nokogiri (~> 1.8)
47
+
48
+ PLATFORMS
49
+ ruby
50
+
51
+ DEPENDENCIES
52
+ parklife!
53
+ sinatra
54
+
55
+ BUNDLED WITH
56
+ 1.17.2
@@ -0,0 +1,21 @@
1
+ require 'parklife'
2
+ require 'sinatra'
3
+
4
+ get '/' do
5
+ '<a href="/hello/foo">foo</foo>, <a href="/hello/bar">bar</foo>, <a href="/hello/baz">baz</foo>'
6
+ end
7
+
8
+ get '/hello/:name' do
9
+ "Hello #{params[:name]}"
10
+ end
11
+
12
+ Parklife.application.configure do |config|
13
+ config.build_dir = 'build'
14
+ config.rack_app = Sinatra::Application
15
+ end
16
+
17
+ Parklife.application.routes do
18
+ root crawl: true
19
+
20
+ get '/hello/other'
21
+ end
data/exe/parklife ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'parklife/cli'
3
+ Parklife::CLI.start(ARGV)
@@ -0,0 +1,39 @@
1
+ require 'fileutils'
2
+ require 'parklife/config'
3
+ require 'parklife/crawler'
4
+ require 'parklife/errors'
5
+ require 'parklife/route_set'
6
+
7
+ module Parklife
8
+ class Application
9
+ attr_reader :config, :crawler
10
+
11
+ def initialize
12
+ @config = Config.new
13
+ @route_set = RouteSet.new
14
+ @crawler = Crawler.new(config, @route_set)
15
+ end
16
+
17
+ def build
18
+ raise BuildDirNotDefinedError if config.build_dir.nil?
19
+ raise RackAppNotDefinedError if config.rack_app.nil?
20
+
21
+ FileUtils.rm_rf(config.build_dir)
22
+ Dir.mkdir(config.build_dir)
23
+
24
+ crawler.start
25
+ end
26
+
27
+ def configure
28
+ yield config
29
+ end
30
+
31
+ def routes(&block)
32
+ if block_given?
33
+ @route_set.instance_eval(&block)
34
+ else
35
+ @route_set
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,36 @@
1
+ require 'thor'
2
+
3
+ module Parklife
4
+ class CLI < Thor
5
+ desc 'build', 'create a production build'
6
+ def build
7
+ application.build
8
+ end
9
+
10
+ desc 'routes', 'list all defined routes'
11
+ def routes
12
+ application.routes.each do |route|
13
+ print route.path
14
+ print "\tcrawl=true" if route.crawl
15
+ puts
16
+ end
17
+ end
18
+
19
+ private
20
+ def application
21
+ @application ||= begin
22
+ # Reach inside the consuming app's directory to load Parklife and
23
+ # apply its config. It's only at this point that the
24
+ # Parklife::Application is defined.
25
+ load discover_Parkfile(Dir.pwd)
26
+
27
+ Parklife.application.config.reporter = $stdout
28
+ Parklife.application
29
+ end
30
+ end
31
+
32
+ def discover_Parkfile(dir)
33
+ File.expand_path('Parkfile', dir)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,14 @@
1
+ require 'stringio'
2
+
3
+ module Parklife
4
+ class Config
5
+ attr_accessor :base, :build_dir, :nested_index, :on_404, :rack_app,
6
+ :reporter
7
+
8
+ def initialize
9
+ self.nested_index = true
10
+ self.on_404 = :error
11
+ self.reporter = StringIO.new
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,104 @@
1
+ require 'capybara'
2
+ require 'nokogiri'
3
+ require 'parklife/route'
4
+ require 'parklife/utils'
5
+ require 'set'
6
+
7
+ module Parklife
8
+ class Crawler
9
+ attr_reader :config, :route_set
10
+
11
+ def initialize(config, route_set)
12
+ @config = config
13
+ @route_set = route_set
14
+
15
+ Capybara.register_driver :parklife do |app|
16
+ Capybara::RackTest::Driver.new(app, follow_redirects: false)
17
+ end
18
+ end
19
+
20
+ def start
21
+ Capybara.app_host = config.base if config.base
22
+ Capybara.save_path = config.build_dir
23
+
24
+ @routes = route_set.to_a
25
+ @visited = Set.new
26
+
27
+ while route = @routes.shift
28
+ process_route(route)
29
+ config.reporter.print '.'
30
+ end
31
+
32
+ config.reporter.puts
33
+ end
34
+
35
+ private
36
+ def process_route(route)
37
+ already_processed = if route.crawl
38
+ # No need to re-process an already-crawled route (but do re-process
39
+ # a route that has been visited but not crawled).
40
+ @visited.include?(route)
41
+ else
42
+ # This route isn't being crawled so there's no need to re-process
43
+ # it if it has already been visited or crawled.
44
+ crawled_route = Route.new(route.path, crawl: true)
45
+ @visited.include?(route) || @visited.include?(crawled_route)
46
+ end
47
+
48
+ return if already_processed
49
+
50
+ session.visit(route.path)
51
+
52
+ case session.status_code
53
+ when 200
54
+ # Continue processing the route.
55
+ when 404
56
+ case config.on_404
57
+ when :error
58
+ raise HTTPError.new(path: route.path, status: 404)
59
+ when :warn
60
+ $stderr.puts HTTPError.new(path: route.path, status: 404).message
61
+ end
62
+ else
63
+ raise HTTPError.new(path: route.path, status: session.status_code)
64
+ end
65
+
66
+ session.save_page(
67
+ Utils::build_path_for(
68
+ dir: config.build_dir,
69
+ path: route.path,
70
+ index: config.nested_index,
71
+ )
72
+ )
73
+
74
+ @visited << route
75
+
76
+ if route.crawl
77
+ scan_for_links(session.html) do |route|
78
+ # Don't revisit the route if it has already been visited with
79
+ # crawl=true but do revisit if it wasn't crawled (the passed route
80
+ # will always have crawl=true).
81
+ next if @visited.include?(route)
82
+
83
+ @routes << route
84
+ end
85
+ end
86
+ end
87
+
88
+ def scan_for_links(html)
89
+ doc = Nokogiri::HTML.parse(html)
90
+ doc.css('a').each do |a|
91
+ uri = URI.parse(a[:href])
92
+
93
+ # Don't visit a page that belongs to a different domain.
94
+ next if uri.host
95
+
96
+ yield Route.new(uri.path, crawl: true)
97
+ end
98
+ end
99
+
100
+ def session
101
+ @session ||= Capybara::Session.new(:parklife, config.rack_app)
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,25 @@
1
+ module Parklife
2
+ Error = Class.new(StandardError)
3
+ BuildDirNotDefinedError = Class.new(Error)
4
+ RackAppNotDefinedError = Class.new(Error)
5
+
6
+ class HTTPError < Error
7
+ def initialize(path:, status:)
8
+ @path = path
9
+ @status = status
10
+ end
11
+
12
+ def message
13
+ %Q(#{status} response from path "#{path}")
14
+ end
15
+
16
+ private
17
+ attr_reader :path, :status
18
+ end
19
+
20
+ class RailsNotDefinedError < Error
21
+ def message
22
+ 'Expected Rails to be defined, require config/environment before parklife.'
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,12 @@
1
+ require 'parklife/errors'
2
+
3
+ raise Parklife::RailsNotDefinedError unless defined?(Rails)
4
+
5
+ require 'parklife'
6
+
7
+ # Allow use of the consuming Rails application's route helpers from within the
8
+ # block when defining Parklife routes.
9
+ Parklife::RouteSet.include(Rails.application.routes.url_helpers)
10
+
11
+ Parklife.application.config.build_dir = Rails.root.join('build')
12
+ Parklife.application.config.rack_app = Rails.application
@@ -0,0 +1,23 @@
1
+ module Parklife
2
+ class Route
3
+ attr_reader :crawl, :path
4
+
5
+ def initialize(path, crawl:)
6
+ @path = path
7
+ @crawl = crawl
8
+ end
9
+
10
+ def ==(other)
11
+ path == other.path && crawl == other.crawl
12
+ end
13
+ alias_method :eql?, :==
14
+
15
+ def hash
16
+ [self.class, path, crawl].hash
17
+ end
18
+
19
+ def inspect
20
+ %(<#{self.class.name} path="#{path}" crawl="#{crawl}">)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,36 @@
1
+ require 'set'
2
+ require_relative 'route'
3
+
4
+ module Parklife
5
+ class RouteSet
6
+ include Enumerable
7
+
8
+ attr_reader :routes
9
+
10
+ def initialize
11
+ @routes = Set.new
12
+ end
13
+
14
+ def each
15
+ routes.each do |path|
16
+ yield path
17
+ end
18
+ end
19
+
20
+ def get(path, crawl: false)
21
+ routes << Route.new(path, crawl: crawl)
22
+ end
23
+
24
+ def root(crawl: false)
25
+ get('/', crawl: crawl)
26
+ end
27
+
28
+ def size
29
+ routes.size
30
+ end
31
+
32
+ def to_a
33
+ routes.to_a
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,20 @@
1
+ module Parklife
2
+ module Utils
3
+ extend self
4
+
5
+ def build_path_for(dir:, path:, index: true)
6
+ path = path.gsub(/^\/|\/$/, '')
7
+
8
+ if File.extname(path).empty?
9
+ if index
10
+ File.join(dir, path, 'index.html')
11
+ else
12
+ name = path.empty? ? 'index.html' : "#{path}.html"
13
+ File.join(dir, name)
14
+ end
15
+ else
16
+ File.join(dir, path)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ module Parklife
2
+ VERSION = '0.2.0'
3
+ end
data/lib/parklife.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'parklife/application'
2
+ require 'parklife/version'
3
+
4
+ module Parklife
5
+ def self.application
6
+ @application ||= Application.new
7
+ end
8
+ end
data/parklife.gemspec ADDED
@@ -0,0 +1,38 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'parklife/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'parklife'
7
+ spec.version = Parklife::VERSION
8
+ spec.authors = ['Ben Pickles']
9
+ spec.email = ['spideryoung@gmail.com']
10
+
11
+ spec.summary = 'Convert a Rack app into a static HTML site.'
12
+ spec.homepage = 'https://github.com/benpickles/parklife'
13
+ spec.license = 'MIT'
14
+
15
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
16
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
17
+ spec.metadata = {
18
+ 'changelog_uri' => 'https://github.com/benpickles/parklife/blob/main/CHANGELOG.md',
19
+ 'source_code_uri' => 'https://github.com/benpickles/parklife',
20
+ }
21
+
22
+ # Specify which files should be added to the gem when it is released.
23
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
25
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ end
27
+ spec.bindir = 'exe'
28
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ['lib']
30
+
31
+ spec.add_dependency 'capybara'
32
+ spec.add_dependency 'nokogiri'
33
+ spec.add_dependency 'thor'
34
+
35
+ spec.add_development_dependency 'bundler'
36
+ spec.add_development_dependency 'rake'
37
+ spec.add_development_dependency 'rspec'
38
+ end