os_suspenders 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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