fuse 0.1.3 → 0.1.4

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.
data/lib/fuse.rb CHANGED
@@ -3,12 +3,36 @@ require 'thin'
3
3
 
4
4
  module Fuse
5
5
 
6
- VERSION = '0.1.3'
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)
@@ -30,7 +30,7 @@ class Fuse::Document::Asset
30
30
  end
31
31
 
32
32
  def relative_path
33
- @relative_path ||= path.sub(%r`^/`, '')
33
+ @relative_path ||= path.sub(%r`^[\\/]`, '')
34
34
  end
35
35
 
36
36
  def raw
@@ -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; ::Sass.compile raw, style: :compressed end
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; ::Sass.compile raw, style: :expanded end
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; Uglifier.compile filtered end
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; CoffeeScript.compile raw end
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
- opts.banner = 'Usage: fuse [command] [options]'
28
- opts.separator ''
29
- opts.separator 'Commands:'
30
- opts.separator ' server : Run a local testing server'
31
- opts.separator ' compile : Compile the document and send to STDOUT'
32
- opts.separator ''
33
- opts.separator 'Options:'
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.') { puts opts.to_s }
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('0.0.0.0', options[:port]) do
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
- print Document.new(options).to_s
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
- $stderr.puts "Found more than one potential #{$!.option_name} document. Please specify one with --#{$!.option_name}."
112
- $stderr.puts $!.options.join "\n"
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 ? $stderr.puts($!.message) : raise
132
+ $!.message ? log($!.message, :error) : raise
115
133
  end
116
134
 
117
135
  else
118
- puts options_parser
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
- doc = render_list($!.options, $!.option_name, request)
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
- doc = render_error($!.message)
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'}, [doc.to_s]]
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.3
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-03 00:00:00.000000000 Z
12
+ date: 2013-03-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thin