leanweb 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c3068af18fa92b34c6129894552a74e184c8ebea84cab6d90066a6e004ce9cc5
4
- data.tar.gz: 4fb4f1a3361cc7d986456de08c463899338743d58abc4c8f5099919347df6d1b
3
+ metadata.gz: da54199f1863128e9bb23baf728dff6be60123b9cf44947370293222816da122
4
+ data.tar.gz: 60e11d76704347858cdffbde24d17b5d0edf1061ea91ef158dd5a6928e48bc4c
5
5
  SHA512:
6
- metadata.gz: 3896c65a6db177ac696a580ae3667ec43981969dd7654eaa87469016712cdfc022a5a64bd8fe48aed97c15e09beb009d97dd79ca85f7328a16293925f52031cf
7
- data.tar.gz: 72489e08ddfd2c08176af510c4b8cfddf6b7e4e0a8846b79173f18676d27dc63540ed359708aa679cfe351c2f9e69b75e28639de895368f97faa0a71cc3bcc2e
6
+ metadata.gz: a3b3abccd00de5d76a06513c021b409d19073c911f3d236b7c7412c42e723bad9e616514a02e278e55271d5faf5709f94fb283af6fa93aa873e2144ff0d3211b
7
+ data.tar.gz: a366dce05e7a8108e7b3ca4096112a3567e8082a0934e64d323401a938dceb24bfdc6c03dd53193827800b04a05c1c4c9ab53189cc45453e7925422dfb58535b
data/bin/leanweb CHANGED
@@ -16,12 +16,15 @@ require 'leanweb'
16
16
  files = [
17
17
  {
18
18
  filename: 'Gemfile',
19
+ # TODO: Use {LeanWeb::VERSION} when v1 is reached.
19
20
  content: <<~RUBY
20
21
  # frozen_string_literal: true
21
22
 
22
23
  source 'https://rubygems.org'
23
24
 
24
- gem 'leanweb', '~> #{LeanWeb::VERSION}'
25
+ gem 'leanweb', '~> 0.2'
26
+ gem 'haml'
27
+ gem 'rake'
25
28
  RUBY
26
29
  }, {
27
30
  filename: 'config.ru',
@@ -29,21 +32,21 @@ files = [
29
32
  # frozen_string_literal: true
30
33
 
31
34
  require 'leanweb'
35
+ require_relative 'routes'
32
36
 
33
37
  if ENV['RACK_ENV'] == 'development'
34
38
  use(Rack::Reloader, 0)
35
- use(Rack::Static, urls: [''], root: 'public', cascade: true)
39
+ use(Rack::Static, urls: ['/assets'], root: 'public', cascade: true)
36
40
  end
37
41
 
38
- app = LeanWeb::App.init
39
- run app
42
+ run LeanWeb::App.new(ROUTES)
40
43
  RUBY
41
44
  }, {
42
45
  filename: 'routes.rb',
43
46
  content: <<~RUBY
44
47
  # frozen_string_literal: true
45
48
 
46
- [{ path: '/' }]
49
+ ROUTES = [{ path: '/' }].freeze
47
50
  RUBY
48
51
  }, {
49
52
  filename: 'Rakefile',
@@ -54,8 +57,9 @@ files = [
54
57
 
55
58
  task default: %w[build]
56
59
 
57
- task :build do
58
- LeanWeb::App.init.build_static
60
+ task :build_static do
61
+ require_relative 'routes'
62
+ LeanWeb::App.new(ROUTES).build_static
59
63
  end
60
64
  RUBY
61
65
  }, {
@@ -65,10 +69,10 @@ files = [
65
69
 
66
70
  require 'leanweb'
67
71
 
68
- # Main controller is the default controller
72
+ # Main controller is the default controller.
69
73
  class MainController < LeanWeb::Controller
70
74
  def index_get
71
- render 'index.haml'
75
+ render_response 'index.haml'
72
76
  end
73
77
  end
74
78
  RUBY
@@ -96,9 +100,10 @@ begin
96
100
  path = ARGV[1] || '.'
97
101
  FileUtils.mkdir_p(path)
98
102
  FileUtils.cd(path)
99
- FileUtils.mkdir_p(['public', 'src/controllers', 'src/views'])
100
- files.each { |file| File.write(file[:filename], file[:content]) }
103
+ FileUtils.mkdir_p(['public/assets', 'src/controllers', 'src/views'])
104
+ files.each{ |file| File.write(file[:filename], file[:content]) }
101
105
  `git init`
106
+ `bundle install`
102
107
  puts("Project '#{File.basename(Dir.getwd)}' successfully created.")
103
108
  rescue # rubocop:disable Style/RescueStandardError
104
109
  puts('Woops! Something went wrong.')
data/lib/leanweb/app.rb CHANGED
@@ -20,19 +20,15 @@ module LeanWeb
20
20
  end
21
21
 
22
22
  # Entry point for dynamic routes (Rack).
23
+ #
23
24
  # @param env [Hash] `env` for Rack.
24
25
  def call(env)
25
26
  request = Rack::Request.new(env)
26
- route = @routes.find do |r|
27
- (r[:method] || 'GET') == request.request_method && begin
28
- r[:path] =~ request.path
29
- rescue TypeError
30
- r[:path] == request.path
31
- end
32
- end
33
- return [404, {}, ['Not found']] unless route_exists?(route)
27
+ route = find_route(request)
28
+ route = Route.new(**route) unless route.nil?
29
+ return [404, {}, ['Not found']] unless route&.available?
34
30
 
35
- Route.new(**route).respond(request)
31
+ route.respond(request)
36
32
  end
37
33
 
38
34
  # Build static routes to files.
@@ -42,31 +38,23 @@ module LeanWeb
42
38
  next unless route.static
43
39
 
44
40
  begin
45
- route.static.each { |seed| route.build(route.seed_path(seed)) }
41
+ route.static.each{ |seed| route.build(route.seed_path(seed)) }
46
42
  rescue NoMethodError
47
43
  route.build
48
44
  end
49
45
  end
50
46
  end
51
47
 
52
- # Initialize by evaluating the routes file.
53
- # Do this here so users don't freak out for using eval and rubocop is happy
54
- # on client side.
55
- # @param file [String] Routes file.
56
- def self.init(file = 'routes.rb')
57
- new(eval(File.read(file))) # rubocop:disable Security/Eval
58
- end
59
-
60
48
  protected
61
49
 
62
- # Check if route exists.
63
- # If not on development environment, serve only dynamic routes.
64
- # @param route [Hash]
65
- def route_exists?(route)
66
- return false if route.nil? \
67
- || (ENV['RACK_ENV'] != 'development' && route[:static] != false)
68
-
69
- true
50
+ def find_route(request)
51
+ @routes.find do |r|
52
+ (r[:method] || 'GET') == request.request_method && begin
53
+ r[:path] =~ request.path
54
+ rescue TypeError
55
+ r[:path] == request.path
56
+ end
57
+ end
70
58
  end
71
59
  end
72
60
  end
@@ -8,13 +8,14 @@
8
8
  # see <https://hacktivista.org/licenses/>.
9
9
 
10
10
  require 'rack'
11
+ require 'tilt'
11
12
 
12
13
  module LeanWeb
13
14
  # Controller is a base controller with `@route`, `@request` and `@response`
14
- # private attributes that will be shared with your views when you {render}
15
- # Haml documents.
15
+ # private attributes that will be shared with your views when you
16
+ # {#render_response}.
16
17
  #
17
- # Even if you don't {render}, you can use the `.finish` method from
18
+ # Even if you don't {#render_response}, you can use the `.finish` method from
18
19
  # `Rack::Response` on `@response` to return a proper `Rack` response.
19
20
  class Controller
20
21
  # @param route [Route]
@@ -25,65 +26,65 @@ module LeanWeb
25
26
  @response = Rack::Response.new(nil, 200)
26
27
  end
27
28
 
28
- # Render magic. Supports dynamic (and static) Haml documents, other
29
- # documents don't support dynamic data.
30
- #
31
- # Depending on {Route#path} and {render} `path` you will render different
32
- # documents:
33
- #
34
- # - {Route#path} `/a/b/c` and `render('d')` will render `src/views/a/b/d`
35
- # - {Route#path} `/a/b/c/` and `render('d')` will render `src/views/a/b/c/d`
36
- # - `render('~/custom')` will render `src/views/custom`.
37
- # - `render('/custom')` will render `/custom`.
29
+ # Render magic. Supports every file extension that Tilt supports. Defaults
30
+ # to ERB when file extension is unknown.
38
31
  #
39
32
  # @param path [String] Might be an absolute path or a relative path to
40
- # `src/views/` + the parent path of the last non-capture-group on
41
- # `@route.path`. You can also make it relative to {LeanWeb::VIEW_PATH} by
42
- # prepending `~`.
33
+ # `src/views/`.
43
34
  # @param content_type [String] Defaults to the proper Content-Type for file
44
35
  # extension, `text/plain` on unknown files.
36
+ # @yield Optionally pass a block for nested rendering.
37
+ # @return [Rack::Request#finish] A valid Rack response.
38
+ def render_response(path, content_type = nil, &block)
39
+ template = create_template(path)
40
+ @response.set_header(
41
+ 'Content-Type',
42
+ content_type || template.class.metadata[:mime_type] || 'text/plain'
43
+ )
44
+ @response.write(template.render(self){ block.call if block_given? })
45
+ @response.finish
46
+ end
47
+
48
+ # Template rendering engine. Useful for partials / nested views.
45
49
  #
46
- # @return [Rack::Request#finish] A valid rack response.
47
- def render(path, content_type = nil) # rubocop:disable Metrics/MethodLength
50
+ # @param path [String] Same as on {#render_response}.
51
+ # @param options [Hash] Options for Tilt, defaults to
52
+ # template_defaults[extension].
53
+ # @return [String] Rendered `path`.
54
+ def create_template(path, options = nil)
48
55
  path = absolute_view_path(path)
49
- content = File.read(path)
50
- case File.extname(path)
51
- when '.haml'
52
- require('haml')
53
- @response.write(Haml::Engine.new(content).render(binding))
54
- @response.set_header('Content-Type', content_type || 'text/html')
55
- else
56
- require('erb')
57
- @response.write(ERB.new(content).result(binding))
58
- @response.set_header('Content-Type', content_type || 'text/plain')
59
- end
60
- @response.finish
56
+ ext = File.extname(path)[1..] || ''
57
+ ext = 'erb' unless Tilt.registered?(ext)
58
+ Tilt[ext].new(path, 1, options || template_defaults[ext] || {})
59
+ end
60
+
61
+ # Relative route to path from public directory considering current route.
62
+ #
63
+ # @param path [String] path from public directory, never begins with `/`.
64
+ def base_url(path = '.')
65
+ @base_url ||= @route.str_path[1..]
66
+ .sub(%r{[^/]*$}, '')
67
+ .gsub(%r{[^/]+}, '..')
68
+
69
+ @base_url + path
70
+ end
71
+
72
+ # Request params.
73
+ def params
74
+ @request.params
61
75
  end
62
76
 
63
77
  protected
64
78
 
65
- # @param relative_path [String]
66
- # @return [String] Full path.
67
- def absolute_view_path(relative_path)
68
- case relative_path[0]
69
- when '/'
70
- relative_path
71
- when '~'
72
- relative_path.sub('~', LeanWeb::VIEW_PATH)
73
- else
74
- "#{view_path_by_route_path}/#{relative_path}"
75
- end
79
+ # Set default options for Tilt in the format 'extension' => { options }.
80
+ def template_defaults
81
+ {}
76
82
  end
77
83
 
78
- def view_path_by_route_path
79
- LeanWeb::VIEW_PATH +
80
- if @route.path.instance_of?(Regexp)
81
- File.dirname(@route.str_path.sub(%r{/?\(.*}, ''))
82
- elsif @route.path[-1] != '/'
83
- File.dirname(@route.path)
84
- else
85
- @route.path.chomp('/')
86
- end
84
+ # @param path [String]
85
+ # @return [String] Full path.
86
+ def absolute_view_path(path)
87
+ path[0] == '/' ? path : "#{LeanWeb::VIEW_PATH}/#{path}"
87
88
  end
88
89
  end
89
90
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2022 Felix Freeman <libsys@hacktivista.org>
4
+ #
5
+ # This file is part of "LeanWeb" and licensed under the terms of the Hacktivista
6
+ # General Public License version 0.1 or (at your option) any later version. You
7
+ # should have received a copy of this license along with the software. If not,
8
+ # see <https://hacktivista.org/licenses/>.
9
+
10
+ # String helpers.
11
+ class String
12
+ # String to PascalCase.
13
+ def pascalize
14
+ camelize(pascal: true)
15
+ end
16
+
17
+ # String to camelCase.
18
+ # @param pascal [Boolean] If true first letter is uppercase.
19
+ def camelize(pascal: false)
20
+ str = gsub(/[-_\s]+(.?)/){ |match| match[1].upcase }
21
+ str[0] = pascal ? str[0].upcase : str[0].downcase
22
+ str
23
+ end
24
+ end
data/lib/leanweb/route.rb CHANGED
@@ -7,12 +7,13 @@
7
7
  # should have received a copy of this license along with the software. If not,
8
8
  # see <https://hacktivista.org/licenses/>.
9
9
 
10
+ require 'rack/mock'
10
11
 
11
12
  module LeanWeb
12
13
  # Action for {Route#action}.
13
14
  Action = Struct.new(:file, :controller, :action, keyword_init: true)
14
15
 
15
- # A single route which routes with the {respond} method. It can also {build}
16
+ # A single route which routes with the {#respond} method. It can also {#build}
16
17
  # an static file.
17
18
  class Route
18
19
  attr_reader :path, :method, :action, :static
@@ -21,7 +22,7 @@ module LeanWeb
21
22
  #
22
23
  # @param path [String, Regexp] Path matcher, can be an String or Regexp with
23
24
  # positional or named capture groups, `@action` will receive these as
24
- # positional or named arguments.
25
+ # positional or named arguments. Always begins with `/`.
25
26
  # @param method [String, nil] Must be an HTTP verb such as `GET` or `POST`.
26
27
  # @param action [Proc, Hash, String, nil] References a Method/Proc to be
27
28
  # triggered. It can be:
@@ -30,19 +31,29 @@ module LeanWeb
30
31
  # - A hash with `{ 'file' => 'action' }` only (which has a controller
31
32
  # class name `{File}Controller`).
32
33
  # - A simple string (which will consider file `main.rb` and controller
33
- # `MainController`). Defaults to "{path_basename}_{method}", (ex:
34
+ # `MainController`). Defaults to "{#path_basename}_{#method}", (ex:
34
35
  # `index_get`).
35
36
  # - It can also be a `Proc`.
36
37
  #
37
- # @param static [Boolean|Array] Defines a route as static. Set to `false` to
38
- # say it can only work dynamically. You can also supply an array of arrays
39
- # or hashes to generate static files based on that positional or keyword
40
- # params.
41
- def initialize(path:, method: 'GET', action: nil, static: true)
38
+ # @param static [Boolean|Array] Defines a route as static. Defaults true for
39
+ # GET method, false otherwise. Set to `false` to say it can only work
40
+ # dynamically. You can also supply an array of arrays or hashes to
41
+ # generate static files based on that positional or keyword params.
42
+ def initialize(path:, method: 'GET', action: nil, static: nil)
42
43
  @path = path
43
44
  @method = method
44
45
  self.action = action
45
- @static = static
46
+ @static = static.nil? ? @method == 'GET' : static
47
+ end
48
+
49
+ # Check if route is available.
50
+ #
51
+ # If on production environment (not `development`), should serve only
52
+ # dynamic (not `static`) routes.
53
+ def available?
54
+ return @static == false if ENV['RACK_ENV'] != 'development'
55
+
56
+ true
46
57
  end
47
58
 
48
59
  # Last identifier on a path, returns `index` for `/`.
@@ -51,14 +62,14 @@ module LeanWeb
51
62
  end
52
63
 
53
64
  # @param request [Rack::Request]
54
- # @return a valid rack response.
65
+ # @return [Array] a valid rack response.
55
66
  def respond(request)
56
67
  return respond_proc(request) if @action.instance_of?(Proc)
57
68
 
58
69
  respond_method(request)
59
70
  end
60
71
 
61
- # String path, independent if {path} is Regexp or String.
72
+ # String path, independent if {#path} is Regexp or String.
62
73
  def str_path
63
74
  @path.source.gsub(/[\^$]/, '')
64
75
  rescue NoMethodError
@@ -66,26 +77,26 @@ module LeanWeb
66
77
  end
67
78
 
68
79
  # On Regexp paths, return a string valid for making a request to this route.
80
+ #
69
81
  # @param seed [Array, Hash] Seeds to use as replacement on capture groups.
70
82
  # @return [String] sown path.
71
83
  def seed_path(seed)
72
84
  sown_path = str_path
73
85
  if seed.instance_of?(Hash)
74
- seed.each { |key, val| sown_path.sub!(/\(\?<#{key}>[^)]+\)/, val) }
86
+ seed.each{ |key, val| sown_path.sub!(/\(\?<#{key}>[^)]+\)/, val) }
75
87
  else
76
- seed.each { |val| sown_path.sub!(/\([^)]+\)/, val) }
88
+ seed.each{ |val| sown_path.sub!(/\([^)]+\)/, val) }
77
89
  end
78
90
  sown_path
79
91
  end
80
92
 
81
93
  # Build this route as an static file and place it relative to
82
94
  # {LeanWeb::PUBLIC_PATH}.
95
+ #
83
96
  # @param request_path [String] Request path for dynamic (regex) routes.
84
97
  def build(request_path = @path)
85
98
  response = respond(
86
- Rack::Request.new(
87
- { 'PATH_INFO' => request_path, 'REQUEST_METHOD' => 'GET' }
88
- )
99
+ Rack::Request.new(Rack::MockRequest.env_for(request_path))
89
100
  )
90
101
  out_path = output_path(request_path, response[1]['Content-Type'] || nil)
91
102
  FileUtils.mkdir_p(File.dirname(out_path))
@@ -104,36 +115,44 @@ module LeanWeb
104
115
  end
105
116
  end
106
117
 
107
- # @param value [Hash, String, nil] Check {initialize} action param for
118
+ # @param src_value [Hash, String, nil] Check {#initialize} action param for
108
119
  # valid input.
109
120
  # @return [Hash] valid hash for {Action}.
110
- def prepare_action_hash(value)
121
+ def prepare_action_hash(src_value) # rubocop:disable Metrics/MethodLength
111
122
  begin
112
- value[:file], value[:action] = value.first \
113
- unless %i[file controller action].include?(value.keys.first)
123
+ if %i[file controller action].include?(src_value.keys.first)
124
+ value = src_value
125
+ else
126
+ value = {}
127
+ value[:file], value[:action] = src_value.first
128
+ end
114
129
  rescue NoMethodError
115
- value = { action: value }
130
+ value = { action: src_value }
116
131
  end
117
132
  value[:file] ||= 'main'
118
- value[:controller] ||= "#{value[:file].capitalize}Controller"
119
- value[:action] ||= "#{path_basename}_#{@method.downcase}"
133
+ value[:controller] ||= "#{value[:file].pascalize}Controller"
134
+ value[:action] ||= default_action_name
120
135
  value
121
136
  end
122
137
 
138
+ def default_action_name
139
+ "#{path_basename.gsub('-', '_')}_#{@method.downcase}"
140
+ end
141
+
123
142
  # @param request [Rack::Request]
124
- # @return a valid rack response.
143
+ # @return [Array] a valid Rack response.
125
144
  def respond_method(request)
126
145
  params = action_params(request.path)
127
146
  require_relative("#{LeanWeb::CONTROLLER_PATH}/#{@action.file}")
128
147
  controller = Object.const_get(@action.controller).new(self, request)
129
- return controller.public_send(@action.action, **params)\
148
+ return controller.public_send(@action.action, **params) \
130
149
  if params.instance_of?(Hash)
131
150
 
132
151
  controller.public_send(@action.action, *params)
133
152
  end
134
153
 
135
154
  # @param request [Rack::Request]
136
- # @return a valid rack response.
155
+ # @return [Array] a valid Rack response.
137
156
  def respond_proc(request)
138
157
  params = action_params(request.path)
139
158
  return @action.call(**params) if params.instance_of?(Hash)
@@ -147,13 +166,14 @@ module LeanWeb
147
166
  return nil unless @path.instance_of?(Regexp)
148
167
 
149
168
  matches = @path.match(request_path)
150
- return matches.named_captures.transform_keys(&:to_sym)\
169
+ return matches.named_captures.transform_keys(&:to_sym) \
151
170
  if matches.named_captures != {}
152
171
 
153
172
  matches.captures
154
173
  end
155
174
 
156
175
  # Output path for public file.
176
+ #
157
177
  # @param path [String]
158
178
  # @param content_type [String]
159
179
  # @return [String] absolute route to path + extension based on content_type.
data/lib/leanweb.rb CHANGED
@@ -9,9 +9,9 @@
9
9
 
10
10
  # LeanWeb is a minimal hybrid static / dynamic web framework.
11
11
  module LeanWeb
12
- VERSION = '0.1.3'
12
+ VERSION = '0.2.0'
13
13
 
14
- ROOT_PATH = ENV['LEANWEB_ROOT_PATH'] || Dir.pwd
14
+ ROOT_PATH = ENV.fetch('LEANWEB_ROOT_PATH', Dir.pwd)
15
15
  CONTROLLER_PATH = "#{ROOT_PATH}/src/controllers"
16
16
  VIEW_PATH = "#{ROOT_PATH}/src/views"
17
17
  PUBLIC_PATH = "#{ROOT_PATH}/public"
@@ -21,10 +21,18 @@ module LeanWeb
21
21
  'application/javascript' => '.js',
22
22
  'application/json' => '.json',
23
23
  'text/html' => '.html',
24
- 'text/plain' => '.txt'
24
+ 'text/plain' => '.txt',
25
+ 'text/css' => '.css',
26
+ 'text/csv' => '.csv'
25
27
  }.freeze
26
28
 
27
29
  autoload :Route, 'leanweb/route.rb'
28
30
  autoload :Controller, 'leanweb/controller.rb'
29
31
  autoload :App, 'leanweb/app.rb'
30
32
  end
33
+
34
+ require_relative 'leanweb/helpers'
35
+
36
+ # TODO: Remove if/when tilt-emacs_org gets merged on a Tilt release.
37
+ require 'tilt'
38
+ Tilt.register_lazy(:EmacsOrgTemplate, 'tilt/emacs_org', 'org')
metadata CHANGED
@@ -1,113 +1,141 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leanweb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix Freeman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-07 00:00:00.000000000 Z
11
+ date: 2022-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: haml
14
+ name: rack
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 2.2.4
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: 2.2.4
27
27
  - !ruby/object:Gem::Dependency
28
- name: rack
28
+ name: tilt
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 2.0.10
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 2.0.10
41
41
  - !ruby/object:Gem::Dependency
42
- name: rake
42
+ name: haml
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :runtime
47
+ version: 5.2.2
48
+ type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 5.2.2
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: minitest
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 5.16.2
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 5.16.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 13.0.6
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 13.0.6
83
+ - !ruby/object:Gem::Dependency
84
+ name: redcarpet
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
60
88
  - !ruby/object:Gem::Version
61
- version: '0'
89
+ version: 3.5.1
62
90
  type: :development
63
91
  prerelease: false
64
92
  version_requirements: !ruby/object:Gem::Requirement
65
93
  requirements:
66
- - - ">="
94
+ - - "~>"
67
95
  - !ruby/object:Gem::Version
68
- version: '0'
96
+ version: 3.5.1
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: rubocop
71
99
  requirement: !ruby/object:Gem::Requirement
72
100
  requirements:
73
- - - ">="
101
+ - - "~>"
74
102
  - !ruby/object:Gem::Version
75
- version: '0'
103
+ version: 1.31.2
76
104
  type: :development
77
105
  prerelease: false
78
106
  version_requirements: !ruby/object:Gem::Requirement
79
107
  requirements:
80
- - - ">="
108
+ - - "~>"
81
109
  - !ruby/object:Gem::Version
82
- version: '0'
110
+ version: 1.31.2
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: rubocop-minitest
85
113
  requirement: !ruby/object:Gem::Requirement
86
114
  requirements:
87
- - - ">="
115
+ - - "~>"
88
116
  - !ruby/object:Gem::Version
89
- version: '0'
117
+ version: 0.20.1
90
118
  type: :development
91
119
  prerelease: false
92
120
  version_requirements: !ruby/object:Gem::Requirement
93
121
  requirements:
94
- - - ">="
122
+ - - "~>"
95
123
  - !ruby/object:Gem::Version
96
- version: '0'
124
+ version: 0.20.1
97
125
  - !ruby/object:Gem::Dependency
98
126
  name: yard
99
127
  requirement: !ruby/object:Gem::Requirement
100
128
  requirements:
101
- - - ">="
129
+ - - "~>"
102
130
  - !ruby/object:Gem::Version
103
- version: '0'
131
+ version: 0.9.28
104
132
  type: :development
105
133
  prerelease: false
106
134
  version_requirements: !ruby/object:Gem::Requirement
107
135
  requirements:
108
- - - ">="
136
+ - - "~>"
109
137
  - !ruby/object:Gem::Version
110
- version: '0'
138
+ version: 0.9.28
111
139
  description:
112
140
  email:
113
141
  - libsys@hacktivista.org
@@ -120,14 +148,17 @@ files:
120
148
  - lib/leanweb.rb
121
149
  - lib/leanweb/app.rb
122
150
  - lib/leanweb/controller.rb
151
+ - lib/leanweb/helpers.rb
123
152
  - lib/leanweb/route.rb
124
- homepage: https://git.hacktivista.org/leanweb
153
+ homepage: https://leanweb.hacktivista.org
125
154
  licenses:
126
155
  - LicenseRef-LICENSE
127
156
  metadata:
128
- homepage_uri: https://git.hacktivista.org/leanweb
157
+ homepage_uri: https://leanweb.hacktivista.org
129
158
  source_code_uri: https://git.hacktivista.org/leanweb
159
+ changelog_uri: https://leanweb.hacktivista.org/file.CHANGELOG.html
130
160
  rubygems_mfa_required: 'true'
161
+ yard.run: yri
131
162
  post_install_message:
132
163
  rdoc_options: []
133
164
  require_paths:
@@ -136,7 +167,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
136
167
  requirements:
137
168
  - - ">="
138
169
  - !ruby/object:Gem::Version
139
- version: 2.5.0
170
+ version: 2.7.4
140
171
  required_rubygems_version: !ruby/object:Gem::Requirement
141
172
  requirements:
142
173
  - - ">="