xmvc 0.1.8 → 0.1.9

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