philosophies-suspenders 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +123 -0
  7. data/LICENSE +21 -0
  8. data/NEWS.md +399 -0
  9. data/README.md +194 -0
  10. data/Rakefile +8 -0
  11. data/bin/philosophies-suspenders +18 -0
  12. data/bin/rake +16 -0
  13. data/bin/rspec +16 -0
  14. data/lib/suspenders/actions.rb +33 -0
  15. data/lib/suspenders/app_builder.rb +512 -0
  16. data/lib/suspenders/generators/app_generator.rb +249 -0
  17. data/lib/suspenders/version.rb +5 -0
  18. data/lib/suspenders.rb +4 -0
  19. data/spec/fakes/bin/heroku +5 -0
  20. data/spec/fakes/bin/hub +5 -0
  21. data/spec/features/github_spec.rb +10 -0
  22. data/spec/features/heroku_spec.rb +20 -0
  23. data/spec/features/new_project_spec.rb +157 -0
  24. data/spec/spec_helper.rb +23 -0
  25. data/spec/support/fake_github.rb +21 -0
  26. data/spec/support/fake_heroku.rb +43 -0
  27. data/spec/support/suspenders.rb +49 -0
  28. data/suspenders.gemspec +34 -0
  29. data/templates/.rubocop.yml +25 -0
  30. data/templates/Gemfile.erb +58 -0
  31. data/templates/Procfile +2 -0
  32. data/templates/README.md.erb +39 -0
  33. data/templates/_analytics.html.erb +7 -0
  34. data/templates/_flashes.html.erb +7 -0
  35. data/templates/_javascript.html.erb +12 -0
  36. data/templates/action_mailer.rb +5 -0
  37. data/templates/airbrake.rb +5 -0
  38. data/templates/application.js +4 -0
  39. data/templates/application.scss +1 -0
  40. data/templates/bundler_audit.rake +12 -0
  41. data/templates/config_i18n_tasks.yml +13 -0
  42. data/templates/config_locales_en.yml.erb +19 -0
  43. data/templates/database_cleaner_rspec.rb +21 -0
  44. data/templates/disable_xml_params.rb +3 -0
  45. data/templates/errors.rb +34 -0
  46. data/templates/factory_girl_rspec.rb +3 -0
  47. data/templates/flashes_helper.rb +5 -0
  48. data/templates/i18n.rb +3 -0
  49. data/templates/json_encoding.rb +1 -0
  50. data/templates/newrelic.yml.erb +34 -0
  51. data/templates/postgresql_database.yml.erb +26 -0
  52. data/templates/rails_helper.rb +17 -0
  53. data/templates/secrets.yml +14 -0
  54. data/templates/setup.rb +5 -0
  55. data/templates/smtp.rb +17 -0
  56. data/templates/spec_helper.rb +13 -0
  57. data/templates/staging.rb +1 -0
  58. data/templates/suspenders_gitignore +34 -0
  59. data/templates/suspenders_layout.html.erb.erb +21 -0
  60. data/templates/unicorn.rb +30 -0
  61. metadata +160 -0
