xmvc 0.1.2 → 0.1.3

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.1.3
data/bin/xmvc CHANGED
@@ -18,3 +18,5 @@ rescue Xmvc::Error => e
18
18
  Xmvc.ui.error(e.message)
19
19
  exit e.status_code
20
20
  end
21
+
22
+
data/lib/xmvc/builder.rb CHANGED
@@ -10,8 +10,7 @@ module Xmvc
10
10
  setup(options)
11
11
  else
12
12
  begin
13
- @jammit = jammit(options)
14
- @jammit.invoke(:build, [name])
13
+ Xmvc.asset_mgr(options).invoke(:build, [name])
15
14
  rescue Jammit::Error => e
16
15
  raise Xmvc::BuilderError.new(e.message)
17
16
  end
@@ -36,7 +35,7 @@ module Xmvc
36
35
  javascripts.update(vendor["name"] => vendor_assets("javascripts", vendor))
37
36
  end
38
37
 
39
- jammit = Jammit::CLI.new([], options)
38
+ jammit = Xmvc.asset_mgr(options)
40
39
  jammit.invoke(:init)
41
40
  jammit.invoke(:config, ["set", "javascripts", javascripts])
42
41
  jammit.invoke(:build)
@@ -53,10 +52,6 @@ module Xmvc
53
52
  def application_assets(type, assets)
54
53
  assets.map {|f| File.join(f)}
55
54
  end
56
-
57
- def jammit(options={})
58
- Jammit::CLI.new([], options)
59
- end
60
55
  end
61
56
  end
62
57
  end
data/lib/xmvc/cli.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'thor'
2
+ require 'thor/group'
2
3
 
3
4
  require 'jammit-core'
4
5
  require 'jammit-core/cli'
@@ -14,9 +15,10 @@ module Xmvc
14
15
  end
15
16
 
16
17
  desc "generate", "Generate model, controller, view or app"
17
- def generate(which, *params)
18
+ def generate(*params)
19
+ which = params.shift
18
20
  Xmvc.ensure_in_app unless which == 'app'
19
- Xmvc::Generator.dispatch(which, *params)
21
+ Xmvc::Generator.dispatch(which, options, *params)
20
22
  end
21
23
 
22
24
  desc "build", "Build stuff"
@@ -34,7 +36,7 @@ module Xmvc
34
36
  desc "stats", "View code statistics"
35
37
  def stats
36
38
  Xmvc.ensure_in_app
37
- #Xmvc::Stats.new('Frak')
39
+ Xmvc::Stats.dispatch
38
40
  end
39
41
 
40
42
  desc "namespace", "Change the application's namespace"
@@ -46,14 +48,14 @@ module Xmvc
46
48
  def initialize(args=ARGV, config={}, options={})
47
49
 
48
50
  # Boot UI
49
- Xmvc.ui = UI::Shell.new(shell)
51
+ Xmvc.ui = shell
50
52
 
51
53
  unless options[:host]
52
54
  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})")
53
55
  end
54
56
 
55
57
  # Boot environment
56
- Xmvc.environment = Xmvc::Environment.new(:development)
58
+ Xmvc.environment = Xmvc::Environment.load(:development)
57
59
 
58
60
  # Set the framework.
59
61
  Xmvc.host = options[:host]
@@ -1,8 +1,92 @@
1
1
  module Xmvc
