voyage 1.0

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 (93) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +11 -0
  5. data/CONTRIBUTING.md +54 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +21 -0
  8. data/NEWS.md +510 -0
  9. data/README.md +233 -0
  10. data/RELEASING.md +19 -0
  11. data/Rakefile +8 -0
  12. data/USAGE +13 -0
  13. data/bin/rake +16 -0
  14. data/bin/rspec +16 -0
  15. data/bin/setup +13 -0
  16. data/bin/suspenders +23 -0
  17. data/bin/voyage +20 -0
  18. data/lib/suspenders.rb +6 -0
  19. data/lib/suspenders/actions.rb +33 -0
  20. data/lib/suspenders/adapters/heroku.rb +127 -0
  21. data/lib/suspenders/app_builder.rb +486 -0
  22. data/lib/suspenders/generators/app_generator.rb +287 -0
  23. data/lib/suspenders/generators/static_generator.rb +9 -0
  24. data/lib/suspenders/version.rb +8 -0
  25. data/lib/voyage.rb +9 -0
  26. data/lib/voyage/app_builder.rb +469 -0
  27. data/lib/voyage/generators/app_generator.rb +118 -0
  28. data/lib/voyage/templates/Gemfile.erb +118 -0
  29. data/lib/voyage/templates/README.md.erb +28 -0
  30. data/lib/voyage/templates/about.html.erb +1 -0
  31. data/lib/voyage/templates/application.js +19 -0
  32. data/lib/voyage/templates/config_locales_en.yml.erb +25 -0
  33. data/lib/voyage/templates/controller_helpers.rb +14 -0
  34. data/lib/voyage/templates/custom_cancan_matchers.rb +54 -0
  35. data/lib/voyage/templates/rails_helper.rb.erb +99 -0
  36. data/lib/voyage/templates/seeder.rb.erb +46 -0
  37. data/lib/voyage/templates/seeds.rb.erb +50 -0
  38. data/lib/voyage/templates/simplecov.rb +31 -0
  39. data/lib/voyage/templates/users_index.html.slim.erb +25 -0
  40. data/lib/voyage/templates/welcome.html.erb +11 -0
  41. data/lib/voyage/version.rb +8 -0
  42. data/spec/adapters/heroku_spec.rb +57 -0
  43. data/spec/fakes/bin/heroku +5 -0
  44. data/spec/fakes/bin/hub +5 -0
  45. data/spec/features/cli_help_spec.rb +36 -0
  46. data/spec/features/github_spec.rb +16 -0
  47. data/spec/features/heroku_spec.rb +75 -0
  48. data/spec/features/new_project_spec.rb +270 -0
  49. data/spec/spec_helper.rb +20 -0
  50. data/spec/support/fake_github.rb +21 -0
  51. data/spec/support/fake_heroku.rb +53 -0
  52. data/spec/support/suspenders.rb +83 -0
  53. data/suspenders.gemspec +34 -0
  54. data/templates/Gemfile.erb +64 -0
  55. data/templates/Procfile +2 -0
  56. data/templates/README.md.erb +28 -0
  57. data/templates/_analytics.html.erb +7 -0
  58. data/templates/_css_overrides.html.erb +7 -0
  59. data/templates/_flashes.html.erb +7 -0
  60. data/templates/_javascript.html.erb +12 -0
  61. data/templates/action_mailer.rb +5 -0
  62. data/templates/app.json.erb +42 -0
  63. data/templates/application.scss +9 -0
  64. data/templates/bin_deploy +12 -0
  65. data/templates/bin_setup +21 -0
  66. data/templates/bin_setup_review_app.erb +19 -0
  67. data/templates/browserslist +3 -0
  68. data/templates/bundler_audit.rake +12 -0
  69. data/templates/capybara_webkit.rb +5 -0
  70. data/templates/circle.yml.erb +6 -0
  71. data/templates/config_locales_en.yml.erb +19 -0
  72. data/templates/database_cleaner_rspec.rb +21 -0
  73. data/templates/dev.rake +12 -0
  74. data/templates/dotfiles/.ctags +2 -0
  75. data/templates/dotfiles/.env +13 -0
  76. data/templates/errors.rb +34 -0
  77. data/templates/factories.rb +2 -0
  78. data/templates/factory_girl_rspec.rb +3 -0
  79. data/templates/flashes_helper.rb +5 -0
  80. data/templates/hound.yml +14 -0
  81. data/templates/i18n.rb +3 -0
  82. data/templates/json_encoding.rb +1 -0
  83. data/templates/postgresql_database.yml.erb +21 -0
  84. data/templates/puma.rb +28 -0
  85. data/templates/rack_mini_profiler.rb +5 -0
  86. data/templates/rails_helper.rb +22 -0
  87. data/templates/secrets.yml +14 -0
  88. data/templates/shoulda_matchers_config_rspec.rb +6 -0
  89. data/templates/smtp.rb +13 -0
  90. data/templates/spec_helper.rb +29 -0
  91. data/templates/suspenders_gitignore +13 -0
  92. data/templates/suspenders_layout.html.erb.erb +22 -0
  93. metadata +207 -0
