anvil 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README +17 -0
- data/Rakefile +85 -0
- data/app_generators/anvil/USAGE +5 -0
- data/app_generators/anvil/anvil_generator.rb +95 -0
- data/app_generators/anvil/templates/Rakefile +5 -0
- data/app_generators/anvil/templates/app/controllers/application.rb +2 -0
- data/app_generators/anvil/templates/app/controllers/exceptions.rb +3 -0
- data/app_generators/anvil/templates/app/views/application.rb +3 -0
- data/app_generators/anvil/templates/spec/spec.opts +2 -0
- data/app_generators/anvil/templates/spec/spec_helper.rb +1 -0
- data/bin/anvil +8 -0
- data/lib/console.rb +67 -0
- data/lib/core_ext.rb +1 -0
- data/lib/core_ext/class.rb +180 -0
- data/lib/generators.rb +1 -0
- data/lib/generators/anvil_app.rb +19 -0
- data/lib/initializer.rb +116 -0
- data/lib/version.rb +3 -0
- data/spec/console_spec.rb +70 -0
- data/spec/generators/anvil_app_spec.rb +18 -0
- data/spec/initializer_spec.rb +161 -0
- data/spec_helper.rb +2 -0
- metadata +114 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007 Lancelot Carlson
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
== Welcome to Anvil
|
2
|
+
|
3
|
+
Anvil is a ruby framework that utilizes GUI toolkits to create GUI based applications. The instructions for getting started are below:
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
sudo gem install anvil
|
8
|
+
|
9
|
+
Note: This will pull down the widget wrapper gem as well.
|
10
|
+
|
11
|
+
== Getting Started
|
12
|
+
|
13
|
+
Go to your projects directory (where ever that might be) and run the following command:
|
14
|
+
|
15
|
+
anvil my_app
|
16
|
+
|
17
|
+
Replace my_app with the name of the application you are creating. This will generate the files necessary for creating an Anvil application.
|
data/Rakefile
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'spec/rake/spectask'
|
6
|
+
|
7
|
+
require 'lib/version'
|
8
|
+
|
9
|
+
NAME = "anvil"
|
10
|
+
|
11
|
+
windows = (PLATFORM =~ /win32|cygwin/)
|
12
|
+
|
13
|
+
SUDO = windows ? "" : "sudo"
|
14
|
+
|
15
|
+
dist_dirs = [ "lib", "spec", "app_generators" ]
|
16
|
+
|
17
|
+
spec = Gem::Specification.new do |s|
|
18
|
+
s.name = NAME
|
19
|
+
s.version = Anvil::VERSION
|
20
|
+
s.platform = Gem::Platform::RUBY
|
21
|
+
s.summary = "A GUI framework for Ruby"
|
22
|
+
s.description = "A collection of DSL's and frameworks that take full advantage of Ruby's powerful syntax"
|
23
|
+
s.author = "Lance Carlson"
|
24
|
+
s.email = "lancecarlson@gmail.com"
|
25
|
+
s.homepage = "http://anvil.rubyforge.org"
|
26
|
+
s.has_rdoc = true
|
27
|
+
s.executables = ['anvil']
|
28
|
+
|
29
|
+
s.add_dependency('widget_wrapper')
|
30
|
+
s.add_dependency('rubigen')
|
31
|
+
s.add_dependency('rake')
|
32
|
+
|
33
|
+
s.files = [ "MIT-LICENSE", "Rakefile", "README", "spec_helper.rb" ]
|
34
|
+
dist_dirs.each do |dir|
|
35
|
+
s.files = s.files + Dir.glob("#{dir}/**/*")
|
36
|
+
end
|
37
|
+
|
38
|
+
s.rubyforge_project = 'anvil'
|
39
|
+
end
|
40
|
+
|
41
|
+
Rake::GemPackageTask.new(spec) do |p|
|
42
|
+
p.gem_spec = spec
|
43
|
+
end
|
44
|
+
|
45
|
+
Rake::RDocTask.new do |rdoc|
|
46
|
+
rdoc.rdoc_dir = 'doc'
|
47
|
+
rdoc.title = 'Anvil'
|
48
|
+
rdoc.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
|
49
|
+
rdoc.options << '--charset' << 'utf-8'
|
50
|
+
rdoc.rdoc_files.include('README', 'CHANGELOG', 'MIT-LICENSE')
|
51
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
52
|
+
end
|
53
|
+
|
54
|
+
desc 'Run :package and install the resulting .gem'
|
55
|
+
task :install => :package do
|
56
|
+
sh %{#{SUDO} gem install pkg/#{NAME}-#{Anvil::VERSION} --no-rdoc --no-ri}
|
57
|
+
end
|
58
|
+
|
59
|
+
desc 'Run :clean and uninstall the .gem'
|
60
|
+
task :uninstall => [:clean] do
|
61
|
+
sh %{#{SUDO} gem uninstall #{NAME}}
|
62
|
+
end
|
63
|
+
|
64
|
+
desc "Run all specs"
|
65
|
+
Spec::Rake::SpecTask.new('spec') do |t|
|
66
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
67
|
+
t.spec_opts = ['--options', 'spec.opts']
|
68
|
+
end
|
69
|
+
|
70
|
+
desc "Run all specs and generate an rcov report"
|
71
|
+
Spec::Rake::SpecTask.new('spec:rcov') do |t|
|
72
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
73
|
+
t.spec_opts = ['--options', 'spec.opts']
|
74
|
+
t.rcov = true
|
75
|
+
t.rcov_dir = 'coverage'
|
76
|
+
t.rcov_opts = ['--exclude', 'gems', '--exclude', 'spec']
|
77
|
+
end
|
78
|
+
|
79
|
+
task :release => :package do
|
80
|
+
if ENV['RELEASE']
|
81
|
+
sh %{rubyforge add_release #{NAME} #{NAME} "#{ENV['RELEASE']}" pkg/#{NAME}-#{Anvil::VERSION}.gem}
|
82
|
+
else
|
83
|
+
puts 'Must specify release!'
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
class AnvilGenerator < RubiGen::Base
|
2
|
+
DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
|
3
|
+
Config::CONFIG['ruby_install_name']) unless defined? DEFAULT_SHEBANG
|
4
|
+
|
5
|
+
default_options :shebang => DEFAULT_SHEBANG
|
6
|
+
|
7
|
+
attr_reader :name
|
8
|
+
|
9
|
+
def initialize(runtime_args, runtime_options = {})
|
10
|
+
super
|
11
|
+
usage if args.empty?
|
12
|
+
@name = args.shift
|
13
|
+
@destination_root = File.expand_path(@name)
|
14
|
+
extract_options
|
15
|
+
end
|
16
|
+
|
17
|
+
def manifest
|
18
|
+
script_options = { :chmod => 0755, :shebang => options[:shebang] == DEFAULT_SHEBANG ? nil : options[:shebang] }
|
19
|
+
|
20
|
+
record do |m|
|
21
|
+
# Ensure appropriate folder(s) exists
|
22
|
+
m.directory ''
|
23
|
+
BASEDIRS.each { |path| m.directory path }
|
24
|
+
|
25
|
+
# copy skeleton
|
26
|
+
m.file_copy_each %w( Rakefile )
|
27
|
+
m.file_copy_each %w( application.rb exceptions.rb ), "app/controllers"
|
28
|
+
#m.file_copy_each %w( global_helper.rb ), "app/helpers"
|
29
|
+
m.file_copy_each %w( application.rb ), "app/views"
|
30
|
+
#m.file_copy_each %w( boot.rb merb_init.rb router.rb upload.conf dependencies.rb), "config"
|
31
|
+
#m.file_copy_each %w( development.rb production.rb test.rb ), "config/environments"
|
32
|
+
m.file_copy_each %w( spec_helper.rb ), "spec"
|
33
|
+
#m.file_copy_each %w( test_helper.rb), "test"
|
34
|
+
|
35
|
+
# build default config
|
36
|
+
#m.template "config/merb.yml", "config/merb.yml", :assigns => {:key => "#{@name.upcase}#{rand(9999)}"}
|
37
|
+
|
38
|
+
# build scripts
|
39
|
+
#%w( stop_merb generate destroy ).each do |file|
|
40
|
+
#m.file "script/#{file}", "script/#{file}", script_options
|
41
|
+
#m.template "script/win_script.cmd", "script/#{file}.cmd", :assigns => { :filename => file } if windows
|
42
|
+
#end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def windows
|
47
|
+
(RUBY_PLATFORM =~ /dos|win32|cygwin/i) || (RUBY_PLATFORM =~ /(:?mswin|mingw)/)
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
def banner
|
52
|
+
<<-EOS
|
53
|
+
Creates an Anvil application stub.
|
54
|
+
|
55
|
+
USAGE: #{spec.name} -g path"
|
56
|
+
EOS
|
57
|
+
end
|
58
|
+
|
59
|
+
def add_options!(opts)
|
60
|
+
# opts.separator ''
|
61
|
+
# opts.separator 'Options:'
|
62
|
+
# # For each option below, place the default
|
63
|
+
# # at the top of the file next to "default_options"
|
64
|
+
# opts.on("-r", "--ruby=path", String,
|
65
|
+
# "Path to the Ruby binary of your choice (otherwise scripts use env, dispatchers current path).",
|
66
|
+
# "Default: #{DEFAULT_SHEBANG}") { |options[:shebang]| }
|
67
|
+
# opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
68
|
+
end
|
69
|
+
|
70
|
+
def extract_options
|
71
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
72
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
73
|
+
# raw instance variable value.
|
74
|
+
# @author = options[:author]
|
75
|
+
end
|
76
|
+
|
77
|
+
# Installation skeleton. Intermediate directories are automatically
|
78
|
+
# created so don't sweat their absence here.
|
79
|
+
BASEDIRS = %w(
|
80
|
+
app/controllers
|
81
|
+
app/models
|
82
|
+
app/helpers
|
83
|
+
app/views/layout
|
84
|
+
app/views/exceptions
|
85
|
+
config/environments
|
86
|
+
lib
|
87
|
+
log
|
88
|
+
script
|
89
|
+
spec/models
|
90
|
+
spec/controllers
|
91
|
+
test/unit
|
92
|
+
gems
|
93
|
+
)
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# Coming Soon
|
data/bin/anvil
ADDED
data/lib/console.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require File.join(File.dirname(__FILE__), 'initializer')
|
3
|
+
require File.join(File.dirname(__FILE__), 'core_ext')
|
4
|
+
require File.join(File.dirname(__FILE__), 'generators')
|
5
|
+
|
6
|
+
module Anvil
|
7
|
+
class Console
|
8
|
+
@@anvil_opts = {}
|
9
|
+
cattr_accessor :anvil_opts
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
def run
|
14
|
+
parse_opts
|
15
|
+
|
16
|
+
# Start Anvil when option is set
|
17
|
+
Anvil::Initializer.run if @@anvil_opts[:start_anvil]
|
18
|
+
|
19
|
+
# Generate fresh Anvil Application if option is set
|
20
|
+
if @@anvil_opts[:generate]
|
21
|
+
Anvil::AppGenerator.run @@anvil_opts[:generate]
|
22
|
+
exit!
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse_opts(argv = ARGV)
|
27
|
+
options = {}
|
28
|
+
|
29
|
+
options[:start_anvil] = true
|
30
|
+
|
31
|
+
opts = OptionParser.new do |opts|
|
32
|
+
opts.banner = "Usage: anvil [gih] [argument]"
|
33
|
+
opts.define_head "Anvil GUI framework."
|
34
|
+
opts.separator '*'*80
|
35
|
+
opts.separator 'If no flags are given, Anvil starts in the foreground'
|
36
|
+
opts.separator '*'*80
|
37
|
+
|
38
|
+
opts.on("-i", "--irb-console", "This flag will start Anvil in irb console. Your application models and classes will be loaded and available through console.") do |console|
|
39
|
+
options[:console] = true
|
40
|
+
options[:start_anvil] = false
|
41
|
+
puts "Coming Soon!"
|
42
|
+
end
|
43
|
+
|
44
|
+
opts.on("-g", "--generate-app PATH", "Generate a fresh Anvil application at PATH") do |path|
|
45
|
+
options[:generate] = path || Dir.pwd
|
46
|
+
options[:start_anvil] = false
|
47
|
+
end
|
48
|
+
|
49
|
+
opts.on("-?", "-h", "--help", "Show this help message") do
|
50
|
+
puts opts
|
51
|
+
exit
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
opts.parse!(argv)
|
56
|
+
|
57
|
+
# anvil <argument> is the same as anvil -g <argument>
|
58
|
+
if argv.size == 1
|
59
|
+
options[:generate] = File.expand_path(argv.last)
|
60
|
+
options[:start_anvil] = false
|
61
|
+
end
|
62
|
+
|
63
|
+
@@anvil_opts = options
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/core_ext.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Dir[File.dirname(__FILE__) + "/core_ext/*.rb"].sort.each{|file| require(file)}
|
@@ -0,0 +1,180 @@
|
|
1
|
+
# Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of
|
2
|
+
# their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
|
3
|
+
# to, for example, an array without those additions being shared with either their parent, siblings, or
|
4
|
+
# children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
|
5
|
+
class Class # :nodoc:
|
6
|
+
def cattr_reader(*syms)
|
7
|
+
syms.flatten.each do |sym|
|
8
|
+
next if sym.is_a?(Hash)
|
9
|
+
class_eval(<<-EOS, __FILE__, __LINE__)
|
10
|
+
unless defined? @@#{sym}
|
11
|
+
@@#{sym} = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.#{sym}
|
15
|
+
@@#{sym}
|
16
|
+
end
|
17
|
+
|
18
|
+
def #{sym}
|
19
|
+
@@#{sym}
|
20
|
+
end
|
21
|
+
EOS
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def cattr_writer(*syms)
|
26
|
+
options = syms.last.is_a?(Hash) ? syms.pop : {}
|
27
|
+
syms.flatten.each do |sym|
|
28
|
+
class_eval(<<-EOS, __FILE__, __LINE__)
|
29
|
+
unless defined? @@#{sym}
|
30
|
+
@@#{sym} = nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.#{sym}=(obj)
|
34
|
+
@@#{sym} = obj
|
35
|
+
end
|
36
|
+
|
37
|
+
#{"
|
38
|
+
def #{sym}=(obj)
|
39
|
+
@@#{sym} = obj
|
40
|
+
end
|
41
|
+
" unless options[:instance_writer] == false }
|
42
|
+
EOS
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def cattr_accessor(*syms)
|
47
|
+
cattr_reader(*syms)
|
48
|
+
cattr_writer(*syms)
|
49
|
+
end
|
50
|
+
def class_inheritable_reader(*syms)
|
51
|
+
syms.each do |sym|
|
52
|
+
next if sym.is_a?(Hash)
|
53
|
+
class_eval <<-EOS
|
54
|
+
def self.#{sym}
|
55
|
+
read_inheritable_attribute(:#{sym})
|
56
|
+
end
|
57
|
+
|
58
|
+
def #{sym}
|
59
|
+
self.class.#{sym}
|
60
|
+
end
|
61
|
+
EOS
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def class_inheritable_writer(*syms)
|
66
|
+
options = syms.last.is_a?(Hash) ? syms.pop : {}
|
67
|
+
syms.each do |sym|
|
68
|
+
class_eval <<-EOS
|
69
|
+
def self.#{sym}=(obj)
|
70
|
+
write_inheritable_attribute(:#{sym}, obj)
|
71
|
+
end
|
72
|
+
|
73
|
+
#{"
|
74
|
+
def #{sym}=(obj)
|
75
|
+
self.class.#{sym} = obj
|
76
|
+
end
|
77
|
+
" unless options[:instance_writer] == false }
|
78
|
+
EOS
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def class_inheritable_array_writer(*syms)
|
83
|
+
options = syms.last.is_a?(Hash) ? syms.pop : {}
|
84
|
+
syms.each do |sym|
|
85
|
+
class_eval <<-EOS
|
86
|
+
def self.#{sym}=(obj)
|
87
|
+
write_inheritable_array(:#{sym}, obj)
|
88
|
+
end
|
89
|
+
|
90
|
+
#{"
|
91
|
+
def #{sym}=(obj)
|
92
|
+
self.class.#{sym} = obj
|
93
|
+
end
|
94
|
+
" unless options[:instance_writer] == false }
|
95
|
+
EOS
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def class_inheritable_hash_writer(*syms)
|
100
|
+
options = syms.last.is_a?(Hash) ? syms.pop : {}
|
101
|
+
syms.each do |sym|
|
102
|
+
class_eval <<-EOS
|
103
|
+
def self.#{sym}=(obj)
|
104
|
+
write_inheritable_hash(:#{sym}, obj)
|
105
|
+
end
|
106
|
+
|
107
|
+
#{"
|
108
|
+
def #{sym}=(obj)
|
109
|
+
self.class.#{sym} = obj
|
110
|
+
end
|
111
|
+
" unless options[:instance_writer] == false }
|
112
|
+
EOS
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def class_inheritable_accessor(*syms)
|
117
|
+
class_inheritable_reader(*syms)
|
118
|
+
class_inheritable_writer(*syms)
|
119
|
+
end
|
120
|
+
|
121
|
+
def class_inheritable_array(*syms)
|
122
|
+
class_inheritable_reader(*syms)
|
123
|
+
class_inheritable_array_writer(*syms)
|
124
|
+
end
|
125
|
+
|
126
|
+
def class_inheritable_hash(*syms)
|
127
|
+
class_inheritable_reader(*syms)
|
128
|
+
class_inheritable_hash_writer(*syms)
|
129
|
+
end
|
130
|
+
|
131
|
+
def inheritable_attributes
|
132
|
+
@inheritable_attributes ||= EMPTY_INHERITABLE_ATTRIBUTES
|
133
|
+
end
|
134
|
+
|
135
|
+
def write_inheritable_attribute(key, value)
|
136
|
+
if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
|
137
|
+
@inheritable_attributes = {}
|
138
|
+
end
|
139
|
+
inheritable_attributes[key] = value
|
140
|
+
end
|
141
|
+
|
142
|
+
def write_inheritable_array(key, elements)
|
143
|
+
write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
|
144
|
+
write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
|
145
|
+
end
|
146
|
+
|
147
|
+
def write_inheritable_hash(key, hash)
|
148
|
+
write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil?
|
149
|
+
write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash))
|
150
|
+
end
|
151
|
+
|
152
|
+
def read_inheritable_attribute(key)
|
153
|
+
inheritable_attributes[key]
|
154
|
+
end
|
155
|
+
|
156
|
+
def reset_inheritable_attributes
|
157
|
+
@inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
# Prevent this constant from being created multiple times
|
162
|
+
EMPTY_INHERITABLE_ATTRIBUTES = {}.freeze unless const_defined?(:EMPTY_INHERITABLE_ATTRIBUTES)
|
163
|
+
|
164
|
+
def inherited_with_inheritable_attributes(child)
|
165
|
+
inherited_without_inheritable_attributes(child) if respond_to?(:inherited_without_inheritable_attributes)
|
166
|
+
|
167
|
+
if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
|
168
|
+
new_inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
|
169
|
+
else
|
170
|
+
new_inheritable_attributes = inheritable_attributes.inject({}) do |memo, (key, value)|
|
171
|
+
memo.update(key => (value.dup rescue value))
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
child.instance_variable_set('@inheritable_attributes', new_inheritable_attributes)
|
176
|
+
end
|
177
|
+
|
178
|
+
alias inherited_without_inheritable_attributes inherited
|
179
|
+
alias inherited inherited_with_inheritable_attributes
|
180
|
+
end
|
data/lib/generators.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Dir[File.dirname(__FILE__) + "/generators/*.rb"].sort.each{|file| require(file)}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#require 'fileutils'
|
2
|
+
#require 'find'
|
3
|
+
|
4
|
+
module Anvil
|
5
|
+
class AppGenerator
|
6
|
+
def self.run(path)
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
source = RubiGen::PathSource.new(:application,
|
12
|
+
File.join(File.dirname(__FILE__), "../../app_generators"))
|
13
|
+
RubiGen::Base.reset_sources
|
14
|
+
RubiGen::Base.append_sources source
|
15
|
+
#RubiGem::Base.use_application_sources!
|
16
|
+
RubiGen::Scripts::Generate.new.run([path], :generator => 'anvil', :backtrace => true)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/initializer.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
module Anvil
|
4
|
+
class Initializer
|
5
|
+
attr_reader :configuration
|
6
|
+
|
7
|
+
def self.run(command = :process, configuration = Configuration.new)
|
8
|
+
yield configuration if block_given?
|
9
|
+
initializer = new configuration
|
10
|
+
initializer.send(command)
|
11
|
+
initializer
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(configuration)
|
15
|
+
@configuration = configuration
|
16
|
+
end
|
17
|
+
|
18
|
+
def process
|
19
|
+
set_load_paths
|
20
|
+
require_frameworks
|
21
|
+
require_controllers
|
22
|
+
require_models
|
23
|
+
load_application_view
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_load_paths
|
27
|
+
load_paths = configuration.load_paths + configuration.framework_load_paths
|
28
|
+
load_paths.reverse_each{|dir| $LOAD_PATH.unshift(dir) if File.directory?(dir)}
|
29
|
+
$LOAD_PATH.uniq!
|
30
|
+
end
|
31
|
+
|
32
|
+
def require_frameworks
|
33
|
+
configuration.frameworks.each{|framework| require(framework.to_s)}
|
34
|
+
end
|
35
|
+
|
36
|
+
def require_controllers
|
37
|
+
end
|
38
|
+
|
39
|
+
def require_models
|
40
|
+
end
|
41
|
+
|
42
|
+
def load_application_view
|
43
|
+
application_file = File.join(configuration.view_path, 'application.rb')
|
44
|
+
|
45
|
+
if File.exists?(application_file)
|
46
|
+
eval(File.read(application_file))
|
47
|
+
else
|
48
|
+
raise "Cannot find application view in: #{File.expand_path(application_file)}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class Configuration
|
54
|
+
attr_reader :root_path
|
55
|
+
attr_accessor :load_paths
|
56
|
+
attr_accessor :framework_root_path
|
57
|
+
attr_accessor :controller_path
|
58
|
+
attr_accessor :model_path
|
59
|
+
attr_accessor :view_path
|
60
|
+
attr_accessor :frameworks
|
61
|
+
|
62
|
+
def initialize
|
63
|
+
self.load_paths = default_application_load_paths
|
64
|
+
self.frameworks = default_frameworks
|
65
|
+
self.controller_path = default_controller_path
|
66
|
+
self.model_path = default_model_path
|
67
|
+
self.view_path = default_view_path
|
68
|
+
end
|
69
|
+
|
70
|
+
# Default frameworks loaded into anvil applications. Default is widget_wrapper.
|
71
|
+
def default_frameworks
|
72
|
+
[ :widget_wrapper ]
|
73
|
+
end
|
74
|
+
|
75
|
+
# Framework load paths
|
76
|
+
def framework_load_paths
|
77
|
+
%w(
|
78
|
+
anvilties
|
79
|
+
widget_wrapper
|
80
|
+
).map{|dir| "#{framework_root_path}/#{dir}"}.select{|dir| File.directory?(dir)}
|
81
|
+
end
|
82
|
+
|
83
|
+
# Default application load paths. This can be added onto in configuration.
|
84
|
+
def default_application_load_paths
|
85
|
+
%w(
|
86
|
+
app
|
87
|
+
config
|
88
|
+
).map{|dir| "#{root_path}/#{dir}"}.select{|dir| File.directory?(dir)}
|
89
|
+
end
|
90
|
+
|
91
|
+
# Default controller files load path. This can be changed in configuration.
|
92
|
+
def default_controller_path
|
93
|
+
@controller_path ||= File.join(root_path, 'app', 'controllers')
|
94
|
+
end
|
95
|
+
|
96
|
+
# Default model files load path. This can be changed in configuration.
|
97
|
+
def default_model_path
|
98
|
+
@model_path ||= File.join(root_path, 'app', 'models')
|
99
|
+
end
|
100
|
+
|
101
|
+
# Default view files load path. This can be changed in configuration.
|
102
|
+
def default_view_path
|
103
|
+
@view_path ||= File.join(root_path, 'app', 'views')
|
104
|
+
end
|
105
|
+
|
106
|
+
# Default framework root path. This can be changed in configuration.
|
107
|
+
def framework_root_path
|
108
|
+
@framework_root_path ||= File.join(File.dirname(__FILE__), '..')
|
109
|
+
end
|
110
|
+
|
111
|
+
# Root path of the application.
|
112
|
+
def root_path
|
113
|
+
ANVIL_ROOT
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/lib/version.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/console'
|
3
|
+
|
4
|
+
describe Anvil::Console do
|
5
|
+
describe "run sequence" do
|
6
|
+
it "should run the argument parser" do
|
7
|
+
Anvil::Initializer.stub!(:run)
|
8
|
+
Anvil::AppGenerator.stub!(:run)
|
9
|
+
Anvil::Console.stub!(:exit!)
|
10
|
+
|
11
|
+
Anvil::Console.should_receive(:parse_opts)
|
12
|
+
Anvil::Console.run
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should run anvil when the option is supplied" do
|
16
|
+
Anvil::Console.stub!(:parse_opts)
|
17
|
+
Anvil::Console.anvil_opts[:start_anvil] = true
|
18
|
+
Anvil::Console.stub!(:exit!)
|
19
|
+
|
20
|
+
Anvil::Initializer.should_receive(:run)
|
21
|
+
Anvil::Console.run
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should generate a fresh anvil application skeleton when options is supplied" do
|
25
|
+
Anvil::Console.stub!(:parse_opts)
|
26
|
+
Anvil::Console.anvil_opts[:start_anvil] = false
|
27
|
+
Anvil::Console.anvil_opts[:generate] = '/some/path'
|
28
|
+
|
29
|
+
Anvil::Initializer.should_not_receive(:run)
|
30
|
+
Anvil::AppGenerator.should_receive(:run).with('/some/path')
|
31
|
+
Anvil::Console.should_receive(:exit!)
|
32
|
+
Anvil::Console.run
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "argument parser" do
|
37
|
+
it "should start anvil when no arguments are given" do
|
38
|
+
Anvil::Console.parse_opts([])
|
39
|
+
Anvil::Console.anvil_opts[:start_anvil].should be_true
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should run the interactive console when the -i or --irb-console option is specified" do
|
43
|
+
Anvil::Console.should_receive(:puts).twice.with("Coming Soon!")
|
44
|
+
Anvil::Console.parse_opts(["-i"])
|
45
|
+
Anvil::Console.parse_opts(["--irb-console"])
|
46
|
+
pending("Need to get figure how to use irb console")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should generate a fresh anvil application skeleton when -g PATH, --generate-app PATH" do
|
50
|
+
Anvil::Console.parse_opts(["-g", "/some/path"])
|
51
|
+
Anvil::Console.parse_opts(["--generate-app", "/some/path"])
|
52
|
+
Anvil::Console.anvil_opts[:generate].should == '/some/path'
|
53
|
+
Anvil::Console.anvil_opts[:start_anvil].should be_false
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should generate a fresh anvil application skeleton when the application name is given and no options are provided" do
|
57
|
+
File.should_receive(:expand_path).with("cool_app").and_return("/some/path/cool_app")
|
58
|
+
Anvil::Console.parse_opts(["cool_app"])
|
59
|
+
Anvil::Console.anvil_opts[:generate].should == "/some/path/cool_app"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should print the help message when -?, -h or --help option is specified" do
|
63
|
+
Anvil::Console.should_receive(:puts).exactly(3).times
|
64
|
+
Anvil::Console.should_receive(:exit).exactly(3).times
|
65
|
+
Anvil::Console.parse_opts(["-?"])
|
66
|
+
Anvil::Console.parse_opts(["-h"])
|
67
|
+
Anvil::Console.parse_opts(["--help"])
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/../../lib/generators/anvil_app'
|
3
|
+
require 'rubigen'
|
4
|
+
require 'rubigen/scripts/generate'
|
5
|
+
|
6
|
+
describe Anvil::AppGenerator do
|
7
|
+
it "should run the fresh application generator" do
|
8
|
+
@path_source = mock(RubiGen::PathSource)
|
9
|
+
@generator = mock(RubiGen::Scripts::Generate)
|
10
|
+
|
11
|
+
RubiGen::PathSource.should_receive(:new).with(:application, './spec/generators/../../lib/generators/../../app_generators').and_return(@path_source)
|
12
|
+
RubiGen::Base.should_receive(:reset_sources)
|
13
|
+
RubiGen::Base.should_receive(:append_sources).with(@path_source)
|
14
|
+
RubiGen::Scripts::Generate.should_receive(:new).and_return(@generator)
|
15
|
+
@generator.should_receive(:run).with(['/some/path'], {:generator=>"anvil", :backtrace=>true})
|
16
|
+
Anvil::AppGenerator.run('/some/path')
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/initializer'
|
3
|
+
|
4
|
+
include Anvil
|
5
|
+
|
6
|
+
describe Anvil::Initializer do
|
7
|
+
before(:each) do
|
8
|
+
@config = mock(Configuration)
|
9
|
+
@init = mock(Initializer)
|
10
|
+
Initializer.stub!(:new).and_return(@init)
|
11
|
+
@init.stub!(:process)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should run and return a new instance" do
|
15
|
+
Initializer.run(:process, @config).should == @init
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should run and yield a configuration block" do
|
19
|
+
@config.should_receive(:root_path).and_return('test')
|
20
|
+
Initializer.run(:process, @config) {|config| config.root_path}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe Anvil::Initializer, "process" do
|
25
|
+
before(:each) do
|
26
|
+
@config = mock(Configuration)
|
27
|
+
@init = Initializer.new @config
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should have a process method that will step through the entire initialization" do
|
31
|
+
@init.should_receive(:set_load_paths)
|
32
|
+
@init.should_receive(:require_frameworks)
|
33
|
+
@init.should_receive(:require_controllers)
|
34
|
+
@init.should_receive(:require_models)
|
35
|
+
@init.should_receive(:load_application_view)
|
36
|
+
@init.process
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should have a configuration instance" do
|
40
|
+
@init.configuration.should == @config
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should set the load paths" do
|
44
|
+
File.should_receive(:directory?).any_number_of_times.and_return(true)
|
45
|
+
@config.should_receive(:load_paths).and_return(['crap', '1', '2', '3', 'stuff'])
|
46
|
+
@config.should_receive(:framework_load_paths).and_return(['api', 'stuff'])
|
47
|
+
@init.set_load_paths.slice(0..5).should == ['crap', '1', '2', '3', 'stuff', 'api']
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should require the frameworks" do
|
51
|
+
@config.should_receive(:frameworks).and_return([:framework1, :framework2])
|
52
|
+
@init.should_receive(:require).with('framework1').and_return(true)
|
53
|
+
@init.should_receive(:require).with('framework2').and_return(true)
|
54
|
+
@init.require_frameworks
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should require the controllers" do
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should require the models" do
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should load the application view" do
|
64
|
+
@config.should_receive(:view_path).and_return('/view/path')
|
65
|
+
File.should_receive(:exists?).with('/view/path/application.rb').and_return(true)
|
66
|
+
File.should_receive(:read).with('/view/path/application.rb').and_return('')
|
67
|
+
@init.should_receive(:eval).with('')
|
68
|
+
@init.load_application_view
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should raise an error if it can't find the view path" do
|
72
|
+
@config.stub!(:view_path).and_return('')
|
73
|
+
File.should_receive(:exists?).and_return(false)
|
74
|
+
lambda { @init.load_application_view }.should raise_error
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe Anvil::Configuration do
|
79
|
+
before(:each) do
|
80
|
+
ANVIL_ROOT = '/some/root/path'
|
81
|
+
@config = Configuration.new
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should assign default_application_load_paths to load_paths" do
|
85
|
+
@config.load_paths.should == @config.default_application_load_paths
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should assign default_frameworks to frameworks" do
|
89
|
+
@config.frameworks.should == @config.default_frameworks
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should assign default_controller_path to controller_path" do
|
93
|
+
@config.controller_path.should == @config.default_controller_path
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should assign default_model_path to model_path" do
|
97
|
+
@config.model_path.should == @config.default_model_path
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should assign default_view_path to view_path" do
|
101
|
+
@config.view_path.should == @config.default_view_path
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should have frameworks defaulted to widget_wraper" do
|
105
|
+
@config.default_frameworks.should == [ :widget_wrapper ]
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should have default application load paths" do
|
109
|
+
@config.stub!(:framework_root_path).and_return('/root')
|
110
|
+
File.should_receive(:directory?).with('/root/anvilties').and_return(true)
|
111
|
+
File.should_receive(:directory?).with('/root/widget_wrapper').and_return(true)
|
112
|
+
@config.framework_load_paths.should == %w(/root/anvilties /root/widget_wrapper)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should have default application load paths" do
|
116
|
+
@config.stub!(:root_path).and_return('/root')
|
117
|
+
File.should_receive(:directory?).with('/root/app').and_return(true)
|
118
|
+
File.should_receive(:directory?).with('/root/config').and_return(true)
|
119
|
+
@config.default_application_load_paths.should == %w(/root/app /root/config)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should have a default controller path" do
|
123
|
+
@config.controller_path.should == '/some/root/path/app/controllers'
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should allow you to override the default controller path" do
|
127
|
+
@config.controller_path = '/overriding/controller/path'
|
128
|
+
@config.controller_path.should == '/overriding/controller/path'
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should have a default model path" do
|
132
|
+
@config.model_path.should == '/some/root/path/app/models'
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should allow you to override the default model path" do
|
136
|
+
@config.model_path = '/overriding/model/path'
|
137
|
+
@config.model_path.should == '/overriding/model/path'
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should have a default view path" do
|
141
|
+
@config.view_path.should == '/some/root/path/app/views'
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should allow you to override the default view path" do
|
145
|
+
@config.view_path = '/overriding/view/path'
|
146
|
+
@config.view_path.should == '/overriding/view/path'
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should allow you to set the default framework path" do
|
150
|
+
@config.framework_root_path = '/new/path'
|
151
|
+
@config.framework_root_path.should == '/new/path'
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should have a default framework load path" do
|
155
|
+
@config.framework_root_path.should == './spec/../lib/..'
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should have a root path" do
|
159
|
+
@config.root_path.should == '/some/root/path'
|
160
|
+
end
|
161
|
+
end
|
data/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: anvil
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Lance Carlson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2007-12-25 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: widget_wrapper
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "0"
|
23
|
+
version:
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
name: rubigen
|
26
|
+
version_requirement:
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - ">="
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: "0"
|
32
|
+
version:
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rake
|
35
|
+
version_requirement:
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: "0"
|
41
|
+
version:
|
42
|
+
description: A collection of DSL's and frameworks that take full advantage of Ruby's powerful syntax
|
43
|
+
email: lancecarlson@gmail.com
|
44
|
+
executables:
|
45
|
+
- anvil
|
46
|
+
extensions: []
|
47
|
+
|
48
|
+
extra_rdoc_files: []
|
49
|
+
|
50
|
+
files:
|
51
|
+
- MIT-LICENSE
|
52
|
+
- Rakefile
|
53
|
+
- README
|
54
|
+
- spec_helper.rb
|
55
|
+
- bin/anvil
|
56
|
+
- lib/console.rb
|
57
|
+
- lib/core_ext
|
58
|
+
- lib/core_ext/class.rb
|
59
|
+
- lib/core_ext.rb
|
60
|
+
- lib/generators
|
61
|
+
- lib/generators/anvil_app.rb
|
62
|
+
- lib/generators.rb
|
63
|
+
- lib/initializer.rb
|
64
|
+
- lib/version.rb
|
65
|
+
- spec/console_spec.rb
|
66
|
+
- spec/generators
|
67
|
+
- spec/generators/anvil_app_spec.rb
|
68
|
+
- spec/initializer_spec.rb
|
69
|
+
- app_generators/anvil
|
70
|
+
- app_generators/anvil/anvil_generator.rb
|
71
|
+
- app_generators/anvil/templates
|
72
|
+
- app_generators/anvil/templates/app
|
73
|
+
- app_generators/anvil/templates/app/controllers
|
74
|
+
- app_generators/anvil/templates/app/controllers/application.rb
|
75
|
+
- app_generators/anvil/templates/app/controllers/exceptions.rb
|
76
|
+
- app_generators/anvil/templates/app/helpers
|
77
|
+
- app_generators/anvil/templates/app/models
|
78
|
+
- app_generators/anvil/templates/app/views
|
79
|
+
- app_generators/anvil/templates/app/views/application.rb
|
80
|
+
- app_generators/anvil/templates/config
|
81
|
+
- app_generators/anvil/templates/Rakefile
|
82
|
+
- app_generators/anvil/templates/spec
|
83
|
+
- app_generators/anvil/templates/spec/spec.opts
|
84
|
+
- app_generators/anvil/templates/spec/spec_helper.rb
|
85
|
+
- app_generators/anvil/templates/test
|
86
|
+
- app_generators/anvil/USAGE
|
87
|
+
has_rdoc: true
|
88
|
+
homepage: http://anvil.rubyforge.org
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: "0"
|
99
|
+
version:
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: "0"
|
105
|
+
version:
|
106
|
+
requirements: []
|
107
|
+
|
108
|
+
rubyforge_project: anvil
|
109
|
+
rubygems_version: 1.0.0
|
110
|
+
signing_key:
|
111
|
+
specification_version: 2
|
112
|
+
summary: A GUI framework for Ruby
|
113
|
+
test_files: []
|
114
|
+
|