From 70337f8e65685ccffa726a886a235303e6a82862 Mon Sep 17 00:00:00 2001 From: plastmastick Date: Thu, 22 Sep 2022 19:18:50 +0300 Subject: [PATCH 1/9] ci: gitignor & rubocop init --- .gitignore | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ .rubocop.yml | 16 +++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 .gitignore create mode 100644 .rubocop.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..bc854320 --- /dev/null +++ b/.gitignore @@ -0,0 +1,58 @@ +*.gem +*.rbc +*.log +/.idea +/.config +/coverage/ +/InstalledFiles +/pkg/ +/spec/reports/ +/spec/examples.txt +/test/tmp/ +/test/version_tmp/ +/tmp/ + +# Used by dotenv library to load environment variables. +# .env + +# Ignore Byebug command history file. +.byebug_history + +## Specific to RubyMotion: +.dat* +.repl_history +build/ +*.bridgesupport +build-iPhoneOS/ +build-iPhoneSimulator/ + +## Specific to RubyMotion (use of CocoaPods): +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# vendor/Pods/ + +## Documentation cache and generated files: +/.yardoc/ +/_yardoc/ +/doc/ +/rdoc/ + +## Environment normalization: +/.bundle/ +/vendor/bundle +/lib/bundler/man/ + +# for a library or gem, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# Gemfile.lock +# .ruby-version +# .ruby-gemset + +# unless supporting rvm < 1.11.0 or doing something fancy, ignore this: +.rvmrc + +# Used by RuboCop. Remote config files pulled in from inherit_from directive. +# .rubocop-https?--* diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 00000000..1f670a23 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,16 @@ +AllCops: + NewCops: enable + Exclude: + - 'vendor/**/*' + - 'spec/fixtures/**/*' + - 'tmp/**/*' + - '.git/**/*' + - 'bin/*' + TargetRubyVersion: 3.0 + SuggestExtensions: false + +Metrics/AbcSize: + Max: 17 + +Style/Documentation: + Enabled: false From 685553da95e07a6d99dd25c2a2721a05e623dbff Mon Sep 17 00:00:00 2001 From: plastmastick Date: Thu, 22 Sep 2022 19:39:46 +0300 Subject: [PATCH 2/9] feat: test index view upd --- app/controllers/tests_controller.rb | 1 + app/views/tests/index.html.erb | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/controllers/tests_controller.rb b/app/controllers/tests_controller.rb index 1526a689..a1839108 100644 --- a/app/controllers/tests_controller.rb +++ b/app/controllers/tests_controller.rb @@ -2,6 +2,7 @@ class TestsController < Simpler::Controller def index @time = Time.now + @tests = Test.all end def create diff --git a/app/views/tests/index.html.erb b/app/views/tests/index.html.erb index 39fce580..6bf643d0 100644 --- a/app/views/tests/index.html.erb +++ b/app/views/tests/index.html.erb @@ -8,5 +8,11 @@

Simpler framework at work!

<%= @time %>

