xmvc 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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