2
- class Environment
3
- def initialize(environment)
4
- @environment = environment
5
- Xmvc.ui.info("(loaded #{@environment.to_s} environement)")
2
+ module Environment
3
+
4
+ DEFAULT_ENVIRONMENT = File.join(Xmvc::CONFIG_PATH, "environment")
5
+ ENVIRONMENT_PATH = File.join(Xmvc::CONFIG_PATH, "environments")
6
+
7
+ class FileNotFound < Xmvc::Error; status_code(10) ; end
8
+
9
+ class << self
10
+
11
+ ##
12
+ # TODO implement development/production environments
13
+ #
14
+ def load(environment)
15
+ @environment = environment
16
+ @config = load_environment(environment)
17
+ self
18
+ end
19
+
20
+ def get(key)
21
+ config[key]
22
+ end
23
+
24
+ def set(key, value)
25
+ config[key] = value
26
+ save
27
+ end
28
+
29
+ ##
30
+ # write a newly generated controller, model or view to environment.json
31
+ # Unfortunately, we cannot JSON.parse the entire config/environment.json, since it contains comments
32
+ # and such. Have to RegExp, pick-out the requested key, and JSON.parse the returned chunk.
33
+ # Is this Regexp satisfactory?? Could probably be made better.
34
+ #
35
+ def add (key, item)
36
+ key = key.to_s
37
+ config[key] = [] unless config[key] && config[key].kind_of?(Array)
38
+
39
+ unless key == "views"
40
+ config[key] << item
41
+ else
42
+ if controller = config[key].find {|i| i[item[:package]]}
43
+ controller[item[:package]] << item[:filename]
44
+ else
45
+ config[key] << {
46
+ item[:package] => [
47
+ item[:filename]
48
+ ]
49
+ }
50
+ end
51
+ end
52
+ save
53
+ end
54
+
55
+ def render
56
+ File.open("#{DEFAULT_ENVIRONMENT}.json", "w") {|file|
57
+ file << config.to_json
58
+ }
59
+ end
60
+
61
+ private
62
+
63
+ ##
64
+ # TODO: load and merge! specific environemnt.
65
+ #
66
+ def load_environment(environment)
67
+ # When generating a new app, there is no environment yet
68
+ #
69
+ #unless File.exists?("#{DEFAULT_ENVIRONMENT}.yml")
70
+ # raise FileNotFound.new("Failed to load environment #{DEFAULT_ENVIRONMENT}.yml")
71
+ #end
72
+ if File.exists? "#{DEFAULT_ENVIRONMENT}.yml"
73
+ YAML.load_file("#{DEFAULT_ENVIRONMENT}.yml")
74
+ end
75
+ end
76
+
77
+ def config
78
+ @config ||= load_environment(:development)
79
+ end
80
+
81
+ def save
82
+ File.open("#{DEFAULT_ENVIRONMENT}.yml", "w") {|file|
83
+ file << config.to_yaml
84
+ }
85
+ File.open("#{DEFAULT_ENVIRONMENT}.json", "w") {|file|
86
+ file << config.to_json
87
+ }
88
+ end
6
89
  end
7
90
  end
8
- end
91
+ end
92
+
@@ -1,44 +1,54 @@
1
1
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
2
 
3
- require 'hpricot'
4
- require 'generators/base'
5
- require 'generators/app'
6
- require 'generators/model'
7
- require 'generators/view'
8
- require 'generators/controller'
9
- require 'generators/scaffold'
10
-
11
3
  module Xmvc
12
4
  module Generator
13
-
14
- @@generators = %w(app model controller scaffold view namespace)
15
- def self.dispatch(generator, *params)
5
+ autoload :Layout, 'generators/layout'
6
+ autoload :App, 'generators/app'
7
+ autoload :Model, 'generators/model'
8
+ autoload :View, 'generators/view'
9
+ autoload :Controller, 'generators/controller'
10
+ autoload :Scaffold, 'generators/scaffold'
11
+ autoload :Boot, 'generators/boot'
12
+
13
+ GENERATORS = %w(app model controller scaffold view namespace)
14
+
15
+ def self.dispatch(generator, options, *params)
16
16
 
17
- unless @@generators.include?(generator)
18
- raise MVC::ArgumentError.new("Must use one of the following: " + @@generators.join(", ").downcase)
17
+ unless GENERATORS.include?(generator)
18
+ raise MVC::ArgumentError.new("Must use one of the following: " + GENERATORS.join(", ").downcase)
19
19
  end
20
20
 
21
- name = params.shift
22
-
23
21
  case generator
24
22
  when "app"
25
- App.new(name).generate!
23
+ App.start(params, options.dup)
24
+ boot = Boot.new([], options.dup)
25
+ boot.invoke("generate")
26
+
26
27
  when "model"
27
- fields = params.select {|arg| arg != "--force"}.collect {|f| f.split(":")}
28
- Model.new(name, fields).generate!
28
+ model = Model.new([], options.dup)
29
+ model.invoke("generate", [params.shift, *params])
29
30
  when "controller"
30
- actions = params.select {|arg| arg != "--force"}
31
- Controller.new(name, actions).generate!
31
+ name = params.shift
32
+ controller = Controller.new([], options.dup)
33
+ controller.invoke("generate", [name])
34
+ if params.length
35
+ params.each do |v|
36
+ view = View.new([], options.dup) # why have to create new instance for each??
37
+ view.invoke("generate", [name, v])
38
+ end
39
+ end
32
40
  when "scaffold"
33
- fields = params.select {|arg| arg != "--force"}.collect {|f| f.split(":")}
34
- Scaffold.new(name, fields).generate!
35
- when "view"
36
- package = name
37
41
  name = params.shift
