suspenders 0.0.4 → 0.1.0.beta.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/Rakefile +5 -21
- data/bin/suspenders +1 -1
- data/features/rake_clean.feature +1 -1
- data/features/step_definitions/shell.rb +1 -1
- data/lib/create.rb +21 -73
- data/suspenders.gemspec +19 -12
- data/template/files/README_FOR_SUSPENDERS +166 -0
- data/template/files/_flashes.html.erb +5 -0
- data/template/files/_javascript.html.erb +2 -0
- data/template/files/body_class_helper.rb +7 -0
- data/template/files/errors.rb +26 -0
- data/template/files/factory_girl_steps.rb +1 -0
- data/template/files/mysql_database.yml.erb +12 -0
- data/template/files/suspenders_gitignore +10 -0
- data/template/files/suspenders_layout.html.erb.erb +22 -0
- data/template/files/time_formats.rb +5 -0
- data/template/suspenders.rb +143 -0
- data/template/trout/Gemfile +32 -0
- data/template/trout/public/javascripts/jquery-ui.js +1012 -0
- data/template/trout/public/javascripts/jquery.js +154 -0
- data/template/trout/public/javascripts/prefilled_input.js +59 -0
- metadata +35 -129
- data/lib/command.rb +0 -12
data/Rakefile
CHANGED
@@ -4,7 +4,7 @@ require 'cucumber/rake/task'
|
|
4
4
|
require 'date'
|
5
5
|
|
6
6
|
TEST_PROJECT = 'test_project'
|
7
|
-
SUSPENDERS_GEM_VERSION = '0.0.
|
7
|
+
SUSPENDERS_GEM_VERSION = '0.1.0.beta.1'
|
8
8
|
|
9
9
|
#############################################################################
|
10
10
|
#
|
@@ -16,34 +16,18 @@ Cucumber::Rake::Task.new
|
|
16
16
|
|
17
17
|
namespace :test do
|
18
18
|
desc "A full suspenders app's test suite"
|
19
|
-
task :full => ['generate', 'cucumber', 'destroy
|
19
|
+
task :full => ['test_project:generate', 'cucumber', 'test_project:destroy']
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
namespace :generate do
|
22
|
+
namespace :test_project do
|
24
23
|
desc 'Suspend a new project. Pass REPO=... to change the Suspenders repo.'
|
25
|
-
task :
|
24
|
+
task :generate do
|
26
25
|
FileUtils.rm_rf(TEST_PROJECT)
|
27
26
|
sh './bin/suspenders', 'create', TEST_PROJECT, ENV['REPO'].to_s
|
28
27
|
end
|
29
28
|
|
30
|
-
desc 'Finishing touches'
|
31
|
-
task :finish => ['suspenders'] do
|
32
|
-
open(File.join(TEST_PROJECT, 'config', 'environments', 'cucumber.rb'), 'a') do |f|
|
33
|
-
f.puts "config.action_mailer.default_url_options = { :host => 'localhost:3000' }"
|
34
|
-
end
|
35
|
-
|
36
|
-
routes_file = IO.read(File.join(TEST_PROJECT, 'config', 'routes.rb')).split("\n")
|
37
|
-
routes_file = [routes_file[0]] + [%{map.root :controller => 'clearance/sessions', :action => 'new'}] + routes_file[1..-1]
|
38
|
-
open(File.join(TEST_PROJECT, 'config', 'routes.rb'), 'w') do |f|
|
39
|
-
f.puts routes_file.join("\n")
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
namespace :destroy do
|
45
29
|
desc 'Remove a suspended project'
|
46
|
-
task :
|
30
|
+
task :destroy do
|
47
31
|
FileUtils.cd TEST_PROJECT
|
48
32
|
sh "rake db:drop RAILS_ENV=development"
|
49
33
|
sh "rake db:drop RAILS_ENV=test"
|
data/bin/suspenders
CHANGED
data/features/rake_clean.feature
CHANGED
@@ -9,7 +9,7 @@ Feature: Rake works in the suspended project
|
|
9
9
|
|
10
10
|
Scenario: Making a spec then running rake
|
11
11
|
When I drop and create the required databases
|
12
|
-
And I generate "
|
12
|
+
And I generate "model post title:string"
|
13
13
|
And I run the rake task "db:migrate"
|
14
14
|
And I run the rake task "spec"
|
15
15
|
Then I see a successful response in the shell
|
data/lib/create.rb
CHANGED
@@ -1,106 +1,54 @@
|
|
1
1
|
# Methods needed to create a project.
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
-
require 'digest/md5'
|
5
4
|
require File.expand_path(File.dirname(__FILE__) + "/errors")
|
6
|
-
require File.expand_path(File.dirname(__FILE__) + "/command")
|
7
5
|
|
8
6
|
module Suspenders
|
9
7
|
class Create
|
10
|
-
attr_accessor :
|
11
|
-
include Suspenders::Command
|
8
|
+
attr_accessor :project_path
|
12
9
|
|
13
|
-
def self.run!(
|
14
|
-
creator = self.new(
|
10
|
+
def self.run!(project_path)
|
11
|
+
creator = self.new(project_path)
|
15
12
|
creator.create_project!
|
16
13
|
end
|
17
14
|
|
18
|
-
def initialize(
|
19
|
-
|
20
|
-
|
15
|
+
def initialize(project_path)
|
16
|
+
self.project_path = project_path
|
17
|
+
validate_project_path
|
18
|
+
validate_project_name
|
21
19
|
end
|
22
20
|
|
23
21
|
def create_project!
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
Dir.glob("#{project_directory}/**/*.*").each do |file|
|
31
|
-
search_and_replace(file, changeme, project_name)
|
32
|
-
end
|
33
|
-
|
34
|
-
Dir.glob("#{project_directory}/**/session_store.rb").each do |file|
|
35
|
-
datestring = Time.now.strftime("%j %U %w %A %B %d %Y %I %M %S %p %Z")
|
36
|
-
search_and_replace(file, changesession, Digest::MD5.hexdigest("#{project_name} #{datestring}"))
|
37
|
-
end
|
38
|
-
|
39
|
-
run("git commit -a -m 'Initial commit'")
|
40
|
-
|
41
|
-
run("rake gems:refresh_specs")
|
42
|
-
run("rake db:create RAILS_ENV=development")
|
43
|
-
run("rake db:create RAILS_ENV=test")
|
44
|
-
|
45
|
-
run("script/generate clearance")
|
46
|
-
run("script/generate clearance_features -f")
|
47
|
-
run("script/generate clearance_views -f")
|
48
|
-
|
49
|
-
run("git add .")
|
50
|
-
run("git commit -m 'installed clearance'")
|
51
|
-
|
52
|
-
puts
|
53
|
-
puts "Now login to github and add a new project named '#{project_name}'"
|
22
|
+
exec(<<-COMMAND)
|
23
|
+
rails new #{project_path} \
|
24
|
+
--template=#{template} \
|
25
|
+
--skip-test-unit \
|
26
|
+
--skip-prototype
|
27
|
+
COMMAND
|
54
28
|
end
|
55
29
|
|
56
30
|
private
|
57
31
|
|
58
|
-
def
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
def changesession
|
63
|
-
"CHANGESESSION"
|
64
|
-
end
|
65
|
-
|
66
|
-
def valid_project_name!(project_name)
|
32
|
+
def validate_project_name
|
33
|
+
project_name = File.basename(project_path)
|
67
34
|
unless project_name =~ /^[a-z0-9_]+$/
|
68
35
|
raise InvalidInput.new("Project name must only contain [a-z0-9_]")
|
69
|
-
else
|
70
|
-
project_name
|
71
36
|
end
|
72
37
|
end
|
73
38
|
|
74
|
-
def
|
39
|
+
def validate_project_path
|
75
40
|
base_directory = Dir.pwd
|
76
|
-
|
41
|
+
full_path = File.join(base_directory, project_path)
|
77
42
|
|
78
43
|
# This is for the common case for the user's convenience; the race
|
79
44
|
# condition can still occur.
|
80
|
-
if File.exists?(
|
81
|
-
raise InvalidInput.new("Project directory (#{
|
82
|
-
end
|
83
|
-
|
84
|
-
if template_url && !(template_url =~ /^ *$/)
|
85
|
-
[template_url, project_directory]
|
86
|
-
else
|
87
|
-
["git://github.com/thoughtbot/suspenders.git", project_directory]
|
45
|
+
if File.exists?(full_path)
|
46
|
+
raise InvalidInput.new("Project directory (#{project_path}) already exists")
|
88
47
|
end
|
89
48
|
end
|
90
49
|
|
91
|
-
def
|
92
|
-
|
93
|
-
contents = File.read(file)
|
94
|
-
if contents[search]
|
95
|
-
puts "Replacing #{search} with #{replace} in #{file}"
|
96
|
-
contents.gsub!(search, replace)
|
97
|
-
File.open(file, "w") { |f| f << contents }
|
98
|
-
end
|
99
|
-
rescue Errno::EISDIR => e
|
100
|
-
# This is fine, because Dir.glob can't select only files.
|
101
|
-
rescue Errno::ENOENT => e
|
102
|
-
fail "Attempted to perform a find-and-replace on a missing file: #{file}"
|
103
|
-
end
|
50
|
+
def template
|
51
|
+
File.expand_path(File.dirname(__FILE__) + "/../template/suspenders.rb")
|
104
52
|
end
|
105
53
|
end
|
106
54
|
end
|
data/suspenders.gemspec
CHANGED
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
|
|
4
4
|
s.rubygems_version = '1.3.5'
|
5
5
|
|
6
6
|
s.name = 'suspenders'
|
7
|
-
s.version = '0.0.
|
8
|
-
s.date = '2010-
|
7
|
+
s.version = '0.1.0.beta.1'
|
8
|
+
s.date = '2010-09-28'
|
9
9
|
|
10
10
|
s.summary = "Generate a Rails app using thoughtbot's best practices."
|
11
11
|
s.description = <<-HERE
|
@@ -24,15 +24,8 @@ rush to build something amazing; don't use it if you like missing deadlines.
|
|
24
24
|
s.rdoc_options = ["--charset=UTF-8"]
|
25
25
|
s.extra_rdoc_files = %w[README.md LICENSE]
|
26
26
|
|
27
|
-
s.add_dependency('
|
28
|
-
s.add_dependency('
|
29
|
-
s.add_dependency('RedCloth', '4.2.2')
|
30
|
-
s.add_dependency('cucumber-rails', '>=0.3.0')
|
31
|
-
s.add_dependency('mysql', '2.8.1')
|
32
|
-
s.add_dependency('rspec','1.3.0')
|
33
|
-
s.add_dependency('rspec-rails','= 1.3.2')
|
34
|
-
s.add_dependency('webrat','>=0.7.0')
|
35
|
-
s.add_dependency('treetop','1.4.5')
|
27
|
+
s.add_dependency('rails', '>= 3.0.0')
|
28
|
+
s.add_dependency('trout', '>= 0.3.0')
|
36
29
|
|
37
30
|
# = MANIFEST =
|
38
31
|
s.files = %w[
|
@@ -43,10 +36,24 @@ rush to build something amazing; don't use it if you like missing deadlines.
|
|
43
36
|
features/rake_clean.feature
|
44
37
|
features/step_definitions/shell.rb
|
45
38
|
features/support/env.rb
|
46
|
-
lib/command.rb
|
47
39
|
lib/create.rb
|
48
40
|
lib/errors.rb
|
49
41
|
suspenders.gemspec
|
42
|
+
template/files/README_FOR_SUSPENDERS
|
43
|
+
template/files/_flashes.html.erb
|
44
|
+
template/files/_javascript.html.erb
|
45
|
+
template/files/body_class_helper.rb
|
46
|
+
template/files/errors.rb
|
47
|
+
template/files/factory_girl_steps.rb
|
48
|
+
template/files/mysql_database.yml.erb
|
49
|
+
template/files/suspenders_gitignore
|
50
|
+
template/files/suspenders_layout.html.erb.erb
|
51
|
+
template/files/time_formats.rb
|
52
|
+
template/suspenders.rb
|
53
|
+
template/trout/Gemfile
|
54
|
+
template/trout/public/javascripts/jquery-ui.js
|
55
|
+
template/trout/public/javascripts/jquery.js
|
56
|
+
template/trout/public/javascripts/prefilled_input.js
|
50
57
|
]
|
51
58
|
# = MANIFEST =
|
52
59
|
|
@@ -0,0 +1,166 @@
|
|
1
|
+
This is Suspenders, the thoughtbot rails template.
|
2
|
+
|
3
|
+
To create a new project, first install the suspenders gem:
|
4
|
+
|
5
|
+
gem install suspenders
|
6
|
+
|
7
|
+
Then run:
|
8
|
+
|
9
|
+
suspenders create projectname
|
10
|
+
|
11
|
+
This will create a project in ../projectname. You should then follow the
|
12
|
+
instructions on Github to upload that project there. This creates an
|
13
|
+
entirely new git repository, and is not meant to be used against an existing
|
14
|
+
repo.
|
15
|
+
|
16
|
+
When making a change to a project that was created via this template, consider
|
17
|
+
whether it's a change that should be made across all projects. If so, then
|
18
|
+
make the change in suspenders instead of your project. Note: If you don't
|
19
|
+
have commit access to suspenders, create a github ticket and we'll review your
|
20
|
+
suggestion.
|
21
|
+
|
22
|
+
Once that's committed, you can pull into your project to get all the changes
|
23
|
+
that have been made in suspenders since your last pull:
|
24
|
+
|
25
|
+
rake git:pull:suspenders
|
26
|
+
|
27
|
+
About Suspenders
|
28
|
+
----------------
|
29
|
+
|
30
|
+
Suspenders was created for use at thoughtbot, inc. (http://thoughtbot.com) as a
|
31
|
+
baseline application setup, with reasonable default plugins that the majority
|
32
|
+
(if not all) of our applications used, as well as best-practice configuration
|
33
|
+
options.
|
34
|
+
|
35
|
+
Suspenders currently includes a version of Rails from the 2.3 stable branch.
|
36
|
+
You can determine the changeset with the vendor/rails/REVISION_xxxxx file.
|
37
|
+
|
38
|
+
Gems (unpacked in vendor/gems, unless they are compiled gems):
|
39
|
+
--------------------------------------------------------------
|
40
|
+
|
41
|
+
For record pagination:
|
42
|
+
|
43
|
+
will_paginate
|
44
|
+
|
45
|
+
For text formatting:
|
46
|
+
|
47
|
+
RedCloth (4.2.2, not unpacked, this is a compiled gem)
|
48
|
+
|
49
|
+
Form builder:
|
50
|
+
|
51
|
+
Formtastic
|
52
|
+
|
53
|
+
File attachments:
|
54
|
+
|
55
|
+
Paperclip
|
56
|
+
|
57
|
+
Basic user auth:
|
58
|
+
|
59
|
+
Clearance
|
60
|
+
|
61
|
+
For testing:
|
62
|
+
|
63
|
+
jferris-mocha (standard mocha plus test spies)
|
64
|
+
factory_girl (fixture replacement for test data)
|
65
|
+
shoulda (rails test helpers and context framework)
|
66
|
+
timecop (for time sensitive tests)
|
67
|
+
fakeweb (for blocking HTTP calls to third-party services)
|
68
|
+
|
69
|
+
Error notification:
|
70
|
+
|
71
|
+
hoptoad_notifier
|
72
|
+
|
73
|
+
Plugins (in vendor/plugins):
|
74
|
+
----------------------------
|
75
|
+
|
76
|
+
limerick_rake (useful rake tasks)
|
77
|
+
validation_reflection (used by formtastic to find required fields)
|
78
|
+
high_voltage (Rails engine for static pages)
|
79
|
+
|
80
|
+
Initializers (in config/initializers)
|
81
|
+
-------------------------------------
|
82
|
+
|
83
|
+
action_mailer_configs.rb
|
84
|
+
We use SMTP by default in all applications.
|
85
|
+
|
86
|
+
hoptoad.rb
|
87
|
+
Get your API key at http://hoptoadapp.com
|
88
|
+
|
89
|
+
requires.rb
|
90
|
+
Automatically requires everything in
|
91
|
+
lib/
|
92
|
+
lib/extensions
|
93
|
+
test/mocks/RAILS_ENV (Removed in Rails 2, we decided to keep it)
|
94
|
+
Add other things you need to require in here.
|
95
|
+
|
96
|
+
time_formats.rb
|
97
|
+
Two time formats are available by default, :short_date and :long_date.
|
98
|
+
Add other time formats here.
|
99
|
+
|
100
|
+
Rake Tasks
|
101
|
+
----------
|
102
|
+
|
103
|
+
Rake tasks are contained in the limerick_rake gem.
|
104
|
+
|
105
|
+
bootstrap
|
106
|
+
Provides rake tasks for loading data into the database. These are used for
|
107
|
+
an initial application dataset needed for production.
|
108
|
+
|
109
|
+
capistrano
|
110
|
+
Standard capistrano deployment tasks
|
111
|
+
|
112
|
+
Testing
|
113
|
+
-------
|
114
|
+
|
115
|
+
Testing is done utilizing Test::Unit, Shoulda, factory_girl, and mocha.
|
116
|
+
|
117
|
+
factory_girl is a fixture replacement library, following the factory pattern.
|
118
|
+
Place your factories in test/factories.rb. The fixture directory has been
|
119
|
+
removed, as fixtures are not used.
|
120
|
+
|
121
|
+
Shoulda is a pragmatic testing framework for TDD and BDD built on top of
|
122
|
+
Test::Unit. A number of additional testing macros are provided in
|
123
|
+
test/shoulda_macros:
|
124
|
+
|
125
|
+
shoulda_have_form
|
126
|
+
shoulda_paginate_collection
|
127
|
+
|
128
|
+
Timecop is used to freeze the time for the entire test suite. It is frozen to
|
129
|
+
the value of Time.now; that is, the time that the tests suite starts running.
|
130
|
+
|
131
|
+
Deployment
|
132
|
+
----------
|
133
|
+
|
134
|
+
Deployment is done using capistrano, and deploys to a mongrel cluster, running
|
135
|
+
under Apache.
|
136
|
+
|
137
|
+
Rake tasks are provided for managing git branches which the different
|
138
|
+
environments pull from for deploy.
|
139
|
+
|
140
|
+
To push the git master to git staging branch run:
|
141
|
+
|
142
|
+
rake git:push:staging
|
143
|
+
|
144
|
+
To push the git staging branch to production branch run:
|
145
|
+
|
146
|
+
rake git:push:production
|
147
|
+
|
148
|
+
Setup your deployment environment by running:
|
149
|
+
|
150
|
+
cap ENVIRONMENT deploy:setup
|
151
|
+
(You'll be prompted for the environment's database password)
|
152
|
+
|
153
|
+
Deploy to the desired environment by running:
|
154
|
+
|
155
|
+
cap ENVIRONMENT deploy
|
156
|
+
|
157
|
+
The default environment for deploy is staging, to deploy to staging, just run:
|
158
|
+
|
159
|
+
cap deploy
|
160
|
+
|
161
|
+
Mascot
|
162
|
+
------
|
163
|
+
|
164
|
+
The official Suspenders mascot is Suspenders Boy:
|
165
|
+
|
166
|
+
http://media.tumblr.com/1TEAMALpseh5xzf0Jt6bcwSMo1_400.png
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'net/smtp'
|
2
|
+
# Example:
|
3
|
+
# begin
|
4
|
+
# some http call
|
5
|
+
# rescue *HTTP_ERRORS => error
|
6
|
+
# notify_hoptoad error
|
7
|
+
# end
|
8
|
+
|
9
|
+
HTTP_ERRORS = [Timeout::Error,
|
10
|
+
Errno::EINVAL,
|
11
|
+
Errno::ECONNRESET,
|
12
|
+
EOFError,
|
13
|
+
Net::HTTPBadResponse,
|
14
|
+
Net::HTTPHeaderSyntaxError,
|
15
|
+
Net::ProtocolError]
|
16
|
+
|
17
|
+
SMTP_SERVER_ERRORS = [TimeoutError,
|
18
|
+
IOError,
|
19
|
+
Net::SMTPUnknownError,
|
20
|
+
Net::SMTPServerBusy,
|
21
|
+
Net::SMTPAuthenticationError]
|
22
|
+
|
23
|
+
SMTP_CLIENT_ERRORS = [Net::SMTPFatalError,
|
24
|
+
Net::SMTPSyntaxError]
|
25
|
+
|
26
|
+
SMTP_ERRORS = SMTP_SERVER_ERRORS + SMTP_CLIENT_ERRORS
|