funkenplate 0.0.1
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/MIT-LICENSE +20 -0
- data/README.textile +21 -0
- data/funkenplate.rb +263 -0
- data/init.rb +1 -0
- data/lib/dummy +0 -0
- data/templates/deploy/header.rb +17 -0
- data/templates/deploy/helper.rb +53 -0
- data/templates/deploy/options.rb +19 -0
- data/templates/deploy/repositories/fs.rb +7 -0
- data/templates/deploy/repositories/fs_remote_fs +1 -0
- data/templates/deploy/repositories/fs_remote_git +1 -0
- data/templates/deploy/repositories/github.rb +5 -0
- data/templates/deploy/repositories/github_remote +1 -0
- data/templates/deploy/tasks.rb +115 -0
- data/templates/gitignore +15 -0
- data/templates/lib/core_extensions/array.rb +9 -0
- data/templates/lib/core_extensions/object.rb +19 -0
- data/templates/lib/core_extensions/string.rb +7 -0
- data/templates/lib/gem_extensions/formtastic.rb +21 -0
- data/templates/lib/rails_extensions/action_controller_base.rb +37 -0
- data/templates/lib/rails_extensions/action_controller_restful_test_case.rb +56 -0
- data/templates/lib/rails_extensions/active_record.rb +5 -0
- data/templates/lib/rails_extensions/application_helper.rb +10 -0
- data/templates/lib/restful.rb +81 -0
- data/templates/tmproj +26 -0
- metadata +86 -0
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 @@
|
|
1
|
+
fs:/home/git/repositories/~app_name~
|
@@ -0,0 +1 @@
|
|
1
|
+
fs.git:/home/git/repositories/~app_name~
|
@@ -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
|
data/templates/gitignore
ADDED
@@ -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,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
|
+
|