pinion 0.1.1 → 0.1.2

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.
@@ -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