+ + - \ No newline at end of file + From 257188eafa8b99bd11de139965942b0c2bf95f7f Mon Sep 17 00:00:00 2001 From: plastmastick Date: Thu, 22 Sep 2022 21:01:00 +0300 Subject: [PATCH 3/9] feat: add render plain & render types --- lib/simpler/controller.rb | 1 + lib/simpler/view.rb | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/simpler/controller.rb b/lib/simpler/controller.rb index 9383b035..f4f2a399 100644 --- a/lib/simpler/controller.rb +++ b/lib/simpler/controller.rb @@ -47,6 +47,7 @@ def params end def render(template) + template = { file: template} unless template.is_a?(Hash) @request.env['simpler.template'] = template end diff --git a/lib/simpler/view.rb b/lib/simpler/view.rb index 19a73b34..b29006f7 100644 --- a/lib/simpler/view.rb +++ b/lib/simpler/view.rb @@ -4,15 +4,17 @@ module Simpler class View VIEW_BASE_PATH = 'app/views'.freeze + RENDER_TYPE = { + file: :file_render, + plain: :plain_render + }.freeze def initialize(env) @env = env end def render(binding) - template = File.read(template_path) - - ERB.new(template).result(binding) + send(RENDER_TYPE[template.keys.first], binding) end private @@ -30,10 +32,20 @@ def template end def template_path - path = template || [controller.name, action].join('/') + path = template[:file] || [controller.name, action].join('/') Simpler.root.join(VIEW_BASE_PATH, "#{path}.html.erb") end + def file_render(binding) + template = File.read(template_path) + + ERB.new(template).result(binding) + end + + def plain_render(_binding) + template[:plain] + end + end end From c11f6daf8330710ce17258bec946cf86e7a1c1e9 Mon Sep 17 00:00:00 2001 From: plastmastick Date: Thu, 22 Sep 2022 21:49:00 +0300 Subject: [PATCH 4/9] fix: render default view --- lib/simpler/view.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/simpler/view.rb b/lib/simpler/view.rb index b29006f7..f4a96a48 100644 --- a/lib/simpler/view.rb +++ b/lib/simpler/view.rb @@ -14,7 +14,7 @@ def initialize(env) end def render(binding) - send(RENDER_TYPE[template.keys.first], binding) + send(template ? RENDER_TYPE[template.keys.first] : :file_render, binding) end private @@ -32,7 +32,7 @@ def template end def template_path - path = template[:file] || [controller.name, action].join('/') + path = template ? template[:file] : [controller.name, action].join('/') Simpler.root.join(VIEW_BASE_PATH, "#{path}.html.erb") end From 0694f69ec73346bb05b406fe2b1360679c11c283 Mon Sep 17 00:00:00 2001 From: plastmastick Date: Fri, 23 Sep 2022 01:20:31 +0300 Subject: [PATCH 5/9] feat: add set status & header methods for controller; add routes check on init --- config.ru | 2 +- lib/simpler/application.rb | 6 +++++- lib/simpler/controller.rb | 10 ++++++++++ lib/simpler/router.rb | 3 ++- lib/simpler/router/route.rb | 2 +- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/config.ru b/config.ru index 3060cc20..81ec4ae9 100644 --- a/config.ru +++ b/config.ru @@ -1,3 +1,3 @@ require_relative 'config/environment' -run Simpler.application +run Simpler.application.app_routes diff --git a/lib/simpler/application.rb b/lib/simpler/application.rb index 711946a9..b47e6eb8 100644 --- a/lib/simpler/application.rb +++ b/lib/simpler/application.rb @@ -9,7 +9,7 @@ class Application include Singleton - attr_reader :db + attr_reader :db, :app_routes, :router def initialize @router = Router.new @@ -24,6 +24,10 @@ def bootstrap! def routes(&block) @router.instance_eval(&block) + + route_paths = {} + @router.routes.each { |route| route_paths[route.path] = Simpler.application} + @app_routes = Rack::URLMap.new(route_paths) end def call(env) diff --git a/lib/simpler/controller.rb b/lib/simpler/controller.rb index f4f2a399..16792f53 100644 --- a/lib/simpler/controller.rb +++ b/lib/simpler/controller.rb @@ -9,6 +9,7 @@ def initialize(env) @name = extract_name @request = Rack::Request.new(env) @response = Rack::Response.new + @status_code = nil end def make_response(action) @@ -18,6 +19,7 @@ def make_response(action) set_default_headers send(action) write_response + @response.status = @status_code unless @status_code.nil? || @response.status == 500 @response.finish end @@ -51,5 +53,13 @@ def render(template) @request.env['simpler.template'] = template end + def responce_status_set(code) + @status_code = code + end + + def responce_headers_set(headers) + headers.each { |k, v| @response[k.to_s] = v.to_s } + end + end end diff --git a/lib/simpler/router.rb b/lib/simpler/router.rb index 14b3415c..2a7647ad 100644 --- a/lib/simpler/router.rb +++ b/lib/simpler/router.rb @@ -2,6 +2,7 @@ module Simpler class Router + attr_reader :routes def initialize @routes = [] @@ -17,7 +18,7 @@ def post(path, route_point) def route_for(env) method = env['REQUEST_METHOD'].downcase.to_sym - path = env['PATH_INFO'] + path = env['REQUEST_PATH'] @routes.find { |route| route.match?(method, path) } end diff --git a/lib/simpler/router/route.rb b/lib/simpler/router/route.rb index 4c66b4b7..7153c6c6 100644 --- a/lib/simpler/router/route.rb +++ b/lib/simpler/router/route.rb @@ -2,7 +2,7 @@ module Simpler class Router class Route - attr_reader :controller, :action + attr_reader :controller, :action, :path def initialize(method, path, controller, action) @method = method From f1d396ad9b0f2a31240567b380fc13cdd8707c74 Mon Sep 17 00:00:00 2001 From: plastmastick Date: Fri, 23 Sep 2022 20:29:31 +0300 Subject: [PATCH 6/9] feat: params from routes --- app/controllers/tests_controller.rb | 4 +++- app/views/tests/show.html.erb | 14 ++++++++++++++ config/routes.rb | 1 + lib/simpler/application.rb | 15 +++++++++++++++ lib/simpler/controller.rb | 4 ++-- lib/simpler/router/route.rb | 19 ++++++++++++++++++- 6 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 app/views/tests/show.html.erb diff --git a/app/controllers/tests_controller.rb b/app/controllers/tests_controller.rb index a1839108..60ecd1c1 100644 --- a/app/controllers/tests_controller.rb +++ b/app/controllers/tests_controller.rb @@ -5,8 +5,10 @@ def index @tests = Test.all end - def create + def create; end + def show + @params = params end end diff --git a/app/views/tests/show.html.erb b/app/views/tests/show.html.erb new file mode 100644 index 00000000..0429eda3 --- /dev/null +++ b/app/views/tests/show.html.erb @@ -0,0 +1,14 @@ + + + + + Show | Simpler application + + + +

