diff --git a/.gitignore b/.gitignore index b571213..1a572b5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,14 @@ -.DS_Store -.env +!.keep +*.DS_Store +*.swo +*.swp /.bundle -/.sass-cache -/build -/tmp -tags +/.env +/.foreman +/coverage/* +/db/*.sqlite3 +/log/* +/public/system +/public/assets +/tags +/tmp/* diff --git a/.ruby-version b/.ruby-version index 7ec1d6d..c043eea 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.1.0 +2.2.1 diff --git a/.sample.env b/.sample.env index 102817e..a194f48 100644 --- a/.sample.env +++ b/.sample.env @@ -1 +1,5 @@ -EVENTBRITE_ACCESS_TOKEN=changeme +# http://ddollar.github.com/foreman/ +ASSET_HOST=localhost:3000 +HOST=localhost:3000 +RACK_ENV=development +SECRET_KEY_BASE=development_secret diff --git a/.travis.yml b/.travis.yml index dfb8cdb..3ad0924 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,21 @@ -language: ruby -rvm: - - 2.1.0 +before_install: + - "echo '--colour' > ~/.rspec" + - "echo 'gem: --no-document' > ~/.gemrc" + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start +install: + - bin/setup +branches: + only: + - master +cache: + - bundler +language: + - ruby notifications: email: false +rvm: + - 2.2.1 +addons: + postgresql: "9.3" sudo: false diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..b952631 --- /dev/null +++ b/Gemfile @@ -0,0 +1,57 @@ +source "https://rubygems.org" + +ruby "2.2.1" + +gem "airbrake" +gem "autoprefixer-rails" +gem "bourbon", "~> 4.2.0" +gem "coffee-rails", "~> 4.1.0" +gem "delayed_job_active_record" +gem "email_validator" +gem "flutie" +gem "high_voltage" +gem "i18n-tasks" +gem "jquery-rails" +gem "neat", "~> 1.7.0" +gem "newrelic_rpm", ">= 3.9.8" +gem "normalize-rails", "~> 3.0.0" +gem "pg" +gem "rails", "4.2.1" +gem "recipient_interceptor" +gem "refills" +gem "sass-rails", "~> 5.0" +gem "simple_form" +gem "title" +gem "uglifier" +gem "unicorn" + +group :development do + gem "spring" + gem "spring-commands-rspec" + gem "web-console" +end + +group :development, :test do + gem "awesome_print" + gem "bundler-audit", require: false + gem "byebug" + gem "dotenv-rails" + gem "factory_girl_rails" + gem "pry-rails" + gem "rspec-rails", "~> 3.1.0" +end + +group :test do + gem "capybara-webkit", ">= 1.2.0" + gem "database_cleaner" + gem "formulaic" + gem "launchy" + gem "shoulda-matchers", require: false + gem "simplecov", require: false + gem "timecop" + gem "webmock" +end + +group :staging, :production do + gem "rack-timeout" +end diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..7934897 --- /dev/null +++ b/Procfile @@ -0,0 +1,2 @@ +web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb +worker: bundle exec rake jobs:work diff --git a/README.md b/README.md new file mode 100644 index 0000000..1eef235 --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# Railsbridgeboston dot org + +## Getting Started + +After you have cloned this repo, run this setup script to set up your machine +with the necessary dependencies to run and test this app: + + % ./bin/setup + +It assumes you have a machine equipped with Ruby, Postgres, etc. If not, set up +your machine with [this script]. + +[this script]: https://github.com/thoughtbot/laptop + +After setting up, you can run the application using [foreman]: + + % foreman start + +If you don't have `foreman`, see [Foreman's install instructions][foreman]. It +is [purposefully excluded from the project's `Gemfile`][exclude]. + +[foreman]: https://github.com/ddollar/foreman +[exclude]: https://github.com/ddollar/foreman/pull/437#issuecomment-41110407 + +## Guidelines + +Use the following guides for getting things done, programming well, and +programming in style. + +* [Protocol](http://github.com/thoughtbot/guides/blob/master/protocol) +* [Best Practices](http://github.com/thoughtbot/guides/blob/master/best-practices) +* [Style](http://github.com/thoughtbot/guides/blob/master/style) diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..4a77cd0 --- /dev/null +++ b/Rakefile @@ -0,0 +1,17 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require File.expand_path('../config/application', __FILE__) + +Rails.application.load_tasks +task(:default).clear +task default: [:spec] + +if defined? RSpec + task(:spec).clear + RSpec::Core::RakeTask.new(:spec) do |t| + t.verbose = false + end +end + +task default: "bundler:audit" diff --git a/app/assets/images/.keep b/app/assets/images/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js new file mode 100644 index 0000000..646c5ab --- /dev/null +++ b/app/assets/javascripts/application.js @@ -0,0 +1,15 @@ +// This is a manifest file that'll be compiled into application.js, which will include all the files +// listed below. +// +// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, +// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. +// +// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the +// compiled file. +// +// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details +// about supported directives. +// +//= require jquery +//= require jquery_ujs +//= require_tree . diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/stylesheets/application.css.scss new file mode 100644 index 0000000..e701338 --- /dev/null +++ b/app/assets/stylesheets/application.css.scss @@ -0,0 +1,8 @@ +@charset "utf-8"; + +@import "normalize-rails"; +@import "bourbon"; +@import "base/grid-settings"; +@import "neat"; +@import "base/base"; +@import "refills/flashes"; diff --git a/app/assets/stylesheets/base/_base.scss b/app/assets/stylesheets/base/_base.scss new file mode 100644 index 0000000..ddc350d --- /dev/null +++ b/app/assets/stylesheets/base/_base.scss @@ -0,0 +1,15 @@ +// Bitters 1.0.0 +// http://bitters.bourbon.io +// Copyright 2013-2015 thoughtbot, inc. +// MIT License + +@import "variables"; + +// Neat Settings -- uncomment if using Neat -- must be imported before Neat +// @import "grid-settings"; + +@import "buttons"; +@import "forms"; +@import "lists"; +@import "tables"; +@import "typography"; diff --git a/app/assets/stylesheets/base/_buttons.scss b/app/assets/stylesheets/base/_buttons.scss new file mode 100644 index 0000000..f902f60 --- /dev/null +++ b/app/assets/stylesheets/base/_buttons.scss @@ -0,0 +1,31 @@ +#{$all-button-inputs}, +button { + @include appearance(none); + -webkit-font-smoothing: antialiased; + background-color: $action-color; + border-radius: $base-border-radius; + border: none; + color: #fff; + cursor: pointer; + display: inline-block; + font-family: $base-font-family; + font-size: $base-font-size; + font-weight: 600; + line-height: 1; + padding: 0.75em 1em; + text-decoration: none; + user-select: none; + vertical-align: middle; + white-space: nowrap; + + &:hover, + &:focus { + background-color: darken($action-color, 15%); + color: #fff; + } + + &:disabled { + cursor: not-allowed; + opacity: 0.5; + } +} diff --git a/app/assets/stylesheets/base/_forms.scss b/app/assets/stylesheets/base/_forms.scss new file mode 100644 index 0000000..db4a796 --- /dev/null +++ b/app/assets/stylesheets/base/_forms.scss @@ -0,0 +1,78 @@ +fieldset { + background-color: lighten($base-border-color, 10%); + border: $base-border; + margin: 0 0 $small-spacing; + padding: $base-spacing; +} + +input, +label, +select { + display: block; + font-family: $base-font-family; + font-size: $base-font-size; +} + +label { + font-weight: 600; + margin-bottom: $small-spacing / 2; + + &.required::after { + content: "*"; + } + + abbr { + display: none; + } +} + +#{$all-text-inputs}, +select[multiple=multiple], +textarea { + background-color: $base-background-color; + border: $base-border; + border-radius: $base-border-radius; + box-shadow: $form-box-shadow; + box-sizing: border-box; + font-family: $base-font-family; + font-size: $base-font-size; + margin-bottom: $base-spacing / 2; + padding: $base-spacing / 3; + transition: border-color; + width: 100%; + + &:hover { + border-color: darken($base-border-color, 10%); + } + + &:focus { + border-color: $action-color; + box-shadow: $form-box-shadow-focus; + outline: none; + } +} + +textarea { + resize: vertical; +} + +input[type="search"] { + @include appearance(none); +} + +input[type="checkbox"], +input[type="radio"] { + display: inline; + margin-right: $small-spacing / 2; +} + +input[type="file"] { + padding-bottom: $small-spacing; + width: 100%; +} + +select { + margin-bottom: $base-spacing; + max-width: 100%; + width: auto; +} diff --git a/app/assets/stylesheets/base/_grid-settings.scss b/app/assets/stylesheets/base/_grid-settings.scss new file mode 100644 index 0000000..c42bdaf --- /dev/null +++ b/app/assets/stylesheets/base/_grid-settings.scss @@ -0,0 +1,14 @@ +@import "neat-helpers"; // or "../neat/neat-helpers" when not in Rails + +// Neat Overrides +// $column: 90px; +// $gutter: 30px; +// $grid-columns: 12; +// $max-width: em(1088); + +// Neat Breakpoints +$medium-screen: em(640); +$large-screen: em(860); + +$medium-screen-up: new-breakpoint(min-width $medium-screen 4); +$large-screen-up: new-breakpoint(min-width $large-screen 8); diff --git a/app/assets/stylesheets/base/_lists.scss b/app/assets/stylesheets/base/_lists.scss new file mode 100644 index 0000000..c989d90 --- /dev/null +++ b/app/assets/stylesheets/base/_lists.scss @@ -0,0 +1,31 @@ +ul, +ol { + list-style-type: none; + margin: 0; + padding: 0; + + &%default-ul { + list-style-type: disc; + margin-bottom: $small-spacing; + padding-left: $base-spacing; + } + + &%default-ol { + list-style-type: decimal; + margin-bottom: $small-spacing; + padding-left: $base-spacing; + } +} + +dl { + margin-bottom: $small-spacing; + + dt { + font-weight: bold; + margin-top: $small-spacing; + } + + dd { + margin: 0; + } +} diff --git a/app/assets/stylesheets/base/_tables.scss b/app/assets/stylesheets/base/_tables.scss new file mode 100644 index 0000000..8c5cc31 --- /dev/null +++ b/app/assets/stylesheets/base/_tables.scss @@ -0,0 +1,25 @@ +table { + @include font-feature-settings("kern", "liga", "tnum"); + border-collapse: collapse; + margin: $small-spacing 0; + table-layout: fixed; + width: 100%; +} + +th { + border-bottom: 1px solid darken($base-border-color, 15%); + font-weight: 600; + padding: $small-spacing 0; + text-align: left; +} + +td { + border-bottom: $base-border; + padding: $small-spacing 0; +} + +tr, +td, +th { + vertical-align: middle; +} diff --git a/app/assets/stylesheets/base/_typography.scss b/app/assets/stylesheets/base/_typography.scss new file mode 100644 index 0000000..358559c --- /dev/null +++ b/app/assets/stylesheets/base/_typography.scss @@ -0,0 +1,55 @@ +body { + @include font-feature-settings("kern", "liga", "pnum"); + -webkit-font-smoothing: antialiased; + color: $base-font-color; + font-family: $base-font-family; + font-size: $base-font-size; + line-height: $base-line-height; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: $heading-font-family; + font-size: $base-font-size; + line-height: $heading-line-height; + margin: 0 0 $small-spacing; +} + +p { + margin: 0 0 $small-spacing; +} + +a { + color: $action-color; + text-decoration: none; + transition: color 0.1s linear; + + &:active, + &:focus, + &:hover { + color: darken($action-color, 15%); + } + + &:active, + &:focus { + outline: none; + } +} + +hr { + border-bottom: $base-border; + border-left: none; + border-right: none; + border-top: none; + margin: $base-spacing 0; +} + +img, +picture { + margin: 0; + max-width: 100%; +} diff --git a/app/assets/stylesheets/base/_variables.scss b/app/assets/stylesheets/base/_variables.scss new file mode 100644 index 0000000..7594759 --- /dev/null +++ b/app/assets/stylesheets/base/_variables.scss @@ -0,0 +1,35 @@ +// Typography +$base-font-family: $helvetica; +$heading-font-family: $base-font-family; + +// Font Sizes +$base-font-size: 1em; + +// Line height +$base-line-height: 1.5; +$heading-line-height: 1.2; + +// Other Sizes +$base-border-radius: 3px; +$base-spacing: $base-line-height * 1em; +$small-spacing: $base-spacing / 2; +$base-z-index: 0; + +// Colors +$blue: #477dca; +$dark-gray: #333; +$medium-gray: #999; +$light-gray: #ddd; + +// Font Colors +$base-background-color: #fff; +$base-font-color: $dark-gray; +$action-color: $blue; + +// Border +$base-border-color: $light-gray; +$base-border: 1px solid $base-border-color; + +// Forms +$form-box-shadow: inset 0 1px 3px rgba(#000, 0.06); +$form-box-shadow-focus: $form-box-shadow, 0 0 5px adjust-color($action-color, $lightness: -5%, $alpha: -0.3); diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 0000000..d83690e --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,5 @@ +class ApplicationController < ActionController::Base + # Prevent CSRF attacks by raising an exception. + # For APIs, you may want to use :null_session instead. + protect_from_forgery with: :exception +end diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb new file mode 100644 index 0000000..de6be79 --- /dev/null +++ b/app/helpers/application_helper.rb @@ -0,0 +1,2 @@ +module ApplicationHelper +end diff --git a/app/helpers/flashes_helper.rb b/app/helpers/flashes_helper.rb new file mode 100644 index 0000000..bef014f --- /dev/null +++ b/app/helpers/flashes_helper.rb @@ -0,0 +1,5 @@ +module FlashesHelper + def user_facing_flashes + flash.to_hash.slice("alert", "error", "notice", "success") + end +end diff --git a/app/mailers/.keep b/app/mailers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/models/.keep b/app/models/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/views/application/_analytics.html.erb b/app/views/application/_analytics.html.erb new file mode 100644 index 0000000..5ae6470 --- /dev/null +++ b/app/views/application/_analytics.html.erb @@ -0,0 +1,7 @@ +<% if ENV["SEGMENT_KEY"] %> + +<% end %> diff --git a/app/views/application/_flashes.html.erb b/app/views/application/_flashes.html.erb new file mode 100644 index 0000000..3c6a280 --- /dev/null +++ b/app/views/application/_flashes.html.erb @@ -0,0 +1,7 @@ +<% if flash.any? %> +
+ <% user_facing_flashes.each do |key, value| -%> +
<%= value %>
+ <% end -%> +
+<% end %> diff --git a/app/views/application/_javascript.html.erb b/app/views/application/_javascript.html.erb new file mode 100644 index 0000000..a738f79 --- /dev/null +++ b/app/views/application/_javascript.html.erb @@ -0,0 +1,12 @@ +<%= javascript_include_tag :application %> + +<%= yield :javascript %> + +<%= render "analytics" %> + +<% if Rails.env.test? %> + <%= javascript_tag do %> + $.fx.off = true; + $.ajaxSetup({ async: false }); + <% end %> +<% end %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb new file mode 100644 index 0000000..3e38f12 --- /dev/null +++ b/app/views/layouts/application.html.erb @@ -0,0 +1,21 @@ + + + + + + + <%# + Configure default and controller-, and view-specific titles in + config/locales/en.yml. For more see: + https://github.com/calebthompson/title#usage + %> + <%= title %> + <%= stylesheet_link_tag :application, media: "all" %> + <%= csrf_meta_tags %> + + + <%= render "flashes" -%> + <%= yield %> + <%= render "javascript" %> + + diff --git a/app/views/pages/.keep b/app/views/pages/.keep new file mode 100644 index 0000000..e69de29 diff --git a/bin/bundle b/bin/bundle new file mode 100755 index 0000000..66e9889 --- /dev/null +++ b/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/bin/rails b/bin/rails new file mode 100755 index 0000000..5191e69 --- /dev/null +++ b/bin/rails @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +APP_PATH = File.expand_path('../../config/application', __FILE__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/bin/rake b/bin/rake new file mode 100755 index 0000000..1724048 --- /dev/null +++ b/bin/rake @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/bin/setup b/bin/setup new file mode 100755 index 0000000..afe9811 --- /dev/null +++ b/bin/setup @@ -0,0 +1,36 @@ +#!/usr/bin/env sh + +# Set up Rails app. Run this script immediately after cloning the codebase. +# https://github.com/thoughtbot/guides/tree/master/protocol + +# Exit if any subcommand fails +set -e + +# Set up Ruby dependencies via Bundler +gem install bundler --conservative +bundle check || bundle install + +# Set up configurable environment variables +if [ ! -f .env ]; then + cp .sample.env .env +fi + +# Set up database and add any development seed data +bundle exec rake db:setup dev:prime + +# Add binstubs to PATH via export PATH=".git/safe/../../bin:$PATH" in ~/.zshenv +mkdir -p .git/safe + +# Pick a port for Foreman +if ! grep --quiet --no-messages --fixed-strings 'port' .foreman; then + printf 'port: 4000\n' >> .foreman +fi + +if ! command -v foreman > /dev/null; then + printf 'Foreman is not installed.\n' + printf 'See https://github.com/ddollar/foreman for install instructions.\n' +fi + +# Only if this isn't CI +# if [ -z "$CI" ]; then +# fi diff --git a/browserslist b/browserslist new file mode 100644 index 0000000..1e8f87e --- /dev/null +++ b/browserslist @@ -0,0 +1,4 @@ +Last 2 versions +Explorer >= 9 +iOS >= 7.1 +Android >= 4.4 diff --git a/config.ru b/config.ru new file mode 100644 index 0000000..bd83b25 --- /dev/null +++ b/config.ru @@ -0,0 +1,4 @@ +# This file is used by Rack-based servers to start the application. + +require ::File.expand_path('../config/environment', __FILE__) +run Rails.application diff --git a/config/application.rb b/config/application.rb new file mode 100644 index 0000000..4d9a84c --- /dev/null +++ b/config/application.rb @@ -0,0 +1,50 @@ +require File.expand_path('../boot', __FILE__) + +require "rails" +# Pick the frameworks you want: +require "active_model/railtie" +require "active_job/railtie" +require "active_record/railtie" +require "action_controller/railtie" +require "action_mailer/railtie" +require "action_view/railtie" +require "sprockets/railtie" +# require "rails/test_unit/railtie" + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module RailsbridgebostonDotOrg + class Application < Rails::Application + config.i18n.enforce_available_locales = true + + config.generators do |generate| + generate.helper false + generate.javascript_engine false + generate.request_specs false + generate.routing_specs false + generate.stylesheets false + generate.test_framework :rspec + generate.view_specs false + end + + config.action_controller.action_on_unpermitted_parameters = :raise + # Settings in config/environments/* take precedence over those specified here. + # Application configuration should go into files in config/initializers + # -- all .rb files in that directory are automatically loaded. + + # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. + # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. + # config.time_zone = 'Central Time (US & Canada)' + + # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. + # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] + # config.i18n.default_locale = :de + + # Do not swallow errors in after_commit/after_rollback callbacks. + config.active_record.raise_in_transactional_callbacks = true + + config.active_job.queue_adapter = :delayed_job + end +end diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 0000000..6b750f0 --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,3 @@ +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) + +require 'bundler/setup' # Set up gems listed in the Gemfile. diff --git a/config/database.yml b/config/database.yml new file mode 100644 index 0000000..72dbbb2 --- /dev/null +++ b/config/database.yml @@ -0,0 +1,12 @@ +development: &default + adapter: postgresql + database: railsbridgeboston_dot_org_development + encoding: utf8 + host: localhost + min_messages: warning + pool: 2 + timeout: 5000 + +test: + <<: *default + database: railsbridgeboston_dot_org_test diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 0000000..ee8d90d --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require File.expand_path('../application', __FILE__) + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 0000000..64306e1 --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,44 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # In the development environment your application's code is reloaded on + # every request. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = false + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = true + config.action_mailer.delivery_method = :test + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + # Debug mode disables concatenation and preprocessing of assets. + # This option may cause significant delays in view rendering with a large + # number of complex assets. + config.assets.debug = true + + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. + config.assets.digest = true + + # Adds additional error checking when serving assets at runtime. + # Checks for improperly declared sprockets dependencies. + # Raises helpful error messages. + config.assets.raise_runtime_errors = true + + # Raises error for missing translations + config.action_view.raise_on_missing_translations = true + + config.action_mailer.default_url_options = { host: "localhost:4000" } +end diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 0000000..4b6d717 --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,89 @@ +require Rails.root.join("config/smtp") +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.cache_classes = true + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Enable Rack::Cache to put a simple HTTP cache in front of your application + # Add `rack-cache` to your Gemfile before enabling this. + # For large-scale production use, consider using a caching reverse proxy like + # NGINX, varnish or squid. + # config.action_dispatch.rack_cache = true + + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? + config.static_cache_control = "public, max-age=#{1.year.to_i}" + # Enable deflate / gzip compression of controller-generated responses + config.middleware.use Rack::Deflater + + # Compress JavaScripts and CSS. + config.assets.js_compressor = :uglifier + # config.assets.css_compressor = :sass + + # Do not fallback to assets pipeline if a precompiled asset is missed. + config.assets.compile = false + + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. + config.assets.digest = true + + # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + # config.force_ssl = true + + # Use the lowest log level to ensure availability of diagnostic information + # when problems arise. + config.log_level = :debug + + # Prepend all log lines with the following tags. + # config.log_tags = [ :subdomain, :uuid ] + + # Use a different logger for distributed setups. + # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) + + # Use a different cache store in production. + # config.cache_store = :mem_cache_store + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + config.action_controller.asset_host = ENV.fetch("ASSET_HOST", ENV.fetch("HOST")) + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + config.action_mailer.delivery_method = :smtp + config.action_mailer.smtp_settings = SMTP_SETTINGS + + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners. + config.active_support.deprecation = :notify + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false + + config.action_mailer.default_url_options = { host: ENV.fetch("HOST") } +end +Rack::Timeout.timeout = (ENV["RACK_TIMEOUT"] || 10).to_i diff --git a/config/environments/staging.rb b/config/environments/staging.rb new file mode 100644 index 0000000..d0e0f88 --- /dev/null +++ b/config/environments/staging.rb @@ -0,0 +1,11 @@ +require_relative "production" + +Mail.register_interceptor( + RecipientInterceptor.new(ENV.fetch("EMAIL_RECIPIENTS")) +) + +Rails.application.configure do + # ... + + config.action_mailer.default_url_options = { host: ENV.fetch("HOST") } +end diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 0000000..793219d --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,46 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember that + # your test database is "scratch space" for the test suite and is wiped + # and recreated between test runs. Don't rely on the data there! + config.cache_classes = true + + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false + + # Configure static file server for tests with Cache-Control for performance. + config.serve_static_files = true + config.static_cache_control = 'public, max-age=3600' + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Raise exceptions instead of rendering exception templates. + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Randomize the order test cases are executed. + config.active_support.test_order = :random + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raises error for missing translations + config.action_view.raise_on_missing_translations = true + + config.action_mailer.default_url_options = { host: "www.example.com" } + + config.active_job.queue_adapter = :inline +end diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml new file mode 100644 index 0000000..5380ae1 --- /dev/null +++ b/config/i18n-tasks.yml @@ -0,0 +1,13 @@ +search: + paths: + - "app/controllers" + - "app/helpers" + - "app/presenters" + - "app/views" + +ignore_unused: + - activerecord.* + - date.* + - simple_form.* + - time.* + - titles.* diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb new file mode 100644 index 0000000..13abef8 --- /dev/null +++ b/config/initializers/assets.rb @@ -0,0 +1,11 @@ +# Be sure to restart your server when you modify this file. + +# Version of your assets, change this if you want to expire all your assets. +Rails.application.config.assets.version = (ENV["ASSETS_VERSION"] || "1.0") + +# Add additional assets to the asset load path +# Rails.application.config.assets.paths << Emoji.images_path + +# Precompile additional assets. +# application.js, application.css, and all non-JS/CSS in app/assets folder are already added. +# Rails.application.config.assets.precompile += %w( search.js ) diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb new file mode 100644 index 0000000..59385cd --- /dev/null +++ b/config/initializers/backtrace_silencers.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } + +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. +# Rails.backtrace_cleaner.remove_silencers! diff --git a/config/initializers/cookies_serializer.rb b/config/initializers/cookies_serializer.rb new file mode 100644 index 0000000..7f70458 --- /dev/null +++ b/config/initializers/cookies_serializer.rb @@ -0,0 +1,3 @@ +# Be sure to restart your server when you modify this file. + +Rails.application.config.action_dispatch.cookies_serializer = :json diff --git a/config/initializers/disable_xml_params.rb b/config/initializers/disable_xml_params.rb new file mode 100644 index 0000000..c24d969 --- /dev/null +++ b/config/initializers/disable_xml_params.rb @@ -0,0 +1,3 @@ +# Protect against injection attacks +# http://www.kb.cert.org/vuls/id/380039 +ActionDispatch::ParamsParser::DEFAULT_PARSERS.delete(Mime::XML) diff --git a/config/initializers/errors.rb b/config/initializers/errors.rb new file mode 100644 index 0000000..13c1795 --- /dev/null +++ b/config/initializers/errors.rb @@ -0,0 +1,34 @@ +require "net/http" +require "net/smtp" + +# Example: +# begin +# some http call +# rescue *HTTP_ERRORS => error +# notify_hoptoad error +# end + +HTTP_ERRORS = [ + EOFError, + Errno::ECONNRESET, + Errno::EINVAL, + Net::HTTPBadResponse, + Net::HTTPHeaderSyntaxError, + Net::ProtocolError, + Timeout::Error +] + +SMTP_SERVER_ERRORS = [ + IOError, + Net::SMTPAuthenticationError, + Net::SMTPServerBusy, + Net::SMTPUnknownError, + TimeoutError +] + +SMTP_CLIENT_ERRORS = [ + Net::SMTPFatalError, + Net::SMTPSyntaxError +] + +SMTP_ERRORS = SMTP_SERVER_ERRORS + SMTP_CLIENT_ERRORS diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb new file mode 100644 index 0000000..4a994e1 --- /dev/null +++ b/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Configure sensitive parameters which will be filtered from the log file. +Rails.application.config.filter_parameters += [:password] diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 0000000..ac033bf --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.plural /^(ox)$/i, '\1en' +# inflect.singular /^(ox)en/i, '\1' +# inflect.irregular 'person', 'people' +# inflect.uncountable %w( fish sheep ) +# end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym 'RESTful' +# end diff --git a/config/initializers/json_encoding.rb b/config/initializers/json_encoding.rb new file mode 100644 index 0000000..292542f --- /dev/null +++ b/config/initializers/json_encoding.rb @@ -0,0 +1 @@ +ActiveSupport::JSON::Encoding.time_precision = 0 diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb new file mode 100644 index 0000000..dc18996 --- /dev/null +++ b/config/initializers/mime_types.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Add new mime types for use in respond_to blocks: +# Mime::Type.register "text/richtext", :rtf diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb new file mode 100644 index 0000000..62c626a --- /dev/null +++ b/config/initializers/session_store.rb @@ -0,0 +1,3 @@ +# Be sure to restart your server when you modify this file. + +Rails.application.config.session_store :cookie_store, key: '_railsbridgeboston_dot_org_session' diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb new file mode 100644 index 0000000..33725e9 --- /dev/null +++ b/config/initializers/wrap_parameters.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. + +# This file contains settings for ActionController::ParamsWrapper which +# is enabled by default. + +# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. +ActiveSupport.on_load(:action_controller) do + wrap_parameters format: [:json] if respond_to?(:wrap_parameters) +end + +# To enable root element in JSON for ActiveRecord objects. +# ActiveSupport.on_load(:active_record) do +# self.include_root_in_json = true +# end diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 0000000..07c3f6e --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,19 @@ +en: + date: + formats: + default: + "%m/%d/%Y" + with_weekday: + "%a %m/%d/%y" + + time: + formats: + default: + "%a, %b %-d, %Y at %r" + date: + "%b %-d, %Y" + short: + "%B %d" + + titles: + application: Railsbridgeboston dot org diff --git a/config/newrelic.yml b/config/newrelic.yml new file mode 100644 index 0000000..c7ca22b --- /dev/null +++ b/config/newrelic.yml @@ -0,0 +1,34 @@ +common: &default_settings + app_name: "railsbridgeboston_dot_org" + audit_log: + enabled: false + browser_monitoring: + auto_instrument: true + capture_params: false + developer_mode: false + error_collector: + capture_source: true + enabled: true + ignore_errors: "ActionController::RoutingError,Sinatra::NotFound" + license_key: "<%= ENV["NEW_RELIC_LICENSE_KEY"] %>" + log_level: info + monitor_mode: true + transaction_tracer: + enabled: true + record_sql: obfuscated + stack_trace_threshold: 0.500 + transaction_threshold: apdex_f +development: + <<: *default_settings + monitor_mode: false + developer_mode: true +test: + <<: *default_settings + monitor_mode: false +production: + <<: *default_settings + monitor_mode: true +staging: + <<: *default_settings + app_name: "railsbridgeboston_dot_org (Staging)" + monitor_mode: true diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 0000000..1daf9a4 --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,2 @@ +Rails.application.routes.draw do +end diff --git a/config/secrets.yml b/config/secrets.yml new file mode 100644 index 0000000..0bfb22d --- /dev/null +++ b/config/secrets.yml @@ -0,0 +1,14 @@ +default: &default + secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> + +development: + <<: *default + +test: + <<: *default + +staging: + <<: *default + +production: + <<: *default diff --git a/config/smtp.rb b/config/smtp.rb new file mode 100644 index 0000000..0440e09 --- /dev/null +++ b/config/smtp.rb @@ -0,0 +1,9 @@ +SMTP_SETTINGS = { + address: ENV.fetch("SMTP_ADDRESS"), # example: "smtp.sendgrid.net" + authentication: :plain, + domain: ENV.fetch("SMTP_DOMAIN"), # example: "heroku.com" + enable_starttls_auto: true, + password: ENV.fetch("SMTP_PASSWORD"), + port: "587", + user_name: ENV.fetch("SMTP_USERNAME") +} diff --git a/config/unicorn.rb b/config/unicorn.rb new file mode 100644 index 0000000..555cf62 --- /dev/null +++ b/config/unicorn.rb @@ -0,0 +1,30 @@ +# https://devcenter.heroku.com/articles/rails-unicorn + +worker_processes (ENV["UNICORN_WORKERS"] || 3).to_i +timeout (ENV["UNICORN_TIMEOUT"] || 15).to_i +preload_app true + +before_fork do |_server, _worker| + Signal.trap "TERM" do + puts "Unicorn master intercepting TERM, sending myself QUIT instead" + Process.kill "QUIT", Process.pid + end + + if defined? ActiveRecord::Base + ActiveRecord::Base.connection.disconnect! + end +end + +after_fork do |_server, _worker| + Signal.trap "TERM" do + puts "Unicorn worker intercepting TERM, waiting for master to send QUIT" + end + + if defined? ActiveRecord::Base + config = ActiveRecord::Base.configurations[Rails.env] || + Rails.application.config.database_configuration[Rails.env] + config["reaping_frequency"] = (ENV["DB_REAPING_FREQUENCY"] || 10).to_i + config["pool"] = (ENV["DB_POOL"] || 2).to_i + ActiveRecord::Base.establish_connection(config) + end +end diff --git a/db/seeds.rb b/db/seeds.rb new file mode 100644 index 0000000..4edb1e8 --- /dev/null +++ b/db/seeds.rb @@ -0,0 +1,7 @@ +# This file should contain all the record creation needed to seed the database with its default values. +# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). +# +# Examples: +# +# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) +# Mayor.create(name: 'Emanuel', city: cities.first) diff --git a/lib/assets/.keep b/lib/assets/.keep new file mode 100644 index 0000000..e69de29 diff --git a/lib/tasks/.keep b/lib/tasks/.keep new file mode 100644 index 0000000..e69de29 diff --git a/lib/tasks/bundler_audit.rake b/lib/tasks/bundler_audit.rake new file mode 100644 index 0000000..00c1263 --- /dev/null +++ b/lib/tasks/bundler_audit.rake @@ -0,0 +1,12 @@ +if Rails.env.development? || Rails.env.test? + require "bundler/audit/cli" + + namespace :bundler do + desc "Updates the ruby-advisory-db and runs audit" + task :audit do + %w(update check).each do |command| + Bundler::Audit::CLI.start [command] + end + end + end +end diff --git a/lib/tasks/development_seeds.rake b/lib/tasks/development_seeds.rake new file mode 100644 index 0000000..b9a7a2d --- /dev/null +++ b/lib/tasks/development_seeds.rake @@ -0,0 +1,12 @@ +if Rails.env.development? || Rails.env.test? + require "factory_girl" + + namespace :dev do + desc "Seed data for development environment" + task prime: "db:setup" do + include FactoryGirl::Syntax::Methods + + # create(:user, email: "user@example.com", password: "password") + end + end +end diff --git a/public/404.html b/public/404.html new file mode 100644 index 0000000..7b93ab6 --- /dev/null +++ b/public/404.html @@ -0,0 +1,69 @@ + + + + + + + The page you were looking for doesn't exist (404) + + + + + +
+
+

The page you were looking for doesn't exist.

+

You may have mistyped the address or the page may have moved.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/public/422.html b/public/422.html new file mode 100644 index 0000000..db2ff83 --- /dev/null +++ b/public/422.html @@ -0,0 +1,69 @@ + + + + + + + The change you wanted was rejected (422) + + + + + +
+
+

The change you wanted was rejected.

+

Maybe you tried to change something you didn't have access to.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/public/500.html b/public/500.html new file mode 100644 index 0000000..e93b854 --- /dev/null +++ b/public/500.html @@ -0,0 +1,68 @@ + + + + + + + We're sorry, but something went wrong (500) + + + + + +
+
+

We're sorry, but something went wrong.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..3c9c7c0 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,5 @@ +# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file +# +# To ban all spiders from the entire site uncomment the next two lines: +# User-agent: * +# Disallow: / diff --git a/spec/controllers/.keep b/spec/controllers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/spec/features/.keep b/spec/features/.keep new file mode 100644 index 0000000..e69de29 diff --git a/spec/helpers/.keep b/spec/helpers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/spec/i18n_spec.rb b/spec/i18n_spec.rb new file mode 100644 index 0000000..c1b7aee --- /dev/null +++ b/spec/i18n_spec.rb @@ -0,0 +1,18 @@ +require 'spec_helper' +require 'i18n/tasks' + +describe 'I18n' do + let(:i18n) { I18n::Tasks::BaseTask.new } + let(:missing_keys) { i18n.missing_keys } + let(:unused_keys) { i18n.unused_keys } + + it 'does not have missing keys' do + expect(missing_keys).to be_empty, + "Missing #{missing_keys.leaves.count} i18n keys, run `i18n-tasks missing' to show them" + end + + it 'does not have unused keys' do + expect(unused_keys).to be_empty, + "#{unused_keys.leaves.count} unused i18n keys, run `i18n-tasks unused' to show them" + end +end diff --git a/spec/lib/.keep b/spec/lib/.keep new file mode 100644 index 0000000..e69de29 diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb new file mode 100644 index 0000000..6897678 --- /dev/null +++ b/spec/rails_helper.rb @@ -0,0 +1,23 @@ +ENV["RAILS_ENV"] = "test" + +require File.expand_path("../../config/environment", __FILE__) + +require "rspec/rails" +require "shoulda/matchers" + +Dir[Rails.root.join("spec/support/**/*.rb")].each { |file| require file } + +module Features + # Extend this module in spec/support/features/*.rb + include Formulaic::Dsl +end + +RSpec.configure do |config| + config.include Features, type: :feature + config.infer_base_class_for_anonymous_controllers = false + config.infer_spec_type_from_file_location! + config.use_transactional_fixtures = false +end + +ActiveRecord::Migration.maintain_test_schema! +Capybara.javascript_driver = :webkit diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..46e4254 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,22 @@ +if ENV.fetch("COVERAGE", false) + require "simplecov" + SimpleCov.start "rails" +end + +require "webmock/rspec" + +# http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + config.expect_with :rspec do |expectations| + expectations.syntax = :expect + end + + config.mock_with :rspec do |mocks| + mocks.syntax = :expect + mocks.verify_partial_doubles = true + end + + config.order = :random +end + +WebMock.disable_net_connect!(allow_localhost: true) diff --git a/spec/support/action_mailer.rb b/spec/support/action_mailer.rb new file mode 100644 index 0000000..b9563a3 --- /dev/null +++ b/spec/support/action_mailer.rb @@ -0,0 +1,5 @@ +RSpec.configure do |config| + config.before(:each) do + ActionMailer::Base.deliveries.clear + end +end diff --git a/spec/support/database_cleaner.rb b/spec/support/database_cleaner.rb new file mode 100644 index 0000000..36dcc88 --- /dev/null +++ b/spec/support/database_cleaner.rb @@ -0,0 +1,21 @@ +RSpec.configure do |config| + config.before(:suite) do + DatabaseCleaner.clean_with(:deletion) + end + + config.before(:each) do + DatabaseCleaner.strategy = :transaction + end + + config.before(:each, js: true) do + DatabaseCleaner.strategy = :deletion + end + + config.before(:each) do + DatabaseCleaner.start + end + + config.after(:each) do + DatabaseCleaner.clean + end +end diff --git a/spec/support/factory_girl.rb b/spec/support/factory_girl.rb new file mode 100644 index 0000000..eec437f --- /dev/null +++ b/spec/support/factory_girl.rb @@ -0,0 +1,3 @@ +RSpec.configure do |config| + config.include FactoryGirl::Syntax::Methods +end diff --git a/spec/support/features/.keep b/spec/support/features/.keep new file mode 100644 index 0000000..e69de29 diff --git a/spec/support/i18n.rb b/spec/support/i18n.rb new file mode 100644 index 0000000..3d4094d --- /dev/null +++ b/spec/support/i18n.rb @@ -0,0 +1,3 @@ +RSpec.configure do |config| + config.include AbstractController::Translation +end diff --git a/spec/support/matchers/.keep b/spec/support/matchers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/spec/support/mixins/.keep b/spec/support/mixins/.keep new file mode 100644 index 0000000..e69de29 diff --git a/spec/support/shared_examples/.keep b/spec/support/shared_examples/.keep new file mode 100644 index 0000000..e69de29 diff --git a/vendor/assets/javascripts/.keep b/vendor/assets/javascripts/.keep new file mode 100644 index 0000000..e69de29 diff --git a/vendor/assets/stylesheets/.keep b/vendor/assets/stylesheets/.keep new file mode 100644 index 0000000..e69de29