Skip to content
This repository was archived by the owner on Nov 25, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -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?--*
16 changes: 16 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -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
9 changes: 6 additions & 3 deletions app/controllers/tests_controller.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
class TestsController < Simpler::Controller
# frozen_string_literal: true

class TestsController < Simpler::Controller
def index
@time = Time.now
@tests = Test.all
end

def create
def create; end

def show
@params = params
end

end
3 changes: 2 additions & 1 deletion app/models/test.rb
Original file line number Diff line number Diff line change
@@ -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
8 changes: 7 additions & 1 deletion app/views/tests/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,11 @@
<h1>Simpler framework at work!</h1>

<p><%= @time %></p>

<ul>
<% @tests.each do |test| %>
<li><%= test.title %> (<%= test.level %>)</li>
<% end %>
</ul>
</body>
</html>
</html>
14 changes: 14 additions & 0 deletions app/views/tests/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Show | Simpler application</title>
</head>
<body>

<p><%= @time %></p>

<p><%= @params %></p>

</body>
</html>
6 changes: 5 additions & 1 deletion config.ru
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# frozen_string_literal: true

require_relative 'config/environment'
require_relative 'lib/middleware/logger'

run Simpler.application
use AppLogger
run Simpler.application.app_routes
2 changes: 2 additions & 0 deletions config/environment.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require_relative '../lib/simpler'

Simpler.application.bootstrap!
3 changes: 3 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# frozen_string_literal: true

Simpler.application.routes do
get '/tests/:id', 'tests#show'
get '/tests', 'tests#index'
post '/tests', 'tests#create'
end
27 changes: 27 additions & 0 deletions lib/middleware/logger.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# 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
4 changes: 2 additions & 2 deletions lib/simpler.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# frozen_string_literal: true

require 'pathname'
require_relative 'simpler/application'

module Simpler

class << self
def application
Application.instance
Expand All @@ -12,5 +13,4 @@ def root
Pathname.new(File.expand_path('..', __dir__))
end
end

end
22 changes: 20 additions & 2 deletions lib/simpler/application.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'yaml'
require 'singleton'
require 'sequel'
Expand All @@ -6,10 +8,9 @@

module Simpler
class Application

include Singleton

attr_reader :db
attr_reader :db, :app_routes, :router

def initialize
@router = Router.new
Expand All @@ -24,12 +25,17 @@ 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)
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
Expand All @@ -54,5 +60,17 @@ 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
15 changes: 13 additions & 2 deletions lib/simpler/controller.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# frozen_string_literal: true

require_relative 'view'

module Simpler
class Controller

attr_reader :name, :request, :response

def initialize(env)
@name = extract_name
@request = Rack::Request.new(env)
@response = Rack::Response.new
@status_code = nil
end

def make_response(action)
Expand All @@ -18,6 +20,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
Expand All @@ -43,12 +46,20 @@ 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)
@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
6 changes: 4 additions & 2 deletions lib/simpler/router.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# frozen_string_literal: true

require_relative 'router/route'

module Simpler
class Router
attr_reader :routes

def initialize
@routes = []
Expand All @@ -17,7 +20,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
Expand All @@ -36,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
22 changes: 19 additions & 3 deletions lib/simpler/router/route.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# frozen_string_literal: true

module Simpler
class Router
class Route

attr_reader :controller, :action
attr_reader :controller, :action, :path

def initialize(method, path, controller, action)
@method = method
Expand All @@ -12,9 +13,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.start_with?(':') ? 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
end
end
Loading