radical 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +0 -2
- data/CHANGELOG.md +14 -3
- data/README.md +5 -1
- data/lib/radical/app.rb +6 -24
- data/lib/radical/controller.rb +2 -0
- data/lib/radical/database.rb +42 -43
- data/lib/radical/env.rb +1 -0
- data/lib/radical/form.rb +2 -0
- data/lib/radical/migration.rb +45 -0
- data/lib/radical/model.rb +2 -11
- data/lib/radical/router.rb +3 -1
- data/lib/radical/routes.rb +48 -0
- data/lib/radical/table.rb +2 -0
- data/lib/radical/view.rb +2 -0
- data/lib/radical.rb +4 -0
- data/radical.gemspec +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a2836f72234086fb3981b282d57216a2d324ecdd2f14e3b38a1ce57b2757be3
|
4
|
+
data.tar.gz: 14de9ad7784177b1ee837c9b12d2888ffdf50ea268bbcdffc0f3d6a54238a312
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15fd6c727f86820b1644a984d3d125ed02d65aa7aed4f1cfb292a216fda7a6d9b2f232bb680c9ab05417bddf410c6a75495dce74edd2fc278f7a9b7589d0da4b
|
7
|
+
data.tar.gz: 82c51dc592446f8a4492ba36e11e947aa20a8f937ae78b541d952a4156a88fac25b25eaec3d2de583a88a42cccd5de18297ec7b2eeba4f9eb69a7b2cb11bfeb4
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,19 +1,30 @@
|
|
1
1
|
# Changelog
|
2
|
+
|
2
3
|
All notable changes to this project will be documented in this file
|
3
4
|
|
4
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
5
6
|
|
6
7
|
# [Unreleased]
|
7
8
|
|
8
|
-
# 1.0
|
9
|
+
# 1.1.0 (2021-12-06)
|
10
|
+
|
11
|
+
- *Breaking* `root`, `resource` and `resources` methods no longer take class constants
|
12
|
+
- *Breaking* Move route class methods to `Routes` class instead of `App`
|
13
|
+
- *Breaking* Create migration class, use migration classes in migrate!
|
14
|
+
- *Breaking* Make routes take symbols or strings, not classes to better line up with models
|
15
|
+
- *Breaking* Move connection string handling to database
|
16
|
+
- Make everything use `frozen_string_literal`
|
17
|
+
- Purposefully never add callbacks, `before_action` or autoloading
|
18
|
+
|
19
|
+
# 1.0.2 (2021-12-02)
|
9
20
|
|
10
21
|
- Set default views / migrations paths
|
11
22
|
|
12
|
-
# 1.0.1
|
23
|
+
# 1.0.1 (2021-12-02)
|
13
24
|
|
14
25
|
- Fix changelog link in gemspec
|
15
26
|
|
16
|
-
|
27
|
+
# 1.0.0 (2021-12-01)
|
17
28
|
|
18
29
|
- Very basic understanding of how much memory it takes for a basic ruby app
|
19
30
|
- Start to integrate controllers and routing
|
data/README.md
CHANGED
data/lib/radical/app.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rack'
|
2
4
|
require 'rack/flash'
|
3
5
|
require 'rack/csrf'
|
4
6
|
|
5
|
-
require_relative '
|
7
|
+
require_relative 'routes'
|
6
8
|
require_relative 'env'
|
7
9
|
|
8
10
|
# The main entry point for a Radical application
|
@@ -31,24 +33,8 @@ require_relative 'env'
|
|
31
33
|
module Radical
|
32
34
|
class App
|
33
35
|
class << self
|
34
|
-
def
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
def resource(klass)
|
39
|
-
router.add_actions(klass, actions: Router::RESOURCE_ACTIONS)
|
40
|
-
end
|
41
|
-
|
42
|
-
def resources(*classes, &block)
|
43
|
-
prefix = "#{router.route_prefix(@parents)}/" if instance_variable_defined?(:@parents)
|
44
|
-
|
45
|
-
router.add_routes(classes, prefix: prefix)
|
46
|
-
|
47
|
-
return unless block
|
48
|
-
|
49
|
-
@parents ||= []
|
50
|
-
@parents << classes.last
|
51
|
-
block.call
|
36
|
+
def routes(route_class)
|
37
|
+
@routes ||= route_class
|
52
38
|
end
|
53
39
|
|
54
40
|
def env
|
@@ -56,7 +42,7 @@ module Radical
|
|
56
42
|
end
|
57
43
|
|
58
44
|
def app
|
59
|
-
router =
|
45
|
+
router = @routes.router
|
60
46
|
env = self.env
|
61
47
|
|
62
48
|
@app ||= Rack::Builder.app do
|
@@ -91,10 +77,6 @@ module Radical
|
|
91
77
|
end
|
92
78
|
end
|
93
79
|
|
94
|
-
def router
|
95
|
-
@router ||= Router.new
|
96
|
-
end
|
97
|
-
|
98
80
|
def call(env)
|
99
81
|
app.call(env)
|
100
82
|
end
|
data/lib/radical/controller.rb
CHANGED
data/lib/radical/database.rb
CHANGED
@@ -1,40 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'sqlite3'
|
2
4
|
require_relative 'table'
|
5
|
+
require_relative 'migration'
|
3
6
|
|
4
7
|
module Radical
|
5
8
|
class Database
|
6
9
|
class << self
|
7
|
-
|
10
|
+
attr_writer :connection_string
|
11
|
+
attr_accessor :migrations_path
|
12
|
+
|
13
|
+
def connection_string
|
14
|
+
@connection_string || ENV['DATABASE_URL']
|
15
|
+
end
|
16
|
+
|
17
|
+
def connection
|
18
|
+
conn = SQLite3::Database.new(connection_string)
|
19
|
+
conn.results_as_hash = true
|
20
|
+
conn.type_translation = true
|
21
|
+
|
22
|
+
@connection ||= conn
|
23
|
+
end
|
24
|
+
|
25
|
+
def prepend_migrations_path(path)
|
26
|
+
self.migrations_path = path
|
27
|
+
end
|
8
28
|
|
9
29
|
def db
|
10
30
|
connection
|
11
31
|
end
|
12
32
|
|
13
|
-
def
|
14
|
-
|
33
|
+
def migration(file)
|
34
|
+
context = Module.new
|
35
|
+
context.class_eval(File.read(file), file)
|
36
|
+
const = context.constants.find do |constant|
|
37
|
+
context.const_get(constant).ancestors.include?(Radical::Migration)
|
38
|
+
end
|
39
|
+
|
40
|
+
context.const_get(const)
|
41
|
+
end
|
15
42
|
|
43
|
+
def migrate!
|
16
44
|
db.execute 'create table if not exists radical_migrations ( version integer primary key )'
|
17
45
|
|
18
|
-
pending_migrations.each do |
|
19
|
-
puts "Executing migration #{
|
20
|
-
|
21
|
-
|
22
|
-
|
46
|
+
pending_migrations.each do |file|
|
47
|
+
puts "Executing migration #{file}"
|
48
|
+
|
49
|
+
v = version(file)
|
50
|
+
|
51
|
+
migration(file).migrate!(db: db, version: v)
|
23
52
|
end
|
24
53
|
end
|
25
54
|
|
26
55
|
def rollback!
|
27
|
-
@rollback = true
|
28
|
-
|
29
56
|
db.execute 'create table if not exists radical_migrations ( version integer primary key )'
|
30
57
|
|
31
|
-
|
58
|
+
file = applied_migrations.last
|
32
59
|
|
33
|
-
puts "Rolling back migration #{
|
60
|
+
puts "Rolling back migration #{file}"
|
34
61
|
|
35
|
-
|
36
|
-
|
37
|
-
db
|
62
|
+
v = version(file)
|
63
|
+
|
64
|
+
migration(file).rollback!(db: db, version: v)
|
38
65
|
end
|
39
66
|
|
40
67
|
def applied_versions
|
@@ -59,34 +86,6 @@ module Radical
|
|
59
86
|
def version(filename)
|
60
87
|
filename.split(File::SEPARATOR).last.split('_').first.to_i
|
61
88
|
end
|
62
|
-
|
63
|
-
def migration(&block)
|
64
|
-
block.call
|
65
|
-
end
|
66
|
-
|
67
|
-
def change(&block)
|
68
|
-
@change = true
|
69
|
-
|
70
|
-
block.call
|
71
|
-
end
|
72
|
-
|
73
|
-
def up(&block)
|
74
|
-
block.call
|
75
|
-
end
|
76
|
-
|
77
|
-
def down(&block)
|
78
|
-
block.call
|
79
|
-
end
|
80
|
-
|
81
|
-
def create_table(name, &block)
|
82
|
-
return "drop table #{name}" if @change && @rollback
|
83
|
-
|
84
|
-
table = Table.new(name)
|
85
|
-
|
86
|
-
block.call(table)
|
87
|
-
|
88
|
-
"create table #{name} ( id integer primary key, #{table.columns.join(',')} )"
|
89
|
-
end
|
90
89
|
end
|
91
90
|
end
|
92
91
|
end
|
data/lib/radical/env.rb
CHANGED
data/lib/radical/form.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Radical
|
4
|
+
class Migration
|
5
|
+
class << self
|
6
|
+
def change(&block)
|
7
|
+
@change = block
|
8
|
+
end
|
9
|
+
|
10
|
+
def up(&block)
|
11
|
+
@up = block
|
12
|
+
end
|
13
|
+
|
14
|
+
def down(&block)
|
15
|
+
@down = block
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_table(name, &block)
|
19
|
+
return drop_table(name) if @change && @rollback
|
20
|
+
|
21
|
+
table = Table.new(name)
|
22
|
+
|
23
|
+
block.call(table)
|
24
|
+
|
25
|
+
"create table #{name} ( id integer primary key, #{table.columns.join(',')} )"
|
26
|
+
end
|
27
|
+
|
28
|
+
def drop_table(name)
|
29
|
+
"drop table #{name}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def migrate!(db:, version:)
|
33
|
+
db.execute(@change&.call || @up&.call)
|
34
|
+
db.execute 'insert into radical_migrations (version) values (?)', [version]
|
35
|
+
end
|
36
|
+
|
37
|
+
def rollback!(db:, version:)
|
38
|
+
@rollback = true
|
39
|
+
|
40
|
+
db.execute(@change&.call || @down&.call)
|
41
|
+
db.execute 'delete from radical_migrations where version = ?', [version]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/radical/model.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'database'
|
2
4
|
|
3
5
|
module Radical
|
@@ -7,17 +9,6 @@ module Radical
|
|
7
9
|
class << self
|
8
10
|
attr_accessor :table_name
|
9
11
|
|
10
|
-
def database(name)
|
11
|
-
conn = SQLite3::Database.new name
|
12
|
-
conn.results_as_hash = true
|
13
|
-
conn.type_translation = true
|
14
|
-
Database.connection = conn
|
15
|
-
end
|
16
|
-
|
17
|
-
def prepend_migrations_path(path)
|
18
|
-
Database.migrations_path = path
|
19
|
-
end
|
20
|
-
|
21
12
|
def db
|
22
13
|
Database.connection
|
23
14
|
end
|
data/lib/radical/router.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# typed: true
|
3
|
+
|
2
4
|
require 'rack'
|
3
5
|
require 'sorbet-runtime'
|
4
6
|
|
@@ -77,7 +79,7 @@ module Radical
|
|
77
79
|
next unless klass.method_defined?(method)
|
78
80
|
|
79
81
|
path = "/#{prefix}#{name}#{suffix}"
|
80
|
-
path = Regexp.new("^#{path.gsub(/:(\w+)/, '(?<\1>[a-zA-Z0-9_]+)')}$")
|
82
|
+
path = Regexp.new("^#{path.gsub(/:(\w+)/, '(?<\1>[a-zA-Z0-9_]+)')}$").freeze
|
81
83
|
|
82
84
|
if %i[index create show update destroy].include?(method) && !klass.method_defined?(:"#{klass.route_name}_path")
|
83
85
|
klass.define_method :"#{klass.route_name}_path" do |obj = nil|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative 'router'
|
5
|
+
|
6
|
+
module Radical
|
7
|
+
class Routes
|
8
|
+
class << self
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
sig { returns(Router) }
|
12
|
+
def router
|
13
|
+
@router ||= Router.new
|
14
|
+
end
|
15
|
+
|
16
|
+
sig { params(name: T.any(String, Symbol)).void }
|
17
|
+
def root(name)
|
18
|
+
klass = Object.const_get(name)
|
19
|
+
|
20
|
+
router.add_root(klass)
|
21
|
+
end
|
22
|
+
|
23
|
+
sig { params(names: T.any(String, Symbol)).void }
|
24
|
+
def resource(*names)
|
25
|
+
classes = names.map { |c| Object.const_get(c) }
|
26
|
+
|
27
|
+
classes.each do |klass|
|
28
|
+
router.add_actions(klass, actions: Router::RESOURCE_ACTIONS)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
sig { params(names: T.any(String, Symbol), block: T.nilable(T.proc.void)).void }
|
33
|
+
def resources(*names, &block)
|
34
|
+
classes = names.map { |c| Object.const_get(c) }
|
35
|
+
|
36
|
+
prefix = "#{router.route_prefix(@parents)}/" if instance_variable_defined?(:@parents)
|
37
|
+
|
38
|
+
router.add_routes(classes, prefix: prefix)
|
39
|
+
|
40
|
+
return unless block
|
41
|
+
|
42
|
+
@parents ||= []
|
43
|
+
@parents << classes.last
|
44
|
+
block.call
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/radical/table.rb
CHANGED
data/lib/radical/view.rb
CHANGED
data/lib/radical.rb
CHANGED
data/radical.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: radical
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Walker
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -198,8 +198,10 @@ files:
|
|
198
198
|
- lib/radical/database.rb
|
199
199
|
- lib/radical/env.rb
|
200
200
|
- lib/radical/form.rb
|
201
|
+
- lib/radical/migration.rb
|
201
202
|
- lib/radical/model.rb
|
202
203
|
- lib/radical/router.rb
|
204
|
+
- lib/radical/routes.rb
|
203
205
|
- lib/radical/table.rb
|
204
206
|
- lib/radical/view.rb
|
205
207
|
- radical.gemspec
|