os_suspenders 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.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.travis.yml +13 -0
  4. data/CONTRIBUTING.md +38 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +133 -0
  7. data/LICENSE +21 -0
  8. data/NEWS.md +167 -0
  9. data/README.md +2 -0
  10. data/Rakefile +8 -0
  11. data/bin/rspec +16 -0
  12. data/bin/suspenders +18 -0
  13. data/lib/suspenders/actions.rb +35 -0
  14. data/lib/suspenders/app_builder.rb +352 -0
  15. data/lib/suspenders/generators/app_generator.rb +207 -0
  16. data/lib/suspenders/version.rb +3 -0
  17. data/lib/suspenders.rb +3 -0
  18. data/spec/fakes/bin/heroku +5 -0
  19. data/spec/fakes/bin/hub +5 -0
  20. data/spec/features/github_spec.rb +10 -0
  21. data/spec/features/heroku_spec.rb +13 -0
  22. data/spec/features/new_project_spec.rb +38 -0
  23. data/spec/spec_helper.rb +24 -0
  24. data/spec/support/fake_github.rb +21 -0
  25. data/spec/support/fake_heroku.rb +36 -0
  26. data/spec/support/suspenders.rb +50 -0
  27. data/suspenders.gemspec +35 -0
  28. data/templates/Gemfile_clean +44 -0
  29. data/templates/Procfile +2 -0
  30. data/templates/README.md.erb +25 -0
  31. data/templates/_flashes.html.erb +5 -0
  32. data/templates/_javascript.html.erb +10 -0
  33. data/templates/application.css.scss +8 -0
  34. data/templates/background_jobs_rspec.rb +19 -0
  35. data/templates/bin_setup +32 -0
  36. data/templates/config_locales_en.yml +11 -0
  37. data/templates/database_cleaner_rspec.rb +21 -0
  38. data/templates/development_seeds.rb +13 -0
  39. data/templates/disable_xml_params.rb +3 -0
  40. data/templates/errors.rb +28 -0
  41. data/templates/factories_spec.rb +13 -0
  42. data/templates/factories_spec_rake_task.rb +15 -0
  43. data/templates/factory_girl_syntax_rspec.rb +3 -0
  44. data/templates/postgresql_database.yml.erb +11 -0
  45. data/templates/rack_timeout.rb +1 -0
  46. data/templates/sample.env +3 -0
  47. data/templates/secret_token.rb +10 -0
  48. data/templates/smtp.rb +10 -0
  49. data/templates/spec_helper.rb +29 -0
  50. data/templates/staging.rb +3 -0
  51. data/templates/suspenders_gitignore +13 -0
  52. data/templates/suspenders_layout.html.erb.erb +15 -0
  53. data/templates/unicorn.rb +29 -0
  54. metadata +195 -0