@@ -0,0 +1,20 @@
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
+ add_fakes_to_path
14
+ create_tmp_directory
15
+ end
16
+
17
+ config.before(:each) do
18
+ FakeGithub.clear!
19
+ end
20
+ 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,53 @@
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
+ if @args.first == "plugins"
10
+ puts "heroku-pipelines@0.29.0"
11
+ end
12
+ File.open(RECORDER, 'a') do |file|
13
+ file.puts @args.join(' ')
14
+ end
15
+ end
16
+
17
+ def self.clear!
18
+ FileUtils.rm_rf RECORDER
19
+ end
20
+
21
+ def self.has_gem_included?(project_path, gem_name)
22
+ gemfile = File.open(File.join(project_path, 'Gemfile'), 'a')
23
+
24
+ File.foreach(gemfile).any? do |line|
25
+ line.match(/#{Regexp.quote(gem_name)}/)
26
+ end
27
+ end
28
+
29
+ def self.has_created_app_for?(environment, flags = nil)
30
+ app_name = "#{SuspendersTestHelpers::APP_NAME.dasherize}-#{environment}"
31
+
32
+ command = if flags
33
+ "create #{app_name} #{flags} --remote #{environment}\n"
34
+ else
35
+ "create #{app_name} --remote #{environment}\n"
36
+ end
37
+
38
+ File.foreach(RECORDER).any? { |line| line == command }
39
+ end
40
+
41
+ def self.has_configured_vars?(remote_name, var)
42
+ commands_ran =~ /^config:add #{var}=.+ --remote #{remote_name}\n/
43
+ end
44
+
45
+ def self.has_setup_pipeline_for?(app_name)
46
+ commands_ran =~ /^pipelines:create #{app_name} -a #{app_name}-staging --stage staging/ &&
47
+ commands_ran =~ /^pipelines:add #{app_name} -a #{app_name}-production --stage production/
48
+ end
49
+
50
+ def self.commands_ran
51
+ @commands_ran ||= File.read(RECORDER)
52
+ end
53
+ end
@@ -0,0 +1,83 @@
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
+ arguments = "--path=#{root_path} #{arguments}"
14
+ Dir.chdir(tmp_path) do
15
+ Bundler.with_clean_env do
16
+ add_fakes_to_path
17
+ `
18
+ #{suspenders_bin} #{APP_NAME} #{arguments}
19
+ `
20
+ end
21
+ end
22
+ end
23
+
24
+ def suspenders_help_command
25
+ Dir.chdir(tmp_path) do
26
+ Bundler.with_clean_env do
27
+ `
28
+ #{suspenders_bin} -h
29
+ `
30
+ end
31
+ end
32
+ end
33
+
34
+ def setup_app_dependencies
35
+ if File.exist?(project_path)
36
+ Dir.chdir(project_path) do
37
+ Bundler.with_clean_env do
38
+ `bundle check || bundle install`
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ def drop_dummy_database
45
+ if File.exist?(project_path)
46
+ Dir.chdir(project_path) do
47
+ Bundler.with_clean_env do
48
+ `rake db:drop`
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def add_fakes_to_path
55
+ ENV["PATH"] = "#{support_bin}:#{ENV['PATH']}"
56
+ end
57
+
58
+ def project_path
59
+ @project_path ||= Pathname.new("#{tmp_path}/#{APP_NAME}")
60
+ end
61
+
62
+ def usage_file
63
+ @usage_path ||= File.join(root_path, "USAGE")
64
+ end
65
+
66
+ private
67
+
68
+ def tmp_path
69
+ @tmp_path ||= Pathname.new("#{root_path}/tmp")
70
+ end
71
+
72
+ def suspenders_bin
73
+ File.join(root_path, 'bin', 'suspenders')
74
+ end
75
+
76
+ def support_bin
77
+ File.join(root_path, "spec", "fakes", "bin")
78
+ end
79
+
80
+ def root_path
81
+ File.expand_path('../../../', __FILE__)
82
+ end
83
+ end
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'voyage/version'
4
+ require 'date'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.required_ruby_version = ">= #{Voyage::RUBY_VERSION}"
8
+ s.authors = ['thoughtbot, headway']
9
+ s.date = Date.today.strftime('%Y-%m-%d')
10
+
11
+ s.description = <<-HERE
12
+ Voyage is a fork of the suspenders base Rails project from thoughtbot. It
13
+ is used by headway to get a jump start on a working app.
14
+ HERE
15
+
16
+ s.email = 'development@headway.io'
17
+ s.executables = ['voyage']
18
+ s.extra_rdoc_files = %w[README.md LICENSE]
19
+ s.files = `git ls-files`.split("\n")
20
+ s.homepage = 'http://github.com/headwayio/suspenders'
21
+ s.license = 'MIT'
22
+ s.name = 'voyage'
23
+ s.rdoc_options = ['--charset=UTF-8']
24
+ s.require_paths = ['lib']
25
+ s.summary = "Generate a Rails app using headway's best practices."
26
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
+ s.version = Voyage::VERSION
28
+
29
+ s.add_dependency 'bitters', '~> 1.3'
30
+ s.add_dependency 'bundler', '~> 1.3'
31
+ s.add_dependency 'rails', Voyage::RAILS_VERSION
32
+
33
+ s.add_development_dependency 'rspec', '~> 3.2'
34
+ end
@@ -0,0 +1,64 @@
1
+ source "https://rubygems.org"
2
+
3
+ ruby "<%= Suspenders::RUBY_VERSION %>"
4
+
5
+ gem "autoprefixer-rails"
6
+ gem "bourbon", "5.0.0.beta.5"
7
+ gem "delayed_job_active_record"
8
+ gem "flutie"
9
+ gem "honeybadger"
10
+ gem "jquery-rails"
11
+ gem "neat", "~> 1.7.0"
12
+ gem "normalize-rails", "~> 3.0.0"
13
+ gem "pg"
14
+ gem "puma"
15
+ gem "rack-canonical-host"
16
+ gem "rails", "<%= Suspenders::RAILS_VERSION %>"
17
+ gem "recipient_interceptor"
18
+ gem "sass-rails", "~> 5.0"
19
+ gem "simple_form"
20
+ gem "skylight"
21
+ gem "sprockets", ">= 3.0.0"
22
+ gem "sprockets-es6"
23
+ gem "suspenders"
24
+ gem "title"
25
+ gem "uglifier"
26
+
27
+ group :development do
28
+ gem "quiet_assets"
29
+ gem "spring"
30
+ gem "spring-commands-rspec"
31
+ gem "web-console"
32
+ end
33
+
34
+ group :development, :test do
35
+ gem "awesome_print"
36
+ gem "bullet"
37
+ gem "bundler-audit", ">= 0.5.0", require: false
38
+ gem "dotenv-rails"
39
+ gem "factory_girl_rails"
40
+ gem "pry-byebug"
41
+ gem "pry-rails"
42
+ gem "refills"
43
+ gem "rspec-rails", "~> 3.4.0"
44
+ end
45
+
46
+ group :development, :staging do
47
+ gem "rack-mini-profiler", require: false
48
+ end
49
+
50
+ group :test do
51
+ gem "capybara-webkit"
52
+ gem "database_cleaner"
53
+ gem "formulaic"
54
+ gem "launchy"
55
+ gem "shoulda-matchers"
56
+ gem "simplecov", require: false
57
+ gem "timecop"
58
+ gem "webmock"
59
+ end
60
+
61
+ group :staging, :production do
62
+ gem "rack-timeout"
63
+ gem "rails_stdout_logging"
64
+ end
@@ -0,0 +1,2 @@
1
+ web: bundle exec puma -p $PORT -C ./config/puma.rb
2
+ worker: bundle exec rake jobs:work
@@ -0,0 +1,28 @@
1
+ # <%= app_name.humanize %>
2
+
3
+ ## Getting Started
4
+
5
+ After you have cloned this repo, run this setup script to set up your machine
6
+ with the necessary dependencies to run and test this app:
7
+
8
+ % ./bin/setup
9
+
10
+ It assumes you have a machine equipped with Ruby, Postgres, etc. If not, set up
11
+ your machine with [this script].
12
+
13
+ [this script]: https://github.com/thoughtbot/laptop
14
+
15
+ After setting up, you can run the application using [Heroku Local]:
16
+
17
+ % heroku local
18
+
19
+ [Heroku Local]: https://devcenter.heroku.com/articles/heroku-local
20
+
21
+ ## Guidelines
22
+
23
+ Use the following guides for getting things done, programming well, and
24
+ programming in style.
25
+
26
+ * [Protocol](http://github.com/thoughtbot/guides/blob/master/protocol)
27
+ * [Best Practices](http://github.com/thoughtbot/guides/blob/master/best-practices)
28
+ * [Style](http://github.com/thoughtbot/guides/blob/master/style)
@@ -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 Rails.env.test? %>
2
+ <style type="text/css">
3
+ * {
4
+ transition-property: none !important;
5
+ }
6
+ </style>
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,42 @@
1
+ {
2
+ "name":"<%= app_name.dasherize %>",
3
+ "scripts":{},
4
+ "env":{
5
+ "APPLICATION_HOST":{
6
+ "required":true
7
+ },
8
+ "EMAIL_RECIPIENTS":{
9
+ "required":true
10
+ },
11
+ "HEROKU_APP_NAME": {
12
+ "required":true
13
+ },
14
+ "HEROKU_PARENT_APP_NAME": {
15
+ "required":true
16
+ },
17
+ "RACK_ENV":{
18
+ "required":true
19
+ },
20
+ "SECRET_KEY_BASE":{
21
+ "generator":"secret"
22
+ },
23
+ "SMTP_ADDRESS":{
24
+ "required":true
25
+ },
26
+ "SMTP_DOMAIN":{
27
+ "required":true
28
+ },
29
+ "SMTP_PASSWORD":{
30
+ "required":true
31
+ },
32
+ "SMTP_USERNAME":{
33
+ "required":true
34
+ },
35
+ "WEB_CONCURRENCY":{
36
+ "required":true
37
+ }
38
+ },
39
+ "addons":[
40
+ "heroku-postgresql"
41
+ ]
42
+ }
@@ -0,0 +1,9 @@
1
+ @charset "utf-8";
2
+
3
+ @import "normalize-rails";
4
+
5
+ @import "bourbon";
6
+ @import "neat";
7
+
8
+ @import "base/base";
9
+ @import "refills/flashes";
@@ -0,0 +1,12 @@
1
+ #!/bin/sh
2
+
3
+ # Run this script to deploy the app to Heroku.
4
+
5
+ set -e
6
+
7
+ branch="$(git symbolic-ref HEAD --short)"
8
+ target="${1:-staging}"
9
+
10
+ git push "$target" "$branch:master"
11
+ heroku run rake db:migrate --exit-code --remote "$target"
12
+ heroku restart --remote "$target"
@@ -0,0 +1,21 @@
1
+ #!/bin/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
+ gem install bundler --conservative
11
+ bundle check || bundle install
12
+
13
+ # Set up database and add any development seed data
14
+ bin/rake dev:prime
15
+
16
+ # Add binstubs to PATH via export PATH=".git/safe/../../bin:$PATH" in ~/.zshenv
17
+ mkdir -p .git/safe
18
+
19
+ # Only if this isn't CI
20
+ # if [ -z "$CI" ]; then
21
+ # fi