cosmit-suspenders 1.36.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) 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 +51 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +21 -0
  8. data/NEWS.md +475 -0
  9. data/README.md +226 -0
  10. data/RELEASING.md +19 -0
  11. data/Rakefile +8 -0
  12. data/bin/rake +16 -0
  13. data/bin/rspec +16 -0
  14. data/bin/setup +13 -0
  15. data/bin/suspenders +18 -0
  16. data/lib/suspenders/actions.rb +33 -0
  17. data/lib/suspenders/adapters/heroku.rb +125 -0
  18. data/lib/suspenders/app_builder.rb +512 -0
  19. data/lib/suspenders/generators/app_generator.rb +254 -0
  20. data/lib/suspenders/version.rb +5 -0
  21. data/lib/suspenders.rb +5 -0
  22. data/spec/adapters/heroku_spec.rb +52 -0
  23. data/spec/fakes/bin/heroku +5 -0
  24. data/spec/fakes/bin/hub +5 -0
  25. data/spec/features/github_spec.rb +15 -0
  26. data/spec/features/heroku_spec.rb +93 -0
  27. data/spec/features/new_project_spec.rb +215 -0
  28. data/spec/spec_helper.rb +20 -0
  29. data/spec/support/fake_github.rb +21 -0
  30. data/spec/support/fake_heroku.rb +53 -0
  31. data/spec/support/suspenders.rb +58 -0
  32. data/suspenders.gemspec +37 -0
  33. data/templates/Gemfile.erb +63 -0
  34. data/templates/Procfile +1 -0
  35. data/templates/README.md.erb +64 -0
  36. data/templates/_flash.html.slim +6 -0
  37. data/templates/_javascript.html.slim +29 -0
  38. data/templates/action_mailer.rb +5 -0
  39. data/templates/app.json.erb +40 -0
  40. data/templates/application.scss +6 -0
  41. data/templates/bin_deploy +12 -0
  42. data/templates/bin_setup +21 -0
  43. data/templates/bin_setup_review_app.erb +19 -0
  44. data/templates/browserslist +4 -0
  45. data/templates/bundler_audit.rake +12 -0
  46. data/templates/capybara_webkit.rb +5 -0
  47. data/templates/circle.yml.erb +6 -0
  48. data/templates/config_locales_en.yml.erb +19 -0
  49. data/templates/database_cleaner_rspec.rb +21 -0
  50. data/templates/dev.rake +12 -0
  51. data/templates/disable_xml_params.rb +1 -0
  52. data/templates/dotfiles/.ctags +2 -0
  53. data/templates/dotfiles/.env +13 -0
  54. data/templates/errors.rb +34 -0
  55. data/templates/factories.rb +2 -0
  56. data/templates/factory_girl_rspec.rb +3 -0
  57. data/templates/hound.yml +14 -0
  58. data/templates/i18n.rb +3 -0
  59. data/templates/json_encoding.rb +1 -0
  60. data/templates/newrelic.yml.erb +34 -0
  61. data/templates/postgresql_database.yml.erb +21 -0
  62. data/templates/rack_mini_profiler.rb +5 -0
  63. data/templates/rails_helper.rb +22 -0
  64. data/templates/secrets.yml +15 -0
  65. data/templates/shoulda_matchers_config_rspec.rb +6 -0
  66. data/templates/smtp.rb +9 -0
  67. data/templates/spec_helper.rb +29 -0
  68. data/templates/staging.rb +5 -0
  69. data/templates/suspenders_gitignore +15 -0
  70. data/templates/suspenders_layout.html.slim.erb +24 -0
  71. metadata +213 -0
