homeostasis 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.md +23 -0
- data/README.md +83 -0
- data/lib/homeostasis/asset.rb +108 -0
- data/lib/homeostasis/env.rb +19 -0
- data/lib/homeostasis/path.rb +18 -0
- data/lib/homeostasis.rb +3 -0
- metadata +52 -0
data/LICENSE.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright (c) 2012, Hugh Bien
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
Redistributions of source code must retain the above copyright notice, this list
|
8
|
+
of conditions and the following disclaimer.
|
9
|
+
|
10
|
+
Redistributions in binary form must reproduce the above copyright notice, this
|
11
|
+
list of conditions and the following disclaimer in the documentation and/or
|
12
|
+
other materials provided with the distribution.
|
13
|
+
|
14
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
15
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
16
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
17
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
18
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
19
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
20
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
21
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
22
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
23
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
Description
|
2
|
+
===========
|
3
|
+
|
4
|
+
Stasis plugin for asset stamping with git revisions, environment branching,
|
5
|
+
and uri helpers.
|
6
|
+
|
7
|
+
Installation
|
8
|
+
============
|
9
|
+
|
10
|
+
% gem install homeostasis
|
11
|
+
|
12
|
+
In your controller:
|
13
|
+
|
14
|
+
require 'rubygems'
|
15
|
+
require 'homeostasis/asset' # for asset stamping
|
16
|
+
require 'homeostasis/env' # for environment handler
|
17
|
+
require 'homeostasis/path' # for path helpers
|
18
|
+
|
19
|
+
Each component is optional.
|
20
|
+
|
21
|
+
Usage
|
22
|
+
=====
|
23
|
+
|
24
|
+
By default, assets matching `/\.(jpg|png|gif|css|js)$/i` will be stamped.
|
25
|
+
So if your root directory is like this:
|
26
|
+
|
27
|
+
background.jpg
|
28
|
+
index.html.haml
|
29
|
+
script.js
|
30
|
+
styles.css
|
31
|
+
|
32
|
+
You'll end up with something like this:
|
33
|
+
|
34
|
+
background.sha1.jpg
|
35
|
+
index.html
|
36
|
+
script.sha1.js
|
37
|
+
styles.sha1.css
|
38
|
+
|
39
|
+
In your views, use the `asset_path` helper:
|
40
|
+
|
41
|
+
%img{:src => asset_path('background.jpg')}
|
42
|
+
|
43
|
+
For CSS files, I use the extension `.erb` like `styles.css.erb`:
|
44
|
+
|
45
|
+
background: url(<%= asset_path('background.jpg') %>);
|
46
|
+
|
47
|
+
You can set the regex for asset matching in your controller:
|
48
|
+
|
49
|
+
Homeostasis::Asset.matcher = /myregex$/i
|
50
|
+
|
51
|
+
You can even concat your assets into a single file:
|
52
|
+
|
53
|
+
# in controller.rb
|
54
|
+
Homeostasis::Asset.concat 'all.js', %w(jquery.js mine.js)
|
55
|
+
Homeostasis::Asset.concat 'all.css', %w(reset.css mine.css)
|
56
|
+
|
57
|
+
# in views
|
58
|
+
%link{:href => asset_path('all.css')}
|
59
|
+
%script{:src => asset_path('all.js')}
|
60
|
+
|
61
|
+
The environment handler just adds a variable:
|
62
|
+
|
63
|
+
Homeostasis::ENV
|
64
|
+
|
65
|
+
It's set to whatever `HOMEOSTASIS_ENV` or `'development'` by default. You
|
66
|
+
can use this to branch in your view:
|
67
|
+
|
68
|
+
= Homeostasis::ENV.development? ? 'local.js' : 'production.js'
|
69
|
+
|
70
|
+
The path helper uses the environment handler. It just adds the view helper
|
71
|
+
`path` which returns differently depending on the environment:
|
72
|
+
|
73
|
+
path('/blog') # development => '/blog.html'
|
74
|
+
path('/blog') # production => '/blog/'
|
75
|
+
|
76
|
+
This goes along well with an `htaccess` file that drops the `.html` extensions
|
77
|
+
from requests and adds trailing slashes.
|
78
|
+
|
79
|
+
License
|
80
|
+
=======
|
81
|
+
|
82
|
+
Copyright 2012 Hugh Bien - http://hughbien.com.
|
83
|
+
Released under BSD License, see LICENSE.md for more info.
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'homeostasis')
|
2
|
+
|
3
|
+
class Homeostasis::Asset < Stasis::Plugin
|
4
|
+
before_all :before_all
|
5
|
+
after_all :after_all
|
6
|
+
action_method :asset_path
|
7
|
+
|
8
|
+
def initialize(stasis)
|
9
|
+
@stasis = stasis
|
10
|
+
@@matcher = /\.(jpg|png|gif|css|js)/i
|
11
|
+
@@mapping = {}
|
12
|
+
@@concats = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def before_all
|
16
|
+
@stasis.paths.each do |path|
|
17
|
+
relative = path[(@stasis.root.length+1)..-1]
|
18
|
+
ext = Tilt.mappings.keys.find { |ext| File.extname(path)[1..-1] == ext }
|
19
|
+
dest = (ext && File.extname(relative) == ".#{ext}") ?
|
20
|
+
relative[0..-1*ext.length-2] :
|
21
|
+
relative
|
22
|
+
@@mapping[relative] = dest
|
23
|
+
end
|
24
|
+
imapping = @@mapping.invert
|
25
|
+
@@concats.each do |dest, files|
|
26
|
+
full_origs = files.map do |file|
|
27
|
+
orig = imapping[file]
|
28
|
+
raise "Asset not found #{file}" if orig.nil?
|
29
|
+
File.join(@stasis.root, imapping[file])
|
30
|
+
end
|
31
|
+
@@concats[dest] = full_origs
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def after_all
|
36
|
+
@@concats.each do |concatted, files|
|
37
|
+
version = self.class.version(files)
|
38
|
+
full_concatted = File.join(@stasis.destination, concatted)
|
39
|
+
full_concatted = self.class.stamped(full_concatted, version)
|
40
|
+
content = files.map do |full_orig|
|
41
|
+
orig = full_orig[(@stasis.root.length+1)..-1]
|
42
|
+
full_dest = File.join(@stasis.destination, @@mapping[orig])
|
43
|
+
raise "File not found #{full_dest}" if !File.exists?(full_dest)
|
44
|
+
file_contents = File.read(full_dest)
|
45
|
+
@@mapping.delete(orig)
|
46
|
+
File.delete(full_dest)
|
47
|
+
file_contents
|
48
|
+
end.join("\n")
|
49
|
+
File.open(full_concatted, 'w') {|f| f.print(content)}
|
50
|
+
end
|
51
|
+
@@mapping.each do |orig, dest|
|
52
|
+
next if dest !~ @@matcher
|
53
|
+
full_orig = File.join(@stasis.root, orig)
|
54
|
+
full_dest = File.join(@stasis.destination, dest)
|
55
|
+
version = self.class.version(full_orig)
|
56
|
+
File.rename(full_dest, self.class.stamped(full_dest, version))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def asset_path(path)
|
61
|
+
dest = path =~ /^\// ? path[1..-1] : path
|
62
|
+
if (concats = self.class.concats[dest])
|
63
|
+
self.class.stamped(path, self.class.version(concats))
|
64
|
+
else
|
65
|
+
orig = self.class.mapping.invert[dest]
|
66
|
+
raise "Asset not found: #{dest}" if orig.nil?
|
67
|
+
full_orig = File.join(@_stasis.root, orig)
|
68
|
+
self.class.stamped(path, self.class.version(full_orig))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.stamped(path, version)
|
73
|
+
path = path.split('.')
|
74
|
+
path.insert(
|
75
|
+
path.length > 1 ? -2 : -1,
|
76
|
+
version)
|
77
|
+
path.join('.')
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.version(paths)
|
81
|
+
paths = [paths] if !paths.is_a?(Array)
|
82
|
+
versions = paths.map do |path|
|
83
|
+
log = `git log -n1 #{path} 2> /dev/null`.split("\n")
|
84
|
+
log.length > 1 ? log[0].split(' ').last : '0'
|
85
|
+
end
|
86
|
+
versions.size == 1 ?
|
87
|
+
versions[0] :
|
88
|
+
Digest::SHA1.hexdigest(versions.join('.'))
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.matcher=(regex)
|
92
|
+
@@matcher = regex
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.mapping
|
96
|
+
@@mapping
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.concat(dest, files)
|
100
|
+
@@concats[dest] = files
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.concats
|
104
|
+
@@concats
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
Stasis.register(Homeostasis::Asset)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'homeostasis')
|
2
|
+
|
3
|
+
module Homeostasis
|
4
|
+
class Environment
|
5
|
+
def initialize(env)
|
6
|
+
@env = env
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(message, *args, &block)
|
10
|
+
if message =~ /\?$/
|
11
|
+
@env == message[0..-2]
|
12
|
+
else
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
ENV = Environment.new(::ENV['HOMEOSTASIS_ENV'] || 'development')
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'env')
|
2
|
+
|
3
|
+
class Homeostasis::Path < Stasis::Plugin
|
4
|
+
action_method :path
|
5
|
+
|
6
|
+
def initialize(stasis)
|
7
|
+
@stasis = stasis
|
8
|
+
end
|
9
|
+
|
10
|
+
def path(uri)
|
11
|
+
uri = uri[0..-2] if uri =~ /\/$/
|
12
|
+
Homeostasis::ENV.development? ?
|
13
|
+
"#{uri}.html" :
|
14
|
+
"#{uri}/"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Stasis.register(Homeostasis::Path)
|
data/lib/homeostasis.rb
ADDED
metadata
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: homeostasis
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Hugh Bien
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-18 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Provides asset stamping using git revisions, environments, and a few
|
15
|
+
view helpers.
|
16
|
+
email:
|
17
|
+
- hugh@hughbien.com
|
18
|
+
executables: []
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- README.md
|
23
|
+
- LICENSE.md
|
24
|
+
- lib/homeostasis/asset.rb
|
25
|
+
- lib/homeostasis/env.rb
|
26
|
+
- lib/homeostasis/path.rb
|
27
|
+
- lib/homeostasis.rb
|
28
|
+
homepage: https://github.com/hughbien/homeostasis
|
29
|
+
licenses: []
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.3.6
|
46
|
+
requirements: []
|
47
|
+
rubyforge_project:
|
48
|
+
rubygems_version: 1.8.15
|
49
|
+
signing_key:
|
50
|
+
specification_version: 3
|
51
|
+
summary: Stasis plugin for asset stamping and more.
|
52
|
+
test_files: []
|