rail 0.0.7 → 0.0.8
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/CHANGELOG.md +4 -0
- data/Guardfile +10 -0
- data/README.md +10 -12
- data/Rakefile +4 -7
- data/bin/rail +1 -1
- data/lib/rail.rb +7 -21
- data/lib/rail/application.rb +10 -82
- data/lib/rail/browser.rb +6 -10
- data/lib/rail/generator.rb +13 -20
- data/lib/rail/pipeline.rb +13 -13
- data/lib/rail/precompiler.rb +58 -0
- data/lib/rail/processor/base.rb +1 -1
- data/lib/rail/processor/coffee_script.rb +1 -1
- data/lib/rail/processor/haml.rb +2 -2
- data/lib/rail/request.rb +12 -2
- data/lib/rail/tasks/assets.rake +1 -1
- data/lib/rail/version.rb +1 -1
- data/lib/support/generator.rb +76 -0
- data/lib/support/inflector.rb +16 -0
- data/lib/support/loader.rb +55 -0
- data/lib/support/query_string.rb +8 -0
- data/lib/support/query_struct.rb +10 -0
- data/rail.gemspec +5 -0
- data/spec/{coffee_spec.rb → features/coffee_spec.rb} +5 -7
- data/spec/{haml_spec.rb → features/haml_spec.rb} +6 -8
- data/spec/{sass_spec.rb → features/sass_spec.rb} +5 -7
- data/spec/{project → fixtures/project}/app/assets/javascripts/application.js.coffee +0 -0
- data/spec/{project → fixtures/project}/app/assets/javascripts/font.coffee +0 -0
- data/spec/{project → fixtures/project}/app/assets/javascripts/parser.js.coffee +0 -0
- data/spec/{project → fixtures/project}/app/assets/stylesheets/_reset.scss +0 -0
- data/spec/{project → fixtures/project}/app/assets/stylesheets/application.css.scss +0 -0
- data/spec/{project → fixtures/project}/app/helpers/application_helper.rb +0 -0
- data/spec/{project → fixtures/project}/app/views/articles/about.html.haml +0 -0
- data/spec/{project → fixtures/project}/app/views/layouts/application.html.haml +0 -0
- data/spec/{project → fixtures/project}/app/views/layouts/articles.html.haml +0 -0
- data/spec/{project → fixtures/project}/config/application.rb +0 -0
- data/spec/{project → fixtures/project}/controller.rb +0 -0
- data/spec/lib/rail/application_spec.rb +38 -0
- data/spec/lib/rail/generator_spec.rb +14 -0
- data/spec/lib/rail/precompiler_spec.rb +25 -0
- data/spec/lib/rail/request_spec.rb +16 -0
- data/spec/lib/support/inflector_spec.rb +18 -0
- data/spec/lib/support/loader_spec.rb +61 -0
- data/spec/lib/support/query_string_spec.rb +11 -0
- data/spec/lib/support/query_struct_spec.rb +28 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/support/common_helper.rb +5 -0
- metadata +99 -32
- data/lib/generator.rb +0 -73
- data/lib/rail/support.rb +0 -7
data/lib/rail/processor/base.rb
CHANGED
data/lib/rail/processor/haml.rb
CHANGED
@@ -36,9 +36,9 @@ module Rail
|
|
36
36
|
private
|
37
37
|
|
38
38
|
def find_layout(filename)
|
39
|
-
asset = "layouts/#{
|
39
|
+
asset = "layouts/#{filename.split('/')[-2]}"
|
40
40
|
|
41
|
-
[
|
41
|
+
["#{asset}.haml", "#{asset}.html.haml"].each do |asset|
|
42
42
|
filename = pipeline.find(asset)
|
43
43
|
return filename if filename
|
44
44
|
end
|
data/lib/rail/request.rb
CHANGED
@@ -3,15 +3,25 @@ module Rail
|
|
3
3
|
attr_reader :env
|
4
4
|
|
5
5
|
def initialize(env)
|
6
|
-
@env = env
|
6
|
+
@env = rewrite(env)
|
7
7
|
end
|
8
8
|
|
9
9
|
def path
|
10
|
-
|
10
|
+
env['PATH_INFO']
|
11
11
|
end
|
12
12
|
|
13
13
|
def host
|
14
14
|
env['HTTP_HOST']
|
15
15
|
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def rewrite(env)
|
20
|
+
path = env['PATH_INFO']
|
21
|
+
path = '/index.html' if [nil, '', '/'].include?(path)
|
22
|
+
path = "#{path}.html" if File.extname(path).empty?
|
23
|
+
env['PATH_INFO'] = path
|
24
|
+
env
|
25
|
+
end
|
16
26
|
end
|
17
27
|
end
|
data/lib/rail/tasks/assets.rake
CHANGED
data/lib/rail/version.rb
CHANGED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'ostruct'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module Support
|
6
|
+
class Generator
|
7
|
+
attr_reader :destination, :source
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
@destination = options.fetch(:destination)
|
11
|
+
@source = options.fetch(:source)
|
12
|
+
end
|
13
|
+
|
14
|
+
def process(files, locals = {})
|
15
|
+
context = OpenStruct.new(locals)
|
16
|
+
files.each { |file| process_one(file, context) }
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def process_one(file, context)
|
22
|
+
output_file = find(file)
|
23
|
+
input_file = route(file)
|
24
|
+
|
25
|
+
directory = File.dirname(input_file)
|
26
|
+
unless File.directory?(directory)
|
27
|
+
report(directory)
|
28
|
+
make(directory)
|
29
|
+
end
|
30
|
+
|
31
|
+
report(input_file)
|
32
|
+
if template?(file)
|
33
|
+
dump(transform(load(output_file), context), input_file)
|
34
|
+
else
|
35
|
+
copy(output_file, input_file)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def template?(file)
|
40
|
+
File.extname(file) == '.erb'
|
41
|
+
end
|
42
|
+
|
43
|
+
def find(file)
|
44
|
+
File.join(source, file)
|
45
|
+
end
|
46
|
+
|
47
|
+
def route(file)
|
48
|
+
File.join(destination, file).gsub(/\.erb$/, '')
|
49
|
+
end
|
50
|
+
|
51
|
+
def report(message)
|
52
|
+
puts "Creating '#{ message }'..."
|
53
|
+
end
|
54
|
+
|
55
|
+
def make(directory)
|
56
|
+
FileUtils.mkdir_p(directory)
|
57
|
+
end
|
58
|
+
|
59
|
+
def copy(output_file, input_file)
|
60
|
+
FileUtils.cp(output_file, input_file)
|
61
|
+
end
|
62
|
+
|
63
|
+
def load(file)
|
64
|
+
File.read(file)
|
65
|
+
end
|
66
|
+
|
67
|
+
def dump(content, file)
|
68
|
+
File.open(file, 'w') { |file| file.write(content) }
|
69
|
+
end
|
70
|
+
|
71
|
+
def transform(content, context)
|
72
|
+
context.singleton_class.class_eval('def get_binding; binding; end')
|
73
|
+
ERB.new(content).result(context.get_binding)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Support
|
2
|
+
module Inflector
|
3
|
+
def self.titelize(name)
|
4
|
+
name.gsub(/[^\w ]/, '')
|
5
|
+
.gsub(/^[^a-zA-Z]+/, '')
|
6
|
+
.gsub(/_/, ' ')
|
7
|
+
.gsub(/ {2,}/, ' ')
|
8
|
+
.gsub(/ +$/, '')
|
9
|
+
.gsub(/^\w| \w/, &:upcase)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.modulize(name)
|
13
|
+
name.split(/[\s_]+/).map(&:capitalize).join.to_sym
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'support/inflector'
|
2
|
+
|
3
|
+
module Support
|
4
|
+
class Loader
|
5
|
+
def initialize(pattern)
|
6
|
+
@pattern = pattern
|
7
|
+
@files = []
|
8
|
+
@names = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def reload?
|
12
|
+
!last_scanned || !last_loaded || last_loaded < last_modified
|
13
|
+
end
|
14
|
+
|
15
|
+
def find
|
16
|
+
scan!
|
17
|
+
|
18
|
+
if reload?
|
19
|
+
unload!
|
20
|
+
load!
|
21
|
+
end
|
22
|
+
|
23
|
+
modules
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :pattern, :files, :names, :modules
|
29
|
+
attr_reader :last_scanned, :last_loaded
|
30
|
+
|
31
|
+
def scan!
|
32
|
+
@last_scanned = Time.now
|
33
|
+
@files = Dir[pattern]
|
34
|
+
end
|
35
|
+
|
36
|
+
def last_modified
|
37
|
+
files.map { |file| File.mtime(file) }.max || Time.at(0)
|
38
|
+
end
|
39
|
+
|
40
|
+
def unload!
|
41
|
+
names.each { |name| Object.send(:remove_const, name) }
|
42
|
+
names.clear
|
43
|
+
end
|
44
|
+
|
45
|
+
def load!
|
46
|
+
@names = files.map do |file|
|
47
|
+
load file
|
48
|
+
Support::Inflector.modulize(File.basename(file, '.rb'))
|
49
|
+
end
|
50
|
+
|
51
|
+
@modules = names.map { |name| Object.const_get(name) }
|
52
|
+
@last_loaded = last_scanned
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/rail.gemspec
CHANGED
@@ -33,4 +33,9 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_dependency 'uglifier', '~> 2.5'
|
34
34
|
|
35
35
|
spec.add_development_dependency 'bundler', '~> 1.6'
|
36
|
+
|
37
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
38
|
+
|
39
|
+
spec.add_development_dependency 'guard', '~> 2.6'
|
40
|
+
spec.add_development_dependency 'guard-rspec', '~> 4.3'
|
36
41
|
end
|
@@ -1,15 +1,13 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fixtures/project/controller'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
describe Rail::Application do
|
4
|
+
RSpec.describe Rail::Application do
|
7
5
|
it 'handles uncompressed CoffeeScript assets' do
|
8
6
|
controller = Controller.new do
|
9
7
|
config.compress = false
|
10
8
|
end
|
11
9
|
body = controller.process('/application.js')
|
12
|
-
|
10
|
+
expect(body.strip).to eq <<-BODY.strip
|
13
11
|
(function() {
|
14
12
|
window.Parser = (function() {
|
15
13
|
function Parser(format) {
|
@@ -46,7 +44,7 @@ describe Rail::Application do
|
|
46
44
|
config.compress = true
|
47
45
|
end
|
48
46
|
body = controller.process('/application.js')
|
49
|
-
|
47
|
+
expect(body.strip).to eq <<-BODY.strip
|
50
48
|
(function(){window.Parser=function(){function n(n){this.format=n}return n}()}).call(this),function(){window.Font=function(){function n(n){this.name=n}return n}()}.call(this),function(){var n;n=new Font(\"Benton Modern Display\")}.call(this);
|
51
49
|
BODY
|
52
50
|
end
|
@@ -1,15 +1,13 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fixtures/project/controller'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
describe Rail::Application do
|
4
|
+
RSpec.describe Rail::Application do
|
7
5
|
it 'handles uncompressed Haml assets' do
|
8
6
|
controller = Controller.new do
|
9
7
|
config.compress = false
|
10
8
|
end
|
11
9
|
body = controller.process('/')
|
12
|
-
|
10
|
+
expect(body.strip).to eq <<-BODY.strip
|
13
11
|
<!DOCTYPE html>
|
14
12
|
<html>
|
15
13
|
<head>
|
@@ -27,7 +25,7 @@ describe Rail::Application do
|
|
27
25
|
config.compress = true
|
28
26
|
end
|
29
27
|
body = controller.process('/')
|
30
|
-
|
28
|
+
expect(body.strip).to eq <<-BODY.strip
|
31
29
|
<!DOCTYPE html>
|
32
30
|
<html>
|
33
31
|
<head>
|
@@ -45,7 +43,7 @@ describe Rail::Application do
|
|
45
43
|
config.compress = false
|
46
44
|
end
|
47
45
|
body = controller.process('/articles/about')
|
48
|
-
|
46
|
+
expect(body.strip).to eq <<-BODY.strip
|
49
47
|
<!DOCTYPE html>
|
50
48
|
<html>
|
51
49
|
<head>
|
@@ -1,15 +1,13 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fixtures/project/controller'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
describe Rail::Application do
|
4
|
+
RSpec.describe Rail::Application do
|
7
5
|
it 'handles uncompressed Sass assests' do
|
8
6
|
controller = Controller.new do
|
9
7
|
config.compress = false
|
10
8
|
end
|
11
9
|
body = controller.process('/application.css')
|
12
|
-
|
10
|
+
expect(body.strip).to eq <<-BODY.strip
|
13
11
|
* {
|
14
12
|
margin: 0;
|
15
13
|
padding: 0; }
|
@@ -24,7 +22,7 @@ body {
|
|
24
22
|
config.compress = true
|
25
23
|
end
|
26
24
|
body = controller.process('/application.css')
|
27
|
-
|
25
|
+
expect(body.strip).to eq <<-BODY.strip
|
28
26
|
*{margin:0;padding:0}body{font-family:'Benton Modern Display'}
|
29
27
|
BODY
|
30
28
|
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fixtures/project/config/application'
|
3
|
+
|
4
|
+
RSpec.describe Rail::Application do
|
5
|
+
subject { Project::Application.new }
|
6
|
+
|
7
|
+
describe '#call' do
|
8
|
+
context 'when index.html exists' do
|
9
|
+
before do
|
10
|
+
allow(File).to receive(:exist?).and_return(true)
|
11
|
+
end
|
12
|
+
|
13
|
+
['/', '/index.html'].each do |path|
|
14
|
+
it "lets the browser serve #{path}" do
|
15
|
+
expect(subject.browser).to receive(:process)
|
16
|
+
expect(subject.pipeline).not_to receive(:process)
|
17
|
+
|
18
|
+
subject.call('PATH_INFO' => path)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when index.html does not exist' do
|
24
|
+
before do
|
25
|
+
allow(File).to receive(:exist?).and_return(false)
|
26
|
+
end
|
27
|
+
|
28
|
+
['/', '/index.html'].each do |path|
|
29
|
+
it "lets the pipeline serve #{path}" do
|
30
|
+
expect(subject.browser).not_to receive(:process)
|
31
|
+
expect(subject.pipeline).to receive(:process)
|
32
|
+
|
33
|
+
subject.call('PATH_INFO' => path)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rail/generator'
|
3
|
+
|
4
|
+
RSpec.describe Rail::Generator do
|
5
|
+
let(:destination) { 'project' }
|
6
|
+
subject { described_class.new(destination: destination) }
|
7
|
+
|
8
|
+
describe '#run' do
|
9
|
+
it 'raises an exception if the destination folder already exists' do
|
10
|
+
expect(File).to receive(:directory?).and_return(true)
|
11
|
+
expect { subject.run }.to raise_error(ArgumentError)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rail/request'
|
3
|
+
require 'rail/precompiler'
|
4
|
+
|
5
|
+
RSpec.describe Rail::Precompiler do
|
6
|
+
let(:pipeline) { double }
|
7
|
+
let(:storage) { double }
|
8
|
+
|
9
|
+
subject do
|
10
|
+
precompiler = described_class.new(pipeline, storage)
|
11
|
+
allow(precompiler).to receive(:report)
|
12
|
+
precompiler
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#process' do
|
16
|
+
it 'works' do
|
17
|
+
expect(pipeline).to \
|
18
|
+
receive(:process).and_return([200, {}, ['Hello, world!']])
|
19
|
+
expect(storage).to \
|
20
|
+
receive(:write).with('index.html', ['Hello, world!'])
|
21
|
+
|
22
|
+
subject.process(['index.html'])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|