suspenders 0.0.2
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/LICENSE +21 -0
- data/README.md +165 -0
- data/Rakefile +130 -0
- data/bin/suspenders +80 -0
- data/features/rake_clean.feature +7 -0
- data/features/step_definitions/shell.rb +9 -0
- data/features/support/env.rb +1 -0
- data/suspenders.gemspec +43 -0
- metadata +89 -0
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2010 Mike Burns
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
Suspenders is a base Rails project that you can upgrade. It is used by
|
2
|
+
thoughtbot.
|
3
|
+
|
4
|
+

|
5
|
+
|
6
|
+
To create a new project first install suspenders:
|
7
|
+
|
8
|
+
gem install suspenders
|
9
|
+
|
10
|
+
Then run:
|
11
|
+
|
12
|
+
suspenders create projectname
|
13
|
+
|
14
|
+
This will create a project in `projectname'. You should then follow the
|
15
|
+
instructions on Github to upload that project there. This script creates an
|
16
|
+
entirely new git repository, and is not meant to be used against an existing
|
17
|
+
repo.
|
18
|
+
|
19
|
+
When making a change to a project that was created via this template, consider
|
20
|
+
whether it's a change that should be made across all projects. If so, then
|
21
|
+
make the change in suspenders instead of your project. Note: If you don't
|
22
|
+
have commit access to suspenders, create a github ticket and we'll review your
|
23
|
+
suggestion.
|
24
|
+
|
25
|
+
Once that's committed, you can pull into your project to get all the changes
|
26
|
+
that have been made in suspenders since your last pull:
|
27
|
+
|
28
|
+
git pull suspenders master
|
29
|
+
|
30
|
+
About Suspenders
|
31
|
+
----------------
|
32
|
+
|
33
|
+
Suspenders was created for use at thoughtbot, inc. (http://thoughtbot.com) as a
|
34
|
+
baseline application setup, with reasonable default plugins that the majority
|
35
|
+
(if not all) of our applications used, as well as best-practice configuration
|
36
|
+
options.
|
37
|
+
|
38
|
+
Suspenders currently includes a version of Rails from the 2.3 stable branch.
|
39
|
+
You can determine the changeset with the vendor/rails/REVISION_xxxxx file.
|
40
|
+
|
41
|
+
Gems (unpacked in vendor/gems, unless they are compiled gems):
|
42
|
+
--------------------------------------------------------------
|
43
|
+
|
44
|
+
For record pagination:
|
45
|
+
|
46
|
+
will_paginate (2.3.11)
|
47
|
+
|
48
|
+
For text formatting:
|
49
|
+
|
50
|
+
RedCloth (4.2.2, not unpacked, this is a compiled gem)
|
51
|
+
|
52
|
+
Form builder:
|
53
|
+
|
54
|
+
Formtastic (0.2.1)
|
55
|
+
|
56
|
+
File attachments:
|
57
|
+
|
58
|
+
Paperclip (2.3.0)
|
59
|
+
|
60
|
+
Basic user auth:
|
61
|
+
|
62
|
+
Clearance (0.7.0 engine)
|
63
|
+
|
64
|
+
For testing:
|
65
|
+
|
66
|
+
jferris-mocha (standard mocha plus test spies)
|
67
|
+
factory_girl (fixture replacement for test data)
|
68
|
+
shoulda (rails test helpers and context framework)
|
69
|
+
timecop (for time sensitive tests)
|
70
|
+
fakeweb (for blocking HTTP calls to third-party services)
|
71
|
+
|
72
|
+
Plugins (in vendor/plugins):
|
73
|
+
----------------------------
|
74
|
+
|
75
|
+
hoptoad_notifier
|
76
|
+
limerick_rake
|
77
|
+
validation_reflection (used by formtastic to find required fields)
|
78
|
+
|
79
|
+
Initializers (in config/initializers)
|
80
|
+
-------------------------------------
|
81
|
+
|
82
|
+
action_mailer_configs.rb
|
83
|
+
We use SMTP by default in all applications.
|
84
|
+
|
85
|
+
hoptoad.rb
|
86
|
+
Get your API key at http://hoptoadapp.com
|
87
|
+
|
88
|
+
requires.rb
|
89
|
+
Automatically requires everything in
|
90
|
+
lib/
|
91
|
+
lib/extensions
|
92
|
+
test/mocks/RAILS_ENV (Removed in Rails 2, we decided to keep it)
|
93
|
+
Add other things you need to require in here.
|
94
|
+
|
95
|
+
time_formats.rb
|
96
|
+
Two time formats are available by default, :short_date and :long_date.
|
97
|
+
Add other time formats here.
|
98
|
+
|
99
|
+
Rake Tasks
|
100
|
+
----------
|
101
|
+
|
102
|
+
Rake tasks are contained in the limerick_rake gem.
|
103
|
+
|
104
|
+
bootstrap
|
105
|
+
Provides rake tasks for loading data into the database. These are used for
|
106
|
+
an initial application dataset needed for production.
|
107
|
+
|
108
|
+
capistrano
|
109
|
+
Standard capistrano deployment tasks
|
110
|
+
|
111
|
+
Testing
|
112
|
+
-------
|
113
|
+
|
114
|
+
Testing is done utilizing Test::Unit, Shoulda, factory_girl, and mocha.
|
115
|
+
|
116
|
+
factory_girl is a fixture replacement library, following the factory pattern.
|
117
|
+
Place your factories in test/factories.rb. The fixture directory has been
|
118
|
+
removed, as fixtures are not used.
|
119
|
+
|
120
|
+
Shoulda is a pragmatic testing framework for TDD and BDD built on top of
|
121
|
+
Test::Unit. A number of additional testing macros are provided in
|
122
|
+
test/shoulda_macros:
|
123
|
+
|
124
|
+
shoulda_have_form
|
125
|
+
shoulda_paginate_collection
|
126
|
+
|
127
|
+
Timecop is used to freeze the time for the entire test suite. It is frozen to
|
128
|
+
the value of Time.now; that is, the time that the tests suite starts running.
|
129
|
+
|
130
|
+
Deployment
|
131
|
+
----------
|
132
|
+
|
133
|
+
Deployment is done using capistrano, and deploys to a mongrel cluster, running
|
134
|
+
under Apache.
|
135
|
+
|
136
|
+
Rake tasks are provided for managing git branches which the different
|
137
|
+
environments pull from for deploy.
|
138
|
+
|
139
|
+
To push the git master to git staging branch run:
|
140
|
+
|
141
|
+
rake git:push:staging
|
142
|
+
|
143
|
+
To push the git staging branch to production branch run:
|
144
|
+
|
145
|
+
rake git:push:production
|
146
|
+
|
147
|
+
Setup your deployment environment by running:
|
148
|
+
|
149
|
+
cap ENVIRONMENT deploy:setup
|
150
|
+
(You'll be prompted for the environment's database password)
|
151
|
+
|
152
|
+
Deploy to the desired environment by running:
|
153
|
+
|
154
|
+
cap ENVIRONMENT deploy
|
155
|
+
|
156
|
+
The default environment for deploy is staging, to deploy to staging, just run:
|
157
|
+
|
158
|
+
cap deploy
|
159
|
+
|
160
|
+
Mascot
|
161
|
+
------
|
162
|
+
|
163
|
+
The official Suspenders mascot is Suspenders Boy:
|
164
|
+
|
165
|
+
http://media.tumblr.com/1TEAMALpseh5xzf0Jt6bcwSMo1_400.png
|
data/Rakefile
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'cucumber/rake/task'
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
TEST_PROJECT = 'test_project'
|
7
|
+
SUSPENDERS_GEM_VERSION = '0.0.2'
|
8
|
+
|
9
|
+
#############################################################################
|
10
|
+
#
|
11
|
+
# Testing functions
|
12
|
+
#
|
13
|
+
#############################################################################
|
14
|
+
|
15
|
+
Cucumber::Rake::Task.new
|
16
|
+
|
17
|
+
namespace :test do
|
18
|
+
desc "A full suspenders app's test suite"
|
19
|
+
task :full => ['generate:suspenders', 'generate:finish', 'cucumber', 'destroy:suspenders']
|
20
|
+
end
|
21
|
+
|
22
|
+
namespace :generate do
|
23
|
+
desc 'Suspend a new project'
|
24
|
+
task :suspenders do
|
25
|
+
sh './bin/suspenders', 'create', TEST_PROJECT
|
26
|
+
end
|
27
|
+
|
28
|
+
desc 'Finishing touches'
|
29
|
+
task :finish do
|
30
|
+
open(File.join(TEST_PROJECT, 'config', 'environments', 'cucumber.rb'), 'a') do |f|
|
31
|
+
f.puts "config.action_mailer.default_url_options = { :host => 'localhost:3000' }"
|
32
|
+
end
|
33
|
+
|
34
|
+
routes_file = IO.read(File.join(TEST_PROJECT, 'config', 'routes.rb')).split("\n")
|
35
|
+
routes_file = [routes_file[0]] + [%{map.root :controller => 'clearance/sessions', :action => 'new'}] + routes_file[1..-1]
|
36
|
+
open(File.join(TEST_PROJECT, 'config', 'routes.rb'), 'w') do |f|
|
37
|
+
f.puts routes_file.join("\n")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
namespace :destroy do
|
43
|
+
desc 'Remove a suspended project'
|
44
|
+
task :suspenders do
|
45
|
+
FileUtils.rm_rf TEST_PROJECT
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
desc 'Run the test suite'
|
50
|
+
task :default => ['test:full']
|
51
|
+
|
52
|
+
#############################################################################
|
53
|
+
#
|
54
|
+
# Helper functions
|
55
|
+
#
|
56
|
+
#############################################################################
|
57
|
+
|
58
|
+
def name
|
59
|
+
@name ||= Dir['*.gemspec'].first.split('.').first
|
60
|
+
end
|
61
|
+
|
62
|
+
def version
|
63
|
+
SUSPENDERS_GEM_VERSION
|
64
|
+
end
|
65
|
+
|
66
|
+
def date
|
67
|
+
Date.today.to_s
|
68
|
+
end
|
69
|
+
|
70
|
+
def gemspec_file
|
71
|
+
"#{name}.gemspec"
|
72
|
+
end
|
73
|
+
|
74
|
+
def gem_file
|
75
|
+
"#{name}-#{version}.gem"
|
76
|
+
end
|
77
|
+
|
78
|
+
def replace_header(head, header_name)
|
79
|
+
head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
|
80
|
+
end
|
81
|
+
|
82
|
+
#############################################################################
|
83
|
+
#
|
84
|
+
# Packaging tasks
|
85
|
+
#
|
86
|
+
#############################################################################
|
87
|
+
|
88
|
+
task :release => :build do
|
89
|
+
unless `git branch` =~ /^\* master$/
|
90
|
+
puts "You must be on the master branch to release!"
|
91
|
+
exit!
|
92
|
+
end
|
93
|
+
sh "git commit --allow-empty -a -m 'Release #{version}'"
|
94
|
+
sh "git tag v#{version}"
|
95
|
+
sh "git push origin master"
|
96
|
+
sh "git push --tags"
|
97
|
+
sh "gem push pkg/#{name}-#{version}.gem"
|
98
|
+
end
|
99
|
+
|
100
|
+
task :build => :gemspec do
|
101
|
+
sh "mkdir -p pkg"
|
102
|
+
sh "gem build #{gemspec_file}"
|
103
|
+
sh "mv #{gem_file} pkg"
|
104
|
+
end
|
105
|
+
|
106
|
+
task :gemspec do
|
107
|
+
# read spec file and split out manifest section
|
108
|
+
spec = File.read(gemspec_file)
|
109
|
+
head, manifest, tail = spec.split(" # = MANIFEST =\n")
|
110
|
+
|
111
|
+
# replace name version and date
|
112
|
+
replace_header(head, :name)
|
113
|
+
replace_header(head, :version)
|
114
|
+
replace_header(head, :date)
|
115
|
+
|
116
|
+
# determine file list from git ls-files
|
117
|
+
files = `git ls-files`.
|
118
|
+
split("\n").
|
119
|
+
sort.
|
120
|
+
reject { |file| file =~ /^\./ }.
|
121
|
+
reject { |file| file =~ /^(rdoc|pkg)/ }.
|
122
|
+
map { |file| " #{file}" }.
|
123
|
+
join("\n")
|
124
|
+
|
125
|
+
# piece file back together and write
|
126
|
+
manifest = " s.files = %w[\n#{files}\n ]\n"
|
127
|
+
spec = [head, manifest, tail].join(" # = MANIFEST =\n")
|
128
|
+
File.open(gemspec_file, 'w') { |io| io.write(spec) }
|
129
|
+
puts "Updated #{gemspec_file}"
|
130
|
+
end
|
data/bin/suspenders
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'active_support'
|
4
|
+
require 'pathname'
|
5
|
+
require 'digest/md5'
|
6
|
+
|
7
|
+
### currently the only thing you can do is create. So we ignore the first argument
|
8
|
+
project_name = ARGV[1]
|
9
|
+
fail("Usage: #{File.basename(__FILE__)} create new_project_name") unless project_name
|
10
|
+
fail("Project name must only contain [a-z0-9_]") unless project_name =~ /^[a-z0-9_]+$/
|
11
|
+
|
12
|
+
base_directory = Dir.pwd
|
13
|
+
project_directory = File.join(base_directory, project_name)
|
14
|
+
fail("Project directory (#{project_directory}) already exists") if File.exists?(project_directory)
|
15
|
+
|
16
|
+
template_url = "git://github.com/thoughtbot/suspenders.git"
|
17
|
+
changeme = "CHANGEME"
|
18
|
+
changesession = "CHANGESESSION"
|
19
|
+
|
20
|
+
def run(cmd)
|
21
|
+
puts "Running '#{cmd}'"
|
22
|
+
out = `#{cmd}`
|
23
|
+
if $? != 0
|
24
|
+
fail "Command #{cmd} failed: #$?\n#{out}"
|
25
|
+
end
|
26
|
+
out
|
27
|
+
end
|
28
|
+
|
29
|
+
def search_and_replace(file, search, replace)
|
30
|
+
if File.file?(file)
|
31
|
+
contents = File.read(file)
|
32
|
+
if contents[search]
|
33
|
+
puts "Replacing #{search} with #{replace} in #{file}"
|
34
|
+
contents.gsub!(search, replace)
|
35
|
+
File.open(file, "w") { |f| f << contents }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def installed?(gem_name)
|
41
|
+
installed_gems = Gem.source_index.find_name(gem_name)
|
42
|
+
installed_gems.any?
|
43
|
+
end
|
44
|
+
|
45
|
+
run("mkdir #{project_directory}")
|
46
|
+
Dir.chdir(project_directory) or fail("Couldn't change to #{project_directory}")
|
47
|
+
run("git init")
|
48
|
+
run("git remote add suspenders #{template_url}")
|
49
|
+
run("git pull suspenders master")
|
50
|
+
|
51
|
+
Dir.glob("#{project_directory}/**/*").each do |file|
|
52
|
+
search_and_replace(file, changeme, project_name)
|
53
|
+
end
|
54
|
+
|
55
|
+
Dir.glob("#{project_directory}/**/session_store.rb").each do |file|
|
56
|
+
datestring = Time.now.strftime("%j %U %w %A %B %d %Y %I %M %S %p %Z")
|
57
|
+
search_and_replace(file, changesession, Digest::MD5.hexdigest("#{project_name} #{datestring}"))
|
58
|
+
end
|
59
|
+
|
60
|
+
run("git commit -a -m 'Initial commit'")
|
61
|
+
|
62
|
+
# can't vendor nokogiri because it has native extensions
|
63
|
+
unless installed?("nokogiri")
|
64
|
+
run "sudo gem install nokogiri --version='1.4.0'"
|
65
|
+
end
|
66
|
+
|
67
|
+
# need RedCloth installed for clearance generators to run.
|
68
|
+
unless installed?("RedCloth")
|
69
|
+
run "sudo gem install RedCloth --version='4.2.2'"
|
70
|
+
end
|
71
|
+
|
72
|
+
run("script/generate clearance")
|
73
|
+
run("script/generate clearance_features -f")
|
74
|
+
run("script/generate clearance_views -f")
|
75
|
+
|
76
|
+
run("git add .")
|
77
|
+
run("git commit -m 'installed clearance'")
|
78
|
+
|
79
|
+
puts
|
80
|
+
puts "Now login to github and add a new project named '#{project_name.humanize.titleize}'"
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'spec/expectations'
|
data/suspenders.gemspec
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.specification_version = 2 if s.respond_to? :specification_version=
|
3
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
4
|
+
s.rubygems_version = '1.3.5'
|
5
|
+
|
6
|
+
s.name = 'suspenders'
|
7
|
+
s.version = '0.0.2'
|
8
|
+
s.date = '2010-05-14'
|
9
|
+
|
10
|
+
s.summary = "Generate a Rails app using thoughtbot's best practices."
|
11
|
+
s.description = <<-HERE
|
12
|
+
Suspenders is a base Rails project that you can upgrade. It is used by
|
13
|
+
thoughtbot to get a jump start on a working app. Use Suspenders if you're in a
|
14
|
+
rush to build something amazing; don't use it if you like missing deadlines.
|
15
|
+
HERE
|
16
|
+
|
17
|
+
s.authors = ["Mike Burns"]
|
18
|
+
s.email = 'mburns@thoughtbot.com'
|
19
|
+
s.homepage = 'http://github.com/thoughtbot/suspenders-gem'
|
20
|
+
|
21
|
+
s.executables = ["suspenders"]
|
22
|
+
s.default_executable = 'suspenders'
|
23
|
+
|
24
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
25
|
+
s.extra_rdoc_files = %w[README.md LICENSE]
|
26
|
+
|
27
|
+
s.add_development_dependency('cucumber', [">= 0.6.2"])
|
28
|
+
|
29
|
+
# = MANIFEST =
|
30
|
+
s.files = %w[
|
31
|
+
LICENSE
|
32
|
+
README.md
|
33
|
+
Rakefile
|
34
|
+
bin/suspenders
|
35
|
+
features/rake_clean.feature
|
36
|
+
features/step_definitions/shell.rb
|
37
|
+
features/support/env.rb
|
38
|
+
suspenders.gemspec
|
39
|
+
]
|
40
|
+
# = MANIFEST =
|
41
|
+
|
42
|
+
s.test_files = s.files.select {|path| path =~ /^features/ }
|
43
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: suspenders
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Mike Burns
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-14 00:00:00 -04:00
|
18
|
+
default_executable: suspenders
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: cucumber
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 6
|
30
|
+
- 2
|
31
|
+
version: 0.6.2
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
description: |
|
35
|
+
Suspenders is a base Rails project that you can upgrade. It is used by
|
36
|
+
thoughtbot to get a jump start on a working app. Use Suspenders if you're in a
|
37
|
+
rush to build something amazing; don't use it if you like missing deadlines.
|
38
|
+
|
39
|
+
email: mburns@thoughtbot.com
|
40
|
+
executables:
|
41
|
+
- suspenders
|
42
|
+
extensions: []
|
43
|
+
|
44
|
+
extra_rdoc_files:
|
45
|
+
- README.md
|
46
|
+
- LICENSE
|
47
|
+
files:
|
48
|
+
- LICENSE
|
49
|
+
- README.md
|
50
|
+
- Rakefile
|
51
|
+
- bin/suspenders
|
52
|
+
- features/rake_clean.feature
|
53
|
+
- features/step_definitions/shell.rb
|
54
|
+
- features/support/env.rb
|
55
|
+
- suspenders.gemspec
|
56
|
+
has_rdoc: true
|
57
|
+
homepage: http://github.com/thoughtbot/suspenders-gem
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options:
|
62
|
+
- --charset=UTF-8
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
requirements: []
|
80
|
+
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 1.3.6
|
83
|
+
signing_key:
|
84
|
+
specification_version: 2
|
85
|
+
summary: Generate a Rails app using thoughtbot's best practices.
|
86
|
+
test_files:
|
87
|
+
- features/rake_clean.feature
|
88
|
+
- features/step_definitions/shell.rb
|
89
|
+
- features/support/env.rb
|