38
- View.new(package, name).generate!
42
+ Xmvc.ui.warn("scaffold generation is not yet implemented")
43
+ scaffold = Scaffold.new([], options.dup)
44
+ scaffold.invoke("generate", [name, params])
45
+ when "view"
46
+ package = params.shift
47
+ name = params.shift
48
+ view = View.new([], options.dup)
49
+ view.invoke("generate", [package, name])
39
50
  when "namespace"
40
- self.namespace(name)
41
-
51
+ #self.namespace(name)
42
52
  end
43
53
  end
44
54
 
@@ -61,8 +71,6 @@ module Xmvc
61
71
  }
62
72
  end
63
73
 
64
-
65
-
66
74
  private
67
75
 
68
76
  def self.write_namespace(f, current, namespace)
@@ -1,6 +1,8 @@
1
1
  module Xmvc
2
2
  module Generator
3
- class App < Base
3
+ class App < Thor::Group
4
+
5
+ include Thor::Actions
4
6
 
5
7
  FRAMEWORK_ASSETS = [
6
8
  'app/App.js',
@@ -13,122 +15,86 @@ module Xmvc
13
15
  'app/views/*/**.js'
14
16
  ]
15
17
 
16
- def initialize(name, namespace=nil)
17
- @file_re ||= Regexp.new("^\.?\/(.*)")
18
- @name = name
19
- @namespace = namespace || Extlib::Inflection.camelize(name)
20
- @template = "#{TEMPLATE_PATH}/app"
18
+ def self.source_root
19
+ File.join(Xmvc::TEMPLATE_PATH, "app", "public")
21
20
  end
22
-
23
- def generate!
24
- if File.exists?(@name)
25
- raise Xmvc::AppAlreadyExists.new("An app named #{@name} already exists")
26
- end
27
- FileUtils.mkdir(@name)
28
- FileUtils.chdir(@name)
29
-
30
- # Save a ref to app root, need for Jammit config.
31
- app_root = File.expand_path(".")
32
-
33
- # Create the root directory
34
- create_root
35
-
36
- # Now walk into the created public folder to write the javascript framework
37
- FileUtils.chdir("public")
38
- create_app
39
- create_config
40
- create_lib
41
- create_public
42
- create_spec
43
- create_vendor
44
- install_host
45
-
46
- # Build assets.
47
- Xmvc::BuilderManager.dispatch(:setup, {
48
- :asset_root => File.expand_path('.'),
49
- :app_root => app_root,
50
- :vendors => [
51
- Xmvc.host.config
52
- ],
53
- :application => FRAMEWORK_ASSETS
54
- })
55
-
56
- end
57
-
58
- private
21
+
22
+ argument :name, :type => :string, :desc => "Name of application to generate"
23
+ desc "Generates a new Xmvc application"
59
24
 
60
25
  def create_root
61
- FileUtils.mkdir(%w(public))
62
-
63
- # Write config/settings.yml, call-out to Xmvc::Environment isntead.
64
- #FileUtils.cp("#{@template}/config/environment.yml", "config")
65
- copy_file("config", ".")
66
-
26
+ empty_directory(name)
27
+ self.destination_root = name
67
28
  end
68
29
 
69
30
  def create_app
70
- FileUtils.mkdir(%w(app app/models app/views app/controllers))
71
- copy_file("public/app", ".")
72
- show_files("app")
31
+ empty_directory("app")
32
+ inside("app", {}) do
33
+ copy_file("App.js", "#{destination_root}/App.js")
34
+ directory("models", "models")
35
+ directory("views", "views")
36
+ directory("controllers", "controllers")
37
+ end
73
38
  end
74
39
 
75
40
  def create_config
76
- FileUtils.mkdir(%w(config config/environments))
77
- copy_file("public/config", ".")
78
- show_files("config")
41
+ directory("config", "config")
79
42
  end
80
43
 
81
44
  def create_lib
82
- FileUtils.mkdir(%w(lib))
83
- show_files("lib")
45
+ directory("lib", "lib")
84
46
  end
85
47
 
86
48
  def create_public
87
- FileUtils.mkdir(%w(public public/stylesheets public/images public/javascripts))
88
- copy_file("public/public", ".")
89
- show_files("public")
49
+ empty_directory("public")
50
+ inside("public", {}) do
51
+ copy_file("index.html", "index.html")
52
+ directory("images", "images")
53
+ directory("stylesheets", "stylesheets")
54
+ directory("javascripts", "javascripts")
55
+ end
56
+
90
57
  end
91
58
 
92
59
  def create_spec
93
- FileUtils.mkdir(%w(spec spec/controllers spec/models))
94
- copy_file("public/spec", ".")
95
- show_files("spec")
60
+ directory("spec", "spec", :recursive => false)
61
+ inside("spec", {}) do
62
+ directory("models", "models")
63
+ directory("controllers", "controllers")
64
+ end
96
65
  end