data/README.md ADDED
@@ -0,0 +1,226 @@
1
+ # Suspenders
2
+ <!-- [![BuildStatus](https://secure.travis-ci.org/cosmitdev/suspenders.svg?branch=master)](http://travis-ci.org/cosmitdev/suspenders) -->
3
+
4
+ Suspenders is the base Rails application used at
5
+ [COSMIT](http://cosmit.me/) to create powerful applications with less effort.
6
+
7
+ ![Suspenders boy](http://media.tumblr.com/1TEAMALpseh5xzf0Jt6bcwSMo1_400.png)
8
+
9
+ ## Installation
10
+
11
+ First install the suspenders gem:
12
+
13
+ gem install suspenders http://github.com/cosmitdev/suspenders.git
14
+
15
+ Then run:
16
+
17
+ suspenders [your_project_name]
18
+
19
+ This will create a Rails app in `[your_project_name]` using the latest version of Rails.
20
+
21
+ ### Associated services
22
+
23
+ * Enable [Circle CI](https://circleci.com/) Continuous Integration
24
+ * Enable [GitHub auto deploys to Heroku staging and review
25
+ apps](https://dashboard.heroku.com/apps/app-name-staging/deploy/github).
26
+
27
+ ## Gemfile
28
+
29
+ To see the latest and greatest gems, look at Suspenders'
30
+ [Gemfile](templates/Gemfile.erb), which will be appended to the default
31
+ generated projectname/Gemfile.
32
+
33
+ It includes application gems like:
34
+
35
+ * [Delayed Job](https://github.com/collectiveidea/delayed_job) for background
36
+ processing (for default this is disabled to avoid expenses on Heroku)
37
+ * [jQuery Rails](https://github.com/rails/jquery-rails) for jQuery
38
+ * [Normalize](https://necolas.github.io/normalize.css/) for resetting browser styles
39
+ * [Postgres](https://github.com/ged/ruby-pg) for access to the Postgres database
40
+ * [Rack Timeout](https://github.com/heroku/rack-timeout) to abort requests that are
41
+ taking too long
42
+ * [Recipient Interceptor](https://github.com/croaky/recipient_interceptor) to
43
+ avoid accidentally sending emails to real people from staging
44
+ * [Simple Form](https://github.com/plataformatec/simple_form) for form markup
45
+ and style
46
+ * [Passenger](https://github.com/phusion/passenger) to serve HTTP requests
47
+ * [Slim Rails](https://github.com/slim-template/slim-rails) For better HTML code on your files
48
+ * [Active Admin](https://github.com/activeadmin/activeadmin) For administrative interfaces
49
+ * [Twitter Boostrap SASS](http://github.com/twbs/bootstrap-sass) For, of course, Twitter Bootstrap Framework
50
+ * [Meta Tags](https://github.com/kpumuk/meta-tags) SEO is important dude!
51
+ * [Coffee Rails](https://github.com/rails/coffee-rails) Adds support for .coffee files
52
+ * [Devise](https://github.com/plataformatec/devise) For awesome user authentications
53
+ * [InitJS](https://github.com/josemarluedke/initjs) Modularize the execution of your JS files
54
+ * [Font Awesome](https://github.com/bokmann/font-awesome-rails) Awesome Fonts!
55
+
56
+ And development gems like:
57
+
58
+ * [Dotenv](https://github.com/bkeepers/dotenv) for loading environment variables
59
+ * [Pry Rails](https://github.com/rweng/pry-rails) for interactively exploring
60
+ objects
61
+ * [Bullet](https://github.com/flyerhzm/bullet) for help to kill N+1 queries and
62
+ unused eager loading
63
+ * [Bundler Audit](https://github.com/rubysec/bundler-audit) for scanning the
64
+ Gemfile for insecure dependencies based on published CVEs
65
+ * [Spring](https://github.com/rails/spring) for fast Rails actions via
66
+ pre-loading
67
+ * [Quiet Assets](https://github.com/evrone/quiet_assets) for muting assets
68
+ pipeline log messages
69
+ * [Thin](https://github.com/thin/thin) to serve HTTP requests
70
+
71
+ And testing gems like:
72
+
73
+ * [Capybara](https://github.com/jnicklas/capybara) and
74
+ [Capybara Webkit](https://github.com/thoughtbot/capybara-webkit) for
75
+ integration testing
76
+ * [Factory Girl](https://github.com/thoughtbot/factory_girl) for test data
77
+ * [Formulaic](https://github.com/thoughtbot/formulaic) for integration testing
78
+ HTML forms
79
+ * [RSpec](https://github.com/rspec/rspec) for unit testing
80
+ * [RSpec Mocks](https://github.com/rspec/rspec-mocks) for stubbing and spying
81
+ * [Shoulda Matchers](https://github.com/thoughtbot/shoulda-matchers) for common
82
+ RSpec matchers
83
+ * [Timecop](https://github.com/ferndopolis/timecop-console) for testing time
84
+
85
+ ## Other goodies
86
+
87
+ Suspenders also comes with:
88
+
89
+ * The [`./bin/setup`][setup] convention for new developer setup
90
+ * The `./bin/deploy` convention for deploying to Heroku
91
+ * Rails' flashes set up and in application layout
92
+ * A few nice time formats set up for localization
93
+ * `Rack::Deflater` to [compress responses with Gzip][compress]
94
+ * A [low database connection pool limit][pool]
95
+ * [Safe binstubs][binstub]
96
+ * [t() and l() in specs without prefixing with I18n][i18n]
97
+ * An automatically-created `SECRET_KEY_BASE` environment variable in all
98
+ environments
99
+ * Configuration for [CircleCI][circle] Continuous Integration (tests)
100
+ * Configuration for [Hound][hound] Continuous Integration (style)
101
+ * The analytics adapter [Segment][segment] (and therefore config for Google
102
+ Analytics, Intercom, Facebook Ads, Twitter Ads, etc.)
103
+ * Pure Google Analytics script if you don't want to spend money with Segment
104
+ * Google Web Fonts script is already included on "application" layout
105
+
106
+ [setup]: https://robots.thoughtbot.com/bin-setup
107
+ [compress]: https://robots.thoughtbot.com/content-compression-with-rack-deflater
108
+ [pool]: https://devcenter.heroku.com/articles/concurrency-and-database-connections
109
+ [binstub]: https://github.com/thoughtbot/suspenders/pull/282
110
+ [i18n]: https://github.com/thoughtbot/suspenders/pull/304
111
+ [circle]: https://circleci.com/docs
112
+ [hound]: https://houndci.com
113
+ [segment]: https://segment.com
114
+
115
+ ## Heroku
116
+
117
+ You can optionally create Heroku staging and production apps:
118
+
119
+ suspenders app --heroku true
120
+
121
+ This:
122
+
123
+ * Creates a staging and production Heroku app
124
+ * Sets them as `staging` and `production` Git remotes
125
+ * Configures staging with `RACK_ENV` environment variable set
126
+ to `staging`
127
+ * Adds the [Rails Stdout Logging][logging-gem] gem
128
+ to configure the app to log to standard out,
129
+ which is how [Heroku's logging][heroku-logging] works.
130
+ * Creates a [Heroku Pipeline] for review apps
131
+
132
+ [logging-gem]: https://github.com/heroku/rails_stdout_logging
133
+ [heroku-logging]: https://devcenter.heroku.com/articles/logging#writing-to-your-log
134
+ [Heroku Pipeline]: https://devcenter.heroku.com/articles/pipelines
135
+
136
+ You can optionally specify alternate Heroku flags:
137
+
138
+ suspenders app \
139
+ --heroku true \
140
+ --heroku-flags "--region eu --addons sendgrid,ssl"
141
+
142
+ See all possible Heroku flags:
143
+
144
+ heroku help create
145
+
146
+ ## Git
147
+
148
+ This will initialize a new git repository for your Rails app. You can
149
+ bypass this with the `--skip-git` option:
150
+
151
+ suspenders app --skip-git true
152
+
153
+ ## GitHub
154
+
155
+ You can optionally create a GitHub repository for the suspended Rails app. It
156
+ requires that you have [Hub](https://github.com/github/hub) on your system:
157
+
158
+ curl http://hub.github.com/standalone -sLo ~/bin/hub && chmod +x ~/bin/hub
159
+ suspenders app --github organization/project
160
+
161
+ This has the same effect as running:
162
+
163
+ hub create organization/project
164
+
165
+ ## Spring
166
+
167
+ Suspenders uses [spring](https://github.com/rails/spring) by default.
168
+ It makes Rails applications load faster, but it might introduce confusing issues
169
+ around stale code not being refreshed.
170
+ If you think your application is running old code, run `spring stop`.
171
+ And if you'd rather not use spring, add `DISABLE_SPRING=1` to your login file.
172
+
173
+ ## Dependencies
174
+
175
+ Suspenders requires the latest version of Ruby.
176
+
177
+ Some gems included in Suspenders have native extensions. You should have GCC
178
+ installed on your machine before generating an app with Suspenders.
179
+
180
+ Use [OS X GCC Installer](https://github.com/kennethreitz/osx-gcc-installer/) for
181
+ Snow Leopard (OS X 10.6).
182
+
183
+ Use [Command Line Tools for XCode](https://developer.apple.com/downloads/index.action)
184
+ for Lion (OS X 10.7) or Mountain Lion (OS X 10.8).
185
+
186
+ We use [Capybara Webkit](https://github.com/thoughtbot/capybara-webkit) for
187
+ full-stack JavaScript integration testing. It requires QT. Instructions for
188
+ installing QT are
189
+ [here](https://github.com/thoughtbot/capybara-webkit/wiki/Installing-Qt-and-compiling-capybara-webkit).
190
+
191
+ PostgreSQL needs to be installed and running for the `db:create` rake task.
192
+
193
+ ## Issues
194
+
195
+ If you have problems, please create a
196
+ [GitHub Issue](https://github.com/cosmitdev/suspenders/issues).
197
+
198
+ ## Contributing
199
+
200
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
201
+
202
+ Thank you, [contributors]!
203
+
204
+ [contributors]: https://github.com/cosmitdev/suspenders/graphs/contributors
205
+
206
+ ## License
207
+
208
+ Suspenders is Copyright © 2008-2016 thoughtbot.
209
+ It is free software,
210
+ and may be redistributed under the terms specified in the [LICENSE] file.
211
+
212
+ [LICENSE]: LICENSE
213
+
214
+ ## Thanks to: Thoughtbot
215
+
216
+ ![thoughtbot](https://thoughtbot.com/logo.png)
217
+
218
+ Suspenders is maintained and funded by thoughtbot, inc.
219
+ The names and logos for thoughtbot are trademarks of thoughtbot, inc.
220
+
221
+ We love open source software!
222
+ See [our other projects][community].
223
+ We are [available for hire][hire].
224
+
225
+ [community]: https://thoughtbot.com/community?utm_source=github
226
+ [hire]: https://thoughtbot.com?utm_source=github
data/RELEASING.md ADDED
@@ -0,0 +1,19 @@
1
+ # Releasing
2
+
3
+ 1. Update `lib/suspenders/version.rb` file accordingly.
4
+ 2. Update `NEWS.md` to reflect the changes since last release.
5
+ 3. Commit changes. There shouldn't be code changes, and thus CI doesn't need to
6
+ run, you can then add `[ci skip]` to the commit message.
7
+ 4. Tag the release: `git tag vVERSION -a`. The tag message should contain the
8
+ appropriate `NEWS.md` subsection.
9
+ 5. Push changes: `git push --tags`
10
+ 6. Build and publish to rubygems:
11
+ ```bash
12
+ gem build suspenders.gemspec
13
+ gem push suspenders-*.gem
14
+ ```
15
+
16
+ 7. Add a new GitHub release:
17
+ https://github.com/thoughtbot/suspenders/releases/new?tag=vVERSION
18
+ 8. Announce the new release, making sure to say "thank you" to the contributors
19
+ who helped shape this version!
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/setup'
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:rspec)
6
+
7
+ desc 'Run the test suite'
8
+ task :default => :rspec
data/bin/rake ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rake' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rake', 'rake')
data/bin/rspec ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rspec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rspec-core', 'rspec')
data/bin/setup ADDED
@@ -0,0 +1,13 @@
1
+ #!/bin/sh
2
+
3
+ # Run this script immediately after cloning the codebase.
4
+
5
+ # Exit if any subcommand fails
6
+ set -e
7
+
8
+ # Set up Ruby dependencies via Bundler
9
+ bundle install
10
+
11
+ # Add binstubs to PATH in ~/.zshenv like this:
12
+ # export PATH=".git/safe/../../bin:$PATH"
13
+ mkdir -p .git/safe
data/bin/suspenders ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pathname'
3
+
4
+ source_path = (Pathname.new(__FILE__).dirname + '../lib').expand_path
5
+ $LOAD_PATH << source_path
6
+
7
+ require 'suspenders'
8
+
9
+ if ['-v', '--version'].include? ARGV[0]
10
+ puts Suspenders::VERSION
11
+ exit 0
12
+ end
13
+
14
+ templates_root = File.expand_path(File.join("..", "templates"), File.dirname(__FILE__))
15
+ Suspenders::AppGenerator.source_root templates_root
16
+ Suspenders::AppGenerator.source_paths << Rails::Generators::AppGenerator.source_root << templates_root
17
+
18
+ Suspenders::AppGenerator.start
@@ -0,0 +1,33 @@
1
+ module Suspenders
2
+ module Actions
3
+ def replace_in_file(relative_path, find, replace)
4
+ path = File.join(destination_root, relative_path)
5
+ contents = IO.read(path)
6
+ unless contents.gsub!(find, replace)
7
+ raise "#{find.inspect} not found in #{relative_path}"
8
+ end
9
+ File.open(path, "w") { |file| file.write(contents) }
10
+ end
11
+
12
+ def action_mailer_host(rails_env, host)
13
+ config = "config.action_mailer.default_url_options = { host: #{host} }"
14
+ configure_environment(rails_env, config)
15
+ end
16
+
17
+ def configure_application_file(config)
18
+ inject_into_file(
19
+ "config/application.rb",
20
+ "\n\n #{config}",
21
+ before: "\n end"
22
+ )
23
+ end
24
+
25
+ def configure_environment(rails_env, config)
26
+ inject_into_file(
27
+ "config/environments/#{rails_env}.rb",
28
+ "\n\n #{config}",
29
+ before: "\nend"
30
+ )
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,125 @@
1
+ module Suspenders
2
+ module Adapters
3
+ class Heroku
4
+ def initialize(app_builder)
5
+ @app_builder = app_builder
6
+ end
7
+
8
+ def set_heroku_remotes
9
+ remotes = <<-SHELL.strip_heredoc
10
+ #{command_to_join_heroku_app('staging')}
11
+ #{command_to_join_heroku_app('production')}
12
+
13
+ git config heroku.remote staging
14
+ SHELL
15
+
16
+ app_builder.append_file "bin/setup", remotes
17
+ end
18
+
19
+ def set_up_heroku_specific_gems
20
+ app_builder.inject_into_file(
21
+ "Gemfile",
22
+ %{\n\s\sgem "rails_stdout_logging"},
23
+ after: /group :staging, :production do/,
24
+ )
25
+ end
26
+
27
+ def create_staging_heroku_app(flags)
28
+ rack_env = "RACK_ENV=staging"
29
+ app_name = heroku_app_name_for("staging")
30
+
31
+ run_toolbelt_command "create #{app_name} #{flags}", "staging"
32
+ run_toolbelt_command "config:add #{rack_env}", "staging"
33
+ end
34
+
35
+ def create_production_heroku_app(flags)
36
+ app_name = heroku_app_name_for("production")
37
+
38
+ run_toolbelt_command "create #{app_name} #{flags}", "production"
39
+ end
40
+
41
+ def set_heroku_rails_secrets
42
+ %w(staging production).each do |environment|
43
+ run_toolbelt_command(
44
+ "config:add SECRET_KEY_BASE=#{generate_secret}",
45
+ environment,
46
+ )
47
+ end
48
+ end
49
+
50
+ def provide_review_apps_setup_script
51
+ app_builder.template(
52
+ "bin_setup_review_app.erb",
53
+ "bin/setup_review_app",
54
+ force: true,
55
+ )
56
+ app_builder.run "chmod a+x bin/setup_review_app"
57
+ end
58
+
59
+ def create_heroku_pipelines_config_file
60
+ app_builder.template "app.json.erb", "app.json"
61
+ end
62
+
63
+ def create_heroku_pipeline
64
+ pipelines_plugin = `heroku plugins | grep pipelines`
65
+ if pipelines_plugin.empty?
66
+ puts "You need heroku pipelines plugin. Run: heroku plugins:install heroku-pipelines"
67
+ exit 1
68
+ end
69
+
70
+ heroku_app_name = app_builder.app_name.dasherize
71
+ run_toolbelt_command(
72
+ "pipelines:create #{heroku_app_name} \
73
+ -a #{heroku_app_name}-staging --stage staging",
74
+ "staging",
75
+ )
76
+
77
+ run_toolbelt_command(
78
+ "pipelines:add #{heroku_app_name} \
79
+ -a #{heroku_app_name}-production --stage production",
80
+ "production",
81
+ )
82
+ end
83
+
84
+ def set_heroku_serve_static_files
85
+ %w(staging production).each do |environment|
86
+ run_toolbelt_command(
87
+ "config:add RAILS_SERVE_STATIC_FILES=true",
88
+ environment,
89
+ )
90
+ end
91
+ end
92
+
93
+ private
94
+
95
+ attr_reader :app_builder
96
+
97
+ def command_to_join_heroku_app(environment)
98
+ heroku_app_name = heroku_app_name_for(environment)
99
+ <<-SHELL
100
+
101
+ if heroku join --app #{heroku_app_name} &> /dev/null; then
102
+ git remote add #{environment} git@heroku.com:#{heroku_app_name}.git || true
103
+ printf 'You are a collaborator on the "#{heroku_app_name}" Heroku app\n'
104
+ else
105
+ printf 'Ask for access to the "#{heroku_app_name}" Heroku app\n'
106
+ fi
107
+ SHELL
108
+ end
109
+
110
+ def heroku_app_name_for(environment)
111
+ "#{app_builder.app_name.dasherize}-#{environment}"
112
+ end
113
+
114
+ def generate_secret
115
+ SecureRandom.hex(64)
116
+ end
117
+
118
+ def run_toolbelt_command(command, environment)
119
+ app_builder.run(
120
+ "heroku #{command} --remote #{environment}",
121
+ )
122
+ end
123
+ end
124
+ end
125
+ end