pinion 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,5 @@
1
1
  require "pinion/error"
2
+ require "set"
2
3
 
3
4
  module Pinion
4
5
  # A conversion describes how to convert certain types of files and create asset links for them.
@@ -7,6 +8,7 @@ module Pinion
7
8
  @@conversions = {}
8
9
  def self.[](from_and_to) @@conversions[from_and_to] end
9
10
  def self.conversions_for(to) @@conversions.values.select { |c| c.to_type == to } end
11
+ def self.add_watch_directory(path) @@conversions.values.each { |c| c.add_watch_directory(path) } end
10
12
  def self.create(from_and_to, &block)
11
13
  unless from_and_to.is_a?(Hash) && from_and_to.size == 1
12
14
  raise Error, "Unexpected argument to Conversion.create: #{from_and_to.inspect}"
@@ -24,11 +26,14 @@ module Pinion
24
26
  @to_type = to_type
25
27
  @gem_required = nil
26
28
  @conversion_fn = nil
29
+ @watch_fn = Proc.new {} # Don't do anything by default
30
+ @environment = {}
27
31
  end
28
32
 
29
33
  # DSL methods
30
34
  def require_gem(gem_name) @gem_required = gem_name end
31
35
  def render(&block) @conversion_fn = block end
36
+ def watch(&block) @watch_fn = block end
32
37
 
33
38
  # Instance methods
34
39
  def signature() { @from_type => @to_type } end
@@ -40,7 +45,8 @@ module Pinion
40
45
  raise Error, "No known content-type for #{@to_type}."
41
46
  end
42
47
  end
43
- def convert(file_contents) @conversion_fn.call(file_contents) end
48
+ def convert(file_contents) @conversion_fn.call(file_contents, @environment) end
49
+ def add_watch_directory(path) @watch_fn.call(path, @environment) end
44
50
  def require_dependency
45
51
  return unless @gem_required
46
52
  begin
@@ -63,12 +69,26 @@ module Pinion
63
69
  # Define built-in conversions
64
70
  Conversion.create :scss => :css do
65
71
  require_gem "sass"
66
- render { |file_contents| Sass::Engine.new(file_contents, :syntax => :scss).render }
72
+ render do |file_contents, environment|
73
+ load_paths = environment[:load_paths].to_a || []
74
+ Sass::Engine.new(file_contents, :syntax => :scss, :load_paths => load_paths).render
75
+ end
76
+ watch do |path, environment|
77
+ environment[:load_paths] ||= Set.new
78
+ environment[:load_paths] << path
79
+ end
67
80
  end
68
81
 
69
82
  Conversion.create :sass => :css do
70
83
  require_gem "sass"
71
- render { |file_contents| Sass::Engine.new(file_contents, :syntax => :sass).render }
84
+ render do |file_contents, environment|
85
+ load_paths = environment[:load_paths].to_a || []
86
+ Sass::Engine.new(file_contents, :syntax => :sass, :load_paths => load_paths).render
87
+ end
88
+ watch do |path, environment|
89
+ environment[:load_paths] ||= Set.new
90
+ environment[:load_paths] << path
91
+ end
72
92
  end
73
93
 
74
94
  Conversion.create :coffee => :js do
@@ -7,7 +7,6 @@ require "set"
7
7
 
8
8
  module Pinion
9
9
  class Server
10
- #CachedFile = Struct.new :from_path, :to_path, :compiled_contents, :mtime
11
10
  Asset = Struct.new :from_path, :to_path, :from_type, :to_type, :compiled_contents, :length, :mtime,
12
11
  :content_type
13
12
  Watch = Struct.new :path, :from_type, :to_type, :conversion
@@ -18,6 +17,7 @@ module Pinion
18
17
  @watches = []
19
18
  @cached_assets = {}
20
19
  @conversions_used = Set.new
20
+ @file_server = Rack::File.new(Dir.pwd)
21
21
  end
22
22
 
23
23
  def convert(from_and_to, &block)
@@ -43,6 +43,7 @@ module Pinion
43
43
  def watch(path)
44
44
  raise Error, "#{path} is not a directory." unless File.directory? path
45
45
  @watch_directories << path
46
+ Conversion.add_watch_directory path
46
47
  end
47
48
 
48
49
  # Boilerplate mostly stolen from sprockets
@@ -54,10 +55,20 @@ module Pinion
54
55
  env["rack.session.options"] ||= {}
55
56
  env["rack.session.options"].merge! :defer => true, :skip => true
56
57
 
57
- path = env["PATH_INFO"].to_s.sub(%r[^/], "")
58
+ root = env["SCRIPT_NAME"]
59
+ path = Rack::Utils.unescape(env["PATH_INFO"].to_s).sub(%r[^/], "")
58
60
 
59
61
  if path.include? ".."
60
- return with_content_length([403, { "Content-Type" => "text/plain" }, ["Forbidden"]])
62
+ return [403, { "Content-Type" => "text/plain", "Content-Length" => "9" }, ["Forbidden"]]
63
+ end
64
+
65
+ real_file = get_real_file(path)
66
+ if real_file
67
+ # Total hack; this is probably a big misuse of Rack::File but I don't want to have to reproduce a lot
68
+ # of its logic
69
+ # TODO: Fix this
70
+ env["PATH_INFO"] = real_file
71
+ return @file_server.call(env)
61
72
  end
62
73
 
63
74
  asset = get_asset(path)
@@ -72,7 +83,7 @@ module Pinion
72
83
  return [200, headers, []] if env["REQUEST_METHOD"] == "HEAD"
73
84
  [200, headers, asset.compiled_contents]
74
85
  else
75
- with_content_length([404, { "Content-Type" => "text/plain" }, ["Not found"]])
86
+ [404, { "Content-Type" => "text/plain", "Content-Length" => "9" }, ["Not found"]]
76
87
  end
77
88
  rescue Exception => e
78
89
  # TODO: logging
@@ -84,6 +95,14 @@ module Pinion
84
95
 
85
96
  private
86
97
 
98
+ def get_real_file(path)
99
+ @watch_directories.each do |directory|
100
+ file = File.join(directory, path)
101
+ return file if File.file? file
102
+ end
103
+ nil
104
+ end
105
+
87
106
  def get_asset(to_path)
88
107
  asset = @cached_assets[to_path]
89
108
  if asset
@@ -1,3 +1,3 @@
1
1
  module Pinion
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pinion
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-27 00:00:00.000000000Z
12
+ date: 2012-03-01 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
16
- requirement: &11163920 !ruby/object:Gem::Requirement
16
+ requirement: &70301404900360 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '1.0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *11163920
24
+ version_requirements: *70301404900360
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &11161740 !ruby/object:Gem::Requirement
27
+ requirement: &70301404899940 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *11161740
35
+ version_requirements: *70301404899940
36
36
  description: ! 'Pinion is a Rack application that you can use to compile and serve
37
37
  assets (such as Javascript and CSS).
38
38
 
@@ -61,12 +61,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
61
61
  - - ! '>='
62
62
  - !ruby/object:Gem::Version
63
63
  version: '0'
64
+ segments:
65
+ - 0
66
+ hash: -3405067065911020567
64
67
  required_rubygems_version: !ruby/object:Gem::Requirement
65
68
  none: false
66
69
  requirements:
67
70
  - - ! '>='
68
71
  - !ruby/object:Gem::Version
69
72
  version: '0'
73
+ segments:
74
+ - 0
75
+ hash: -3405067065911020567
70
76
  requirements: []
71
77
  rubyforge_project: pinion
72
78
  rubygems_version: 1.8.10