@@ -0,0 +1,23 @@
1
+ require 'bundler/setup'
2
+
3
+ Bundler.require(:default, :test)
4
+
5
+ require (Pathname.new(__FILE__).dirname + '../lib/suspenders').expand_path
6
+
7
+ Dir['./spec/support/**/*.rb'].each { |file| require file }
8
+
9
+ RSpec.configure do |config|
10
+ config.include SuspendersTestHelpers
11
+
12
+ config.before(:all) do
13
+ create_tmp_directory
14
+ end
15
+
16
+ config.before(:each) do
17
+ drop_dummy_database
18
+ remove_project_directory
19
+
20
+ FakeHeroku.clear!
21
+ FakeGithub.clear!
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ class FakeGithub
2
+ RECORDER = File.expand_path(File.join('..', '..', 'tmp', 'hub_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.write @args.join(' ')
11
+ end
12
+ end
13
+
14
+ def self.clear!
15
+ FileUtils.rm_rf RECORDER
16
+ end
17
+
18
+ def self.has_created_repo?(repo_name)
19
+ File.read(RECORDER) == "create #{repo_name}"
20
+ end
21
+ end
@@ -0,0 +1,43 @@
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? do |line|
22
+ line.match(/#{Regexp.quote(gem_name)}/)
23
+ end
24
+ end
25
+
26
+ def self.has_created_app_for?(environment, flags = nil)
27
+ app_name = "#{SuspendersTestHelpers::APP_NAME.dasherize}-#{environment}"
28
+
29
+ command = if flags
30
+ "create #{app_name} #{flags} --remote #{environment}\n"
31
+ else
32
+ "create #{app_name} --remote #{environment}\n"
33
+ end
34
+
35
+ File.foreach(RECORDER).any? { |line| line == command }
36
+ end
37
+
38
+ def self.has_configured_vars?(remote_name, var)
39
+ File.foreach(RECORDER).any? do |line|
40
+ line =~ /^config:add #{var}=.+ --remote #{remote_name}\n$/
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,49 @@
1
+ module SuspendersTestHelpers
2
+ APP_NAME = "dummy_app"
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
+
17
+ %x(#{suspenders_bin} #{APP_NAME} #{arguments})
18
+ end
19
+ end
20
+ end
21
+
22
+ def drop_dummy_database
23
+ if File.exist?(project_path)
24
+ Dir.chdir(project_path) do
25
+ Bundler.with_clean_env do
26
+ `rake db:drop`
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ def project_path
33
+ @project_path ||= Pathname.new("#{tmp_path}/#{APP_NAME}")
34
+ end
35
+
36
+ private
37
+
38
+ def tmp_path
39
+ @tmp_path ||= Pathname.new("#{root_path}/tmp")
40
+ end
41
+
42
+ def suspenders_bin
43
+ File.join(root_path, 'bin', 'suspenders')
44
+ end
45
+
46
+ def root_path
47
+ File.expand_path('../../../', __FILE__)
48
+ end
49
+ end
@@ -0,0 +1,34 @@
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 = ">= #{Suspenders::RUBY_VERSION}"
8
+ s.authors = ['Philosophie']
9
+ s.date = Date.today.strftime('%Y-%m-%d')
10
+
11
+ s.description = <<-HERE
12
+ Suspenders is a base Rails project that you can upgrade. It is used by
13
+ Philosophie 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.email = 'support@thoughtbot.com'
18
+ s.executables = ['philosophies-suspenders']
19
+ s.extra_rdoc_files = %w[README.md LICENSE]
20
+ s.files = `git ls-files`.split("\n")
21
+ s.homepage = 'https://github.com/philosophie/suspenders'
22
+ s.license = 'MIT'
23
+ s.name = 'philosophies-suspenders'
24
+ s.rdoc_options = ['--charset=UTF-8']
25
+ s.require_paths = ['lib']
26
+ s.summary = "Generate a Rails app using Philosophie's best practices."
27
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
28
+ s.version = Suspenders::VERSION
29
+
30
+ s.add_dependency 'bundler', '~> 1.3'
31
+ s.add_dependency 'rails', Suspenders::RAILS_VERSION
32
+
33
+ s.add_development_dependency 'rspec', '~> 3.2'
34
+ end
@@ -0,0 +1,25 @@
1
+ Encoding:
2
+ Enabled: false
3
+
4
+ Documentation:
5
+ Enabled: false
6
+
7
+ ClassAndModuleChildren:
8
+ Enabled: false
9
+
10
+ ClassLength:
11
+ Enabled: false
12
+
13
+ MethodLength:
14
+ Enabled: false
15
+
16
+ DoubleNegation:
17
+ Enabled: false
18
+
19
+ AllCops:
20
+ Exclude:
21
+ - "bin/**/*"
22
+ - "db/**/*"
23
+ - "config/**/*"
24
+ - "Rakefile"
25
+ - "spec/i18n_spec.rb"
@@ -0,0 +1,58 @@
1
+ source "https://rubygems.org"
2
+
3
+ ruby "<%= Suspenders::RUBY_VERSION %>"
4
+
5
+ gem "airbrake"
6
+ gem "autoprefixer-rails"
7
+ gem "bundler", ">= 1.8.4"
8
+ gem "coffee-rails", "~> 4.1.0"
9
+ gem "flutie"
10
+ gem "high_voltage"
11
+ gem "i18n-tasks"
12
+ gem "newrelic_rpm", ">= 3.9.8"
13
+ gem "pg"
14
+ gem "quiet_assets"
15
+ gem "rack-canonical-host"
16
+ gem "rails", "<%= Suspenders::RAILS_VERSION %>"
17
+ gem "sass-rails", "~> 5.0"
18
+ gem "sidekiq"
19
+ gem "simple_form"
20
+ gem "title"
21
+ gem "uglifier"
22
+ gem "unicorn"
23
+
24
+ source "https://rails-assets.org" do
25
+ gem "rails-assets-jquery"
26
+ gem "rails-assets-jquery-ujs"
27
+ end
28
+
29
+ group :development do
30
+ gem "better_errors"
31
+ gem "binding_of_caller"
32
+ gem "spring"
33
+ gem "spring-commands-rspec"
34
+ gem "stairs"
35
+ end
36
+
37
+ group :development, :test do
38
+ gem "bundler-audit", require: false
39
+ gem "dotenv-rails"
40
+ gem "factory_girl_rails"
41
+ gem "pry-byebug"
42
+ gem "pry-rails"
43
+ gem "rspec-rails", "~> 3.1.0"
44
+ gem "rspec-sidekiq"
45
+ gem "rubocop"
46
+ end
47
+
48
+ group :test do
49
+ gem "capybara-webkit", ">= 1.2.0"
50
+ gem "database_cleaner"
51
+ gem "launchy"
52
+ gem "shoulda-matchers", require: false
53
+ gem "timecop"
54
+ end
55
+
56
+ group :staging, :production do
57
+ gem "rack-timeout"
58
+ end
@@ -0,0 +1,2 @@
1
+ web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
2
+ worker: bundle exec sidekiq
@@ -0,0 +1,39 @@
1
+ # <%= app_name.humanize %>
2
+
3
+ ## Setup
4
+
5
+ ```bash
6
+ $ bundle
7
+ $ rake newb
8
+ ```
9
+
10
+ ## Definition of Done
11
+
12
+ In addition to satisfying acceptance criteria, new functionality/changes/etc
13
+ must meet the following requirements before they can be considered "done":
14
+
15
+ 1. Be well-tested according to our
16
+ [Automated Testing Policy](#automated-testing-policy), and the test suite
17
+ must be passing.
18
+ 1. [Conform to the Ruby Community Styleguide.](#styleguide-enforcement)
19
+ 1. Update the seed file with any new data that QA will need to accept your feature
20
+ 1. Ensure that any new ENV vars are added to `setup.rb` and updated on CI and
21
+ servers
22
+ 1. Views render correctly in all [supported browsers](#supported-browsers)
23
+ 1. Have received the :shipit: in peer review via Pull Request.
24
+
25
+ ## Automated Testing Policy
26
+
27
+ TODO: Add your team's agreed upon policy here.
28
+
29
+ ## Styleguide Enforcement
30
+
31
+ We run [rubocop][rubocop] with near vanilla configs to enforce the Ruby Community
32
+ Styleguide. It runs as part of the default `$ rake` task on CI or can be run on
33
+ its own with `$ rubocop`.
34
+
35
+ [rubocop]: https://github.com/bbatsov/rubocop
36
+
37
+ ## Browser Compatibility
38
+
39
+ TODO: Add your team's agreed upon policy here.
@@ -0,0 +1,7 @@
1
+ <% if ENV["SEGMENT_KEY"] %>
2
+ <script type="text/javascript">
3
+ window.analytics=window.analytics||[],window.analytics.methods=["identify","group","track","page","pageview","alias","ready","on","once","off","trackLink","trackForm","trackClick","trackSubmit"],window.analytics.factory=function(t){return function(){var a=Array.prototype.slice.call(arguments);return a.unshift(t),window.analytics.push(a),window.analytics}};for(var i=0;i<window.analytics.methods.length;i++){var key=window.analytics.methods[i];window.analytics[key]=window.analytics.factory(key)}window.analytics.load=function(t){if(!document.getElementById("analytics-js")){var a=document.createElement("script");a.type="text/javascript",a.id="analytics-js",a.async=!0,a.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(a,n)}},window.analytics.SNIPPET_VERSION="2.0.9",
4
+ window.analytics.load("<%= ENV["SEGMENT_KEY"] %>");
5
+ window.analytics.page();
6
+ </script>
7
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <% if flash.any? %>
2
+ <div class="flashes">
3
+ <% user_facing_flashes.each do |key, value| -%>
4
+ <div class="flash-<%= key %>"><%= value %></div>
5
+ <% end -%>
6
+ </div>
7
+ <% end %>
@@ -0,0 +1,12 @@
1
+ <%= javascript_include_tag :application %>
2
+
3
+ <%= yield :javascript %>
4
+
5
+ <%= render "analytics" %>
6
+
7
+ <% if Rails.env.test? %>
8
+ <%= javascript_tag do %>
9
+ $.fx.off = true;
10
+ $.ajaxSetup({ async: false });
11
+ <% end %>
12
+ <% end %>
@@ -0,0 +1,5 @@
1
+ RSpec.configure do |config|
2
+ config.before(:each) do
3
+ ActionMailer::Base.deliveries.clear
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ if ENV.include?('AIRBRAKE_API_KEY')
2
+ Airbrake.configure do |config|
3
+ config.api_key = ENV.fetch('AIRBRAKE_API_KEY')
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ //= require jquery
2
+ //= require jquery-ujs
3
+ //= require_self
4
+ //= require_tree ./application
@@ -0,0 +1 @@
1
+ @charset "utf-8";
@@ -0,0 +1,12 @@
1
+ if Rails.env.development? || Rails.env.test?
2
+ require 'bundler/audit/cli'
3
+
4
+ namespace :bundler do
5
+ desc 'Updates the ruby-advisory-db and runs audit'
6
+ task :audit do
7
+ %w(update check).each do |command|
8
+ Bundler::Audit::CLI.start [command]
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ search:
2
+ paths:
3
+ - "app/controllers"
4
+ - "app/helpers"
5
+ - "app/presenters"
6
+ - "app/views"
7
+
8
+ ignore_unused:
9
+ - activerecord.*
10
+ - date.*
11
+ - simple_form.*
12
+ - time.*
13
+ - titles.*
@@ -0,0 +1,19 @@
1
+ en:
2
+ date:
3
+ formats:
4
+ default:
5
+ "%m/%d/%Y"
6
+ with_weekday:
7
+ "%a %m/%d/%y"
8
+
9
+ time:
10
+ formats:
11
+ default:
12
+ "%a, %b %-d, %Y at %r"
13
+ date:
14
+ "%b %-d, %Y"
15
+ short:
16
+ "%B %d"
17
+
18
+ titles:
19
+ application: <%= app_name.humanize %>
@@ -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,3 @@
1
+ # Protect against injection attacks
2
+ # http://www.kb.cert.org/vuls/id/380039
3
+ ActionDispatch::ParamsParser::DEFAULT_PARSERS.delete(Mime::XML)