xmvc 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/Rakefile +12 -3
  2. data/VERSION +1 -1
  3. data/lib/xmvc/api.rb +22 -31
  4. data/lib/xmvc/builder.rb +5 -22
  5. data/lib/xmvc/generator.rb +0 -2
  6. data/lib/xmvc/generators/app.rb +21 -18
  7. data/lib/xmvc/generators/boot.rb +19 -62
  8. data/lib/xmvc/generators/templates/app/public/config/application.js +2 -2
  9. data/lib/xmvc/generators/templates/index.html +22 -0
  10. data/lib/xmvc/helpers/sprockets.rb +25 -10
  11. data/lib/xmvc/vendor.rb +178 -15
  12. data/lib/xmvc.rb +31 -32
  13. data/test/app/public/javascripts/valid_vendor/valid_vendor-all-debug.js +1 -0
  14. data/test/app/test/app/vendor/ext/vendor.yml +19 -0
  15. data/test/app/vendor/ext/vendor.yml +19 -0
  16. data/test/app/vendor/valid_vendor/src/ValidVendor.js +1 -0
  17. data/test/app/vendor/valid_vendor/vendor.yml +4 -0
  18. data/test/helper.rb +7 -1
  19. data/test/lib/invalid_vendor/invalid_vendor.rb +15 -0
  20. data/test/lib/invalid_vendor/src/InvalidVendor.js +1 -0
  21. data/test/lib/nameless_vendor/nameless_vendor.rb +20 -0
  22. data/test/lib/nameless_vendor/src/ValidVendor.js +1 -0
  23. data/test/lib/nameless_vendor/vendor.yml +4 -0
  24. data/test/lib/valid_vendor/src/ValidVendor.js +1 -0
  25. data/test/lib/valid_vendor/valid_vendor.rb +18 -0
  26. data/test/lib/valid_vendor/vendor.yml +4 -0
  27. data/test/test_app_installer.rb +15 -0
  28. data/test/test_vendor_installer.rb +108 -0
  29. metadata +36 -15
  30. data/lib/xmvc/README +0 -20
  31. data/lib/xmvc/builders/all_builder.rb +0 -13
  32. data/lib/xmvc/builders/app_builder.rb +0 -36
  33. data/lib/xmvc/builders/base.rb +0 -138
  34. data/lib/xmvc/builders/css_builder.rb +0 -34
  35. data/lib/xmvc/builders/mvc_builder.rb +0 -33
  36. data/lib/xmvc/builders/plugin_builder.rb +0 -53
  37. data/lib/xmvc/builders/vendor.rb +0 -85
  38. data/lib/xmvc/plugin.rb +0 -102
  39. data/test/test_extjs-core.rb +0 -7
data/Rakefile CHANGED
@@ -16,8 +16,9 @@ begin
16
16
  gem.add_dependency "whorm", ">= 0.1.0"
17
17
  gem.add_dependency "hpricot", ">= 0.8.2"
18
18
  gem.add_dependency "sprockets"
19
+ gem.add_development_dependency "shoulda", ">= 0"
20
+ gem.add_development_dependency "cucumber", ">= 0"
19
21
 
20
- gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
21
22
  gem.files = FileList["[A-Z]*", "{bin,generators,lib,test}/**/*"]
22
23
 
23
24
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
@@ -47,9 +48,17 @@ rescue LoadError
47
48
  end
48
49
  end
49
50
 
50
- task :test => :check_dependencies
51
+ begin
52
+ require 'cucumber/rake/task'
53
+ Cucumber::Rake::Task.new(:features)
54
+ task :features
55
+ rescue LoadError
56
+ task :features do
57
+ abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
58
+ end
59
+ end
51
60
 
52
- task :default => :test
61
+ task :default => :features
53
62
 
54
63
  require 'rake/rdoctask'
55
64
  Rake::RDocTask.new do |rdoc|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.8