@@ -0,0 +1,36 @@
1
+ class FakeHeroku
2
+ RECORDER = File.expand_path(File.join('..', '..', 'tmp', 'heroku_commands'), File.dirname(__FILE__))
3
+
4
+ def initialize(args)
5
+ @args = args
6
+ end
7
+
8
+ def run!
9
+ File.open(RECORDER, 'a') do |file|
10
+ file.puts @args.join(' ')
11
+ end
12
+ end
13
+
14
+ def self.clear!
15
+ FileUtils.rm_rf RECORDER
16
+ end
17
+
18
+ def self.has_gem_included?(project_path, gem_name)
19
+ gemfile = File.open(File.join(project_path, 'Gemfile'), 'a')
20
+
21
+ File.foreach(gemfile).any?{ |line| line.match(/rails_12factor/) }
22
+ end
23
+
24
+ def self.has_created_app_for?(remote_name)
25
+ app_name = "#{SuspendersTestHelpers::APP_NAME}-#{remote_name}"
26
+ expected_line = "create #{app_name} --remote=#{remote_name}\n"
27
+
28
+ File.foreach(RECORDER).any? { |line| line == expected_line }
29
+ end
30
+
31
+ def self.has_configured_vars?(remote_name, var)
32
+ File.foreach(RECORDER).any? do |line|
33
+ line =~ /^config:add #{var}=.+ --remote=#{remote_name}\n$/
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,50 @@
1
+ module SuspendersTestHelpers
2
+ APP_NAME = 'dummy'
3
+
4
+ def remove_project_directory
5
+ FileUtils.rm_rf(project_path)
6
+ end
7
+
8
+ def create_tmp_directory
9
+ FileUtils.mkdir_p(tmp_path)
10
+ end
11
+
12
+ def run_suspenders(arguments = nil)
13
+ Dir.chdir(tmp_path) do
14
+ Bundler.with_clean_env do
15
+ ENV['TESTING'] = '1'
16
+ ENV['DISABLE_SPRING'] = '1'
17
+
18
+ %x(#{suspenders_bin} #{APP_NAME} #{arguments})
19
+ end
20
+ end
21
+ end
22
+
23
+ def drop_dummy_database
24
+ if File.exists?(project_path)
25
+ Dir.chdir(project_path) do
26
+ Bundler.with_clean_env do
27
+ `rake db:drop`
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ def project_path
34
+ @project_path ||= Pathname.new("#{tmp_path}/#{APP_NAME}")
35
+ end
36
+
37
+ private
38
+
39
+ def tmp_path
40
+ @tmp_path ||= Pathname.new("#{root_path}/tmp")
41
+ end
42
+
43
+ def suspenders_bin
44
+ File.join(root_path, 'bin', 'suspenders')
45
+ end
46
+
47
+ def root_path
48
+ File.expand_path('../../../', __FILE__)
49
+ end
50
+ end
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'suspenders/version'
4
+ require 'date'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.required_ruby_version = '>= 1.9.2'
8
+ s.add_dependency 'bundler', '~> 1.3'
9
+ s.add_dependency 'rails', '4.0.3'
10
+ s.add_development_dependency 'aruba', '~> 0.5.2'
11
+ s.add_development_dependency 'cucumber', '~> 1.2'
12
+ s.authors = ['thoughtbot/os']
13
+ s.date = Date.today.strftime('%Y-%m-%d')
14
+
15
+ s.description = <<-HERE
16
+ Suspenders is a base Rails project that you can upgrade. It is used by
17
+ thoughtbot to get a jump start on a working app. Use Suspenders if you're in a
18
+ rush to build something amazing; don't use it if you like missing deadlines.
19
+ HERE
20
+
21
+ s.email = 'owensims1@gmail.com'
22
+ s.executables = ['suspenders']
23
+ s.extra_rdoc_files = %w[README.md LICENSE]
24
+ s.files = `git ls-files`.split("\n")
25
+ s.homepage = 'http://github.com/owensims1/os_suspenders'
26
+ s.license = 'MIT'
27
+ s.name = 'os_suspenders'
28
+ s.rdoc_options = ['--charset=UTF-8']
29
+ s.require_paths = ['lib']
30
+ s.summary = "Generate a Rails app using thoughtbot's best practices."
31
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
32
+ s.version = Suspenders::VERSION
33
+ s.add_development_dependency 'rspec'
34
+ s.add_development_dependency 'capybara'
35
+ end
@@ -0,0 +1,44 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'airbrake'
4
+ gem 'bourbon'
5
+ gem 'coffee-rails'
6
+ gem 'jquery-rails'
7
+ gem 'neat'
8
+ gem 'pg'
9
+ gem 'rack-timeout'
10
+ gem 'rails', '>= 4.0.3'
11
+ gem 'sass-rails'
12
+ gem 'simple_form'
13
+ gem 'uglifier'
14
+ gem 'unicorn'
15
+ gem 'devise'
16
+
17
+ group :development do
18
+ gem 'foreman'
19
+ gem 'spring'
20
+ gem 'spring-commands-rspec'
21
+ end
22
+
23
+ group :development, :test do
24
+ gem 'awesome_print'
25
+ gem 'dotenv-rails'
26
+ gem 'factory_girl_rails'
27
+ gem 'pry-rails'
28
+ gem 'rspec-rails', '>= 2.14'
29
+ end
30
+
31
+ group :test do
32
+ gem 'capybara-webkit', '>= 1.0.0'
33
+ gem 'database_cleaner'
34
+ gem 'shoulda-matchers'
35
+ gem 'simplecov', require: false
36
+ gem 'timecop'
37
+ gem 'webmock'
38
+ gem 'vcr'
39
+ end
40
+
41
+ group :staging, :production do
42
+ gem 'newrelic_rpm', '>= 3.6.7'
43
+ gem 'rails_12factor'
44
+ end
@@ -0,0 +1,2 @@
1
+ web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
2
+ worker: bundle exec rake jobs:work
@@ -0,0 +1,25 @@
1
+ <%= app_name.humanize %>
2
+ <%= '=' * app_name.humanize.length %>
3
+
4
+ Getting Started
5
+ ---------------
6
+
7
+ This repository comes equipped with a self-setup script:
8
+
9
+ % ./bin/setup
10
+
11
+ After setting up, you can run the application using [foreman]:
12
+
13
+ % foreman start
14
+
15
+ [foreman]: http://ddollar.github.io/foreman/
16
+
17
+ Guidelines
18
+ ----------
19
+
20
+ Use the following guides for getting things done, programming well, and
21
+ programming in style.
22
+
23
+ * [Protocol](http://github.com/thoughtbot/guides/blob/master/protocol)
24
+ * [Best Practices](http://github.com/thoughtbot/guides/blob/master/best-practices)
25
+ * [Style](http://github.com/thoughtbot/guides/blob/master/style)
@@ -0,0 +1,5 @@
1
+ <div id="flash">
2
+ <% flash.each do |key, value| -%>
3
+ <div id="flash_<%= key %>"><%= value %></div>
4
+ <% end -%>
5
+ </div>
@@ -0,0 +1,10 @@
1
+ <%= javascript_include_tag :application %>
2
+
3
+ <%= yield :javascript %>
4
+
5
+ <% if Rails.env.test? %>
6
+ <%= javascript_tag do %>
7
+ $.fx.off = true;
8
+ $.ajaxSetup({ async: false });
9
+ <% end %>
10
+ <% end %>
@@ -0,0 +1,8 @@
1
+ @charset 'utf-8';
2
+
3
+ ///////////////////////////////////////////////////////////////////////////////
4
+
5
+ @import 'bourbon';
6
+ @import 'neat';
7
+
8
+ ///////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,19 @@
1
+ module BackgroundJobs
2
+ def run_background_jobs_immediately
3
+ delay_jobs = Delayed::Worker.delay_jobs
4
+ Delayed::Worker.delay_jobs = false
5
+ yield
6
+ ensure
7
+ Delayed::Worker.delay_jobs = delay_jobs
8
+ end
9
+ end
10
+
11
+ RSpec.configure do |config|
12
+ config.around(:each, type: :feature) do |example|
13
+ run_background_jobs_immediately do
14
+ example.run
15
+ end
16
+ end
17
+
18
+ config.include BackgroundJobs
19
+ end
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env sh
2
+
3
+ # Set up Rails app. Run this script immediately after cloning the codebase.
4
+ # https://github.com/thoughtbot/guides/tree/master/protocol
5
+
6
+ # Exit if any subcommand fails
7
+ set -e
8
+
9
+ # Set up Ruby dependencies via Bundler
10
+ bundle install
11
+
12
+ # Set up database and add any development seed data
13
+ bundle exec rake dev:prime
14
+
15
+ # Add binstubs to PATH via export PATH=".git/safe/../../bin:$PATH" in ~/.zshenv
16
+ mkdir -p .git/safe
17
+
18
+ # Set up configurable environment variables
19
+ if [ ! -f .env ]; then
20
+ cp .sample.env .env
21
+ fi
22
+
23
+ # Pick a port for Foreman
24
+ echo "port: 7000" > .foreman
25
+
26
+ # Set up DNS via Pow
27
+ if [ -d ~/.pow ]
28
+ then
29
+ echo 7000 > ~/.pow/`basename $PWD`
30
+ else
31
+ echo "Pow not set up but the team uses it for this project. Setup: http://goo.gl/RaDPO"
32
+ fi
@@ -0,0 +1,11 @@
1
+ en:
2
+ date:
3
+ formats:
4
+ default: '%m/%d/%Y'
5
+ with_weekday: '%a %m/%d/%y'
6
+
7
+ time:
8
+ formats:
9
+ default: '%a, %b %-d, %Y at %r'
10
+ date: '%b %-d, %Y'
11
+ short: '%B %d'
@@ -0,0 +1,21 @@
1
+ RSpec.configure do |config|
2
+ config.before(:suite) do
3
+ DatabaseCleaner.clean_with(:deletion)
4
+ end
5
+
6
+ config.before(:each) do
7
+ DatabaseCleaner.strategy = :transaction
8
+ end
9
+
10
+ config.before(:each, :js => true) do
11
+ DatabaseCleaner.strategy = :deletion
12
+ end
13
+
14
+ config.before(:each) do
15
+ DatabaseCleaner.start
16
+ end
17
+
18
+ config.after(:each) do
19
+ DatabaseCleaner.clean
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ if Rails.env.development?
2
+ require 'factory_girl'
3
+
4
+ namespace :dev do
5
+ desc 'Seed data for development environment'
6
+ task prime: 'db:setup' do
7
+ FactoryGirl.find_definitions
8
+ include FactoryGirl::Syntax::Methods
9
+
10
+ # create(:user, email: 'user@example.com', password: 'password')
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ # Protect against injection attacks
2
+ # http://www.kb.cert.org/vuls/id/380039
3
+ ActionDispatch::ParamsParser::DEFAULT_PARSERS.delete(Mime::XML)
@@ -0,0 +1,28 @@
1
+ require 'net/http'
2
+ require 'net/smtp'
3
+
4
+ # Example:
5
+ # begin
6
+ # some http call
7
+ # rescue *HTTP_ERRORS => error
8
+ # notify_hoptoad error
9
+ # end
10
+
11
+ HTTP_ERRORS = [Timeout::Error,
12
+ Errno::EINVAL,
13
+ Errno::ECONNRESET,
14
+ EOFError,
15
+ Net::HTTPBadResponse,
16
+ Net::HTTPHeaderSyntaxError,
17
+ Net::ProtocolError]
18
+
19
+ SMTP_SERVER_ERRORS = [TimeoutError,
20
+ IOError,
21
+ Net::SMTPUnknownError,
22
+ Net::SMTPServerBusy,
23
+ Net::SMTPAuthenticationError]
24
+
25
+ SMTP_CLIENT_ERRORS = [Net::SMTPFatalError,
26
+ Net::SMTPSyntaxError]
27
+
28
+ SMTP_ERRORS = SMTP_SERVER_ERRORS + SMTP_CLIENT_ERRORS
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'factories' do
4
+ FactoryGirl.factories.map(&:name).each do |factory_name|
5
+ specify "#{factory_name} factory is valid", :factory do
6
+ factory = build(factory_name)
7
+
8
+ if factory.respond_to?(:valid?)
9
+ expect(factory).to be_valid, factory.errors.full_messages.join(',')
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ if defined?(RSpec)
2
+ task(:spec).clear
3
+
4
+ desc 'Run all specs'
5
+ RSpec::Core::RakeTask.new(:spec) do |t|
6
+ t.rspec_opts = '--tag ~factory'
7
+ end
8
+
9
+ desc 'Run factory specs.'
10
+ RSpec::Core::RakeTask.new(:factory_specs) do |t|
11
+ t.pattern = './spec/models/factories_spec.rb'
12
+ end
13
+
14
+ task spec: :factory_specs
15
+ end
@@ -0,0 +1,3 @@
1
+ RSpec.configure do |config|
2
+ config.include FactoryGirl::Syntax::Methods
3
+ end
@@ -0,0 +1,11 @@
1
+ development: &default
2
+ adapter: postgresql
3
+ database: <%= app_name %>_development
4
+ encoding: utf8
5
+ min_messages: warning
6
+ pool: 2
7
+ timeout: 5000
8
+
9
+ test:
10
+ <<: *default
11
+ database: <%= app_name %>_test
@@ -0,0 +1 @@
1
+ Rack::Timeout.timeout = (ENV['TIMEOUT_IN_SECONDS'] || 5).to_i
@@ -0,0 +1,3 @@
1
+ # http://ddollar.github.com/foreman/
2
+ RACK_ENV=development
3
+ SECRET_KEY_BASE=development_secret
@@ -0,0 +1,10 @@
1
+ # Your secret key is used for verifying the integrity of signed cookies.
2
+ # If you change this key, all old signed cookies will become invalid!
3
+
4
+ # Make sure the secret is at least 30 characters and all random,
5
+ # no regular words or you'll be exposed to dictionary attacks.
6
+ # You can use `rake secret` to generate a secure secret key.
7
+
8
+ # Make sure your secret_key_base is kept private
9
+ # if you're sharing your code publicly.
10
+ <%= app_const %>.config.secret_key_base = ENV['SECRET_KEY_BASE']
data/templates/smtp.rb ADDED
@@ -0,0 +1,10 @@
1
+ if Rails.env.staging? || Rails.env.production?
2
+ SMTP_SETTINGS = {
3
+ address: ENV.fetch('SMTP_ADDRESS'), # example: 'smtp.sendgrid.net'
4
+ authentication: :plain,
5
+ domain: ENV.fetch('SMTP_DOMAIN'), # example: 'this-app.com'
6
+ password: ENV.fetch('SMTP_PASSWORD'),
7
+ port: '587',
8
+ user_name: ENV.fetch('SMTP_USERNAME')
9
+ }
10
+ end
@@ -0,0 +1,29 @@
1
+ require 'simplecov'
2
+ SimpleCov.start 'rails'
3
+
4
+ ENV['RAILS_ENV'] = 'test'
5
+
6
+ require File.expand_path('../../config/environment', __FILE__)
7
+
8
+ require 'rspec/rails'
9
+ require 'webmock/rspec'
10
+
11
+ Dir[Rails.root.join('spec/support/**/*.rb')].each { |file| require file }
12
+
13
+ module Features
14
+ # Extend this module in spec/support/features/*.rb
15
+ end
16
+
17
+ RSpec.configure do |config|
18
+ config.expect_with :rspec do |c|
19
+ c.syntax = :expect
20
+ end
21
+
22
+ config.include Features, type: :feature
23
+ config.infer_base_class_for_anonymous_controllers = false
24
+ config.order = 'random'
25
+ config.use_transactional_fixtures = false
26
+ end
27
+
28
+ Capybara.javascript_driver = :webkit
29
+ WebMock.disable_net_connect!(allow_localhost: true)
@@ -0,0 +1,3 @@
1
+ require_relative 'production'
2
+
3
+ Mail.register_interceptor RecipientInterceptor.new(ENV['EMAIL_RECIPIENTS'])
@@ -0,0 +1,13 @@
1
+ !.keep
2
+ *.DS_Store
3
+ *.swo
4
+ *.swp
5
+ /.bundle
6
+ /.env
7
+ /.foreman
8
+ /coverage/*
9
+ /db/*.sqlite3
10
+ /log/*
11
+ /public/system
12
+ /tags
13
+ /tmp/*
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="ROBOTS" content="NOODP" />
6
+ <title><%%= title %></title>
7
+ <%%= stylesheet_link_tag :application, :media => 'all' %>
8
+ <%%= csrf_meta_tags %>
9
+ </head>
10
+ <body class="<%%= body_class %>">
11
+ <%%= render 'flashes' -%>
12
+ <%%= yield %>
13
+ <%%= render 'javascript' %>
14
+ </body>
15
+ </html>
@@ -0,0 +1,29 @@
1
+ # https://devcenter.heroku.com/articles/rails-unicorn
2
+
3
+ worker_processes (ENV['WEB_CONCURRENCY'] || 3).to_i
4
+ timeout (ENV['WEB_TIMEOUT'] || 5).to_i
5
+ preload_app true
6
+
7
+ before_fork do |server, worker|
8
+ Signal.trap 'TERM' do
9
+ puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
10
+ Process.kill 'QUIT', Process.pid
11
+ end
12
+
13
+ if defined? ActiveRecord::Base
14
+ ActiveRecord::Base.connection.disconnect!
15
+ end
16
+ end
17
+
18
+ after_fork do |server, worker|
19
+ Signal.trap 'TERM' do
20
+ puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT'
21
+ end
22
+
23
+ if defined? ActiveRecord::Base
24
+ config = Rails.application.config.database_configuration[Rails.env]
25
+ config['reaping_frequency'] = (ENV['DB_REAPING_FREQUENCY'] || 10).to_i
26
+ config['pool'] = (ENV['DB_POOL'] || 2).to_i
27
+ ActiveRecord::Base.establish_connection(config)
28
+ end
29
+ end