97
66
 
98
67
  def create_vendor
99
- FileUtils.mkdir(%w(vendor vendor/plugins))
100
- copy_file("public/vendor", ".")
101
- show_files("vendor", false)
68
+ directory("vendor", "vendor")
69
+ inside("vendor", {}) do
70
+ empty_directory("plugins")
71
+ end
102
72
  end
103
73
 
104
74
  def install_host
105
- begin
106
- Xmvc.host.install("vendor")
107
- Xmvc.ui.confirm(" install vendor/#{Xmvc.host.config['name']}")
108
- rescue StandardError => e
109
- Xmvc.ui.error('An error occured while installing the host framework')
110
- raise Xmvc::HostError.new(e.message)
75
+ inside("vendor", {}) do
76
+ directory(Xmvc.host::VENDOR_PATH, Xmvc.host.config["name"])
111
77
  end
112
-
113
- end
114
-
115
-
116
- def notify(f)
117
- m = f.match(@file_re)
118
- Xmvc.ui.confirm(" create #{(m) ? m[1] : f}")
119
78
  end
120
79
 
121
- def copy_file(src, dest)
122
- FileUtils.cp_r("#{@template}/#{src}", dest)
80
+ def install_plugins
81
+ inside("vendor/plugins", {}) do
82
+ # install vendor/plugins here
83
+ end
123
84
  end
124
85
 
125
- def show_files(dir, recursive=true)
126
- pattern = (recursive) ? "./#{dir}/**/*.*" : "./#{dir}/*"
127
- notify(dir)
128
- Dir[pattern].each do |f|
129
- notify(f)
130
- end
86
+ def build_assets
87
+ # Build assets.
88
+ Xmvc::BuilderManager.dispatch(:setup, {
89
+ :asset_root => destination_root,
90
+ :vendors => [
91
+ Xmvc.host.config
92
+ ],
93
+ :application => FRAMEWORK_ASSETS
94
+ })
95
+ FileUtils.chdir(destination_root)
96
+ Xmvc.environment.render
131
97
  end
132
98
  end
133
99
  end
134
- end
100
+ end
@@ -0,0 +1,43 @@
1
+ module Xmvc
2
+ module Generator
3
+ class Boot < Thor
4
+ include Thor::Actions
5
+
6
+ def self.source_root
7
+ File.join(Xmvc::TEMPLATE_PATH)
8
+ end
9
+
10
+ desc "generate", "Generate the config/boot.js file"
11
+ def generate
12
+
13
+ host = Xmvc.host.config["name"]
14
+
15
+ @development = [
16
+ 'http://extjs.cachefly.net/ext-3.1.1/adapter/ext/ext-base.js',
17
+ 'http://extjs.cachefly.net/ext-3.1.1/ext-all-debug.js'
18
+ ]
19
+ @development << url_for(host, "js", Jammit::DEBUG_SUFFIX)
20
+
21
+ @production = [
22
+ 'http://extjs.cachefly.net/ext-3.1.1/adapter/ext/ext-base.js',
23
+ 'http://extjs.cachefly.net/ext-3.1.1/ext-all.js'
24
+ ]
25
+ @production << url_for(host, "js", Jammit::SUFFIX)
26
+
27
+ @test = @development.dup
28
+ @test << url_for(host, "js", Jammit::DEBUG_SUFFIX)
29
+ @test << File.join("/", Xmvc::PUBLIC_PATH, "vendor", "jspec", "lib", "jspec.js")
30
+ @test << File.join("/", Xmvc::PUBLIC_PATH, "vendor", "spec", "TestHelper.js")
31
+
32
+ template("boot.js", "config/boot.js")
33
+ end
34
+
35
+ private
36
+
37
+ def url_for(name, ext, suffix)
38
+ File.join("/", Xmvc::PUBLIC_PATH, name, Jammit.filename(name, ext, suffix))
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -1,41 +1,26 @@
1
1
  module Xmvc
2
2
  module Generator
3
- class Controller < Base
4
- def initialize(name, actions = [])
5
- super
6
-
7
- @name = name
8
- @actions = actions
9
- @package = name.downcase
10
-
11
- @gsubs.merge!({
12
- 'controller_name' => Extlib::Inflection.underscore(name),
13
- 'short_name' => @package,
14
- 'actions' => generate_actions
15
- })
3
+ class Controller < Thor
4
+ include Thor::Actions
16
5
 