1
+ 0.1.9
data/lib/xmvc/api.rb CHANGED
@@ -2,12 +2,25 @@ require 'thor'
2
2
  require 'thor/group'
3
3
 
4
4
  module Xmvc
5
- class API < Thor
6
- ARGV = ::ARGV.dup
5
+ class API < Vendor
7
6
 
8
- class_option :environment, :default => :development
7
+ vendor_name :app
9
8
 
10
- desc "build", "Build stuff"
9
+ class << self
10
+ protected
11
+
12
+ def prepare_vendor(options)
13
+ vendor = new([], options)
14
+ vendor.inside(File.expand_path(options[:root])) do |root|
15
+ vendor.destination_root = root
16
+ yield vendor if block_given?
17
+ configure(vendor)
18
+ end
19
+ vendor
20
+ end
21
+ end
22
+
23
+ class_option :environment, :default => :development
11
24
 
12
25
  desc "stats", "View code statistics"
13
26
  def stats
@@ -16,36 +29,14 @@ module Xmvc
16
29
  end
17
30
 
18
31
  desc "secretary", "Return Sprockets::Secretary for app javascripts"
19
- def secretary
20
- say_status "Xmvc::API", "secretary #{config[:root]}, #{FileUtils.pwd}"
32
+ def secretary(type = :js)
33
+ say_status "secretary", self.class.to_s
21
34
  Sprockets::Secretary.new({
22
- :source_files => Xmvc::Config["javascripts"]
35
+ :root => destination_root,
36
+ :source_files => config["javascripts"]
23
37
  })
24
38
  end
25
-
26
- def initialize(args=ARGV, options={}, config={})
27
-
28
- unless File.expand_path("../#{options[:root]}") == FileUtils.pwd
29
- FileUtils.chdir(options[:root])
30
- end
31
-
32
- Xmvc::Config.setup(options)
33
-
34
- #host = options.delete(:host)
35
- #unless host
36
- # raise Xmvc::NoFramework.new("Xmvc is meant to be supplied with a framework extension, eg extjs-mvc, via Xmvc::CLI.start(ARGV, {:framework => Your::Framework})")
37
- #end
38
-
39
- # Set the framework.
40
- #Xmvc.host = host
41
- #options.delete(:shell)
42
-
43
- #Xmvc::Config.setup(options)
44
-
45
- #Xmvc.environment = Xmvc::Config[:environment]
46
-
47
- super
48
- end
49
39
 
50
40
  end
41
+
51
42
  end
data/lib/xmvc/builder.rb CHANGED
@@ -1,32 +1,15 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__))
2
1
  module Xmvc
3
2
  class Builder < Thor
4
-
5
- autoload :Vendor, 'builders/vendor'
6
-
3
+
7
4
  include Thor::Actions
8
5
 
9
6
  desc "all", "Build all assets"
10
7
  def all(*params)
11
- Xmvc.ui.warn('build all assets with sprcokets')
12
- sec = Sprockets::Secretary.new({
13
- :source_files => Xmvc::Config["javascripts"]
14
- })
8
+ #Xmvc.ui.warn('build all assets with sprcokets')
9
+ #sec = Sprockets::Secretary.new({
10
+ # :source_files => Xmvc::Config["javascripts"]
11
+ #})
15
12
  #create_file("public/javascripts/app/app-all-debug.js", sec.concatenation)
16
13
  end
17
-
18
- desc "setup", "Initialize config file"
19
- def setup
20
- Xmvc.secretary = Sprockets::Secretary.new({})
21
- Xmvc.public_path = File.expand_path("public")
22
- host = Vendor.new([], {
23
- :environment => Xmvc.environment
24
- })
25
- host.invoke("app")
26
- end
27
-
28
- private
29
-
30
-
31
14
  end
32
15
  end
@@ -22,9 +22,7 @@ module Xmvc
22
22
  case generator
23
23
  when "app"
24
24
  options = options.dup
25
-
26
25
  App.start(params, options)
27
-
28
26
  when "model"
