cubic 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a588fe718db876392ee7fb498a236d57045b32e1
4
+ data.tar.gz: 6223844472a330f8db725c9cdf8d8f9e44e5d51e
5
+ SHA512:
6
+ metadata.gz: 498d21669a59aebf9ec20cf52cb0bde1e1c2e0e9882fd92781e34e91bb52e802c584401d954e03320e065fff9103aae63ce24c02b0f0f78f411aace44f907ba7
7
+ data.tar.gz: ce24c69ee6c6ccb11902de0ff9f9eb23a3a53aaf1775158d02ceaf55066d1fdd3a714a4c8e513dce18172975ea80bdcce2f440aabf2a75c3be7b736d8cef3b3c
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'simplecov', :require => false, :group => :test
4
+ gemspec
@@ -0,0 +1,141 @@
1
+ # Cubic
2
+
3
+ Cubic is a small framework built with a focus on quickly creating applications through a neat, easily readable file that defines the basic structure of you app.
4
+
5
+ ## Sitemap (Generator)
6
+ ---
7
+ Cubic expects an application to be generated using a 'sitemap.rb' file. In general, you will place this file in the directory you would like to generate your application inside of, but you can also tell the Cubic to generate your application in a directory other than the one your sitemap currently resides in.
8
+ Within the sitemap.rb file, you will design a basic structure for your application,
9
+ then run that file with `ruby sitemap.rb` to generate it.
10
+
11
+ Here is an example of how such a file might look.
12
+
13
+ ```ruby
14
+ require 'cubic'
15
+
16
+ Cubic.sitemap do
17
+
18
+ config do
19
+ root_path File.expand_path('../', __FILE__)
20
+ html_type 'haml'
21
+ css_type 'css'
22
+ end
23
+
24
+ models do
25
+ design(:user, {email: :string, password_digest: :string}).add('# comment')
26
+ design(:post, {title: :string, content: :string})
27
+ end
28
+
29
+ controllers do
30
+ design(:home, actions: [:index])
31
+ design(:user, actions: [:new])
32
+ design(:session, actions: [:new])
33
+ design(:post, actions: [:new, :show, :edit])
34
+ end
35
+ end
36
+ ```
37
+
38
+ Let's quickly run through the blocks within the sitemap file.
39
+
40
+ ### Config
41
+ ```ruby
42
+ root_path File.expand_path('../', __FILE__)
43
+ ```
44
+ The root_path options tells the generator where you would like the application to be generated.
45
+ ```ruby
46
+ html_type 'haml'
47
+ css_type 'css'
48
+ ```
49
+ html_type and css_type tell the generator what template engine and preprocessor language you would files to be generated with.
50
+
51
+ ### Models
52
+ The models block does exactly what you think; it generates your models!
53
+ ```ruby
54
+ design(:post, {title: :string, content: :string})
55
+ ```
56
+ The first argument passed to the design
57
+ method tells the generator what you would like to name your model. The next argument, a hash,
58
+ is what will be passed to the migrations generator to create a database table for your model.
59
+
60
+ You can call `add()` on the design method to add code directly into the model to be generated.
61
+ Every argument is a new line, so something like:
62
+ ```ruby
63
+ add('one_to_many :authorships', 'many_to_many :books')
64
+ ```
65
+ generates the following
66
+
67
+ ```ruby
68
+ class SomeModel < Sequel::Model
69
+ one_to_many :authorships
70
+ many_to_many :books
71
+
72
+ end
73
+ ```
74
+
75
+ ### Controllers
76
+ ```ruby
77
+ design(:post, actions: [:new, :show, :edit])
78
+ ```
79
+ Generating a controller is similar to model. The first argument given is the name of the controller,
80
+ then you add your actions. The array associated with the action key is what will be used to create the necessary
81
+ views for your controller, but also the routes held within the controller. If that is kind of confusing,
82
+ the routing section below will explain.
83
+
84
+ That is about as deep as the generator goes for now, so lets move on.
85
+
86
+ ## Defining routes
87
+ ---
88
+ In a Cubic application, you define your routes within the controllers you have generated. You will notice each
89
+ controller has a namespace block, which all of your routes are defined within. It's okay
90
+ to create a route outside of this block, but to keep things easy to find, all routes are defined within it by default.
91
+
92
+ Below you can see an example of a normal Cubic controller. All http methods you see defined within the
93
+ namespace block are the ones given to you at the moment.
94
+
95
+ ```ruby
96
+ class HomeController < Cubic::CubicController
97
+ namespace 'home' do
98
+
99
+ get 'index' do
100
+ end
101
+
102
+ post 'index' do
103
+ end
104
+
105
+ put 'index' do
106
+ end
107
+
108
+ destroy 'index' do
109
+ end
110
+ end
111
+ end
112
+ ```
113
+
114
+ Your route can have variables, which will be translated into a params hash.
115
+
116
+ ```ruby
117
+ get 'post/:title' do
118
+
119
+ end
120
+ ```
121
+
122
+ Then you could get the value passed in the url from within the controller or view
123
+ using the following:
124
+
125
+ ```ruby
126
+ params[:title]
127
+ ```
128
+
129
+ ## ORM
130
+ ---
131
+ Cubic uses Sequel as its ORM. To learn more about Sequel, read the documentation here: https://github.com/jeremyevans/sequel
132
+
133
+ ## Differences Between Environments
134
+ ---
135
+ As of now, Cubic's only major difference between Development and Production is the reloading of controller actions.
136
+ Because controller actions in Cubic are also routes, they must reloaded everytime a new call is made, which also means
137
+ any changes you make to a route also resets.
138
+
139
+ ## License
140
+ ---
141
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,29 @@
1
+ require 'rack'
2
+ require 'haml'
3
+ require 'erb'
4
+
5
+ require 'cubic/version'
6
+ require 'cubic/core_extensions'
7
+ require 'cubic/engine'
8
+ require 'cubic/application'
9
+ require 'cubic/render'
10
+ require 'cubic/generator'
11
+ require 'cubic/router'
12
+ require 'cubic/response'
13
+
14
+ require 'cubic/middleware/static'
15
+
16
+ # Cubic is a small framework built on the idea of quick generation using templates.
17
+ module Cubic
18
+ class << self
19
+
20
+ # First method to be called in the generation process.
21
+ def sitemap(&block)
22
+ Generator.run(&block)
23
+ end
24
+
25
+ def application
26
+ @app ||= Application
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,61 @@
1
+ require 'cubic/application/logable'
2
+ require 'cubic/application/configurator'
3
+ require 'cubic/application/controller'
4
+
5
+ module Cubic
6
+ # A cubic application inherits from the Application
7
+ # class, allowing it to change things such as
8
+ # configuration options.
9
+ class Application < Engine
10
+ class << self
11
+
12
+ # Requires all files from the generated application
13
+ # during startup.
14
+ def load_app
15
+ start_load if load_acceptable?
16
+ end
17
+
18
+ # Allows configuration options to be set within
19
+ # the config/application.rb file.
20
+ def config
21
+ Configurator
22
+ end
23
+
24
+ private
25
+
26
+ def load_acceptable?
27
+ !run_before? || development? ? has_run : false
28
+ end
29
+
30
+ def start_load
31
+ prime_app
32
+ Dir.glob(required_files).each { |f| load f }
33
+ end
34
+
35
+ def run_before?
36
+ @run_before ||= false
37
+ end
38
+
39
+ def has_run
40
+ @run_before = true
41
+ end
42
+
43
+ # Remove routes
44
+ def prime_app
45
+ Router.routes.clear
46
+ end
47
+
48
+ def development?
49
+ ENV['name'] == 'development'
50
+ end
51
+
52
+ def required_files
53
+ ctrls = File.join(config.root_dir, %w(app controllers *_controller.rb))
54
+ lib_files = File.join(config.root_dir, %w(lib ** *))
55
+ models = File.join(config.root_dir, %w(app models *.rb))
56
+
57
+ [ctrls, lib_files, models]
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,16 @@
1
+ module Cubic
2
+ # Configuration stores details given during startup.
3
+ class Configurator
4
+ class << self
5
+ attr_accessor :template_engine
6
+
7
+ def design
8
+ yield self
9
+ end
10
+
11
+ def root_dir
12
+ APP_PATH
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,48 @@
1
+ module Cubic
2
+ # All classes generated by Cubic inherit from CubicController
3
+ class CubicController
4
+ extend Logable
5
+
6
+ class << self
7
+ attr_accessor :namespace
8
+
9
+ # Allows for namespacing within controllers who inherit
10
+ # from CubicController
11
+ def namespace(name, &b)
12
+ @namespace = name
13
+ b.call
14
+ ensure
15
+ @namespace = nil
16
+ end
17
+
18
+ def get(url, &block)
19
+ namespace_url(url) if @namespace
20
+ url[0] == '/' ? url : url.prepend('/')
21
+ route_setter('GET', url, block)
22
+ end
23
+
24
+ def post(url, &block)
25
+ namespace_url(url) if @namespace
26
+ route_setter('POST', url, block)
27
+ end
28
+
29
+ def put(url, &block)
30
+ namespace_url(url) if @namespace
31
+ route_setter('PUT', url, block)
32
+ end
33
+
34
+ def delete(url, &block)
35
+ namespace_url(url) if @namespace
36
+ route_setter('DELETE', url, block)
37
+ end
38
+
39
+ def route_setter(request_method, url, block)
40
+ Router.set_route(request_method, url, block)
41
+ end
42
+
43
+ def namespace_url(url)
44
+ url.prepend(@namespace + '/')
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,19 @@
1
+ module Cubic
2
+ # Responsibe for logging information to the current environment log file.
3
+ module Logable
4
+
5
+ def log(message)
6
+ File.open(log_path, 'a') { |file| file.write(message) }
7
+ end
8
+
9
+ private
10
+
11
+ def log_path
12
+ File.join(APP_PATH, "log/#{env}.log")
13
+ end
14
+
15
+ def env
16
+ ENV['name'] || 'test'
17
+ end
18
+ end
19
+ end
@@ -0,0 +1 @@
1
+ require 'cubic/core_extensions/string'
@@ -0,0 +1 @@
1
+ require 'cubic/core_extensions/string/parse'
@@ -0,0 +1,17 @@
1
+ module Cubic
2
+ module CoreExtensions
3
+ module Parse
4
+ def integer?
5
+ [
6
+ /^[-+]?[1-9]([0-9]*)?$/,
7
+ /^0[0-7]+$/,
8
+ /^0x[0-9A-Fa-f]+$/,
9
+ /^0b[01]+$/
10
+ ].each do |match_pattern|
11
+ return true if self =~ match_pattern
12
+ end
13
+ false
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,49 @@
1
+ require 'cubic/router'
2
+ require 'erb'
3
+
4
+ module Cubic
5
+ # Engine is what makes Cubic a Rack application.
6
+ class Engine
7
+
8
+ def self.call(env)
9
+ new(env).response.finish
10
+ end
11
+
12
+ def initialize(env)
13
+ @request = Rack::Request.new(env)
14
+ end
15
+
16
+ def response
17
+ Application.load_app
18
+ if search_routes
19
+ Response.new render
20
+ else
21
+ Response.new(status_404)
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def status_404
28
+ { body: 'not found', status: 404 }
29
+ end
30
+
31
+ # Combines the params generated when checking routes
32
+ # with the params given by Rack::Request.
33
+ def merge_params
34
+ @request.params.merge(Router.params)
35
+ end
36
+
37
+ # Render a view.
38
+ def render
39
+ Render.new(merge_params, @content[:block]).template
40
+ end
41
+
42
+ # Checks if path given by Rack::Request matches
43
+ # any defined routes.
44
+ def search_routes
45
+ route = Router.search @request.request_method, @request.path
46
+ route ? @content = route : nil
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,42 @@
1
+ require_relative 'generators/config'
2
+ require_relative 'generators/base'
3
+ require_relative 'generators/controller'
4
+ require_relative 'generators/model'
5
+ require_relative 'generators/migrations'
6
+ require_relative 'generators/gemfile'
7
+ require_relative 'generators/view'
8
+ require_relative 'generators/app'
9
+
10
+ module Cubic
11
+ # The generator is what reads your sitemap file
12
+ # and generates the proper files.
13
+ module Generator
14
+ class << self
15
+
16
+ # Begins the generation process by running the block
17
+ # given from sitemap.rb file.
18
+ def run(&b)
19
+ @model = Model.new
20
+ @controller = Controller.new
21
+ @gemfile = Gemfile.new
22
+
23
+ instance_exec(&b)
24
+ App.create(@model, @controller, @gemfile)
25
+ end
26
+
27
+ private
28
+
29
+ def config(&b)
30
+ Config.instance_exec(&b)
31
+ end
32
+
33
+ def models(&b)
34
+ @model.instance_exec(&b)
35
+ end
36
+
37
+ def controllers(&b)
38
+ @controller.instance_exec(&b)
39
+ end
40
+ end
41
+ end
42
+ end