soca 0.2.0 → 0.3.0
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/Gemfile +10 -8
- data/Gemfile.lock +34 -26
- data/HISTORY +16 -0
- data/Rakefile +4 -4
- data/lib/soca.rb +1 -1
- data/lib/soca/plugin.rb +3 -5
- data/lib/soca/plugins/coffeescript.rb +3 -3
- data/lib/soca/plugins/compass.rb +12 -4
- data/lib/soca/plugins/haml.rb +35 -0
- data/lib/soca/plugins/jim.rb +3 -1
- data/lib/soca/plugins/macro.rb +23 -19
- data/lib/soca/plugins/mustache.rb +1 -1
- data/lib/soca/pusher.rb +39 -12
- data/lib/soca/templates/config.js.erb +4 -1
- data/soca.gemspec +35 -49
- data/test/helper.rb +2 -0
- data/test/test_compass_plugin.rb +57 -0
- data/test/test_macro_plugin.rb +35 -0
- data/test/test_soca_pusher.rb +16 -2
- data/test/testapp/config.js +5 -1
- data/test/testapp/hooks/before_build.rb +1 -1
- data/test/testapp/hooks/before_push.rb +1 -1
- metadata +148 -258
- data/test/test_plugins.rb +0 -39
data/Gemfile
CHANGED
@@ -3,15 +3,17 @@ source "http://rubygems.org"
|
|
3
3
|
|
4
4
|
gem 'json', '~>1.4.6'
|
5
5
|
gem 'mime-types', '~>1.16'
|
6
|
-
gem 'typhoeus', '~>0.2'
|
6
|
+
gem 'typhoeus', '~>0.2.4'
|
7
7
|
gem 'thor', '~>0.14.0'
|
8
8
|
gem 'jim', '~>0.3.1'
|
9
|
-
gem 'compass', '~>0.
|
10
|
-
gem 'mustache', '~>0.
|
11
|
-
gem 'coffee-script', '~>
|
9
|
+
gem 'compass', '~>0.11'
|
10
|
+
gem 'mustache', '~>0.99'
|
11
|
+
gem 'coffee-script', '~>2.2'
|
12
|
+
|
12
13
|
group :development do
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
gem 'rake'
|
15
|
+
gem 'jeweler'
|
16
|
+
end
|
17
|
+
group :test do
|
18
|
+
gem "shoulda", ">= 0"
|
17
19
|
end
|
data/Gemfile.lock
CHANGED
@@ -2,25 +2,30 @@ GEM
|
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
4
|
archive-tar-minitar (0.5.2)
|
5
|
-
|
5
|
+
chunky_png (1.2.5)
|
6
|
+
coffee-script (2.2.0)
|
6
7
|
coffee-script-source
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
execjs
|
9
|
+
coffee-script-source (1.1.2)
|
10
|
+
compass (0.11.5)
|
11
|
+
chunky_png (~> 1.2)
|
12
|
+
fssm (>= 0.2.7)
|
13
|
+
sass (~> 3.1)
|
10
14
|
downlow (0.1.4)
|
11
15
|
archive-tar-minitar (>= 0.5.2)
|
12
16
|
rubyzip (>= 0.9.4)
|
17
|
+
execjs (1.2.9)
|
18
|
+
multi_json (~> 1.0)
|
13
19
|
fakeweb (1.3.0)
|
14
|
-
fssm (0.2.
|
20
|
+
fssm (0.2.7)
|
15
21
|
git (1.2.5)
|
16
|
-
|
17
|
-
|
18
|
-
bundler (~> 1.0.0)
|
22
|
+
jeweler (1.6.4)
|
23
|
+
bundler (~> 1.0)
|
19
24
|
git (>= 1.2.5)
|
20
25
|
rake
|
21
26
|
jim (0.3.1)
|
22
|
-
downlow (~> 0.1.4)
|
23
27
|
downlow (~> 0.1.3)
|
28
|
+
downlow (~> 0.1.4)
|
24
29
|
fakeweb (>= 1.2.8)
|
25
30
|
fssm
|
26
31
|
fssm (~> 0.2.0)
|
@@ -31,44 +36,47 @@ GEM
|
|
31
36
|
rake
|
32
37
|
shoulda
|
33
38
|
test-unit
|
34
|
-
thor (~> 0.14.4)
|
35
39
|
thor
|
40
|
+
thor (~> 0.14.4)
|
36
41
|
version_sorter (~> 1.1.0)
|
37
42
|
version_sorter (~> 1.1.0)
|
38
43
|
yajl-ruby
|
39
44
|
yajl-ruby
|
40
45
|
json (1.4.6)
|
41
|
-
leftright (0.9.
|
46
|
+
leftright (0.9.1)
|
47
|
+
metaclass (0.0.1)
|
42
48
|
mime-types (1.16)
|
43
|
-
mocha (0.
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
rack
|
49
|
+
mocha (0.10.0)
|
50
|
+
metaclass (~> 0.0.1)
|
51
|
+
multi_json (1.0.3)
|
52
|
+
mustache (0.99.4)
|
53
|
+
rack (1.3.3)
|
54
|
+
rack-test (0.6.1)
|
48
55
|
rack (>= 1.0)
|
49
|
-
rake (0.
|
56
|
+
rake (0.9.2)
|
50
57
|
rubyzip (0.9.4)
|
58
|
+
sass (3.1.8)
|
51
59
|
shoulda (2.11.3)
|
52
|
-
test-unit (2.
|
60
|
+
test-unit (2.4.0)
|
53
61
|
thor (0.14.6)
|
54
|
-
typhoeus (0.2.
|
62
|
+
typhoeus (0.2.4)
|
63
|
+
mime-types
|
64
|
+
mime-types
|
55
65
|
version_sorter (1.1.0)
|
56
|
-
yajl-ruby (0.
|
57
|
-
yard (0.6.4)
|
66
|
+
yajl-ruby (1.0.0)
|
58
67
|
|
59
68
|
PLATFORMS
|
60
69
|
ruby
|
61
70
|
|
62
71
|
DEPENDENCIES
|
63
|
-
coffee-script (~> 2.
|
64
|
-
compass (~> 0.
|
72
|
+
coffee-script (~> 2.2)
|
73
|
+
compass (~> 0.11)
|
65
74
|
jeweler
|
66
75
|
jim (~> 0.3.1)
|
67
76
|
json (~> 1.4.6)
|
68
77
|
mime-types (~> 1.16)
|
69
|
-
mustache (~> 0.
|
78
|
+
mustache (~> 0.99)
|
70
79
|
rake
|
71
80
|
shoulda
|
72
81
|
thor (~> 0.14.0)
|
73
|
-
typhoeus (~> 0.2)
|
74
|
-
yard
|
82
|
+
typhoeus (~> 0.2.4)
|
data/HISTORY
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
== 0.3.0 [01-21-12]
|
2
|
+
|
3
|
+
* Big release with a lot of breaking changes
|
4
|
+
|
5
|
+
- New plugin architecture: Instead of including plugins in hooks, plugins define their own hook methods like `before_build`.
|
6
|
+
See: https://github.com/quirkey/soca/tree/master/lib/soca/plugin
|
7
|
+
Plugins are then activated/included by creating an array of ordered plugins in the config.json
|
8
|
+
See: https://github.com/quirkey/soca/blob/master/test/testapp/config.js#L12
|
9
|
+
- New HAML plugin [ Eric Wollesen ]
|
10
|
+
- Write json-files as json into the document [ Niko Uphoff ]
|
11
|
+
- Allow https in env db_url [Alexis Hildebrandt]
|
12
|
+
- Optionally configure sass and css directories in compass plugin [ Neal Clark ]
|
13
|
+
- Macro should play nice with built-in reduce functions [ Gabor Ratky ]
|
14
|
+
- added a new flag to config.js called {"not_design": true} to allow non-design documents to be autopushed. [Kevin Malakoff]
|
15
|
+
- Read files in using binread rather than read. Otherwise binary attachments such as images get totally screwed. [Pete Bacon Darwin]
|
16
|
+
|
1
17
|
== 0.2.0 [03-02-11]
|
2
18
|
|
3
19
|
- Allow rewrite rules to be pushed with rewrites.js
|
data/Rakefile
CHANGED
@@ -15,12 +15,12 @@ begin
|
|
15
15
|
gem.authors = ["Aaron Quint"]
|
16
16
|
gem.add_dependency 'json', '~>1.4.6'
|
17
17
|
gem.add_dependency 'mime-types', '~>1.16'
|
18
|
-
gem.add_dependency 'typhoeus', '~>0.2'
|
18
|
+
gem.add_dependency 'typhoeus', '~>0.2.4'
|
19
19
|
gem.add_dependency 'thor', '~>0.14.0'
|
20
20
|
gem.add_dependency 'jim', '~>0.3.1'
|
21
|
-
gem.add_dependency 'compass', '~>0.
|
22
|
-
gem.add_dependency 'mustache', '~>0.
|
23
|
-
gem.add_dependency 'coffee-script', '~> 2.
|
21
|
+
gem.add_dependency 'compass', '~>0.12'
|
22
|
+
gem.add_dependency 'mustache', '~>0.99'
|
23
|
+
gem.add_dependency 'coffee-script', '~> 2.2'
|
24
24
|
gem.add_development_dependency "shoulda", ">= 0"
|
25
25
|
gem.add_development_dependency "yard", ">= 0"
|
26
26
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
data/lib/soca.rb
CHANGED
data/lib/soca/plugin.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Soca
|
2
2
|
class Plugin
|
3
3
|
attr_reader :pusher
|
4
|
+
attr_accessor :options
|
4
5
|
|
5
6
|
def self.name(plugin_name)
|
6
7
|
@@plugins ||= {}
|
@@ -11,12 +12,9 @@ module Soca
|
|
11
12
|
@@plugins ||= {}
|
12
13
|
end
|
13
14
|
|
14
|
-
def initialize(pusher)
|
15
|
+
def initialize(pusher, options = {})
|
15
16
|
@pusher = pusher
|
16
|
-
|
17
|
-
|
18
|
-
def run(options = {})
|
19
|
-
raise "you need to subclass plugin and provide your own logic, please"
|
17
|
+
@options = options
|
20
18
|
end
|
21
19
|
|
22
20
|
def logger
|
@@ -14,7 +14,7 @@ module Soca
|
|
14
14
|
# * :vars - Additional variables to interpolate. By default the `env` and
|
15
15
|
# `config` are interpolated.
|
16
16
|
#
|
17
|
-
def
|
17
|
+
def before_build
|
18
18
|
file_patterns = options[:files] || '**/*.coffee'
|
19
19
|
files = Dir[*[file_patterns].flatten]
|
20
20
|
vars = {
|
@@ -30,11 +30,11 @@ module Soca
|
|
30
30
|
parts = basename.split(/\./)
|
31
31
|
new_file = (parts.length > 2 ? parts[0..-2].join('.') : parts[0]) + ".js"
|
32
32
|
|
33
|
-
|
33
|
+
output_dir = options[:output_dir] || dir
|
34
|
+
File.open(File.join(output_dir, new_file), 'w') do |f|
|
34
35
|
f << ::CoffeeScript.compile(File.read(file), vars)
|
35
36
|
end
|
36
37
|
Soca.logger.debug "Wrote to #{new_file}"
|
37
|
-
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
data/lib/soca/plugins/compass.rb
CHANGED
@@ -8,18 +8,26 @@ module Soca
|
|
8
8
|
|
9
9
|
name 'compass'
|
10
10
|
|
11
|
-
def
|
11
|
+
def before_build
|
12
12
|
Soca.logger.info "compiling compass"
|
13
|
-
|
14
|
-
compass_to = File.join(app_dir, 'css')
|
13
|
+
|
15
14
|
unless Soca.debug
|
16
|
-
options = {:logger => ::Compass::NullLogger.new}.merge(options)
|
15
|
+
options = {:logger => ::Compass::NullLogger.new}.merge(self.options)
|
17
16
|
end
|
17
|
+
|
18
18
|
compass = ::Compass::Compiler.new(app_dir, compass_from, compass_to, ::Compass.sass_engine_options.merge(options || {}))
|
19
19
|
Soca.logger.debug "compass: #{compass.inspect}"
|
20
20
|
compass.run
|
21
21
|
end
|
22
22
|
|
23
|
+
private
|
24
|
+
def compass_from
|
25
|
+
options.has_key?(:from) ? File.join(app_dir, options[:from]) : File.join(app_dir, 'sass')
|
26
|
+
end
|
27
|
+
|
28
|
+
def compass_to
|
29
|
+
options.has_key?(:to) ? File.join(app_dir, options[:to]) : File.join(app_dir, 'css')
|
30
|
+
end
|
23
31
|
end
|
24
32
|
end
|
25
33
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'haml'
|
2
|
+
|
3
|
+
module Soca
|
4
|
+
module Plugins
|
5
|
+
class Haml < Soca::Plugin
|
6
|
+
|
7
|
+
name 'haml'
|
8
|
+
|
9
|
+
def before_build
|
10
|
+
Dir[File.join(haml_from, "**/*.haml")].each do |file|
|
11
|
+
Soca.logger.debug "Running #{file} through Haml."
|
12
|
+
basename = File.basename(file, ".haml")
|
13
|
+
dir = File.dirname(file).sub(/^#{haml_from}/, haml_to)
|
14
|
+
new_file = basename + ".html"
|
15
|
+
FileUtils.mkdir_p(dir) unless File.exists?(dir)
|
16
|
+
|
17
|
+
File.open(File.join(dir, new_file), 'w') do |f|
|
18
|
+
f << ::Haml::Engine.new(File.read(file)).render
|
19
|
+
end
|
20
|
+
Soca.logger.debug "Wrote to #{File.join(dir, new_file)}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def haml_from
|
26
|
+
options.has_key?(:from) ? File.join(app_dir, options[:from]) : File.join(app_dir, 'haml')
|
27
|
+
end
|
28
|
+
|
29
|
+
def haml_to
|
30
|
+
options.has_key?(:to) ? File.join(app_dir, options[:to]) : File.join(app_dir, '')
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/soca/plugins/jim.rb
CHANGED
@@ -6,11 +6,13 @@ module Soca
|
|
6
6
|
|
7
7
|
name 'jim'
|
8
8
|
|
9
|
-
def
|
9
|
+
def before_build
|
10
10
|
jimfile = File.join(app_dir, 'Jimfile')
|
11
11
|
::Jim.logger = logger
|
12
12
|
logger.debug "bundling js"
|
13
13
|
bundler = ::Jim::Bundler.new(File.read(jimfile), ::Jim::Index.new(app_dir))
|
14
|
+
# set the base dir relative to the app
|
15
|
+
bundler.bundle_dir = app_dir + bundler.bundle_dir
|
14
16
|
bundler.bundle!
|
15
17
|
end
|
16
18
|
|
data/lib/soca/plugins/macro.rb
CHANGED
@@ -1,25 +1,29 @@
|
|
1
|
-
# see http://tinyurl.com/6ab5svl views in coucdb < 1.1.x
|
1
|
+
# see http://tinyurl.com/6ab5svl views in coucdb < 1.1.x
|
2
|
+
# does not allow you to require modules so we can use couchapp
|
3
|
+
# style macros instead
|
2
4
|
module Soca
|
3
|
-
|
4
|
-
|
5
|
+
module Plugins
|
6
|
+
class Macro < Soca::Plugin
|
5
7
|
|
6
|
-
|
8
|
+
name 'macro'
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def macro_expand_on(part,code)
|
15
|
-
code[part] = code[part].split("\n").inject(" ") do |res,line|
|
16
|
-
if line =~ /\/\/ !code (.*)/
|
17
|
-
res += "\n#{File.read($1)}\n"
|
18
|
-
else
|
19
|
-
res += "#{line}\n"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
10
|
+
def before_push
|
11
|
+
@pusher.document['views'].each do |view,code|
|
12
|
+
['map','reduce'].each{|part| macro_expand_on(part,code) if code[part]}
|
23
13
|
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def macro_expand_on(part,code)
|
18
|
+
code[part] = code[part].split("\n").inject(" ") do |res,line|
|
19
|
+
if line =~ /\/\/ !code (.*)/
|
20
|
+
res += "\n#{File.read(File.join(pusher.app_dir, $1))}\n"
|
21
|
+
else
|
22
|
+
res += "#{line}\n"
|
23
|
+
end
|
24
|
+
end.strip
|
25
|
+
end
|
26
|
+
|
24
27
|
end
|
28
|
+
end
|
25
29
|
end
|
@@ -14,7 +14,7 @@ module Soca
|
|
14
14
|
# * :vars - Additional variables to interpolate. By default the `env` and
|
15
15
|
# `config` are interpolated.
|
16
16
|
#
|
17
|
-
def
|
17
|
+
def before_build
|
18
18
|
file_patterns = options[:files] || '*.mustache'
|
19
19
|
files = Dir[*[file_patterns].flatten]
|
20
20
|
vars = {
|
data/lib/soca/pusher.rb
CHANGED
@@ -30,13 +30,13 @@ module Soca
|
|
30
30
|
|
31
31
|
def build
|
32
32
|
@document = {}
|
33
|
-
|
33
|
+
run_hooks!(:before_build)
|
34
34
|
logger.debug "building app JSON"
|
35
35
|
Dir.glob(app_dir + '**/**') do |path|
|
36
36
|
next if File.directory?(path)
|
37
37
|
@document = map_file(path, @document)
|
38
38
|
end
|
39
|
-
|
39
|
+
run_hooks!(:after_build)
|
40
40
|
@document
|
41
41
|
end
|
42
42
|
|
@@ -45,7 +45,7 @@ module Soca
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def db_url
|
48
|
-
if env =~ /^
|
48
|
+
if env =~ /^https?\:\/\// # the env is actual a db_url
|
49
49
|
env
|
50
50
|
else
|
51
51
|
env_config = config['couchapprc']['env'][env]
|
@@ -56,7 +56,7 @@ module Soca
|
|
56
56
|
|
57
57
|
def push_url
|
58
58
|
raise "no app id specified in config" unless config['id']
|
59
|
-
"#{db_url}/_design/#{config['id']}"
|
59
|
+
config['not_design'] ? "#{db_url}/#{config['id']}" : "#{db_url}/_design/#{config['id']}"
|
60
60
|
end
|
61
61
|
|
62
62
|
def app_url
|
@@ -81,13 +81,13 @@ module Soca
|
|
81
81
|
def push!
|
82
82
|
create_db!
|
83
83
|
build
|
84
|
-
|
84
|
+
run_hooks!(:before_push)
|
85
85
|
get_current_revision
|
86
86
|
document['_rev'] = revision if revision
|
87
87
|
post_body = JSON.generate(document)
|
88
88
|
logger.debug "pushing document to #{push_url}"
|
89
89
|
put!(push_url, post_body)
|
90
|
-
|
90
|
+
run_hooks!(:after_push)
|
91
91
|
end
|
92
92
|
|
93
93
|
def purge!
|
@@ -107,6 +107,11 @@ module Soca
|
|
107
107
|
Soca.logger
|
108
108
|
end
|
109
109
|
|
110
|
+
def run_hooks!(hook)
|
111
|
+
run_hook_file!(hook)
|
112
|
+
run_plugin_hooks!(hook)
|
113
|
+
end
|
114
|
+
|
110
115
|
def run_hook_file!(hook)
|
111
116
|
hook_file_path = File.join(app_dir, 'hooks', "#{hook}.rb")
|
112
117
|
if File.readable? hook_file_path
|
@@ -118,15 +123,33 @@ module Soca
|
|
118
123
|
end
|
119
124
|
end
|
120
125
|
|
121
|
-
def
|
122
|
-
|
123
|
-
|
124
|
-
|
126
|
+
def run_plugin_hooks!(hook)
|
127
|
+
plugins.each do |plugin_name, plugin|
|
128
|
+
if plugin.respond_to?(hook)
|
129
|
+
plugin.send(hook)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def plugins
|
135
|
+
return @plugins if @plugins
|
136
|
+
if config['plugins']
|
137
|
+
@plugins = config['plugins'].map do |plugin_config|
|
138
|
+
plugin_name, plugin_options = [plugin_config].flatten
|
139
|
+
require "soca/plugins/#{plugin_name}"
|
140
|
+
plugin_options ||= {}
|
141
|
+
plugin_options.each {|k, v| plugin_options[k.to_sym] = v }
|
142
|
+
[plugin_name, Soca::Plugin.plugins[plugin_name].new(self, plugin_options)]
|
143
|
+
end
|
144
|
+
else
|
145
|
+
@plugins = []
|
146
|
+
end
|
147
|
+
@plugins
|
125
148
|
end
|
126
149
|
|
127
150
|
private
|
128
151
|
def map_file(path, hash)
|
129
|
-
file_data = File.
|
152
|
+
file_data = File.binread(path)
|
130
153
|
base_path = path.gsub(app_dir, '')
|
131
154
|
if map = mapped_directories.detect {|k,v| k =~ base_path }
|
132
155
|
logger.debug "Matched #{path} against #{map.inspect}"
|
@@ -147,7 +170,11 @@ module Soca
|
|
147
170
|
while !parts.empty?
|
148
171
|
part = parts.shift
|
149
172
|
if parts.empty?
|
150
|
-
|
173
|
+
if part =~ /.json$/
|
174
|
+
current_hash[part.gsub(/.json$/, '')] = JSON.parse(file_data)
|
175
|
+
else
|
176
|
+
current_hash[part] = file_data
|
177
|
+
end
|
151
178
|
else
|
152
179
|
current_hash[part] ||= {}
|
153
180
|
current_hash = current_hash[part]
|