tetrahedron 0.0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f11bb282f14b3b5c27899cdb70fef27f4154dc20
4
+ data.tar.gz: a04eafc6d60df291569009131ee564c5fc404b44
5
+ SHA512:
6
+ metadata.gz: acb35b1fe3d7a07905a753ff2d8422db1478a097f22d18840230085cf14b8c108e0257a5c71ebc10e5969c7bd8eb3ef565638ed343f883ae8512b4195c47dce6
7
+ data.tar.gz: 1c7365409ba0e9bf0d686a849df7d4a445730a23685af903c50bb2193e702960224be195dc8cc0e0265a5d0f33fd39ed3057443cb7f7f834456ef9b97794a2ab
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ # Sublime Text 2/3
2
+ *.sublime-workspace
3
+
4
+ # RubyGems
5
+ *.gem
6
+ pkg/
data/AUTHORS ADDED
File without changes
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ ruby '2.2.3'
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,65 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ tetrahedron (0.0.0.1)
5
+ activesupport
6
+ sequel
7
+ sinatra
8
+ sinatra-contrib
9
+ thor
10
+
11
+ GEM
12
+ remote: https://rubygems.org/
13
+ specs:
14
+ activesupport (4.2.5)
15
+ i18n (~> 0.7)
16
+ json (~> 1.7, >= 1.7.7)
17
+ minitest (~> 5.1)
18
+ thread_safe (~> 0.3, >= 0.3.4)
19
+ tzinfo (~> 1.1)
20
+ backports (3.6.7)
21
+ coderay (1.1.0)
22
+ i18n (0.7.0)
23
+ json (1.8.3)
24
+ method_source (0.8.2)
25
+ minitest (5.8.3)
26
+ multi_json (1.11.2)
27
+ pry (0.10.3)
28
+ coderay (~> 1.1.0)
29
+ method_source (~> 0.8.1)
30
+ slop (~> 3.4)
31
+ rack (1.6.4)
32
+ rack-protection (1.5.3)
33
+ rack
34
+ rack-test (0.6.3)
35
+ rack (>= 1.0)
36
+ rake (10.4.2)
37
+ sequel (4.28.0)
38
+ sinatra (1.4.6)
39
+ rack (~> 1.4)
40
+ rack-protection (~> 1.4)
41
+ tilt (>= 1.3, < 3)
42
+ sinatra-contrib (1.4.6)
43
+ backports (>= 2.0)
44
+ multi_json
45
+ rack-protection
46
+ rack-test
47
+ sinatra (~> 1.4.0)
48
+ tilt (>= 1.3, < 3)
49
+ slop (3.6.0)
50
+ thor (0.19.1)
51
+ thread_safe (0.3.5)
52
+ tilt (2.0.1)
53
+ tzinfo (1.2.2)
54
+ thread_safe (~> 0.1)
55
+
56
+ PLATFORMS
57
+ ruby
58
+
59
+ DEPENDENCIES
60
+ pry
61
+ rake
62
+ tetrahedron!
63
+
64
+ BUNDLED WITH
65
+ 1.10.6
data/LICENSE ADDED
File without changes
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ Tetrahedron
2
+ ===========
3
+
4
+ [Welcome to the Tet.](https://www.youtube.com/watch?v=lt-udg9zQSE)
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/bin/tetrahedron ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # TODO(mtwilliams): Command line tool.
4
+ exit 1
data/config/app.ru ADDED
@@ -0,0 +1,21 @@
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
@@ -0,0 +1,8 @@
1
+ # TODO(mtwilliams): Better multitenancy.
2
+
3
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+ require 'tetrahedron'
5
+
6
+ require File.join(Tetrahedron.config.root, "config", "application")
7
+
8
+ Tetrahedron::Configuration.load
@@ -0,0 +1,18 @@
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 ADDED
@@ -0,0 +1,29 @@
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
@@ -0,0 +1,59 @@
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
+ require 'active_support'
19
+ require 'active_support/core_ext'
20
+
21
+ module Tetrahedron
22
+ def self.root
23
+ @root ||= File.expand_path(File.join(File.dirname(__FILE__), '..'))
24
+ end
25
+ 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'
@@ -0,0 +1,16 @@
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
@@ -0,0 +1,43 @@
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
@@ -0,0 +1,34 @@
1
+ module Tetrahedron
2
+ 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
+ # Errors are bubbled so they can be handled by middleware.
10
+ set :dump_errors, false
11
+ set :raise_errors, true
12
+ set :show_exceptions, false
13
+
14
+ # Fuck you, IE9.
15
+ disable :method_override
16
+
17
+ configure :development do
18
+ # King of iteration, baby.
19
+ register Sinatra::Reloader
20
+ end
21
+
22
+ configure do
23
+ disable :static
24
+ end
25
+
26
+ get '/*' do
27
+ # Try to serve statically first.
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
33
+ end
34
+ end
@@ -0,0 +1,43 @@
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
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ module Tetrahedron
5
+ module Bundler
6
+ def self.require
7
+ ::Bundler.require(:default, :assets, :db, :redis, Tetrahedron.env.to_sym)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,44 @@
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
@@ -0,0 +1,17 @@
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
@@ -0,0 +1,113 @@
1
+ module Tetrahedron
2
+ module Database
3
+ class Configuration
4
+ Options = %i{adapter user password host port database pool}
5
+ attr_reader *Options
6
+
7
+ def initialize(configuration={})
8
+ Options.each do |opt|
9
+ self.instance_variable_set(:"@#{opt}", configuration[opt])
10
+ end
11
+ end
12
+
13
+ def override(overrides={})
14
+ configuration = self.dup
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
21
+
22
+ def self.configured?
23
+ !@configuration.nil?
24
+ end
25
+
26
+ def self.configure(configuration)
27
+ # TODO(mtwilliams): Validate |configuration|.
28
+ configuration[:database] ||= Terahedron.config.app.to_s.underscore.gsub(/::/,'_')
29
+ configuration[:pool] ||= 1
30
+ @configuration = Configuration.new(configuration)
31
+ end
32
+
33
+ # TODO(mtwilliams): Refactor into Terahedron::Service.wait_until_reachable
34
+ def self.wait_until_reachable(overrides={})
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
56
+ end
57
+
58
+ def self.wait_until_reachable!(overrides={})
59
+ # TODO(mtwilliams): Raise a custom exception type.
60
+ raise "Database is unreachable!" unless wait_until_reachable
61
+ end
62
+
63
+ def self.connect(overrides={})
64
+ # Wait some amount of time before assuming the database is down.
65
+ Tetrahedron::Database.wait_until_reachable!(overrides)
66
+
67
+ configuration = @configuration.override(overrides) if configured?
68
+ configuration ||= Configuration.new(overrides)
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
84
+ end
85
+
86
+ def self.disconnect
87
+ connection = @connection
88
+
89
+ # TODO(mtwilliams): Ensure this is thread safe.
90
+ # Make sure no one tries to use the disconnected connection pool.
91
+ Tetrahedron::Model.db = Sequel.mock
92
+ @connection = nil
93
+
94
+ connection.disconnect unless connection.nil?
95
+ end
96
+
97
+ def self.connection
98
+ @connection
99
+ end
100
+
101
+ def self.reset
102
+ # TODO(mtwilliams): Drop and recreate database.
103
+ end
104
+
105
+ def self.migrate
106
+ Sequel::IntegerMigrator.run(connection, File.join(Tetrahedron.config.root, 'db', 'migrations'))
107
+ end
108
+
109
+ def self.seed
110
+ Kernel.load(File.join(Tetrahedron.config.root, 'db', 'seed.rb'))
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,4 @@
1
+ module Tetrahedron
2
+ class Endpoint < Tetrahedron::Base
3
+ end
4
+ end
@@ -0,0 +1,28 @@
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
@@ -0,0 +1,4 @@
1
+ module Tetrahedron
2
+ class Error < StandardError
3
+ end
4
+ end
@@ -0,0 +1,7 @@
1
+ module Tetrahedron
2
+ class MisconfiguredError < Error
3
+ def initialize(setting, reason)
4
+ super("The setting `#{setting}` is misconfigured: #{reason}!")
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,58 @@
1
+ require 'ostruct'
2
+
3
+ module Tetrahedron
4
+ module Gem
5
+ # The name of this Gem.
6
+ def self.name
7
+ "tetrahedron"
8
+ end
9
+
10
+ # The name and email address of the primary author.
11
+ def self.author
12
+ self.authors.first
13
+ end
14
+
15
+ # The name and email addresses of all authors.
16
+ def self.authors
17
+ [["Michael Williams", "m.t.williams@live.com"]].map do |author|
18
+ name, email = author
19
+ OpenStruct.new(name: name, email: email)
20
+ end
21
+ end
22
+
23
+ # This Gem's homepage URL.
24
+ def self.homepage
25
+ "http://github.com/mtwilliams/tetrahedron"
26
+ end
27
+
28
+ # This Gem's URL.
29
+ def self.url
30
+ "https://rubygems.org/gems/#{self.name}"
31
+ end
32
+
33
+ # A short summary of this Gem.
34
+ def self.summary
35
+ "Opinionated Sinatra."
36
+ end
37
+
38
+ # A full description of this Gem.
39
+ def self.description
40
+ "Tetrahedron is an opinionated web development framework."
41
+ end
42
+
43
+ module VERSION #:nodoc:
44
+ MAJOR, MINOR, PATCH, PRE = [0, 0, 0, 1]
45
+ STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
46
+ end
47
+
48
+ # The semantic version of the this Gem.
49
+ def self.version
50
+ Gem::VERSION::STRING
51
+ end
52
+
53
+ # The license covering Tetrahedron.
54
+ def self.license
55
+ "Public Domain"
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,32 @@
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
@@ -0,0 +1,16 @@
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
@@ -0,0 +1,4 @@
1
+ module Tetrahedron
2
+ module Redis
3
+ end
4
+ end
@@ -0,0 +1,28 @@
1
+ module Tetrahedron
2
+ module Sessions
3
+ class Configuration
4
+ Options = %i{cookie domain lifetime secret}
5
+ attr_reader *Options
6
+
7
+ def initialize(configuration={})
8
+ Options.each do |opt|
9
+ self.instance_variable_set(:"@#{opt}", configuration[opt])
10
+ end
11
+ end
12
+ end
13
+
14
+ def self.config
15
+ @configuration
16
+ end
17
+
18
+ def self.configured?
19
+ !@configuration.nil?
20
+ end
21
+
22
+ def self.configure(configuration)
23
+ # TODO(mtwilliams): Validate |configuration|.
24
+ configuration[:cookie] ||= "#{Tetrahedron.config.app.to_s.downcase.gsub(/::/,'.')}.session"
25
+ @configuration = Sessions::Configuration.new(configuration)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ namespace :tet do
2
+ task :up do
3
+ exec "puma -C #{File.join(Tetrahedron.root, 'config', 'puma.rb')}"
4
+ end
5
+ end
@@ -0,0 +1,34 @@
1
+ $:.push File.expand_path(File.join(File.dirname(__FILE__), 'lib'))
2
+ require 'tetrahedron/gem'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = Tetrahedron::Gem.name
6
+ s.version = Tetrahedron::Gem.version
7
+ s.platform = Gem::Platform::RUBY
8
+ s.author = Tetrahedron::Gem.author.name
9
+ s.email = Tetrahedron::Gem.author.email
10
+ s.homepage = Tetrahedron::Gem.homepage
11
+ s.summary = Tetrahedron::Gem.summary
12
+ s.description = Tetrahedron::Gem.description
13
+ s.license = Tetrahedron::Gem.license
14
+
15
+ s.required_ruby_version = '>= 2.2.3'
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+
21
+ s.require_paths = %w(lib)
22
+
23
+ s.add_development_dependency("rake")
24
+ s.add_development_dependency("pry")
25
+
26
+ s.add_dependency("activesupport")
27
+
28
+ s.add_dependency("sinatra")
29
+ s.add_dependency("sinatra-contrib")
30
+
31
+ s.add_dependency("sequel")
32
+
33
+ s.add_dependency("thor")
34
+ end
metadata ADDED
@@ -0,0 +1,174 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tetrahedron
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Michael Williams
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-11-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
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'
55
+ - !ruby/object:Gem::Dependency
56
+ name: sinatra
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sinatra-contrib
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: sequel
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'
97
+ - !ruby/object:Gem::Dependency
98
+ name: thor
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: Tetrahedron is an opinionated web development framework.
112
+ email: m.t.williams@live.com
113
+ executables:
114
+ - tetrahedron
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".gitignore"
119
+ - AUTHORS
120
+ - Gemfile
121
+ - Gemfile.lock
122
+ - LICENSE
123
+ - README.md
124
+ - Rakefile
125
+ - bin/tetrahedron
126
+ - config/app.ru
127
+ - config/application.rb
128
+ - config/environment.rb
129
+ - config/puma.rb
130
+ - lib/tetrahedron.rb
131
+ - lib/tetrahedron/app.rb
132
+ - lib/tetrahedron/assets.rb
133
+ - 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
+ - lib/tetrahedron/database.rb
139
+ - lib/tetrahedron/endpoint.rb
140
+ - lib/tetrahedron/environment.rb
141
+ - lib/tetrahedron/error.rb
142
+ - lib/tetrahedron/errors.rb
143
+ - lib/tetrahedron/gem.rb
144
+ - lib/tetrahedron/model.rb
145
+ - lib/tetrahedron/rake.rb
146
+ - lib/tetrahedron/redis.rb
147
+ - lib/tetrahedron/sessions.rb
148
+ - lib/tetrahedron/tasks/tet.rake
149
+ - tetrahedron.gemspec
150
+ homepage: http://github.com/mtwilliams/tetrahedron
151
+ licenses:
152
+ - Public Domain
153
+ metadata: {}
154
+ post_install_message:
155
+ rdoc_options: []
156
+ require_paths:
157
+ - lib
158
+ required_ruby_version: !ruby/object:Gem::Requirement
159
+ requirements:
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: 2.2.3
163
+ required_rubygems_version: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ requirements: []
169
+ rubyforge_project:
170
+ rubygems_version: 2.4.5.1
171
+ signing_key:
172
+ specification_version: 4
173
+ summary: Opinionated Sinatra.
174
+ test_files: []