29
27
  model = Model.new([], options.dup)
30
28
  model.invoke("generate", [params.shift, *params])
@@ -60,20 +60,13 @@ module Xmvc
60
60
 
61
61
  def create_vendor
62
62
  directory("vendor", "vendor")
63
- inside("vendor", {}) do |pwd|
63
+ inside("vendor", {}) do |vendor_dir|
64
64
  empty_directory("plugins")
65
-
66
- #host = Xmvc.host::API.new([], {})
67
- #host.invoke(:install, [dir])
68
-
65
+ # install vendors
69
66
  Xmvc.vendors.each do |vendor|
70
- say_status("install", vendor)
71
- api = vendor::API.new([], {
72
- :root => pwd,
73
- :format => :js,
74
- :asset_root => "public"
67
+ vendor::API.install({
68
+ :root => vendor_dir
75
69
  })
76
- api.invoke(:install)
77
70
  end
78
71
  end
79
72
  end
@@ -93,24 +86,34 @@ module Xmvc
93
86
  # We want to get rid of Xmvc::Builder in favour of each vendor providing its own secretary
94
87
  #
95
88
  @vendors = []
96
- asset_root = File.join(self.destination_root, "public")
89
+ # bundle all vendor assets
97
90
  inside "vendor" do |dir|
98
91
  Xmvc.vendors.each do |vendor|
99
- @vendors << vendor::API.new([], {
92
+ api = vendor::API.load({
100
93
  :root => dir,
101
94
  :format => :js,
102
- :asset_root => asset_root
95
+ :asset_root => Xmvc::PUBLIC_PATH
103
96
  })
97
+ api.invoke(:bundle)
98
+ @vendors << api
104
99
  end
105
100
  end
106
-
101
+
102
+ # Bundle application code last
103
+ app = Xmvc::API.load({
104
+ :root => ".",
105
+ :format => :js,
106
+ :asset_root => Xmvc::PUBLIC_PATH
107
+ })
108
+ app.invoke(:bundle)
109
+ @vendors << app
110
+
111
+ # Create a boot-generator
107
112
  boot = Xmvc::Generator::Boot.new([], {
108
113
  :root => self.destination_root,
109
114
  :vendors => @vendors
110
115
  })
111
- Xmvc.ui.warn("Disabled default bundling")
112
- #boot.invoke(:default)
113
-
116
+ boot.invoke(:default)
114
117
  boot.invoke(:sprockets)
115
118
  end
116
119
  end
@@ -11,44 +11,28 @@ module Xmvc
11
11
 
12
12
  desc "default", "Generate the default index.html with config/boot.js"
13
13
  def default
14
- puts "Boot default is disabled"
15
- return false
16
14
 
17
- #builder = Xmvc::Builder.new([], {})
18
- #packages = builder.invoke(:setup, [])
15
+ ext = options[:type] || :js
19
16
 
20
- host = Xmvc.host.config["name"]
17
+ #host = Xmvc.host.config["name"]
21
18
  @development = []
22
19
  @production = []
23
20
  @test = []
24
21
 
25
- packages.each do |pkg|
26
- if pkg[:vendor] == :host
27
- pkg[:source_files].each do |file|
28
- #@development << url_for_path(file.pathname.to_s)
29
- end
30
- @production << Xmvc.public_build_url(:js, "app")
31
- else
32
- spec = pkg[:vendor]
33
- # No source-files generated but host defined? cachefly resources (ie: ext)?
34
- if pkg[:source_files].empty? and spec["host"]
35
- package = spec["name"].to_s
36
- version = spec["version"].to_s
37
- package += "-#{version}" unless version.empty?
38
- spec["javascripts"].each do |file|
39
- debug = file.gsub(/(\.js)/, "-debug.js")
40
- #TODO Fix this hard-coded "-debug" hack for Ext cachefly resources.
41
- @development << File.join(spec["host"], package, debug)
42
- @production << File.join(spec["host"], package, file)
43
- end
44
- elsif pkg[:source_files].length
45
- @development << Xmvc.public_build_url(:js, spec["name"], spec["version"], "debug")
46
- @production << Xmvc.public_build_url(:js, spec["name"], spec["version"])
47
- end
48
- end
49
- end
50
- @test = @development
22
+ # Don't render app assets, those will be auto-loaded by javascript asset-mgr
23
+ options[:vendors].reject{|v|v.class.vendor_name == :app}.each do |vendor|
24
+ @development.concat(vendor.class.asset_urls(vendor, :development, :js))
25
+ @development.concat(vendor.class.asset_urls(vendor, :production, :css))
26
+
27
+ @production.concat(vendor.class.asset_urls(vendor, :production, :js))
28
+ @production.concat(vendor.class.asset_urls(vendor, :production, :css))
29
+ end
30
+ @test = @development # <-- TODO Think about test-resources
31
+
32
+ @boot_filename = "/config/boot.js"
33
+ @stylesheets = []
51
34
 
35
+ template("index.html", "#{Xmvc::PUBLIC_PATH}/index.html", {:force => true})
52
36
  template("boot.js", "config/boot.js")
53
37
  end
54
38
 
@@ -57,45 +41,18 @@ module Xmvc
57
41
  @javascripts = []
58
42
  @stylesheets = []
59
43
  options[:vendors].each do |vendor|
60
- config = vendor.invoke(:config)
61
- if config["host"] # <-- Host as in http://extjs.cachefly.net/...
62
- config["javascripts"].each do |script|
63
- @javascripts << File.join(config["host"], script)
64
- end
65
- config["stylesheets"].each do |url|
66
- @stylesheets << File.join(config["host"], url)
67
- end
68
- else
69
- @javascripts << File.join("/sprockets", "#{config['name']}.js")
70
- if config["stylesheets"] # <-- We wanna' use Sass!
71
- config["stylesheets"].each do |url|
72
- @stylesheets << File.join("/public", "stylesheets", config["name"], url)
73
- end
74
- end
75
- end
44
+ @javascripts.concat(vendor.class.asset_urls(vendor, :development, :js, "sprockets"))
45
+ @stylesheets.concat(vendor.class.asset_urls(vendor, :production, :css))
76
46
  end
77
47
 
78
- # Finallly, add the xmvc assets (ie: controllers, models, views, plugins, etc)
79
- @javascripts << File.join("/sprockets", "app.js")
80
-
81
48
  # Application sass / css??
82
-
83
49
  template("index.html.sprockets", "public/index.html.sprockets")
84
50
  end
85
51
 
86
52
  private
87
53
 
88
- def url_for_path(path)
89
- @re ||= Regexp.new("^#{FileUtils.pwd}(.*)$")
90
- begin
91
- path.match(@re)[1]
92
- rescue StandardError
93
- raise PathError.new("Xmvc::Generator::Boot failed to determine the relative filename for the path #{path}")
94
- end
95
- end
96
-
97
- def url_for(name, ext, suffix)
98
- File.join("/", Xmvc::PUBLIC_PATH, name, Jammit.filename(name, ext, suffix))
54
+ def hosted_asset(vendor, type)
55
+
99
56
  end
100
57
 
101
58
  end
@@ -1,5 +1,3 @@
1
- ExtMVC.model.modelNamespace = MyApp.models;
2
-
3
1
  /**
4
2
  * @class MyApp.App
5
3
  * @extends ExtMVC.App
@@ -63,4 +61,6 @@ ExtMVC.App.define({
63
61
  }
64
62
  });
65
63
 
64
+ ExtMVC.model.modelNamespace = MyApp.models;
65
+
66
66
 
@@ -0,0 +1,22 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html>
4
+ <head>
5
+ <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
6
+ <% @stylesheets.each do |url| %>
7
+ <link href="<%= url %>" rel="stylesheet" type="text/css" />
8
+ <% end %>
9
+
10
+ <title>Ext MVC Application</title>
11
+ </head>
12
+
13
+ <body>
14
+ <script type="text/javascript" src="<%= @boot_filename %>">></script>
15
+ <div id="loading-mask"></div>
16
+ <div id="loading">
17
+ <div class="loading-indicator">
18
+ Loading...
19
+ </div>
20
+ </div>
21
+ </body>
22
+ </html>
@@ -23,8 +23,12 @@ module Xmvc
23
23
  # xmvc_vendors :extjs => ExtJS::API, :"extjs-mvc" => ExtJS::MVC::API
24
24
  #
25
25
  def xmvc_vendors(vendors)
26
- @vendors = vendors
27
-
26
+ #hashify the incoming array of vendors.
27
+ @vendors = {}
28
+ vendors.each do |vendor|
29
+ @vendors[vendor.vendor_name.to_sym] = vendor
30
+ end
31
+
28
32
  # Add the Xmvc API
29
33
  @vendors[:app] = Xmvc::API
30
34
  end
@@ -41,7 +45,7 @@ module Xmvc
41
45
  # Defines teh Sprockets asset_root param where concatenation files will be created.
42
46
  #
43
47
  def xmvc_asset_root(asset_root)
44
- @xmvc_asset_root = asset_root
48
+ @xmvc_asset_root = File.expand_path(asset_root)
45
49
  end
46
50
 
47
51
  ##
@@ -51,11 +55,18 @@ module Xmvc
51
55
  #
52
56
  def xmvc_asset(vid, format)
53
57
  sec = secretary(vid.to_sym, format)
54
- filename = File.join(@xmvc_root, @xmvc_asset_root, "javascripts", vid.to_s, "#{vid}-all.#{format.to_s}")
58
+ vendor = @vendors[vid.to_sym]
59
+
60
+ #asset_root = File.join(@xmvc_root, @xmvc_asset_root, "javascripts", vendor.class.vendor_name.to_s)
61
+
62
+ #FileUtils.mkdir(dir) unless File.exists?(asset_root)
63
+ #filename = File.join(dir, "#{@vendors[vid].build_name}.#{format.to_s}")
64
+ @paths ||= {}
55
65
  unless source_is_unchanged?(sec)
56
- sec.concatenation.save_to(filename)
66
+ #sec.concatenation.save_to(filename)
67
+ @paths[vid] = vendor.class.bundle_js(vendor, sec, File.join(@xmvc_root, Xmvc::PUBLIC_PATH))
57
68
  end
58
- filename
69
+ @paths[vid] || ''
59
70
  end
60
71
 
61
72
  private
@@ -66,6 +77,13 @@ module Xmvc
66
77
  @vendors[vid]
67
78
  end
68
79
 
80
+ def load_vendor(vid)
81
+ @vendors[vid.to_sym] = @vendors[vid.to_sym].load({
82
+ :format => :js,
83
+ :root => (vid.to_sym == :app) ? @xmvc_root : File.join(@xmvc_root, "vendor")
84
+ })
85
+ end
86
+
69
87
  ##
70
88
  # return last modified time of Secretary concatenation
71
89
  # @param {Sprockets::Secretary}
@@ -92,10 +110,7 @@ module Xmvc
92
110
  @secretary ||= {}
93
111
  unless @secretary[vid]
94
112
  begin
95
- @secretary[vid] = vendor(vid).new([], {
96
- :format => :js,
97
- :root => (vid == :app) ? @xmvc_root : File.join(@xmvc_root, "vendor"),
98
- }).invoke(:secretary, [])
113
+ @secretary[vid] = load_vendor(vid).invoke(:secretary, [:js])
99
114
  rescue Xmvc::Error => e
100
115
  halt e.message
101
116
  end
data/lib/xmvc/vendor.rb CHANGED
@@ -1,21 +1,184 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__))
2
-
3
1
  module Xmvc
4
-
2
+
3
+ ##
4
+ # A base thor-extension for which to build vendors/plugins for the Xmvc framework
5
+ # Extensions must impmlement several methods including :install and :secretary.
6
+ # Vendors are run in a root-dir named after themselves through the Xmvc::Vendor class-method
7
+ # #vendor_name. A Vendor must at least provide a file named 'vendor.yml' in the root of its
8
+ # template namespace
9
+ # this file is used to define asset and meta-data
10
+ #
11
+ # name: some-vendor
12
+ # javascripts:
13
+ # - App.js
14
+ # - app/view/**/*.js
15
+ # - app/model/*.js
16
+ # - app/controller/*.js
17
+ #
18
+
5
19
  class Vendor < Thor
6
- autoload :Plugin, 'vendor/plugin'
20
+ include Thor::Actions
21
+
22
+ class Error < StandardError
23
+ end
24
+
25
+ class SpecNotFound < Error
26
+ end
7
27
 
8
- #CONFIG_PATH = File.join(ROOT, "vendor.yml")
9
- #ROOT = File.dirname(__FILE__)
10
- #class << self
11
- # def config(root)
12
- # @config ||= YAML.load(File.read(File.join(root, "vendor.yml", ))).to_mash
13
- # end
14
- #end
28
+ ##
29
+ # all vendors must implement vendor.yml in the same directory their extension lives
30
+ #
31
+ CONFIG_FILENAME = "vendor.yml"
32
+
33
+ attr_accessor :config
34
+ attr_accessor :js
35
+ attr_accessor :css
36
+
37
+ class << self
38
+
39
+ ##
40
+ # get / set the vendor name
41
+ #
42
+ def vendor_name(name=nil)
43
+ @name ||= name
44
+ end
45
+
46
+ ##
47
+ # Install a vendor
48
+ # @return {Xmvc::Vendor}
49
+ #
50
+ def install(options)
51
+ unless vendor_name
52
+ raise Vendor::Error.new("Vendors must specify a name using the class-method vendor_name")
53
+ end
54
+
55
+ prepare_vendor(options) do |vendor|
56
+ vendor.say_status("install", vendor.class.to_s)
57
+ vendor.invoke(:install)
58
+ begin
59
+ vendor.copy_file(CONFIG_FILENAME, CONFIG_FILENAME) unless File.exists? CONFIG_FILENAME
60
+ rescue StandardError => e
61
+ raise SpecNotFound.new("Vendors must have available in their source-directory, a file named 'vendor.yml' or the class-method #source_root defined, which provides the base-path to the location of vendor.yml. Xmvc::Vendor attempted to automatically copy this file into the installation directory.")
62
+ end
63
+ end
64
+ end
65
+
66
+ ##
67
+ # Loads and configures an Xmvc::Vendor instance
68
+ # @return {Xmvc::Vendor}
69
+ #
70
+ def load(options)
71
+ prepare_vendor(options)
72
+ end
73
+
74
+ ##
75
+ # @param {Xmvc::Vendor} vendor
76
+ # @param {Symbol} environment
77
+ # @param {Symbol} ext File-extension of requested resource, :js, :css, etc
78
+ # @param {String} host
79
+ #
80
+ def asset_urls(vendor, environment = :development, ext = :js, host=nil)
81
+ config = vendor.config
82
+ host = config['host'] unless host
83
+ type = Xmvc.asset_dir(ext)
84
+ rs = []
85
+ # Note, we check config['host'] here, not host as defined above, since cachefly urls
86
+ # override host requested as function param. Host as in http://extjs.cachefly.net/...
87
+ if config['host'].include?("http://")
88
+ config[type].each do |file|
89
+ rs << cachefly_url(environment, config['host'], config['name'], file, config['version'], ext)
90
+ end
91
+ elsif host != Xmvc::PUBLIC_PATH
92
+ rs << File.join("/#{host}", "#{config['name']}.#{ext.to_s}")
93
+ else
94
+ rs << Xmvc.build_path(environment, host, config['name'], config['version'], ext)
95
+ end
96
+ rs
97
+ end
98
+
99
+ def bundle_js(vendor, sec, root=Xmvc::PUBLIC_PATH)
100
+ config = vendor.config
101
+ vendor.destination_root = root
102
+ path = ""
103
+ vendor.inside "javascripts" do
104
+ vendor.empty_directory(config['name']) unless File.exists? config['name']
105
+ vendor.inside config['name'] do |dir|
106
+ path = File.expand_path(File.join(dir, Xmvc.build_name(vendor.options[:environment]||:development, config['name'], config['version'], :js)))
107
+ sec.concatenation.save_to(path)
108
+ end
109
+ end
110
+ path
111
+ end
112
+
113
+ def bundle_css(vendor)
114
+ vendor.destination_root = Xmvc::PUBLIC_PATH
115
+ vendor.inside "stylesheets" do
116
+ Xmvc.ui.warn(' - bundle css -- no implementation')
117
+ end
118
+ end
119
+
120
+ protected
121
+
122
+ def cachefly_url(environment, host, name, file, version, ext)
123
+ version = (version.nil? or version.empty?) ? "" : "-#{version}"
124
+ File.join(host, "#{name}#{version}", "#{file}.#{ext.to_s}")
125
+ end
126
+
127
+ def prepare_vendor(options)
128
+ vendor = new([], options)
129
+ vendor.inside(File.expand_path(options[:root])) do
130
+ vendor.inside vendor_name do |root|
131
+ vendor.destination_root = root
132
+ yield vendor if block_given?
133
+ configure(vendor)
134
+ end
135
+ end
136
+ vendor
137
+ end
138
+
139
+ def defaults
140
+ @defaults ||= {
141
+ "name" => "",
142
+ "host" => "public", # <-- http://foo.cachefly.net, /sprockets, /public, (defaults to /public)
143
+ "version" => "",
144
+ "javascripts" => [],
145
+ "stylesheets" => []
146
+ }
147
+ end
148
+
149
+ def configure(vendor)
150
+ begin
151
+ vendor.config = defaults.merge(YAML.load_file(File.join(vendor.destination_root, CONFIG_FILENAME)))
152
+
153
+ # Enforce config name to that defined in the class, ignoring that
154
+ # defined in YAML, which can't be trusted. #vendor_name in the class-extension is the only
155
+ # way to ID a vendor.
156
+ vendor.config.update("name" => vendor_name)
157
+ rescue StandardError => e
158
+ raise SpecNotFound.new("Tried to load vendor #{vendor_name} but found no #{CONFIG_FILENAME} in the directory #{vendor.destination_root}")
159
+ end
160
+ vendor
161
+ end
162
+ end # end Vendor class
163
+
164
+ desc "secretary", "Return this vendor's Sprockets::Secretary"
165
+ def secretary(type = :js)
166
+ say_status "secretary", self.class.to_s
167
+ case type
168
+ when :js then @secretary ||= Sprockets::Secretary.new({
169
+ :root => destination_root,
170
+ :source_files => config["javascripts"]
171
+ })
172
+ end
173
+ end
15
174
 
16
- def initialize(args, options, config)
17
- puts "options: #{options}, config: #{config}"
18
- say_status("Xmvc::Vendor initialized, load teh config file")
175
+ desc "bundle", "Bundle a vendor's assets"
176
+ def bundle(sec = secretary(:js))
177
+ # ugly hack for root in order to satisfy both Sprockts helper and CLI.
178
+ root = (self.class.vendor_name == :app) ? Xmvc::PUBLIC_PATH : "../#{Xmvc::PUBLIC_PATH}"
179
+
180
+ self.class.bundle_js(self, sec, root) unless config['host'].include?('http://')
181
+ self.class.bundle_css(self) unless config['host'].include?('http://')
19
182
  end
20
183
  end
21
- end
184
+ end