17
- @controller_filename = "app/controllers/#{@gsubs['controller_name']}_controller.js"
6
+ def self.source_root
7
+ File.join(Xmvc::TEMPLATE_PATH)
18
8
  end
19
-
20
- def generate!
21
- ensure_no_overwrite! @controller_filename
22
- ensure_directories_present! "app", "app/controllers"
23
-
24
- template "Controller.js", @controller_filename
25
-
26
- Xmvc::Settings.add(:controllers, @gsubs["controller_name"])
9
+
10
+ desc "generate", "Generate a new Controller"
11
+ def generate(name, *actions)
12
+ @name = name
13
+ @actions = actions
14
+ @package = name.downcase
15
+ @controller_name = Extlib::Inflection.underscore(name)
16
+ @filename = "app/controllers/#{@controller_name}_controller.js"
27
17
 
28
- generate_views!
29
- end
30
-
31
- private
32
- def generate_actions
33
- @actions.collect {|act| render_template("_Action.js", {'action_name' => act})}.join("")
34
- end
35
-
36
- def generate_views!
37
- @actions.each {|a| View.new(@package, a).generate!}
18
+ unless File.exists? @filename
19
+ Xmvc.environment.add(:controllers, @controller_name)
20
+ end
21
+
22
+ template "Controller.js", @filename
38
23
  end
39
24
  end
40
25
  end
41
- end
26
+ end
@@ -0,0 +1,25 @@
1
+ module Xmvc
2
+ module Generator
3
+
4
+ def self.script_tag(file)
5
+ '<script type="text/javascript" src="' + file + '"></script>'
6
+ end
7
+
8
+ class Layout < Thor::Group
9
+ include Thor::Actions
10
+
11
+ def self.source_root
12
+ puts "source_root"
13
+ "."
14
+ end
15
+
16
+ desc "Generates a new application"
17
+ argument :name, :type => :string, :desc => "The name of your new Xmvc application"
18
+ def build
19
+ @javascripts = Jammit.packager.individual_urls("application", :js).map {|file| Generator.script_tag(file) }.join("\n")
20
+
21
+ template("#{Generator::TEMPLATE_PATH}/layout.html.erb", 'layout.html')
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,42 +1,33 @@
1
1
  module Xmvc
2
2
  module Generator
3
- class Model < Base
4
- def initialize(name, fields = [])
5
- super
6
-
7
- @fields = fields
8
- @gsubs['inst_name'] = name.downcase
9
- @gsubs['class_name'] = Extlib::Inflection.camelize(name)
10
- @gsubs['file_name'] = Extlib::Inflection.underscore(name)
11
- @gsubs['fields'] = fields.collect {|f| field_template(f[0], f[1])}.join(",\n")
12
-
13
- @model_filename = "app/models/#{@gsubs['file_name']}.js"
14
- @spec_filename = "spec/models/#{@gsubs['file_name']}.spec.js"
3
+ class Model < Thor
4
+ include Thor::Actions
5
+
6
+ def self.source_root
7
+ File.join(Xmvc::TEMPLATE_PATH)
15
8
  end
16
-
17
- def generate!
18
- ensure_no_overwrite! @model_filename, @spec_filename
19
-
20
- ensure_directories_present! "app", "app/models"
21
- ensure_directories_present! "spec", "spec/models"
9
+
10
+ desc "generate", "Generates a new Model"
11
+ def generate(name, *fields)
12
+ filename = Extlib::Inflection.underscore(name)
22
13
 
23
- template "Model.js", @model_filename
24
- template "ModelSpec.js", @spec_filename
14
+ @var_name = filename
15
+ @class_name = Extlib::Inflection.camelize(name)
16
+ @fields = fields.map {|f|
17
+ field = f.split(':')
18
+ {:name => field.shift, :type => field.shift}
19
+ }
20
+
21
+ model_filename = "app/models/#{filename}.js"
22
+ spec_filename = "spec/models/#{filename}.spec.js"
25
23
 
26
- #to_environment(:models, @gsubs["file_name"])
27
- Xmvc::Settings.add(:models, @gsubs["file_name"])
24
+ unless File.exists?(model_filename)
25
+ Xmvc.environment.add(:models, filename)
26
+ end
28
27
 
29
- end
30
-
31
- private
32
- def field_template(name, type)
33
- padding = longest_field_length - name.length
34
- " {name: '#{name}', #{" " * padding}type: '#{type}'}"
35
- end
36
-
37
- def longest_field_length
38
- @fields.collect {|f| f[0].length}.max
28
+ template("Model.js", model_filename)
29
+ template("ModelSpec.js", spec_filename)
39
30
  end
40
31
  end
41
32
  end
42
- end
33
+ end