<%= @time %>

+ +

<%= @params %>

+ + + diff --git a/config/routes.rb b/config/routes.rb index 4a751251..347c4041 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Simpler.application.routes do + get '/tests/:id', 'tests#show' get '/tests', 'tests#index' post '/tests', 'tests#create' end diff --git a/lib/simpler/application.rb b/lib/simpler/application.rb index b47e6eb8..a95f284a 100644 --- a/lib/simpler/application.rb +++ b/lib/simpler/application.rb @@ -34,6 +34,7 @@ def call(env) route = @router.route_for(env) controller = route.controller.new(env) action = route.action + env['simpler.request_params'] = setup_params(route, env['REQUEST_PATH']) make_response(controller, action) end @@ -58,5 +59,19 @@ def make_response(controller, action) controller.make_response(action) end + def setup_params(route, path) + params = {} + self_elements = route.route_elements + path_elements = path.split('/') + + + path_elements.each do |e| + p_index = path_elements.index(e) + params[self_elements[p_index]] = e.to_i if e.to_i.positive? && self_elements[p_index].is_a?(Symbol) + end + + params + end + end end diff --git a/lib/simpler/controller.rb b/lib/simpler/controller.rb index 16792f53..3c3cc6c5 100644 --- a/lib/simpler/controller.rb +++ b/lib/simpler/controller.rb @@ -45,11 +45,11 @@ def render_body end def params - @request.params + @request.env['simpler.request_params'] end def render(template) - template = { file: template} unless template.is_a?(Hash) + template = { file: template } unless template.is_a?(Hash) @request.env['simpler.template'] = template end diff --git a/lib/simpler/router/route.rb b/lib/simpler/router/route.rb index 7153c6c6..49c54382 100644 --- a/lib/simpler/router/route.rb +++ b/lib/simpler/router/route.rb @@ -12,7 +12,24 @@ def initialize(method, path, controller, action) end def match?(method, path) - @method == method && path.match(@path) + @method == method && convert_to_route_format(path).match(@path) + end + + def route_elements + @path.split('/').map { |e| e.include?(':') ? e[1..].to_sym : e } + end + + private + + def convert_to_route_format(path) + self_elements = route_elements + path_elements = path.split('/') + + + path_elements.map do |e| + p_index = path_elements.index(e) + e.to_i.positive? && self_elements[p_index].is_a?(Symbol) ? ":#{self_elements[p_index]}" : e + end.join('/') end end From 9f7a166b69148d69f3cdb13de325aedb968f6ecf Mon Sep 17 00:00:00 2001 From: plastmastick Date: Fri, 23 Sep 2022 21:04:05 +0300 Subject: [PATCH 7/9] fix: route elements extract --- lib/simpler/router/route.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/simpler/router/route.rb b/lib/simpler/router/route.rb index 49c54382..aa81e651 100644 --- a/lib/simpler/router/route.rb +++ b/lib/simpler/router/route.rb @@ -16,7 +16,7 @@ def match?(method, path) end def route_elements - @path.split('/').map { |e| e.include?(':') ? e[1..].to_sym : e } + @path.split('/').map { |e| e.start_with?(':') ? e[1..].to_sym : e } end private From ed162d4c18a74832101576d36e0f6c4a5315d403 Mon Sep 17 00:00:00 2001 From: plastmastick Date: Fri, 23 Sep 2022 21:46:24 +0300 Subject: [PATCH 8/9] feat: add logger --- config.ru | 2 ++ lib/middleware/logger.rb | 33 +++++++++++++++++++++++++++++++++ lib/simpler/view.rb | 3 ++- 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 lib/middleware/logger.rb diff --git a/config.ru b/config.ru index 81ec4ae9..56cfc944 100644 --- a/config.ru +++ b/config.ru @@ -1,3 +1,5 @@ require_relative 'config/environment' +require_relative 'lib/middleware/logger' +use AppLogger run Simpler.application.app_routes diff --git a/lib/middleware/logger.rb b/lib/middleware/logger.rb new file mode 100644 index 00000000..b5b8d5c0 --- /dev/null +++ b/lib/middleware/logger.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'logger' + +class AppLogger + + def initialize(app) + @logger = Logger.new(Simpler.root.join('log/app.log')) + @app = app + end + + def call(env) + status, headers, response = @app.call(env) + @logger.info(log_create(env, status, headers)) + [status, headers, response] + end + + private + + def log_create(env, status, headers) + { + Request: "#{env['REQUEST_METHOD']} #{env['REQUEST_PATH']}", + Handler: "#{env['simpler.controller'].class}##{env['simpler.action']}", + Parameters: env['simpler.request_params'], + Response: "#{status} [#{headers['Content-Type']}] #{env['simpler.template_path']}" + } + end +end + +# Request: GET /tests?category=Backend +# Handler: TestsController#index +# Parameters: {'category' => 'Backend'} +# Response: 200 OK [text/html] tests/index.html.erb diff --git a/lib/simpler/view.rb b/lib/simpler/view.rb index f4a96a48..9781a12e 100644 --- a/lib/simpler/view.rb +++ b/lib/simpler/view.rb @@ -33,8 +33,9 @@ def template def template_path path = template ? template[:file] : [controller.name, action].join('/') + @env['simpler.template_path'] = "#{path}.html.erb" - Simpler.root.join(VIEW_BASE_PATH, "#{path}.html.erb") + Simpler.root.join(VIEW_BASE_PATH, @env['simpler.template_path']) end def file_render(binding) From dd69bbff96ec7d44b3d21f9e6dc884f2af0367af Mon Sep 17 00:00:00 2001 From: plastmastick Date: Fri, 23 Sep 2022 21:47:08 +0300 Subject: [PATCH 9/9] rubocop fixs --- app/controllers/tests_controller.rb | 4 ++-- app/models/test.rb | 3 ++- config.ru | 2 ++ config/environment.rb | 2 ++ config/routes.rb | 2 ++ lib/middleware/logger.rb | 6 ------ lib/simpler.rb | 4 ++-- lib/simpler/application.rb | 7 +++---- lib/simpler/controller.rb | 4 ++-- lib/simpler/router.rb | 3 ++- lib/simpler/router/route.rb | 5 ++--- lib/simpler/view.rb | 6 +++--- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/app/controllers/tests_controller.rb b/app/controllers/tests_controller.rb index 60ecd1c1..ed7e9732 100644 --- a/app/controllers/tests_controller.rb +++ b/app/controllers/tests_controller.rb @@ -1,5 +1,6 @@ -class TestsController < Simpler::Controller +# frozen_string_literal: true +class TestsController < Simpler::Controller def index @time = Time.now @tests = Test.all @@ -10,5 +11,4 @@ def create; end def show @params = params end - end diff --git a/app/models/test.rb b/app/models/test.rb index 86376668..db135e04 100644 --- a/app/models/test.rb +++ b/app/models/test.rb @@ -1,8 +1,9 @@ +# frozen_string_literal: true + # Simpler.application.db.create_table(:tests) do # primary_key :id # String :title, null: false # Integer :level, default: 0 # end class Test < Sequel::Model - end diff --git a/config.ru b/config.ru index 56cfc944..c582bf46 100644 --- a/config.ru +++ b/config.ru @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative 'config/environment' require_relative 'lib/middleware/logger' diff --git a/config/environment.rb b/config/environment.rb index 7a0d38c3..a566c8d3 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative '../lib/simpler' Simpler.application.bootstrap! diff --git a/config/routes.rb b/config/routes.rb index 347c4041..f6c3b1e0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Simpler.application.routes do get '/tests/:id', 'tests#show' get '/tests', 'tests#index' diff --git a/lib/middleware/logger.rb b/lib/middleware/logger.rb index b5b8d5c0..6b54d0c5 100644 --- a/lib/middleware/logger.rb +++ b/lib/middleware/logger.rb @@ -3,7 +3,6 @@ require 'logger' class AppLogger - def initialize(app) @logger = Logger.new(Simpler.root.join('log/app.log')) @app = app @@ -26,8 +25,3 @@ def log_create(env, status, headers) } end end - -# Request: GET /tests?category=Backend -# Handler: TestsController#index -# Parameters: {'category' => 'Backend'} -# Response: 200 OK [text/html] tests/index.html.erb diff --git a/lib/simpler.rb b/lib/simpler.rb index f9dfe3c4..6fb23105 100644 --- a/lib/simpler.rb +++ b/lib/simpler.rb @@ -1,8 +1,9 @@ +# frozen_string_literal: true + require 'pathname' require_relative 'simpler/application' module Simpler - class << self def application Application.instance @@ -12,5 +13,4 @@ def root Pathname.new(File.expand_path('..', __dir__)) end end - end diff --git a/lib/simpler/application.rb b/lib/simpler/application.rb index a95f284a..b3f7f45d 100644 --- a/lib/simpler/application.rb +++ b/lib/simpler/application.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'yaml' require 'singleton' require 'sequel' @@ -6,7 +8,6 @@ module Simpler class Application - include Singleton attr_reader :db, :app_routes, :router @@ -26,7 +27,7 @@ def routes(&block) @router.instance_eval(&block) route_paths = {} - @router.routes.each { |route| route_paths[route.path] = Simpler.application} + @router.routes.each { |route| route_paths[route.path] = Simpler.application } @app_routes = Rack::URLMap.new(route_paths) end @@ -64,7 +65,6 @@ def setup_params(route, path) self_elements = route.route_elements path_elements = path.split('/') - path_elements.each do |e| p_index = path_elements.index(e) params[self_elements[p_index]] = e.to_i if e.to_i.positive? && self_elements[p_index].is_a?(Symbol) @@ -72,6 +72,5 @@ def setup_params(route, path) params end - end end diff --git a/lib/simpler/controller.rb b/lib/simpler/controller.rb index 3c3cc6c5..915aec4b 100644 --- a/lib/simpler/controller.rb +++ b/lib/simpler/controller.rb @@ -1,8 +1,9 @@ +# frozen_string_literal: true + require_relative 'view' module Simpler class Controller - attr_reader :name, :request, :response def initialize(env) @@ -60,6 +61,5 @@ def responce_status_set(code) def responce_headers_set(headers) headers.each { |k, v| @response[k.to_s] = v.to_s } end - end end diff --git a/lib/simpler/router.rb b/lib/simpler/router.rb index 2a7647ad..a84ced96 100644 --- a/lib/simpler/router.rb +++ b/lib/simpler/router.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative 'router/route' module Simpler @@ -37,6 +39,5 @@ def add_route(method, path, route_point) def controller_from_string(controller_name) Object.const_get("#{controller_name.capitalize}Controller") end - end end diff --git a/lib/simpler/router/route.rb b/lib/simpler/router/route.rb index aa81e651..5c8ac51f 100644 --- a/lib/simpler/router/route.rb +++ b/lib/simpler/router/route.rb @@ -1,7 +1,8 @@ +# frozen_string_literal: true + module Simpler class Router class Route - attr_reader :controller, :action, :path def initialize(method, path, controller, action) @@ -25,13 +26,11 @@ def convert_to_route_format(path) self_elements = route_elements path_elements = path.split('/') - path_elements.map do |e| p_index = path_elements.index(e) e.to_i.positive? && self_elements[p_index].is_a?(Symbol) ? ":#{self_elements[p_index]}" : e end.join('/') end - end end end diff --git a/lib/simpler/view.rb b/lib/simpler/view.rb index 9781a12e..4d60b5ca 100644 --- a/lib/simpler/view.rb +++ b/lib/simpler/view.rb @@ -1,9 +1,10 @@ +# frozen_string_literal: true + require 'erb' module Simpler class View - - VIEW_BASE_PATH = 'app/views'.freeze + VIEW_BASE_PATH = 'app/views' RENDER_TYPE = { file: :file_render, plain: :plain_render @@ -47,6 +48,5 @@ def file_render(binding) def plain_render(_binding) template[:plain] end - end end