soca 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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.5'
10
- gem 'mustache', '~>0.11.2'
11
- gem 'coffee-script', '~> 2.1.2'
9
+ gem 'compass', '~>0.11'
10
+ gem 'mustache', '~>0.99'
11
+ gem 'coffee-script', '~>2.2'
12
+
12
13
  group :development do
13
- gem 'rake'
14
- gem 'jeweler'
15
- gem "shoulda", ">= 0"
16
- gem "yard", ">= 0"
14
+ gem 'rake'
15
+ gem 'jeweler'
16
+ end
17
+ group :test do
18
+ gem "shoulda", ">= 0"
17
19
  end
@@ -2,25 +2,30 @@ GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
4
  archive-tar-minitar (0.5.2)
5
- coffee-script (2.1.3)
5
+ chunky_png (1.2.5)
6
+ coffee-script (2.2.0)
6
7
  coffee-script-source
7
- coffee-script-source (1.0.1)
8
- compass (0.10.6)
9
- haml (>= 3.0.4)
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.5)
20
+ fssm (0.2.7)
15
21
  git (1.2.5)
16
- haml (3.0.25)
17
- jeweler (1.5.2)
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.0)
46
+ leftright (0.9.1)
47
+ metaclass (0.0.1)
42
48
  mime-types (1.16)
43
- mocha (0.9.10)
44
- rake
45
- mustache (0.11.2)
46
- rack (1.2.1)
47
- rack-test (0.5.7)
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.8.7)
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.1.2)
60
+ test-unit (2.4.0)
53
61
  thor (0.14.6)
54
- typhoeus (0.2.0)
62
+ typhoeus (0.2.4)
63
+ mime-types
64
+ mime-types
55
65
  version_sorter (1.1.0)
56
- yajl-ruby (0.8.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.1.2)
64
- compass (~> 0.10.5)
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.11.2)
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.10.5'
22
- gem.add_dependency 'mustache', '~>0.11.2'
23
- gem.add_dependency 'coffee-script', '~> 2.1.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
@@ -7,7 +7,7 @@ require 'logger'
7
7
  $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__))))
8
8
 
9
9
  module Soca
10
- VERSION = '0.2.0'
10
+ VERSION = '0.3.0'
11
11
 
12
12
  class << self
13
13
  attr_accessor :debug
@@ -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
- end
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 run(options = {})
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
- File.open(File.join(dir, new_file), 'w') do |f|
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
 
@@ -8,18 +8,26 @@ module Soca
8
8
 
9
9
  name 'compass'
10
10
 
11
- def run(options = {})
11
+ def before_build
12
12
  Soca.logger.info "compiling compass"
13
- compass_from = File.join(app_dir, 'sass')
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
@@ -6,11 +6,13 @@ module Soca
6
6
 
7
7
  name 'jim'
8
8
 
9
- def run(options = {})
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
 
@@ -1,25 +1,29 @@
1
- # see http://tinyurl.com/6ab5svl views in coucdb < 1.1.x does not allow require of modules therfor we need to use macors
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
- module Plugins
4
- class Macro < Soca::Plugin
5
+ module Plugins
6
+ class Macro < Soca::Plugin
5
7
 
6
- name 'macro'
8
+ name 'macro'
7
9
 
8
- def run(options = {})
9
- @pusher.document['views'].each do |view,code|
10
- ['map','reduce'].each{|part| macro_expand_on(part,code) if code[part]}
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 run(options = {})
17
+ def before_build
18
18
  file_patterns = options[:files] || '*.mustache'
19
19
  files = Dir[*[file_patterns].flatten]
20
20
  vars = {
@@ -30,13 +30,13 @@ module Soca
30
30
 
31
31
  def build
32
32
  @document = {}
33
- run_hook_file!(:before_build)
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
- run_hook_file!(:after_build)
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 =~ /^http\:\/\// # the env is actual a db_url
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
- run_hook_file!(:before_push)
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
- run_hook_file!(:after_push)
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 plugin(plugin_name, options = {})
122
- require "soca/plugins/#{plugin_name}"
123
- p = Soca::Plugin.plugins[plugin_name].new(self)
124
- p.run(options)
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.read(path)
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
- current_hash[part] = file_data
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]