funkenplate 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 funkensturm.
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.textile ADDED
@@ -0,0 +1,21 @@
1
+ h2. Funkenplate
2
+
3
+ A standard template for funkensturm. applications.
4
+
5
+ h2. Requirements
6
+
7
+ * Ruby >= 1.8.7
8
+ * Rails >= 3.0.0
9
+
10
+ h3. Design guidelines
11
+
12
+ * Funkenplate works even when you are offline
13
+
14
+ h3. Assumptions
15
+
16
+ * The application is deployed to @/u/apps/APP@ where @APP@ stands for the name of the application you just created using funkenplate. If you need to change this, it is _safe_ to modify @deploy.rb@ afterwards without breaking any dependencies.
17
+
18
+ h3. Usage
19
+
20
+ rails myapp --template http://github.com/funkensturm/funkenplate/raw/master/funkenplate.rb
21
+
data/funkenplate.rb ADDED
@@ -0,0 +1,263 @@
1
+ # ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
2
+ # This template initializes a Rails app with git and capistrano
3
+ # for a repository located on the application server or github.
4
+ #
5
+ # Installation: sudo gem install funkenplate
6
+ # Online Usage: rails myapp --template http://github.com/funkensturm/funkenplate/raw/master/funkenplate.rb
7
+ # Offline Usage: rails myapp --template ~/.funkenplate/funkenplate.rb
8
+ # Documentation: http://github.com/funkensturm/funkenplate
9
+ # ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
10
+
11
+ # –––––––––––––––––––––
12
+ # Checking envirionment
13
+ # –––––––––––––––––––––
14
+
15
+ unless defined?(Rails)
16
+ puts %(This is not a standalone application, it is to be used as a template for Rails.)
17
+ exit 1
18
+ end
19
+
20
+ unless Gem.available?('funkenplate')
21
+ say_status :error, 'Please install the funkenplate gem first with "gem install funkenplate".', :red
22
+ exit 1
23
+ end
24
+
25
+ say_status :WELCOME, 'Welcome to funkenplate', :green
26
+
27
+ # –––––––––––––––––––––––––––
28
+ # OBTAINING GEM PATH AND LIBS
29
+ # –––––––––––––––––––––––––––
30
+
31
+ # Main paths
32
+ gem_path = Gem.source_index.find_name('funkenplate').last.full_gem_path
33
+ gem_version = Gem.source_index.find_name('funkenplate').last.version.version
34
+ templates_path = File.join(gem_path, 'templates')
35
+
36
+ # This is where we will search for funkenplate.yml containing individual secrets
37
+ secret_files = []
38
+ directories = ['..', ENV['HOME'], File.join(ENV['HOME'], '.ssh')]
39
+ files = ['funkenplate.yml', '.funkenplate.yml']
40
+ directories.each { |directory| files.each { |file| secret_files << File.expand_path(File.join(directory, file)) } }
41
+
42
+ # ––––––––––––––
43
+ # HELPER METHODS
44
+ # ––––––––––––––
45
+
46
+ def shout_status(*args)
47
+ puts
48
+ say_status(*args)
49
+ puts
50
+ end
51
+
52
+ def ask(question)
53
+ puts
54
+ say_status :QUESTION, question, :blue
55
+ print ' ' * 16
56
+ $stdin.gets.strip
57
+ end
58
+
59
+ def yes?(question)
60
+ answer = ask("#{question} (ENTER: yes)").downcase
61
+ puts
62
+ answer == '' or answer == "\n" or answer == 'y' or answer == 'yes' or answer == 'j' or answer == 'ja'
63
+ end
64
+
65
+ def read_template(file)
66
+ File.new(file).read
67
+ end
68
+
69
+ def apply_template(file)
70
+ read_template(file).
71
+ gsub('~app_name~', app_name).
72
+ gsub('~github_account~', @secrets[:deploy][:app_server][:user].to_s).
73
+ gsub('~domain~', @secrets[:deploy][:app_server][:domain].to_s).
74
+ gsub('~user~', @secrets[:deploy][:app_server][:user].to_s).
75
+ gsub('~port~', @secrets[:deploy][:app_server][:port].to_s).
76
+ gsub('~keys~', @secrets[:deploy][:app_server][:keys].to_s)
77
+ end
78
+
79
+ # –––––––––––––––
80
+ # DEFAULT SECRETS
81
+ # –––––––––––––––
82
+
83
+ # Default secrets
84
+ default_secrets = {
85
+ :version => gem_version,
86
+ :deploy => {
87
+ :app_server => {
88
+ :user => ENV['USER'].downcase,
89
+ :domain => 'YOUR_SERVER_DOMAIN_OR_IP_GOES_HERE',
90
+ :port => 22,
91
+ :keys => File.expand_path(File.join(ENV['HOME'], '.ssh', 'YOUR_PRIVATE_KEY'))
92
+ },
93
+ :github => {
94
+ :account => 'YOUR_GITHUB_ACCOUNT_NAME_GOES_HERE'
95
+ }
96
+ }
97
+ }
98
+
99
+ # –––––––––––––––––
100
+ # OBTAINING SECRETS
101
+ # –––––––––––––––––
102
+
103
+ @secrets = default_secrets
104
+ if secret_file = secret_files.find { |file| File.file? file }
105
+ @secrets = YAML.load_file secret_file
106
+ else
107
+ shout_status :error, "I could not find funkenplate.yml anywhere but I created one for you. You must edit it and then re-apply this template.", :red
108
+ say_status :info, "Note that you can put that yml file into any of these locations (top ones with higher priority):", :yellow
109
+ secret_files.each { |location| say_status '', " #{location}" }
110
+ shout_status :create, secret_files.first
111
+ File.open(secret_files.first, 'w') { |file| file.write YAML::dump(default_secrets) }
112
+ exit 1
113
+ end
114
+
115
+ shout_status :ENVIRONMENT, "These is the stuff we're working with here:", :yellow
116
+ print_table [
117
+ ['Application name:', app_name],
118
+ ['Application location:', destination_root],
119
+ ['Funkenplate gem:', gem_path],
120
+ ['Secret file:', secret_file],
121
+ ], :ident => 16
122
+
123
+ shout_status :SECRETS, "I was able to obtain these secrets from the secret file:", :yellow
124
+ print_table [
125
+ ['Application Server domain:', @secrets[:deploy][:app_server][:domain]],
126
+ ['Application Server SSH user:', @secrets[:deploy][:app_server][:user]],
127
+ ['Application Server SSH port:', @secrets[:deploy][:app_server][:port]],
128
+ ['Github account:', @secrets[:deploy][:app_server][:user]],
129
+ ['Location of your SSH key:', @secrets[:deploy][:app_server][:keys]],
130
+ ], :ident => 16
131
+
132
+ unless yes?("Are these values correct?")
133
+ shout_status :EXITING, "OK, please edit this file first: #{secret_file}"
134
+ exit 1
135
+ end
136
+
137
+ # ––––––––––––––
138
+ # TEMPLATE TASKS
139
+ # ––––––––––––––
140
+
141
+ say_status :TASKS, 'Running template tasks...', :yellow
142
+
143
+ say_status :TASK, 'Clearing tmp directories...', :magenta
144
+ ['tmp/pids', 'tmp/sessions', 'tmp/sockets', 'tmp/cache'].each { |dir| remove_file dir }
145
+
146
+ say_status :TASK, 'Creating additional directories...', :magenta
147
+ ['private', 'lib/core_extensions', 'lib/rails_extensions'].each { |dir| empty_directory dir }
148
+
149
+ say_status :TASK, 'Deleting some boring files...', :magenta
150
+ ['public/index.html', 'public/images/rails.png'].each { |dir| remove_file dir }
151
+
152
+ # ––––––––––––––
153
+ # TEMPLATE TASKS
154
+ # ––––––––––––––
155
+
156
+ say_status :TASK, 'Doing some beauty errands...', :magenta
157
+ run 'echo TODO > README'
158
+ run 'mv README README.textile'
159
+
160
+ say_status :TASK, 'Creating lib extensions...', :magenta
161
+ lib 'core_extensions/object.rb', read_template(File.join(templates_path, 'lib', 'core_extensions', 'object.rb'))
162
+ lib 'rails_extensions/active_record.rb', read_template(File.join(templates_path, 'lib', 'rails_extensions', 'active_record.rb'))
163
+ lib 'rails_extensions/action_controller_base.rb', read_template(File.join(templates_path, 'lib', 'rails_extensions', 'action_controller_base.rb'))
164
+ lib 'rails_extensions/application_helper.rb', read_template(File.join(templates_path, 'lib', 'rails_extensions', 'application_helper.rb'))
165
+ lib 'gem_extensions/formtastic.rb', read_template(File.join(templates_path, 'lib', 'gem_extensions', 'formtastic.rb'))
166
+
167
+ say_status :TASK, 'Creating initializer for lib extensions...', :magenta
168
+ initializer 'extensions.rb',
169
+ "Dir.glob(File.join(Rails.root, 'lib', 'core_extensions', '*.rb')) { |file| require file }\n
170
+ Dir.glob(File.join(Rails.root, 'lib', 'rails_extensions', '*.rb')) { |file| require file }\n
171
+ Dir.glob(File.join(Rails.root, 'lib', 'gem_extensions', '*.rb')) { |file| require file }\n"
172
+
173
+
174
+ say_status :TASK, 'Creating sample database.yml...', :magenta
175
+ file 'config/database.yml.sample', "
176
+ # HINT: If you are on the server, you might want to delete
177
+ # the :development and :test database definition in this file.
178
+ # This way you won't accidentally work on a development database.
179
+ #
180
+ \n\n#{File.new('config/database.yml').read}"
181
+
182
+ say_status :TASK, 'Creating TextMate project file...', :magenta
183
+ file "#{app_name}.tmproj", apply_template(File.join(templates_path, 'tmproj'))
184
+
185
+ say_status :TASK, 'Adding backtrace silencers...', :magenta
186
+ append_file 'config/initializers/backtrace_silencers.rb' do
187
+ "bc.add_silencer { |line| line =~ /^\s*passenger/ }\n
188
+ bc.clean(exception.backtrace)"
189
+ end
190
+
191
+ # –––––––
192
+ # GIT
193
+ # –––––––
194
+
195
+ say_status :GIT, 'Gitifying application...', :yellow
196
+
197
+ say_status :GIT, 'Create .gitignore recursively in every empty directory...', :magenta
198
+ run 'find . \\( -type d -empty \\) -and \\( -not -regex ./\\.git.* \\) -exec touch {}/.gitignore \\;'
199
+
200
+ say_status :GIT, 'Create .gitignore in root...', :magenta
201
+ remove_file '.gitignore'
202
+ file '.gitignore', read_template(File.join(templates_path, 'gitignore'))
203
+
204
+ say_status :GIT, 'Initial commit...', :magenta
205
+ git :init
206
+ git :add => '.'
207
+ git :commit => "-a -m 'Initial commit.'"
208
+
209
+ say_status :GIT, 'Adding repository remotes for the fs server ...', :magenta
210
+ run "git remote add fs #{apply_template(File.join(templates_path, 'deploy', 'repositories', 'fs_remote_fs'))}"
211
+ run "git remote add fs.git #{apply_template(File.join(templates_path, 'deploy', 'repositories', 'fs_remote_git'))}"
212
+
213
+ # ––––––––––
214
+ # CAPISTRANO
215
+ # ––––––––––
216
+
217
+ say_status :CAPISTRANO, 'Capifying application...', :yellow
218
+
219
+ say_status :CAPISTRANO, 'Capify...', :magenta
220
+ capify!
221
+
222
+ say_status :CAPISTRANO, 'Backup original deploy.rb...', :magenta
223
+ run 'cp config/deploy.rb config/deploy.rb.sample'
224
+
225
+ deploy_header = [
226
+ apply_template(File.join(templates_path, 'deploy', 'header.rb')),
227
+ apply_template(File.join(templates_path, 'deploy', 'options.rb'))
228
+ ].join("\n")
229
+
230
+ deploy_footer = [
231
+ apply_template(File.join(templates_path, 'deploy', 'tasks.rb')),
232
+ apply_template(File.join(templates_path, 'deploy', 'helper.rb'))
233
+ ].join("\n")
234
+
235
+ say_status :CAPISTRANO, 'Generating deploy.fs.rb for repositories on fs server...', :magenta
236
+ file 'config/deploy.fs.rb', deploy_header + "\n" + apply_template(File.join(templates_path, 'deploy', 'repositories', 'fs.rb')) + "\n" + deploy_footer
237
+
238
+ say_status :CAPISTRANO, 'Generating deploy.github.rb for repositories on github.com...', :magenta
239
+ file 'config/deploy.github.rb', deploy_header + "\n" + apply_template(File.join(templates_path, 'deploy', 'repositories', 'github.rb')) + "\n" + deploy_footer
240
+
241
+ say_status :GIT, 'Commiting capistrano changes...', :magenta
242
+ git :add => '.'
243
+ git :commit => "-a -m 'Capified the app.'"
244
+
245
+ # –––––––––
246
+ # GEMS
247
+ # –––––––––
248
+
249
+ say_status :GEMFILE, 'Adding some gems...', :magenta
250
+ append_file "Gemfile", "
251
+ gem 'will_paginate'
252
+ gem 'formtastic'
253
+ gem 'geokit'
254
+ "
255
+
256
+ say_status :GIT, 'Commiting Gemfile changes...', :magenta
257
+ git :commit => "-a -m 'Added default gems to Gemfile.'"
258
+
259
+ # ––––––
260
+ # FINISH
261
+ # ––––––
262
+
263
+ shout_status :FINISHED, 'Congratulations.', :green
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'funkenplate'
data/lib/dummy ADDED
File without changes
@@ -0,0 +1,17 @@
1
+ # —————————————————————
2
+ # CAPISTRANO QUICKSTART
3
+ # —————————————————————
4
+ # cap deploy:check Dry check for permissions and so forth to mae sure you can deploy
5
+ # cap deploy:setup Create necessary directories
6
+ # cap deploy:cold Install application and run migrations
7
+ # cap deploy Update application
8
+ #
9
+
10
+ # ––––––––––––––––––
11
+ # APPLICATION SERVER
12
+ # ————————————————––
13
+
14
+ set :application, "~app_name~"
15
+ set :user, "~user~"
16
+ set :domain, "~domain~"
17
+ set :port, ~port~
@@ -0,0 +1,53 @@
1
+ # ———————————–––
2
+ # HELPER METHODS
3
+ # ————————————––
4
+
5
+ # Creates a bare git repository if needed and possible
6
+ def git_init(path)
7
+ return true if test_remote? :file, File.join(path, 'HEAD')
8
+ return false unless test_remote? :writable, path
9
+ run "cd #{path}; git --bare init"
10
+ test_remote?(:file, File.join(path, 'HEAD')) ? true : false
11
+ end
12
+
13
+ # Creates a directory only if needed and possible
14
+ def mkdir(path)
15
+ return true if test_remote? :directory, path
16
+ return false unless test_remote? :writable, '/' + path.split('/')[1..path.split('/').size-2].join('/')
17
+ run "mkdir #{path}"
18
+ test_remote?(:directory, path) ? true : false
19
+ end
20
+
21
+ # Performs various file tests on the remote server
22
+ def test_remote?(type, full_path)
23
+ arg = case type
24
+ when :file then '-f'
25
+ when :directory then '-d'
26
+ when :writable then '-w'
27
+ when :file_with_content then '-s'
28
+ end
29
+ 'true' == capture("if [ #{arg} #{full_path} ]; then echo 'true'; fi").strip
30
+ end
31
+
32
+ # Returns the repository path if it is located on the deploy server
33
+ def repository_on_server?
34
+ return false unless repository =~ /^file/
35
+ repository.gsub('file://', '')
36
+ end
37
+
38
+ # Creates a directory in the shared path
39
+ def mkshared(path)
40
+ mkdir File.join(deploy_to, 'shared', path)
41
+ end
42
+
43
+ # Creates a symlink from <tt>deploy_to/shared/...</tt> to <tt>release_path/...</tt>
44
+ # If <tt>to</tt> is omitted, the release path mirrors in the shared path
45
+ def symlinker(from, to='')
46
+ to = from if to == ''
47
+ run "ln -nfs #{File.join deploy_to, 'shared', from} #{File.join release_path, to}"
48
+ end
49
+
50
+ # Quick helper for the database in the shared directory
51
+ def shared_database
52
+ File.join(deploy_to, 'shared', 'config', 'database.yml')
53
+ end
@@ -0,0 +1,19 @@
1
+ # ––––––––––––––
2
+ # DEPLOY OPTIONS
3
+ # —————————————–
4
+
5
+ role :app, domain
6
+ role :web, domain
7
+ role :db, domain, :primary => true
8
+
9
+ set :scm, :git
10
+ set :use_sudo, false
11
+ set :keep_releases, 3
12
+ set :default_run_options, { :pty => true }
13
+
14
+ set :ssh_options, {
15
+ :forward_agent => true,
16
+ :paranoid => false,
17
+ :keys => ["~keys~"],
18
+ :port => port
19
+ }
@@ -0,0 +1,7 @@
1
+ # ––––––––––––––
2
+ # REPOSITORY: FS
3
+ # ––––––––––––––
4
+
5
+ set :repository, "file:///home/git/repositories/~app_name~"
6
+ set :local_repository, "fs.git:/home/git/repositories/~app_name~"
7
+ set :deploy_via, :remote_cache
@@ -0,0 +1 @@
1
+ fs:/home/git/repositories/~app_name~
@@ -0,0 +1 @@
1
+ fs.git:/home/git/repositories/~app_name~
@@ -0,0 +1,5 @@
1
+ # ––––––––––––––––––
2
+ # REPOSITORY: GITHUB
3
+ # ––––––––––––––––––
4
+
5
+ set :repository, "git://github.com/~github_account~/~app_name~.git"
@@ -0,0 +1 @@
1
+ git://github.com/~github_account~/~app_name~.git
@@ -0,0 +1,115 @@
1
+ # ———————————–––––—
2
+ # FUNKENPLATE HOOKS
3
+ # ————————————–––––
4
+
5
+ before 'deploy:setup', :funkenplate
6
+ after 'deploy:setup', 'deploy:setup_additions'
7
+ after 'deploy:update_code', 'deploy:additional_symlinks'
8
+
9
+ # ———————————–
10
+ # DEPLOY TASKS
11
+ # ————————————
12
+
13
+ namespace :quick do
14
+
15
+ # Quickly update git and deploy the app
16
+ desc 'Quick commit and deploy'
17
+ task :default do
18
+ system 'git add .; git add -u; git commit -m "cap quick"; git push origin master; cap deploy'
19
+ end
20
+
21
+ end
22
+
23
+ namespace :deploy do
24
+
25
+ # Manually restart for the Rails application
26
+ desc 'Restart passenger'
27
+ task :restart, :roles => :app, :except => { :no_release => true } do
28
+ run "touch #{File.join(current_path,'tmp','restart.txt')}"
29
+ end
30
+
31
+ # Happens after initial setup
32
+ desc "Add some more dirs into shared"
33
+ task :setup_additions do
34
+ mkshared 'private'
35
+ mkshared 'config'
36
+ run "touch #{shared_database}"
37
+ logger.important "REMEMBER TO EDIT #{shared_database} ON THE SERVER - NOT in THIS shell!" unless test_remote? :file_with_content, repository_on_server?
38
+ end
39
+
40
+ # Happens with each release
41
+ desc "Link in critical data from shared"
42
+ task :additional_symlinks do
43
+ symlinker 'config/database.yml'
44
+ symlinker 'private'
45
+ end
46
+
47
+ # Overwriting default spin scripts
48
+ task :start do; end
49
+ task :stop do; end
50
+
51
+ end
52
+
53
+ # ———————————––––––
54
+ # FUNKENPLATE TASKS
55
+ # ————————————–––––
56
+
57
+ namespace :funkenplate do
58
+
59
+ # Default run for funkenplate's pre-setup
60
+ task :default do
61
+ deploy_directory
62
+ remote_repository if repository_on_server? # i.e. if not github
63
+ end
64
+
65
+ # Creates the deploy_to directory (if possible)
66
+ task :deploy_directory do
67
+ mkdir deploy_to
68
+ unless test_remote? :directory, deploy_to
69
+ puts "\n-------------- DIRECTOY NOT FOUND --------------"
70
+ puts "Please run these commands as root on the server:"
71
+ puts "mkdir #{deploy_to}"
72
+ puts "chown #{user}:#{user} #{deploy_to}"
73
+ puts "------------------------------------------------\n\n"
74
+ exit
75
+ end
76
+ unless test_remote? :writable, deploy_to
77
+ puts "\n------------ DIRECTOY NOT WRITABLE -------------"
78
+ puts "Please run this command as root on the server:"
79
+ puts "chown #{user}:#{user} #{deploy_to} --recursively"
80
+ puts "------------------------------------------------\n\n"
81
+ exit
82
+ end
83
+ end
84
+
85
+ # Creates the repository if it is locally on the remote server
86
+ task :remote_repository do
87
+ mkdir repository_on_server?
88
+ unless test_remote? :directory, repository_on_server?
89
+ puts "\n-------- REPOSITORY ON SERVER NOT FOUND --------"
90
+ puts "Please run these commands as root on the server:"
91
+ puts "mkdir #{repository}"
92
+ puts "chown git:git #{repository}"
93
+ puts "------------------------------------------------\n\n"
94
+ exit
95
+ end
96
+ unless git_init repository_on_server?
97
+ puts "\n----- REPOSITORY ON SERVER NOT INITIALIZED -----"
98
+ puts "Please run these commands as root on the server:"
99
+ puts "cd #{repository}; git init --bare"
100
+ puts "chown git:git #{repository} --recursively"
101
+ puts "------------------------------------------------\n\n"
102
+ exit
103
+ end
104
+ unless test_remote? :file, File.join(repository_on_server?, 'refs', 'heads', 'master')
105
+ puts "\n-------- REPOSITORY ON SERVER IS EMPTY ---------"
106
+ puts "You need to do a local:"
107
+ puts "git push fs master (when using fs with your user)"
108
+ puts "git push fs.git master (when using fs with git user)"
109
+ puts "git push github master (when using github)"
110
+ puts "------------------------------------------------\n\n"
111
+ exit
112
+ end
113
+ end
114
+
115
+ end
@@ -0,0 +1,15 @@
1
+ .DS_Store
2
+ .bundle
3
+ .tmproj
4
+ log/*.log
5
+ log/*.pid
6
+ db/*.db
7
+ db/*.sqlite3
8
+ db/schema.rb
9
+ tmp/*
10
+ tmp/**/*
11
+ doc/api
12
+ doc/app
13
+ config/database.yml
14
+ config/deploy.rb
15
+ private
@@ -0,0 +1,9 @@
1
+ module ArrayExtensions
2
+
3
+ end
4
+
5
+ class Array #:nodoc:
6
+ include ArrayExtensions
7
+ end
8
+
9
+
@@ -0,0 +1,19 @@
1
+ module ObjectExtensions
2
+
3
+ def not_nil?
4
+ !nil?
5
+ end
6
+
7
+ def not_blank?
8
+ !blank?
9
+ end
10
+
11
+ def not_empty?
12
+ !empty?
13
+ end
14
+
15
+ end
16
+
17
+ class Object #:nodoc:
18
+ include ObjectExtensions
19
+ end
@@ -0,0 +1,7 @@
1
+ module StringExtensions
2
+
3
+ end
4
+
5
+ class String #:nodoc:
6
+ include StringExtensions
7
+ end
@@ -0,0 +1,21 @@
1
+ module Formtastic #:nodoc:
2
+ class SemanticFormBuilder < ActionView::Helpers::FormBuilder
3
+
4
+ # Adapted from Formtastic::SemanticFormBuilder.input
5
+ #
6
+ def note(options={})
7
+ options[:label] = localized_string(:note, nil, :label) unless options.key?(:label)
8
+ html_class = [ :note, (options[:pointer] ? 'pointer' : nil) ]
9
+ tab_id = (options[:tab] ? "#{options[:tab]}_" : nil)
10
+
11
+ wrapper_html = options.delete(:wrapper_html) || {}
12
+
13
+ wrapper_html[:id] ||= generate_html_id("#{tab_id}note").gsub(/_input$/, '')
14
+ wrapper_html[:class] = (html_class << wrapper_html[:class]).flatten.compact.join(' ')
15
+
16
+ list_item_content = template.content_tag(:label, options[:label]) + template.content_tag(:span, options[:message])
17
+ return template.content_tag(:li, list_item_content, wrapper_html)
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,37 @@
1
+ module ActionController
2
+ module BaseExtensions
3
+
4
+ # "DummiesController" => "Dummies"
5
+ def bare_name
6
+ self.class.name.sub(/Test$/, '').sub(/Controller$/, '')
7
+ end
8
+
9
+ # "DummiesController" => "dummy"
10
+ def to_variable_name
11
+ bare_name.singularize.downcase
12
+ end
13
+
14
+ # "DummiesController" => "dummies"
15
+ def to_variables_name
16
+ bare_name.downcase
17
+ end
18
+
19
+ # "DummiesController" => Dummy
20
+ def to_model
21
+ bare_name.singularize.constantize
22
+ end
23
+
24
+ end
25
+ end
26
+
27
+ module ActionController
28
+ class Base
29
+ include BaseExtensions
30
+ end
31
+ end
32
+
33
+ module ActionController
34
+ class TestCase
35
+ include BaseExtensions
36
+ end
37
+ end
@@ -0,0 +1,56 @@
1
+ module ActionController
2
+ module RestfulTestCase
3
+
4
+ def test_index
5
+ get :index
6
+ assert_template 'index'
7
+ end
8
+
9
+ def test_show
10
+ get :show, :id => to_model.first
11
+ assert_template 'show'
12
+ end
13
+
14
+ def test_new
15
+ get :new
16
+ assert_template 'new'
17
+ end
18
+
19
+ def test_create_invalid
20
+ to_model.any_instance.stubs(:valid?).returns(false)
21
+ post :create
22
+ assert_template 'new'
23
+ end
24
+
25
+ def test_create_valid
26
+ to_model.any_instance.stubs(:valid?).returns(true)
27
+ post :create
28
+ assert_redirected_to eval("#{to_variables_name}_url")
29
+ end
30
+
31
+ def test_edit
32
+ get :edit, :id => to_model.first
33
+ assert_template 'edit'
34
+ end
35
+
36
+ def test_update_invalid
37
+ to_model.any_instance.stubs(:valid?).returns(false)
38
+ put :update, :id => to_model.first
39
+ assert_template 'edit'
40
+ end
41
+
42
+ def test_update_valid
43
+ to_model.any_instance.stubs(:valid?).returns(true)
44
+ put :update, :id => to_model.first
45
+ assert_redirected_to eval("#{to_variables_name}_url")
46
+ end
47
+
48
+ def test_destroy
49
+ continent = to_model.first
50
+ delete :destroy, :id => continent
51
+ assert_redirected_to eval("#{to_variables_name}_url")
52
+ assert !to_model.exists?(continent.id)
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,5 @@
1
+ module ActiveRecord
2
+ class Base
3
+
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ module ApplicationHelper
2
+ module_eval do
3
+
4
+ # Example:
5
+ #def back_link(text='Back', *args)
6
+ # link_to text, (request.referrer || 'javascript:history.go(-1)'), *args
7
+ #end
8
+
9
+ end
10
+ end
@@ -0,0 +1,81 @@
1
+ module Restful
2
+
3
+ def index
4
+ eval "@#{to_variables_name} = #{to_model}.all"
5
+ respond_to do |format|
6
+ format.html
7
+ format.js { render :layout => false }
8
+ end
9
+ end
10
+
11
+ def show
12
+ eval "@#{to_variable_name} = #{to_model}.find(params[:id])"
13
+ respond_to do |format|
14
+ format.html
15
+ format.js { render :layout => false }
16
+ format.json { render :json => eval("@#{to_variable_name}").to_json }
17
+ end
18
+ end
19
+
20
+ def new
21
+ eval "@#{to_variable_name} = #{to_model}.new"
22
+ respond_to do |format|
23
+ format.html
24
+ format.js { render :layout => false }
25
+ end
26
+ end
27
+
28
+ def create
29
+ eval <<-END
30
+ @#{to_variable_name} = #{to_model}.new(params[:#{to_variable_name}])
31
+ if @#{to_variable_name}.save
32
+ flash[:notice] = "Successfully created #{to_variable_name}."
33
+ redirect_to #{to_variables_name}_url and return
34
+ else
35
+ render :action => 'new' and return
36
+ end
37
+ END
38
+ respond_to do |format|
39
+ format.html
40
+ format.js { render :layout => false }
41
+ end
42
+ end
43
+
44
+ def edit
45
+ eval "@#{to_variable_name} = #{to_model}.find(params[:id])"
46
+ respond_to do |format|
47
+ format.html
48
+ format.js { render :layout => false }
49
+ end
50
+ end
51
+
52
+ def update
53
+ eval <<-END
54
+ @#{to_variable_name} = #{to_model}.find(params[:id])
55
+ if @#{to_variable_name}.update_attributes(params[:#{to_variable_name}])
56
+ flash[:notice] = "Successfully updated #{to_variable_name}."
57
+ redirect_to #{to_variables_name}_url and return
58
+ else
59
+ render :action => 'edit' and return
60
+ end
61
+ END
62
+ respond_to do |format|
63
+ format.html
64
+ format.js { render :layout => false }
65
+ end
66
+ end
67
+
68
+ def destroy
69
+ eval <<-END
70
+ @#{to_variable_name} = #{to_model}.find(params[:id])
71
+ @#{to_variable_name}.destroy
72
+ flash[:notice] = "Successfully destroyed continent."
73
+ redirect_to #{to_variables_name}_url and return
74
+ END
75
+ respond_to do |format|
76
+ format.html
77
+ format.js { render :layout => false }
78
+ end
79
+ end
80
+
81
+ end
data/templates/tmproj ADDED
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
2
+ <plist version="1.0">
3
+ <dict>
4
+ <key>documents</key>
5
+ <array>
6
+ <dict>
7
+ <key>expanded</key>
8
+ <true/>
9
+ <key>name</key>
10
+ <string>~app_name~</string>
11
+ <key>regexFolderFilter</key>
12
+ <string>!.*/(\.[^/]*|CVS|_darcs|_MTN|\{arch\}|blib|.*~\.nib|.*\.(framework|app|pbproj|pbxproj|xcode(proj)?|bundle))$</string>
13
+ <key>sourceDirectory</key>
14
+ <string></string>
15
+ </dict>
16
+ </array>
17
+ <key>fileHierarchyDrawerWidth</key>
18
+ <integer>184</integer>
19
+ <key>metaData</key>
20
+ <dict/>
21
+ <key>showFileHierarchyDrawer</key>
22
+ <true/>
23
+ <key>windowFrame</key>
24
+ <string>{{32, 4}, {1056, 735}}</string>
25
+ </dict>
26
+ </plist>
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: funkenplate
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Captain Future
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-03-05 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: " funkenplate is a Rails Template according to the funkensturm. standards.\n"
22
+ email:
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - README.textile
29
+ files:
30
+ - init.rb
31
+ - funkenplate.rb
32
+ - MIT-LICENSE
33
+ - README.textile
34
+ - templates/deploy/header.rb
35
+ - templates/deploy/helper.rb
36
+ - templates/deploy/options.rb
37
+ - templates/deploy/repositories/fs.rb
38
+ - templates/deploy/repositories/fs_remote_fs
39
+ - templates/deploy/repositories/fs_remote_git
40
+ - templates/deploy/repositories/github.rb
41
+ - templates/deploy/repositories/github_remote
42
+ - templates/deploy/tasks.rb
43
+ - templates/gitignore
44
+ - templates/lib/core_extensions/array.rb
45
+ - templates/lib/core_extensions/object.rb
46
+ - templates/lib/core_extensions/string.rb
47
+ - templates/lib/gem_extensions/formtastic.rb
48
+ - templates/lib/rails_extensions/action_controller_base.rb
49
+ - templates/lib/rails_extensions/action_controller_restful_test_case.rb
50
+ - templates/lib/rails_extensions/active_record.rb
51
+ - templates/lib/rails_extensions/application_helper.rb
52
+ - templates/lib/restful.rb
53
+ - templates/tmproj
54
+ - lib/dummy
55
+ has_rdoc: true
56
+ homepage: http://github.com/funkensturm/funkenplate
57
+ licenses: []
58
+
59
+ post_install_message:
60
+ rdoc_options: []
61
+
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ segments:
76
+ - 0
77
+ version: "0"
78
+ requirements: []
79
+
80
+ rubyforge_project:
81
+ rubygems_version: 1.3.6
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: Rails Template used by funkensturm.
85
+ test_files: []
86
+