tetrahedron 0.0.0.1 → 0.0.1.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +15 -1
- data/README.md +1 -2
- data/lib/tetrahedron/application/base.rb +16 -0
- data/lib/tetrahedron/application/controller.rb +16 -0
- data/lib/tetrahedron/application/endpoint.rb +7 -0
- data/lib/tetrahedron/application.rb +31 -0
- data/lib/tetrahedron/base.rb +9 -20
- data/lib/tetrahedron/database.rb +66 -90
- data/lib/tetrahedron/databases/postgres.rb +48 -0
- data/lib/tetrahedron/databases/sqlite3.rb +30 -0
- data/lib/tetrahedron/gem.rb +2 -2
- data/lib/tetrahedron/middleware.rb +25 -0
- data/lib/tetrahedron/service.rb +61 -0
- data/lib/tetrahedron/sessions.rb +26 -17
- data/lib/tetrahedron.rb +26 -54
- data/tetrahedron.gemspec +7 -2
- metadata +82 -21
- data/config/app.ru +0 -21
- data/config/application.rb +0 -8
- data/config/environment.rb +0 -18
- data/config/puma.rb +0 -29
- data/lib/tetrahedron/app.rb +0 -16
- data/lib/tetrahedron/assets.rb +0 -43
- data/lib/tetrahedron/bootfile.rb +0 -43
- data/lib/tetrahedron/bundler.rb +0 -10
- data/lib/tetrahedron/configuration.rb +0 -44
- data/lib/tetrahedron/controller.rb +0 -17
- data/lib/tetrahedron/endpoint.rb +0 -4
- data/lib/tetrahedron/environment.rb +0 -28
- data/lib/tetrahedron/errors.rb +0 -7
- data/lib/tetrahedron/model.rb +0 -32
- data/lib/tetrahedron/rake.rb +0 -16
- data/lib/tetrahedron/redis.rb +0 -4
- data/lib/tetrahedron/tasks/tet.rake +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b9d0311bd16dd7fb7b8c35d19fcce8ae77a2036
|
4
|
+
data.tar.gz: 9ee81f6f029ba59b260b1e56f49db1dbb0233e87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c2ac0f186880b502265c894461fba56c33e30b931069e614df647627c5fdb8981a65529a3a849a584d9aae7b7dba456f14d48a0a74c5e86a72f826212897b1b
|
7
|
+
data.tar.gz: 1a3cb3c6184c50a59bc0b76eff23b72af0717d4b96283646ee90b58286609cccef8386c7587a7cccf0afdc4e52c2e1e30479a8d1646fb01f17b5164d1d69b150
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
tetrahedron (0.0.0
|
4
|
+
tetrahedron (0.0.1.0)
|
5
5
|
activesupport
|
6
|
+
erubis
|
7
|
+
mail
|
8
|
+
rack
|
9
|
+
rack-contrib
|
10
|
+
redis
|
6
11
|
sequel
|
7
12
|
sinatra
|
8
13
|
sinatra-contrib
|
@@ -19,9 +24,14 @@ GEM
|
|
19
24
|
tzinfo (~> 1.1)
|
20
25
|
backports (3.6.7)
|
21
26
|
coderay (1.1.0)
|
27
|
+
erubis (2.7.0)
|
28
|
+
git-version-bump (0.15.1)
|
22
29
|
i18n (0.7.0)
|
23
30
|
json (1.8.3)
|
31
|
+
mail (2.6.3)
|
32
|
+
mime-types (>= 1.16, < 3)
|
24
33
|
method_source (0.8.2)
|
34
|
+
mime-types (2.99)
|
25
35
|
minitest (5.8.3)
|
26
36
|
multi_json (1.11.2)
|
27
37
|
pry (0.10.3)
|
@@ -29,11 +39,15 @@ GEM
|
|
29
39
|
method_source (~> 0.8.1)
|
30
40
|
slop (~> 3.4)
|
31
41
|
rack (1.6.4)
|
42
|
+
rack-contrib (1.4.0)
|
43
|
+
git-version-bump (~> 0.15)
|
44
|
+
rack (~> 1.4)
|
32
45
|
rack-protection (1.5.3)
|
33
46
|
rack
|
34
47
|
rack-test (0.6.3)
|
35
48
|
rack (>= 1.0)
|
36
49
|
rake (10.4.2)
|
50
|
+
redis (3.2.2)
|
37
51
|
sequel (4.28.0)
|
38
52
|
sinatra (1.4.6)
|
39
53
|
rack (~> 1.4)
|
data/README.md
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
Tetrahedron
|
2
|
-
===========
|
1
|
+
# Tetrahedron [](https://rubygems.org/gems/tetrahedron) [](https://travis-ci.org/mtwilliams/tetrahedron) [](https://codeclimate.com/github/mtwilliams/tetrahedron) [](https://gemnasium.com/mtwilliams/tetrahedron)
|
3
2
|
|
4
3
|
[Welcome to the Tet.](https://www.youtube.com/watch?v=lt-udg9zQSE)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Tetrahedron
|
2
|
+
class Application
|
3
|
+
class Base < Tetrahedron::Base
|
4
|
+
def self.inherited(base)
|
5
|
+
super(base)
|
6
|
+
base.send :define_singleton_method, :inherited do |basee|
|
7
|
+
super(basee)
|
8
|
+
basee.set :application, Proc.new { basee.to_s.split('::')[0..-2].join('::').constantize }
|
9
|
+
basee.set :environment, Proc.new { application.environment.to_sym }
|
10
|
+
basee.set :root, Proc.new { application.root }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Tetrahedron
|
2
|
+
class Application
|
3
|
+
class Controller < Tetrahedron::Application::Base
|
4
|
+
set :views, Proc.new { "#{root}/app/broadsheet/views" }
|
5
|
+
|
6
|
+
# Recognize *.html.erb as Erubis templates.
|
7
|
+
Tilt.register Tilt::ErubisTemplate, 'html.erb'
|
8
|
+
|
9
|
+
# Don't recognize *.erb templates.
|
10
|
+
def erb(template, options={}, locals={})
|
11
|
+
options[:layout] = settings.erb[:layout] if options[:layout].nil?
|
12
|
+
render 'html.erb', template, options, locals
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'sinatra/contrib/all'
|
3
|
+
|
4
|
+
module Tetrahedron
|
5
|
+
class Application < Tetrahedron::Base
|
6
|
+
def self.env
|
7
|
+
components = self.to_s.upcase.split('::')
|
8
|
+
possibilities = (components.size.downto(1).map{|n| components.first(n).join('_')+'_ENV'})
|
9
|
+
environments = (possibilities+['RACK_ENV']).map{|possibility| ENV[possibility]}
|
10
|
+
@env ||= ::ActiveSupport::StringInquirer.new(environments.reject(&:nil?).first)
|
11
|
+
end
|
12
|
+
|
13
|
+
set :environment, Proc.new { self.env.to_sym }
|
14
|
+
set :root, Dir.pwd
|
15
|
+
|
16
|
+
# Don't use the built-in web-server.
|
17
|
+
set :run, false
|
18
|
+
|
19
|
+
def self.inherited(application)
|
20
|
+
super(application)
|
21
|
+
|
22
|
+
Tetrahedron::Middleware.install(application)
|
23
|
+
Tetrahedron::Sessions.install(application)
|
24
|
+
|
25
|
+
application.const_set('Controller', Class.new(Controller))
|
26
|
+
application.const_set('Endpoint', Class.new(Endpoint))
|
27
|
+
|
28
|
+
Tetrahedron::Database.install(application)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/tetrahedron/base.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'sinatra/contrib/all'
|
3
|
+
|
1
4
|
module Tetrahedron
|
2
5
|
class Base < Sinatra::Base
|
3
|
-
set :environment, Tetrahedron.env.to_sym
|
4
|
-
set :root, Tetrahedron.config.root
|
5
|
-
|
6
|
-
# Don't use the built-in web-server.
|
7
|
-
set :run, false
|
8
|
-
|
9
6
|
# Errors are bubbled so they can be handled by middleware.
|
10
7
|
set :dump_errors, false
|
11
8
|
set :raise_errors, true
|
@@ -14,21 +11,13 @@ module Tetrahedron
|
|
14
11
|
# Fuck you, IE9.
|
15
12
|
disable :method_override
|
16
13
|
|
17
|
-
|
18
|
-
|
19
|
-
register Sinatra::Reloader
|
20
|
-
end
|
14
|
+
# TODO(mtwilliams): Re-enable basic protections, like traversal.
|
15
|
+
disable :protection
|
21
16
|
|
22
|
-
|
23
|
-
|
24
|
-
end
|
17
|
+
# Let users handle serving static files.
|
18
|
+
disable :static
|
25
19
|
|
26
|
-
|
27
|
-
|
28
|
-
server = Rack::Static.new(proc {[404, {}, []]}, root: File.join(Tetrahedron.config.root, '/public'))
|
29
|
-
status, headers, response = server.call(env)
|
30
|
-
pass if status == 404
|
31
|
-
[status, headers, response]
|
32
|
-
end
|
20
|
+
# Hot-reload in development.
|
21
|
+
register Sinatra::Reloader
|
33
22
|
end
|
34
23
|
end
|
data/lib/tetrahedron/database.rb
CHANGED
@@ -1,113 +1,89 @@
|
|
1
|
-
|
2
|
-
module Database
|
3
|
-
class Configuration
|
4
|
-
Options = %i{adapter user password host port database pool}
|
5
|
-
attr_reader *Options
|
1
|
+
require 'sequel'
|
6
2
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
end
|
3
|
+
# Everyone needs these.
|
4
|
+
Sequel.extension :migration
|
5
|
+
Sequel::Model.plugin :timestamps
|
12
6
|
|
13
|
-
|
14
|
-
|
15
|
-
Options.each do |opt|
|
16
|
-
configuration.instance_variable_set(:"@#{opt}", overrides[opt]) if overrides.include? opt
|
17
|
-
end
|
18
|
-
configuration
|
19
|
-
end
|
20
|
-
end
|
7
|
+
# The Tet needs this for the magic performed in `Model.db=`.
|
8
|
+
Sequel::Model.plugin :subclasses
|
21
9
|
|
22
|
-
|
23
|
-
|
10
|
+
module Tetrahedron
|
11
|
+
class Database < Service
|
12
|
+
class Configuration < Service::Configuration
|
24
13
|
end
|
25
14
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@configuration = Configuration.new(configuration)
|
15
|
+
class Provider < Service::Provider
|
16
|
+
def connection; end
|
17
|
+
def connect; raise NotImplementedError; end
|
18
|
+
def disconnect; raise NotImplementedError; end
|
31
19
|
end
|
32
20
|
|
33
|
-
|
34
|
-
|
35
|
-
# By default, we wait up to 15 seconds.
|
36
|
-
overrides[:timeout] ||= 15
|
37
|
-
|
38
|
-
configuration = @configuration.override(overrides) if configured?
|
39
|
-
configuration ||= Configuration.new(overrides)
|
40
|
-
|
41
|
-
# TODO(mtwilliams): Don't assume TCP.
|
42
|
-
# Look at |configuration.adapter|.
|
43
|
-
Timeout::timeout(overrides[:timeout]) do
|
44
|
-
while true
|
45
|
-
begin
|
46
|
-
TCPSocket.new(configuration.host, configuration.port).close
|
47
|
-
return true
|
48
|
-
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, SocketError
|
49
|
-
# We're all good citizens, right?
|
50
|
-
Kernel.sleep(1)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
rescue Timeout::Error
|
55
|
-
false
|
21
|
+
def self.connected?
|
22
|
+
!self.connection.nil?
|
56
23
|
end
|
57
24
|
|
58
|
-
def self.
|
59
|
-
|
60
|
-
|
25
|
+
def self.connection
|
26
|
+
configured!
|
27
|
+
self.class_variable_get(:@@provider).connection
|
61
28
|
end
|
62
29
|
|
63
|
-
def self.connect
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
@connection = Sequel.connect(:adapter => configuration.adapter,
|
71
|
-
:user => configuration.user,
|
72
|
-
:password => configuration.password,
|
73
|
-
:host => configuration.host,
|
74
|
-
:port => configuration.port,
|
75
|
-
:database => configuration.database,
|
76
|
-
:test => true,
|
77
|
-
:sslmode => :prefer,
|
78
|
-
:max_connections => configuration.pool)
|
79
|
-
|
80
|
-
# Reback our models with the new connection pool.
|
81
|
-
Tetrahedron::Model.db = @connection
|
82
|
-
|
83
|
-
true
|
30
|
+
def self.connect
|
31
|
+
configured!
|
32
|
+
connected = self.class_variable_get(:@@provider).connect
|
33
|
+
# Back our models with the new connection.
|
34
|
+
model = self.class_variable_get(:@@application).const_get("Model")
|
35
|
+
model.db = self.connection if connected
|
36
|
+
connected
|
84
37
|
end
|
85
38
|
|
86
39
|
def self.disconnect
|
87
|
-
|
40
|
+
configured!
|
41
|
+
# TODO(mtwilliams): Verify that this is thread-safe.
|
42
|
+
model = self.class_variable_get(:@@application).const_get("Model")
|
43
|
+
model.db = Sequel.mock
|
44
|
+
self.class_variable_get(:@@provider).disconnect
|
45
|
+
end
|
88
46
|
|
89
|
-
|
90
|
-
|
91
|
-
Tetrahedron::Model.db = Sequel.mock
|
92
|
-
@connection = nil
|
47
|
+
def self.install(application)
|
48
|
+
super(application)
|
93
49
|
|
94
|
-
|
95
|
-
end
|
50
|
+
# TODO(mtwilliams): Refactor out this horrid mess.
|
96
51
|
|
97
|
-
|
98
|
-
|
99
|
-
|
52
|
+
# We can't build an inheritence heirarchy.
|
53
|
+
# See https://groups.google.com/d/msg/sequel-talk/OG5ti9JAJIE/p1iqO57cwqwJ.
|
54
|
+
application.class_eval("Model = Class.new(Sequel::Model);")
|
55
|
+
model = application.const_get("Model")
|
100
56
|
|
101
|
-
|
102
|
-
#
|
103
|
-
|
57
|
+
# Stop Sequel from bitching when we users subclass models before the
|
58
|
+
# database connection is established.
|
59
|
+
model.db = Sequel.mock
|
104
60
|
|
105
|
-
|
106
|
-
|
107
|
-
|
61
|
+
# Back descendents.
|
62
|
+
model.send :define_singleton_method, :db= do |db|
|
63
|
+
super(db)
|
64
|
+
# All the way down, boys.
|
65
|
+
self.descendents.each do |descendent|
|
66
|
+
descendent.db = db
|
67
|
+
end
|
68
|
+
end
|
108
69
|
|
109
|
-
|
110
|
-
|
70
|
+
# Custom names are cool, m'kay.
|
71
|
+
application.send :define_singleton_method, :Model do |source|
|
72
|
+
anonymous_model_class = model::ANONYMOUS_MODEL_CLASSES_MUTEX.synchronize do
|
73
|
+
model::ANONYMOUS_MODEL_CLASSES[source]
|
74
|
+
end
|
75
|
+
unless anonymous_model_class
|
76
|
+
anonymous_model_class = if source.is_a?(Sequel::Database)
|
77
|
+
Class.new(model).db = source
|
78
|
+
else
|
79
|
+
Class.new(model).set_dataset(source)
|
80
|
+
end
|
81
|
+
model::ANONYMOUS_MODEL_CLASSES_MUTEX.synchronize do
|
82
|
+
model::ANONYMOUS_MODEL_CLASSES[source] = anonymous_model_class
|
83
|
+
end
|
84
|
+
end
|
85
|
+
anonymous_model_class
|
86
|
+
end
|
111
87
|
end
|
112
88
|
end
|
113
89
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Tetrahedron
|
2
|
+
module Databases
|
3
|
+
class Postgres < Database::Provider
|
4
|
+
class Configuration < Database::Configuration
|
5
|
+
attr_accessor :host,
|
6
|
+
:port,
|
7
|
+
:user,
|
8
|
+
:password,
|
9
|
+
:database,
|
10
|
+
:pool
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@configuration = Configuration.new
|
15
|
+
yield @configuration if block_given?
|
16
|
+
end
|
17
|
+
|
18
|
+
def connection
|
19
|
+
@connection
|
20
|
+
end
|
21
|
+
|
22
|
+
def connect
|
23
|
+
# Wait some amount of time before assuming the database is down.
|
24
|
+
Service.wait_until_reachable!(:protocol => :tcp,
|
25
|
+
:host => @configuration.host,
|
26
|
+
:port => @configuration.port,
|
27
|
+
:timeout => 15)
|
28
|
+
|
29
|
+
@connection = Sequel.postgres(:host => @configuration.host,
|
30
|
+
:port => @configuration.port,
|
31
|
+
:user => @configuration.user,
|
32
|
+
:password => @configuration.password,
|
33
|
+
:database => @configuration.database,
|
34
|
+
:test => true,
|
35
|
+
:sslmode => :prefer,
|
36
|
+
:max_connections => @configuration.pool)
|
37
|
+
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
def disconnect
|
42
|
+
@connection.disconnect if @connection
|
43
|
+
@connection = nil
|
44
|
+
true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Tetrahedron
|
2
|
+
module Databases
|
3
|
+
class SQLite3 < Database::Provider
|
4
|
+
class Configuration < Database::Configuration
|
5
|
+
attr_accessor :path
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@configuration = Configuration.new
|
10
|
+
yield @configuration if block_given?
|
11
|
+
end
|
12
|
+
|
13
|
+
def connection
|
14
|
+
@connection
|
15
|
+
end
|
16
|
+
|
17
|
+
def connect
|
18
|
+
# If no path was specified, default to a transient in-memory database.
|
19
|
+
@connection = Sequel.sqlite(:database => (@configuration.path || ':memory:'))
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
def disconnect
|
24
|
+
@connection.disconnect if @connection
|
25
|
+
@connection = nil
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/tetrahedron/gem.rb
CHANGED
@@ -32,7 +32,7 @@ module Tetrahedron
|
|
32
32
|
|
33
33
|
# A short summary of this Gem.
|
34
34
|
def self.summary
|
35
|
-
"
|
35
|
+
"Welcome to the Tet."
|
36
36
|
end
|
37
37
|
|
38
38
|
# A full description of this Gem.
|
@@ -41,7 +41,7 @@ module Tetrahedron
|
|
41
41
|
end
|
42
42
|
|
43
43
|
module VERSION #:nodoc:
|
44
|
-
MAJOR, MINOR, PATCH, PRE = [0, 0,
|
44
|
+
MAJOR, MINOR, PATCH, PRE = [0, 0, 1, 0]
|
45
45
|
STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
|
46
46
|
end
|
47
47
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Tetrahedron
|
2
|
+
class Middleware
|
3
|
+
def self.use(middleware, *args, &block)
|
4
|
+
stack = self.class_variable_get(:@@stack)
|
5
|
+
stack << proc { |app| middleware.new(app, *args, &block) }
|
6
|
+
self.class_variable_set(:@@stack, stack)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(app)
|
10
|
+
@app = app
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
middlewares = self.class.class_variable_get(:@@stack).reverse
|
15
|
+
wrapped = middlewares.inject(@app) {|_, middleware| middleware[_]}
|
16
|
+
wrapped.call(env)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.install(application)
|
20
|
+
middleware = Class.new(self)
|
21
|
+
application.const_set('Middleware', middleware)
|
22
|
+
middleware.class_variable_set(:@@stack, [])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Tetrahedron
|
2
|
+
class Service
|
3
|
+
def self.install(application)
|
4
|
+
service = Class.new(self)
|
5
|
+
service.class_variable_set(:@@application, application)
|
6
|
+
application.const_set(self.to_s.split('::').last, service)
|
7
|
+
end
|
8
|
+
|
9
|
+
Unconfigured = Class.new(Tetrahedron::Error)
|
10
|
+
Misconfigured = Class.new(Tetrahedron::Error)
|
11
|
+
AlreadyConfigured = Class.new(Tetrahedron::Error)
|
12
|
+
|
13
|
+
class Configuration
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.configured?
|
17
|
+
self.class_variable_defined?(:@@provider)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.configured!
|
21
|
+
raise Unconfigured unless self.configured?
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.configure(&configurator)
|
25
|
+
raise AlreadyConfigured if self.configured?
|
26
|
+
provider = configurator.call()
|
27
|
+
raise Misconfigured unless provider.is_a? Provider
|
28
|
+
self.class_variable_set(:@@provider, provider)
|
29
|
+
end
|
30
|
+
|
31
|
+
Unreachable = Class.new(Tetrahedron::Error)
|
32
|
+
|
33
|
+
class Provider
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.wait_until_reachable(opts={})
|
37
|
+
Timeout::timeout(opts.fetch(:timeout, 15)) do
|
38
|
+
while true
|
39
|
+
begin
|
40
|
+
case opts[:protocol]
|
41
|
+
when :tcp
|
42
|
+
TCPSocket.new(opts[:host], opts[:port]).close
|
43
|
+
return true
|
44
|
+
when :udp
|
45
|
+
raise "This makes no sense!"
|
46
|
+
end
|
47
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, SocketError
|
48
|
+
# We're all good citizens, right?
|
49
|
+
Kernel.sleep(1)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
rescue Timeout::Error
|
54
|
+
false
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.wait_until_reachable!(opts={})
|
58
|
+
raise Unreachable unless self.wait_until_reachable(opts)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/tetrahedron/sessions.rb
CHANGED
@@ -1,28 +1,37 @@
|
|
1
1
|
module Tetrahedron
|
2
|
-
|
2
|
+
class Sessions
|
3
3
|
class Configuration
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
OPTIONS = [:key, :domain, :path, :expires, :secret]
|
5
|
+
attr_accessor *OPTIONS
|
6
|
+
def dsl(&block)
|
7
|
+
config = self
|
8
|
+
dsl = Class.new
|
9
|
+
OPTIONS.each do |option|
|
10
|
+
dsl.send :define_method, option.to_sym do |value|
|
11
|
+
config.instance_variable_set(:"@#{option}", value)
|
12
|
+
end
|
10
13
|
end
|
14
|
+
dsl.new.instance_eval(&block)
|
11
15
|
end
|
12
16
|
end
|
13
17
|
|
14
|
-
def self.
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
def self.configure(&configurator)
|
19
|
+
application = self.class_variable_get(:@@application)
|
20
|
+
configuration = Configuration.new
|
21
|
+
configuration.key = (application.to_s.underscore.split('::')+['session']).join('.')
|
22
|
+
configuration.dsl(&configurator)
|
23
|
+
middleware = application.const_get('Middleware')
|
24
|
+
middleware.use(Rack::Session::Cookie, :key => configuration.key,
|
25
|
+
:domain => configuration.domain,
|
26
|
+
:path => configuration.path,
|
27
|
+
:expire_after => configuration.expires,
|
28
|
+
:secret => configuration.secret)
|
20
29
|
end
|
21
30
|
|
22
|
-
def self.
|
23
|
-
|
24
|
-
|
25
|
-
|
31
|
+
def self.install(application)
|
32
|
+
sessions = Class.new(self)
|
33
|
+
application.const_set('Sessions', sessions)
|
34
|
+
sessions.class_variable_set(:@@application, application)
|
26
35
|
end
|
27
36
|
end
|
28
37
|
end
|
data/lib/tetrahedron.rb
CHANGED
@@ -1,59 +1,31 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bundler'
|
3
|
-
|
4
|
-
Bundler.require(:default)
|
5
|
-
|
6
|
-
# Some things aren't nicely cut gems, unforunately.
|
7
|
-
require 'base64'
|
8
|
-
require 'erb'
|
9
|
-
require 'net/http'
|
10
|
-
require 'ostruct'
|
11
|
-
require 'securerandom'
|
12
|
-
require 'socket'
|
13
|
-
require 'time'
|
14
|
-
require 'uri'
|
15
|
-
require 'yaml'
|
16
|
-
|
17
|
-
# Smells like Rails...
|
18
1
|
require 'active_support'
|
19
2
|
require 'active_support/core_ext'
|
20
3
|
|
21
4
|
module Tetrahedron
|
22
|
-
|
23
|
-
|
24
|
-
|
5
|
+
require 'tetrahedron/gem'
|
6
|
+
require 'tetrahedron/error'
|
7
|
+
|
8
|
+
require 'tetrahedron/middleware'
|
9
|
+
require 'tetrahedron/sessions'
|
10
|
+
|
11
|
+
require 'tetrahedron/base'
|
12
|
+
require 'tetrahedron/application'
|
13
|
+
require 'tetrahedron/application/base'
|
14
|
+
require 'tetrahedron/application/controller'
|
15
|
+
require 'tetrahedron/application/endpoint'
|
16
|
+
|
17
|
+
require 'tetrahedron/service'
|
18
|
+
require 'tetrahedron/database'
|
19
|
+
require 'tetrahedron/databases/sqlite3'
|
20
|
+
require 'tetrahedron/databases/postgres'
|
21
|
+
|
22
|
+
# require 'tetrahedron/cache'
|
23
|
+
# require 'tetrahedron/caches/null' #=> ActiveSupport::Cache::NullStore
|
24
|
+
# require 'tetrahedron/caches/memory' #=> ActiveSupport::Cache::MemoryStore
|
25
|
+
# require 'tetrahedron/caches/memcache' #=> Dalli
|
26
|
+
# require 'tetrahedron/caches/redis' #=> Hiredis
|
27
|
+
# require 'tetrahedron/queue'
|
28
|
+
# require 'tetrahedron/queues/null' #=> .*~~~ The Abyss ~~~*.
|
29
|
+
# require 'tetrahedron/queues/spawn' #=> Thread.new
|
30
|
+
# require 'tetrahedron/queues/sidekiq' #=> Sidekiq (from Redis, with Love)
|
25
31
|
end
|
26
|
-
|
27
|
-
require 'tetrahedron/gem'
|
28
|
-
require 'tetrahedron/bundler'
|
29
|
-
|
30
|
-
require 'tetrahedron/error'
|
31
|
-
require 'tetrahedron/errors'
|
32
|
-
|
33
|
-
require 'tetrahedron/configuration'
|
34
|
-
require 'tetrahedron/environment'
|
35
|
-
require 'tetrahedron/bootfile'
|
36
|
-
|
37
|
-
Tetrahedron::Bundler.require
|
38
|
-
|
39
|
-
require 'sinatra/base'
|
40
|
-
require 'sinatra/contrib'
|
41
|
-
|
42
|
-
require 'sequel'
|
43
|
-
|
44
|
-
Sequel.extension :migration
|
45
|
-
|
46
|
-
Sequel::Model.plugin :timestamps
|
47
|
-
Sequel::Model.plugin :subclasses
|
48
|
-
|
49
|
-
require 'tetrahedron/base'
|
50
|
-
|
51
|
-
require 'tetrahedron/assets'
|
52
|
-
|
53
|
-
require 'tetrahedron/database'
|
54
|
-
require 'tetrahedron/sessions'
|
55
|
-
|
56
|
-
require 'tetrahedron/app'
|
57
|
-
require 'tetrahedron/model'
|
58
|
-
require 'tetrahedron/controller'
|
59
|
-
require 'tetrahedron/endpoint'
|
data/tetrahedron.gemspec
CHANGED
@@ -23,12 +23,17 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.add_development_dependency("rake")
|
24
24
|
s.add_development_dependency("pry")
|
25
25
|
|
26
|
+
s.add_dependency("thor")
|
27
|
+
|
26
28
|
s.add_dependency("activesupport")
|
27
29
|
|
30
|
+
s.add_dependency("rack")
|
31
|
+
s.add_dependency("rack-contrib")
|
28
32
|
s.add_dependency("sinatra")
|
29
33
|
s.add_dependency("sinatra-contrib")
|
34
|
+
s.add_dependency("erubis")
|
30
35
|
|
31
36
|
s.add_dependency("sequel")
|
32
|
-
|
33
|
-
s.add_dependency("
|
37
|
+
s.add_dependency("redis")
|
38
|
+
s.add_dependency("mail")
|
34
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tetrahedron
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.0
|
4
|
+
version: 0.0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: thor
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: activesupport
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +66,34 @@ dependencies:
|
|
52
66
|
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rack
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rack-contrib
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
55
97
|
- !ruby/object:Gem::Dependency
|
56
98
|
name: sinatra
|
57
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +122,20 @@ dependencies:
|
|
80
122
|
- - ">="
|
81
123
|
- !ruby/object:Gem::Version
|
82
124
|
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: erubis
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
83
139
|
- !ruby/object:Gem::Dependency
|
84
140
|
name: sequel
|
85
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,7 +151,21 @@ dependencies:
|
|
95
151
|
- !ruby/object:Gem::Version
|
96
152
|
version: '0'
|
97
153
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
154
|
+
name: redis
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: mail
|
99
169
|
requirement: !ruby/object:Gem::Requirement
|
100
170
|
requirements:
|
101
171
|
- - ">="
|
@@ -123,29 +193,20 @@ files:
|
|
123
193
|
- README.md
|
124
194
|
- Rakefile
|
125
195
|
- bin/tetrahedron
|
126
|
-
- config/app.ru
|
127
|
-
- config/application.rb
|
128
|
-
- config/environment.rb
|
129
|
-
- config/puma.rb
|
130
196
|
- lib/tetrahedron.rb
|
131
|
-
- lib/tetrahedron/
|
132
|
-
- lib/tetrahedron/
|
197
|
+
- lib/tetrahedron/application.rb
|
198
|
+
- lib/tetrahedron/application/base.rb
|
199
|
+
- lib/tetrahedron/application/controller.rb
|
200
|
+
- lib/tetrahedron/application/endpoint.rb
|
133
201
|
- lib/tetrahedron/base.rb
|
134
|
-
- lib/tetrahedron/bootfile.rb
|
135
|
-
- lib/tetrahedron/bundler.rb
|
136
|
-
- lib/tetrahedron/configuration.rb
|
137
|
-
- lib/tetrahedron/controller.rb
|
138
202
|
- lib/tetrahedron/database.rb
|
139
|
-
- lib/tetrahedron/
|
140
|
-
- lib/tetrahedron/
|
203
|
+
- lib/tetrahedron/databases/postgres.rb
|
204
|
+
- lib/tetrahedron/databases/sqlite3.rb
|
141
205
|
- lib/tetrahedron/error.rb
|
142
|
-
- lib/tetrahedron/errors.rb
|
143
206
|
- lib/tetrahedron/gem.rb
|
144
|
-
- lib/tetrahedron/
|
145
|
-
- lib/tetrahedron/
|
146
|
-
- lib/tetrahedron/redis.rb
|
207
|
+
- lib/tetrahedron/middleware.rb
|
208
|
+
- lib/tetrahedron/service.rb
|
147
209
|
- lib/tetrahedron/sessions.rb
|
148
|
-
- lib/tetrahedron/tasks/tet.rake
|
149
210
|
- tetrahedron.gemspec
|
150
211
|
homepage: http://github.com/mtwilliams/tetrahedron
|
151
212
|
licenses:
|
@@ -170,5 +231,5 @@ rubyforge_project:
|
|
170
231
|
rubygems_version: 2.4.5.1
|
171
232
|
signing_key:
|
172
233
|
specification_version: 4
|
173
|
-
summary:
|
234
|
+
summary: Welcome to the Tet.
|
174
235
|
test_files: []
|
data/config/app.ru
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
#!/usr/bin/env rackup
|
2
|
-
|
3
|
-
require_relative 'application'
|
4
|
-
require_relative 'environment'
|
5
|
-
|
6
|
-
# TODO(mtwilliams): Request tracking (make Heroku compatiable).
|
7
|
-
# TODO(mtwilliams): Performance monitoring (make Heroku compatiable).
|
8
|
-
# TODO(mtwilliams): Error handling.
|
9
|
-
|
10
|
-
if Tetrahedron::Sessions.configured?
|
11
|
-
use Rack::Session::Cookie, :key => Tetrahedron::Sessions.config.cookie,
|
12
|
-
:domain => Tetrahedron::Sessions.config.domain,
|
13
|
-
:expire_after => Tetrahedron::Sessions.config.lifetime,
|
14
|
-
:secret => Tetrahedron::Sessions.config.secret
|
15
|
-
else
|
16
|
-
# TODO(mtwilliams): Use a logger.
|
17
|
-
$stderr.puts "Sessions not configured!\n => Use Tetrahedron::Sessions.configure in config/environment.rb!"
|
18
|
-
end
|
19
|
-
|
20
|
-
# TODO(mtwilliams): Remove cylcical dependency so we can use a constantized version.
|
21
|
-
run Tetrahedron.config.app.constantize
|
data/config/application.rb
DELETED
data/config/environment.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
require_relative 'application'
|
2
|
-
|
3
|
-
Tetrahedron::Environment.load
|
4
|
-
|
5
|
-
if Tetrahedron.env.development?
|
6
|
-
# Synchronize STDOUT and STDERR to make debugging easier.
|
7
|
-
STDOUT.sync = STDERR.sync = true
|
8
|
-
end
|
9
|
-
|
10
|
-
require File.join(Tetrahedron.config.root, "config", "environment")
|
11
|
-
|
12
|
-
unless Tetrahedron::Database.configured?
|
13
|
-
$stderr.puts "Database not configured!\n => Use Tetrahedron::Database.configure in config/environment.rb!"
|
14
|
-
end
|
15
|
-
|
16
|
-
# unless Tetrahedron::Redis.configured?
|
17
|
-
# $stderr.puts "Redis not configured!\n => Use Tetrahedron::Redis.configure in config/environment.rb!"
|
18
|
-
# end
|
data/config/puma.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
require_relative 'application'
|
2
|
-
require_relative 'environment'
|
3
|
-
|
4
|
-
rackup File.join(Tetrahedron.root, 'config', 'app.ru')
|
5
|
-
|
6
|
-
environment Tetrahedron.env.to_s
|
7
|
-
bind "tcp://#{ENV['HOST'] || '0.0.0.0'}:#{ENV['PORT'] || 80}"
|
8
|
-
port (ENV['PORT'] || 80).to_i
|
9
|
-
workers (ENV['PUMA_WORKERS'] || 1).to_i
|
10
|
-
threads (ENV['PUMA_MIN_THREADS'] || 1).to_i,
|
11
|
-
(ENV['PUMA_MAX_THREADS'] || 1).to_i
|
12
|
-
|
13
|
-
preload_app!
|
14
|
-
|
15
|
-
before_fork do
|
16
|
-
if Tetrahedron.env.production?
|
17
|
-
# TODO(mtwilliams): Precompile assets.
|
18
|
-
Tetrahedron::Assets.precompile
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
on_worker_boot do
|
23
|
-
Tetrahedron.bootfile.up.call() if Tetrahedron.bootfile.up
|
24
|
-
end
|
25
|
-
|
26
|
-
# TODO(mtwilliams): Report low-level errors in production.
|
27
|
-
# lowlevel_error_handler do |e|
|
28
|
-
# ...
|
29
|
-
# end
|
data/lib/tetrahedron/app.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
module Tetrahedron
|
2
|
-
class App < Tetrahedron::Base
|
3
|
-
configure do
|
4
|
-
environment = Tetrahedron::Assets::Environment.new
|
5
|
-
set :assets, environment: environment
|
6
|
-
sprockets_based_server = Tetrahedron::Assets::Server.new(settings.assets[:environment])
|
7
|
-
set :assets, server: sprockets_based_server
|
8
|
-
end
|
9
|
-
|
10
|
-
get %r{^/assets/*} do
|
11
|
-
# Assets are handled by Sprockets.
|
12
|
-
env['PATH_INFO'].sub('/assets', '')
|
13
|
-
settings.assets[:server].call!(env)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
data/lib/tetrahedron/assets.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
module Tetrahedron
|
2
|
-
module Assets
|
3
|
-
class Environment < Sprockets::Environment
|
4
|
-
def initialize
|
5
|
-
super(Tetrahedron.config.root)
|
6
|
-
|
7
|
-
self.append_path('vendor/assets/styles')
|
8
|
-
self.append_path('vendor/assets/scripts')
|
9
|
-
self.append_path('vendor/assets/fonts')
|
10
|
-
self.append_path('vendor/assets/images')
|
11
|
-
|
12
|
-
self.append_path('assets/styles')
|
13
|
-
self.append_path('assets/scripts')
|
14
|
-
self.append_path('assets/fonts')
|
15
|
-
self.append_path('assets/images')
|
16
|
-
|
17
|
-
if Tetrahedron.env.production?
|
18
|
-
self.css_compressor = CSSminify.new
|
19
|
-
self.js_compressor = Uglifier.new
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class Server
|
25
|
-
def initialize(environment)
|
26
|
-
@environment = environment
|
27
|
-
end
|
28
|
-
|
29
|
-
def call(env)
|
30
|
-
@environment.call(env)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
class Precompiler
|
35
|
-
# Precompile.
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.precompile
|
39
|
-
# TODO(mtwilliams): Implement asset precompilation.
|
40
|
-
$stderr.puts "Asset precompilation is not implemented yet!"
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
data/lib/tetrahedron/bootfile.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
module Tetrahedron
|
2
|
-
class Bootfile
|
3
|
-
DEFAULT = "config/boot.rb"
|
4
|
-
|
5
|
-
attr_reader :up
|
6
|
-
attr_reader :down
|
7
|
-
|
8
|
-
def initialize()
|
9
|
-
# TODO(mtwilliams): Provide reasonable defaults.
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.load(filename=Tetrahedron::Bootfile::DEFAULT)
|
13
|
-
bootfile = Tetrahedron::Bootfile.new
|
14
|
-
require File.join(Tetrahedron.root, "config", "application")
|
15
|
-
DomainSpecificLanguage.for(bootfile).instance_eval(File.read(filename), filename)
|
16
|
-
bootfile
|
17
|
-
end
|
18
|
-
|
19
|
-
class DomainSpecificLanguage
|
20
|
-
def initialize(bootfile)
|
21
|
-
@bootfile = bootfile
|
22
|
-
end
|
23
|
-
|
24
|
-
def up(&block)
|
25
|
-
@bootfile.instance_variable_set(:@up, block)
|
26
|
-
end
|
27
|
-
|
28
|
-
def down(&block)
|
29
|
-
@bootfile.instance_variable_set(:@down, block)
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.for(bootfile)
|
33
|
-
DomainSpecificLanguage.new(bootfile)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.bootfile(path=Tetrahedron::Bootfile::DEFAULT)
|
39
|
-
@bootfile ||= begin
|
40
|
-
Bootfile.load(path)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
data/lib/tetrahedron/bundler.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
module Tetrahedron
|
2
|
-
class Configuration
|
3
|
-
DEFAULT = "config/tetrahedron.rb"
|
4
|
-
|
5
|
-
attr_reader :app
|
6
|
-
attr_reader :root
|
7
|
-
|
8
|
-
def initialize()
|
9
|
-
# TODO(mtwilliams): Best guess @app and @root.
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.load(filename=Tetrahedron::Configuration::DEFAULT)
|
13
|
-
configuration = Tetrahedron::Configuration.new
|
14
|
-
DomainSpecificLanguage.for(configuration).instance_eval(File.read(filename), filename)
|
15
|
-
configuration
|
16
|
-
end
|
17
|
-
|
18
|
-
class DomainSpecificLanguage
|
19
|
-
def initialize(configuration)
|
20
|
-
@configuration = configuration
|
21
|
-
end
|
22
|
-
|
23
|
-
def app(name)
|
24
|
-
@configuration.instance_variable_set(:@app, name)
|
25
|
-
end
|
26
|
-
|
27
|
-
def root(directory)
|
28
|
-
raise Tetrahedron::MisconfiguredError.new(:root, 'the path given does not exist') unless File.exist?(directory)
|
29
|
-
raise Tetrahedron::MisconfiguredError.new(:root, 'the path given is not a directory') unless File.directory?(directory)
|
30
|
-
@configuration.instance_variable_set(:@root, directory)
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.for(configuration)
|
34
|
-
DomainSpecificLanguage.new(configuration)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.config(path=Tetrahedron::Configuration::DEFAULT)
|
40
|
-
@configuration ||= begin
|
41
|
-
Configuration.load(path)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module Tetrahedron
|
2
|
-
class Controller < Tetrahedron::Base
|
3
|
-
set :views, File.join(Tetrahedron.config.root, 'app', Tetrahedron.config.app.underscore, 'views')
|
4
|
-
|
5
|
-
# Use app/<app>/views/_layouts/default as the default layout.
|
6
|
-
set :erb, :layout => :'_layouts/default'
|
7
|
-
|
8
|
-
# Recognize *.html.erb as Erubis templates.
|
9
|
-
Tilt.register Tilt::ErubisTemplate, 'html.erb'
|
10
|
-
|
11
|
-
# Don't recognize *.erb templates.
|
12
|
-
def erb(template, options={}, locals={})
|
13
|
-
options[:layout] = settings.erb[:layout] if options[:layout].nil?
|
14
|
-
render 'html.erb', template, options, locals
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
data/lib/tetrahedron/endpoint.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
module Tetrahedron
|
2
|
-
module Environment
|
3
|
-
# Loads `ENV` from `.env` if available.
|
4
|
-
def self.load
|
5
|
-
# TODO(mtwilliams): Use a proper logger.
|
6
|
-
$stdout.puts "Loading environment from `.env` if available..."
|
7
|
-
require 'dotenv'
|
8
|
-
Dotenv.load! File.join(Tetrahedron.config.root, '.env')
|
9
|
-
$stdout.puts " => Loaded from `.env`."
|
10
|
-
rescue LoadError => _
|
11
|
-
$stderr.puts " => The 'dotenv' Gem is not available on this system."
|
12
|
-
false
|
13
|
-
rescue Errno::ENOENT
|
14
|
-
$stderr.puts " => No `.env' file."
|
15
|
-
false
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.env
|
20
|
-
env = ENV["#{Tetrahedron.config.app.upcase.gsub(/::/,'_')}_ENV"] || ENV['TETRAHEDRON_ENV'] || ENV['RACK_ENV']
|
21
|
-
@env ||= ::ActiveSupport::StringInquirer.new(env)
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.env=(new_environment)
|
25
|
-
ENV["#{Tetrahedron.config.app.upcase.gsub(/::/,'_')}_ENV"] = ENV['TETRAHEDRON_ENV'] = new_environment
|
26
|
-
@env = ::ActiveSupport::StringInquirer.new(new_environment)
|
27
|
-
end
|
28
|
-
end
|
data/lib/tetrahedron/errors.rb
DELETED
data/lib/tetrahedron/model.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
module Tetrahedron
|
2
|
-
Model = Class.new(Sequel::Model)
|
3
|
-
|
4
|
-
# Stop Sequel from bitching if it's subclassed before the first database
|
5
|
-
# connection is established.
|
6
|
-
Model.db = Sequel.mock if Sequel::DATABASES.empty?
|
7
|
-
|
8
|
-
class Model
|
9
|
-
def self::db=(db)
|
10
|
-
super(db)
|
11
|
-
|
12
|
-
# All the way down, boys.
|
13
|
-
self.descendents.each do |subclass|
|
14
|
-
subclass.db = db
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def self::Model(source)
|
20
|
-
unless Sequel::Model::ANONYMOUS_MODEL_CLASSES.key?(source)
|
21
|
-
anonymous_model_class = nil
|
22
|
-
if source.is_a?(Sequel::Database)
|
23
|
-
anonymous_model_class = Class.new(Tetrahedron::Model)
|
24
|
-
anonymous_model_class.db = source
|
25
|
-
else
|
26
|
-
anonymous_model_class = Class.new(Tetrahedron::Model).set_dataset(source)
|
27
|
-
end
|
28
|
-
Sequel::Model::ANONYMOUS_MODEL_CLASSES[source] = anonymous_model_class
|
29
|
-
end
|
30
|
-
return Sequel::Model::ANONYMOUS_MODEL_CLASSES[source]
|
31
|
-
end
|
32
|
-
end
|
data/lib/tetrahedron/rake.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
module Tetrahedron
|
2
|
-
module Rake
|
3
|
-
def self.install
|
4
|
-
root = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
|
5
|
-
require_relative 'configuration'
|
6
|
-
Tetrahedron::Configuration.load
|
7
|
-
require_relative 'environment'
|
8
|
-
Tetrahedron::Environment.load
|
9
|
-
require File.join(root, 'config', 'application')
|
10
|
-
require File.join(root, 'config', 'environment')
|
11
|
-
Dir.glob(File.join(root, 'lib', 'tetrahedron', 'tasks', '**.rake')).each do |path|
|
12
|
-
Kernel.load(path)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
data/lib/tetrahedron/redis.rb
DELETED