fuse 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/fuse.rb +25 -1
- data/lib/fuse/document.rb +2 -1
- data/lib/fuse/document/asset.rb +1 -1
- data/lib/fuse/document/asset_types.rb +24 -4
- data/lib/fuse/main.rb +44 -18
- data/lib/fuse/server.rb +14 -3
- metadata +2 -2
data/lib/fuse.rb
CHANGED
@@ -3,12 +3,36 @@ require 'thin'
|
|
3
3
|
|
4
4
|
module Fuse
|
5
5
|
|
6
|
-
VERSION = '0.1.
|
6
|
+
VERSION = '0.1.4'
|
7
|
+
|
8
|
+
LOG_COLOURS = {
|
9
|
+
info: 6, # cyan
|
10
|
+
success: 2, # green
|
11
|
+
error: 1, # red
|
12
|
+
notice: 3 # yellow
|
13
|
+
}
|
7
14
|
|
8
15
|
def self.root
|
9
16
|
@root ||= File.expand_path File.dirname(__FILE__)
|
10
17
|
end
|
11
18
|
|
19
|
+
def self.log_file=(file)
|
20
|
+
@log_file = file
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.log_file
|
24
|
+
@log_file ||= $stderr
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.log(message, type = nil)
|
28
|
+
m = "\x1b["
|
29
|
+
m << (30 + (LOG_COLOURS[type] || LOG_COLOURS[:info])).to_s
|
30
|
+
m << 'm'
|
31
|
+
m << message
|
32
|
+
m << "\x1b[0m"
|
33
|
+
log_file.puts m
|
34
|
+
end
|
35
|
+
|
12
36
|
end
|
13
37
|
|
14
38
|
$:.unshift Fuse.root unless $:.include?(Fuse.root)
|
data/lib/fuse/document.rb
CHANGED
@@ -37,6 +37,7 @@ class Fuse::Document
|
|
37
37
|
collection = assets.of_type(klass).sort!
|
38
38
|
next unless collection.length > 0
|
39
39
|
if @options[:embed_assets]
|
40
|
+
#todo recreate stylesheet media attributes
|
40
41
|
tag = Nokogiri::XML::Node.new(klass::EMBED_WITH, document)
|
41
42
|
raw = collection.map do |asset|
|
42
43
|
tag['type'] = asset.type
|
@@ -125,7 +126,7 @@ class Fuse::Document
|
|
125
126
|
raise Fuse::Exception::SourceUnknown::NotFound.new(option_value) unless File.exists?(option_value)
|
126
127
|
return [option_value] unless File.directory? option_value
|
127
128
|
end
|
128
|
-
Dir[File.join(option_value || root, "**/*.{#{extensions.join(',')}}")]
|
129
|
+
Dir[File.join(option_value || root, "**/*.{#{extensions.join(',')}}")].select{ |f| File.size? f }
|
129
130
|
end
|
130
131
|
|
131
132
|
def expect_one(list, option, missing_exception)
|
data/lib/fuse/document/asset.rb
CHANGED
@@ -53,10 +53,20 @@ class Fuse::Document::Asset
|
|
53
53
|
def media
|
54
54
|
@media ||= (match = MEDIA_PATTERN.match(path)) && match[1].split(/,\s*/).sort.join(', ')
|
55
55
|
end
|
56
|
-
def compress
|
56
|
+
def compress
|
57
|
+
original = raw
|
58
|
+
compressed = ::Sass.compile original, style: :compressed
|
59
|
+
Fuse.log "SASS: Compressed #{path} from #{original.length} bytes to #{compressed.length} bytes", :success
|
60
|
+
compressed
|
61
|
+
end
|
57
62
|
def type; 'text/css' end
|
58
63
|
class Sass < self
|
59
|
-
def filter
|
64
|
+
def filter
|
65
|
+
original = raw
|
66
|
+
compiled = ::Sass.compile original, style: :expanded
|
67
|
+
Fuse.log "SASS: Compiled #{path} from #{original.length} bytes to #{compiled.length} bytes", :success
|
68
|
+
compiled
|
69
|
+
end
|
60
70
|
end
|
61
71
|
end
|
62
72
|
|
@@ -73,10 +83,20 @@ class Fuse::Document::Asset
|
|
73
83
|
}
|
74
84
|
}
|
75
85
|
end
|
76
|
-
def compress
|
86
|
+
def compress
|
87
|
+
original = filtered
|
88
|
+
compressed = Uglifier.compile original
|
89
|
+
Fuse.log "Uglifier: Compressed #{path} from #{original.length} bytes to #{compressed.length} bytes", :success
|
90
|
+
compressed
|
91
|
+
end
|
77
92
|
def type; 'text/javascript' end
|
78
93
|
class Coffee < self
|
79
|
-
def filter
|
94
|
+
def filter
|
95
|
+
original = raw
|
96
|
+
compiled = CoffeeScript.compile original
|
97
|
+
Fuse.log "CoffeeScript: Compiled #{path} from #{original.length} bytes to #{compiled.length} bytes", :success
|
98
|
+
compiled
|
99
|
+
end
|
80
100
|
end
|
81
101
|
end
|
82
102
|
|
data/lib/fuse/main.rb
CHANGED
@@ -9,6 +9,7 @@ module Fuse
|
|
9
9
|
encoding: 'UTF-8'
|
10
10
|
},
|
11
11
|
server: {
|
12
|
+
addr: '127.0.0.1',
|
12
13
|
port: 9460,
|
13
14
|
embed_assets: false
|
14
15
|
},
|
@@ -18,19 +19,33 @@ module Fuse
|
|
18
19
|
}
|
19
20
|
}
|
20
21
|
|
22
|
+
SUMMARY_WIDTH = 30
|
23
|
+
SUMMARY_INDENT = 4
|
24
|
+
|
21
25
|
def self.main
|
22
26
|
|
23
27
|
options = {}
|
24
28
|
|
25
29
|
options_parser = OptionParser.new do |opts|
|
26
30
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
"
|
32
|
+
|
33
|
+
Usage: #{$0} [command] [options]
|
34
|
+
|
35
|
+
Commands:
|
36
|
+
server : Run a local testing server
|
37
|
+
compile : Compile the document and send to STDOUT
|
38
|
+
|
39
|
+
Options:
|
40
|
+
|
41
|
+
".strip.lines.each { |line| opts.separator line }
|
42
|
+
|
43
|
+
opts.on('-a',
|
44
|
+
'--addr',
|
45
|
+
wrap("Server binding address. Defaults to #{DEFAULTS[:server][:addr]}. Use 0.0.0.0 for access from other computers. Be careful; server will allow access to any locally accessible file of Fuse's supported types.")
|
46
|
+
) do |addr|
|
47
|
+
options[:addr] = addr
|
48
|
+
end
|
34
49
|
|
35
50
|
opts.on('-c',
|
36
51
|
'--[no-]compress-assets',
|
@@ -41,7 +56,7 @@ module Fuse
|
|
41
56
|
|
42
57
|
opts.on('-e',
|
43
58
|
'--encoding CHARSET',
|
44
|
-
"Output encoding. Default is #{DEFAULTS[:common][:encoding]}."
|
59
|
+
wrap("Output encoding. Default is #{DEFAULTS[:common][:encoding]}.")
|
45
60
|
) do |e|
|
46
61
|
options[:encoding] = e
|
47
62
|
end
|
@@ -56,14 +71,14 @@ module Fuse
|
|
56
71
|
opts.on('-p',
|
57
72
|
'--port PORT',
|
58
73
|
Integer,
|
59
|
-
"Port on which to listen (only with 'server' command). Default is #{DEFAULTS[:server][:port]}."
|
74
|
+
wrap("Port on which to listen (only with 'server' command). Default is #{DEFAULTS[:server][:port]}.")
|
60
75
|
) do |port|
|
61
76
|
options[:port] = port
|
62
77
|
end
|
63
78
|
|
64
79
|
opts.on('-s',
|
65
80
|
'--source [FILE|DIR]',
|
66
|
-
'The source directory, or HTML or XML document. Default is current directory.'
|
81
|
+
wrap('The source directory, or HTML or XML document. Default is current directory.')
|
67
82
|
) do |doc|
|
68
83
|
options[:source] = doc
|
69
84
|
end
|
@@ -82,13 +97,13 @@ module Fuse
|
|
82
97
|
|
83
98
|
opts.on('-x',
|
84
99
|
'--xsl FILE',
|
85
|
-
'XSL transformation stylesheet. Default is current directory.'
|
100
|
+
wrap('XSL transformation stylesheet. Default is current directory.')
|
86
101
|
) do |xsl|
|
87
102
|
abort "#{xsl} isn't a valid XSL stylesheet" unless xsl.match(/\.xsl$/i)
|
88
103
|
options[:xsl] = xsl
|
89
104
|
end
|
90
105
|
|
91
|
-
opts.on_tail('-h', '--help', 'Show this message.') {
|
106
|
+
opts.on_tail('-h', '--help', 'Show this message.') { summary opts }
|
92
107
|
|
93
108
|
end
|
94
109
|
|
@@ -99,23 +114,26 @@ module Fuse
|
|
99
114
|
case ARGV[0]
|
100
115
|
|
101
116
|
when 'server'
|
102
|
-
Thin::Server.start(
|
117
|
+
Thin::Server.start(options[:addr], options[:port]) do
|
103
118
|
use Rack::ShowExceptions
|
104
119
|
run Server.new(options)
|
105
120
|
end
|
106
121
|
|
107
122
|
when 'compile'
|
108
123
|
begin
|
109
|
-
|
124
|
+
doc = Document.new(options)
|
125
|
+
log "Compiling #{doc.source_path}"
|
126
|
+
print doc.to_s
|
127
|
+
log 'Done.', :success
|
110
128
|
rescue Exception::SourceUnknown::TooManySources
|
111
|
-
|
112
|
-
|
129
|
+
log "Found more than one potential #{$!.option_name} document. Please specify one with --#{$!.option_name}.", :notice
|
130
|
+
log $!.options.join "\n"
|
113
131
|
rescue Exception
|
114
|
-
$!.message ?
|
132
|
+
$!.message ? log($!.message, :error) : raise
|
115
133
|
end
|
116
134
|
|
117
135
|
else
|
118
|
-
|
136
|
+
summary options_parser
|
119
137
|
|
120
138
|
end
|
121
139
|
|
@@ -131,4 +149,12 @@ module Fuse
|
|
131
149
|
end
|
132
150
|
end
|
133
151
|
|
152
|
+
def self.wrap(text, width = 80 - SUMMARY_WIDTH)
|
153
|
+
text.gsub(/(.{1,#{width}})(\s+|$)/, "\\1\n#{' ' * (SUMMARY_WIDTH + SUMMARY_INDENT + 1)}").strip
|
154
|
+
end
|
155
|
+
|
156
|
+
def self.summary(opts)
|
157
|
+
abort opts.summarize([], SUMMARY_WIDTH, SUMMARY_WIDTH - 1, ' ' * SUMMARY_INDENT).join
|
158
|
+
end
|
159
|
+
|
134
160
|
end
|
data/lib/fuse/server.rb
CHANGED
@@ -13,28 +13,39 @@ class Fuse::Server
|
|
13
13
|
call_options = @options.merge Hash[request.GET.map{ |k, v| [k.to_sym, v] }]
|
14
14
|
|
15
15
|
if @root && (asset = Fuse::Document::Asset.for(request.path))
|
16
|
+
log env, "Serve asset #{asset.path}"
|
16
17
|
return asset.call(env)
|
17
18
|
end
|
18
19
|
|
19
20
|
begin
|
20
21
|
doc = Fuse::Document.new(call_options)
|
21
22
|
@root = doc.root
|
23
|
+
result = doc.to_s
|
24
|
+
log env, "Using #{doc.xsl_path} for transformation" if doc.xsl_path
|
25
|
+
log env, "Rendered #{doc.source_path} (#{result.length} bytes)", :success
|
22
26
|
rescue Fuse::Exception::SourceUnknown::TooManySources
|
23
|
-
|
27
|
+
result = render_list($!.options, $!.option_name, request)
|
28
|
+
log env, 'Multiple source document options', :notice
|
24
29
|
rescue Fuse::Exception
|
25
30
|
if $!.message
|
26
|
-
|
31
|
+
result = render_error($!.message)
|
32
|
+
log env, $!.message, :notice
|
27
33
|
else
|
28
34
|
raise
|
29
35
|
end
|
30
36
|
end
|
31
37
|
|
32
|
-
[200, {'Content-Type' => 'text/html'}, [
|
38
|
+
[200, {'Content-Type' => 'text/html'}, [result]]
|
33
39
|
|
34
40
|
end
|
35
41
|
|
36
42
|
private
|
37
43
|
|
44
|
+
def log(env, message, *args)
|
45
|
+
Fuse.log_file.write "#{Time.now.strftime '%Y-%m-%d %H:%M:%S'} [#{env['REMOTE_ADDR']}] GET #{env['REQUEST_PATH']} "
|
46
|
+
Fuse.log message, *args
|
47
|
+
end
|
48
|
+
|
38
49
|
def render_error(text)
|
39
50
|
render_body do |h|
|
40
51
|
h.p { h.text text }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fuse
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: thin
|