├── .codoopts ├── .gitignore ├── .rspec ├── .ruby-gemset ├── .ruby-version ├── CONTRIBUTING.md ├── Gemfile ├── Gemfile.d ├── _before.rb ├── assets.rb ├── authentication.rb ├── concurrency.rb ├── development.rb ├── dogfood.rb ├── framework.rb ├── integration.rb ├── mail.rb ├── models.rb ├── specs.rb ├── utilities.rb ├── views.rb └── ~after.rb ├── Gemfile.lock ├── LICENSE.txt ├── README.md ├── Rakefile ├── app ├── assets │ ├── images │ │ ├── bug.png │ │ ├── comment-arrow.png │ │ └── footer.png │ ├── javascripts │ │ ├── aggregation.js.coffee │ │ ├── application.js │ │ ├── flash.js.coffee │ │ ├── histogram.js.coffee │ │ ├── navbar.js.coffee │ │ └── search.js.coffee │ └── stylesheets │ │ ├── _alerts.scss │ │ ├── _badges.scss │ │ ├── _breadcrumbs.scss │ │ ├── _containers.scss │ │ ├── _controls.scss │ │ ├── _footer.scss │ │ ├── _forms.scss │ │ ├── _modal.scss │ │ ├── _navbar.scss │ │ ├── _pills.scss │ │ ├── _tables.scss │ │ ├── _typography.scss │ │ ├── _vars.scss │ │ ├── accounts.css.scss │ │ ├── application.css │ │ ├── bugs.css.scss │ │ ├── feed.css.scss │ │ ├── flash.css.scss │ │ ├── membership.css.scss │ │ ├── occurrences.css.scss │ │ ├── projects.css.scss │ │ ├── sessions.css.scss │ │ ├── squash.css.scss │ │ └── users.css.scss ├── controllers │ ├── account │ │ ├── bugs_controller.rb │ │ ├── events_controller.rb │ │ └── memberships_controller.rb │ ├── accounts_controller.rb │ ├── additions │ │ ├── authentication_helpers.rb │ │ ├── event_decoration.rb │ │ ├── json_detail_responder.rb │ │ ├── ldap_authentication_helpers.rb │ │ └── password_authentication_helpers.rb │ ├── api │ │ └── v1_controller.rb │ ├── application_controller.rb │ ├── bugs_controller.rb │ ├── comments_controller.rb │ ├── commits_controller.rb │ ├── emails_controller.rb │ ├── environments_controller.rb │ ├── events_controller.rb │ ├── jira │ │ ├── issues_controller.rb │ │ ├── projects_controller.rb │ │ └── statuses_controller.rb │ ├── notification_thresholds_controller.rb │ ├── occurrences_controller.rb │ ├── project │ │ ├── membership_controller.rb │ │ └── memberships_controller.rb │ ├── projects_controller.rb │ ├── search_controller.rb │ ├── sessions_controller.rb │ └── users_controller.rb ├── helpers │ ├── application_helper.rb │ ├── mail_helper.rb │ └── occurrences_helper.rb ├── mailers │ ├── .gitkeep │ └── notification_mailer.rb ├── middleware │ └── ping.rb ├── models │ ├── .gitkeep │ ├── additions │ │ ├── ldap_authentication.rb │ │ └── password_authentication.rb │ ├── blame.rb │ ├── bug.rb │ ├── comment.rb │ ├── deploy.rb │ ├── device_bug.rb │ ├── email.rb │ ├── environment.rb │ ├── event.rb │ ├── membership.rb │ ├── notification_threshold.rb │ ├── obfuscation_map.rb │ ├── observers │ │ ├── bug_observer.rb │ │ ├── comment_observer.rb │ │ ├── deploy_observer.rb │ │ ├── event_observer.rb │ │ ├── occurrence_observer.rb │ │ └── watch_observer.rb │ ├── occurrence.rb │ ├── project.rb │ ├── slug.rb │ ├── source_map.rb │ ├── symbolication.rb │ ├── user.rb │ ├── user_event.rb │ └── watch.rb └── views │ ├── accounts │ ├── show.html.rb │ └── show.js.erb │ ├── additions │ ├── accordion.rb │ ├── html_backtrace_rendering.rb │ └── text_backtrace_rendering.rb │ ├── bugs │ ├── index.atom.builder │ ├── index.html.rb │ ├── index.js.erb │ ├── show.html.rb │ └── show.js.erb │ ├── layouts │ └── application.html.rb │ ├── notification_mailer │ ├── assign.text.erb │ ├── blame.text.erb │ ├── comment.text.erb │ ├── critical.text.erb │ ├── deploy.text.erb │ ├── initial.text.erb │ ├── occurrence.text.erb │ ├── reopened.text.erb │ ├── resolved.text.erb │ └── threshold.text.erb │ ├── occurrences │ ├── index.atom.builder │ ├── show.html.rb │ └── show.js.erb │ ├── project │ └── membership │ │ ├── edit.html.rb │ │ └── edit.js.erb │ ├── projects │ ├── edit.html.rb │ ├── edit.js.erb │ ├── index.html.rb │ ├── index.js.erb │ ├── show.html.rb │ └── show.js.erb │ ├── sessions │ └── new.html.rb │ └── users │ └── show.html.rb ├── bin ├── bundle ├── rails ├── rake └── setup ├── config.ru ├── config ├── application.rb ├── boot.rb ├── database.yml ├── environment.rb ├── environments │ ├── common │ │ ├── activerecord.yml │ │ ├── authentication.yml │ │ ├── concurrency.yml │ │ ├── dogfood.yml │ │ ├── javascript_dogfood.yml │ │ ├── jira.yml │ │ ├── mailer.yml │ │ ├── pagerduty.yml │ │ └── repositories.yml │ ├── development.rb │ ├── development │ │ ├── dogfood.yml │ │ └── mailer.yml │ ├── production.rb │ ├── production │ │ ├── dogfood.yml │ │ ├── javascript_dogfood.yml │ │ └── mailer.yml │ ├── test.rb │ └── test │ │ ├── dogfood.yml │ │ ├── jira.yml │ │ ├── mailer.yml │ │ ├── people.yml │ │ └── squash_javascript.yml ├── initializers │ ├── active_record.rb │ ├── active_record_observer_hooks.rb │ ├── assets.rb │ ├── backtrace_silencers.rb │ ├── concurrency.rb │ ├── cookies_serializer.rb │ ├── dogfood.rb │ ├── field_error_proc.rb │ ├── filter_parameter_logging.rb │ ├── find_in_batches.rb │ ├── html5.rb │ ├── inflections.rb │ ├── jdbc_fixes.rb │ ├── jira.rb │ ├── load_autoload_paths.rb │ ├── mail.rb │ ├── mime_types.rb │ ├── secret_token.rb │ ├── session_store.rb │ └── wrap_parameters.rb ├── locales │ └── en.yml ├── preinitializers │ ├── jruby.rb │ ├── safe_yaml.rb │ └── source_maps.rb ├── routes.rb └── secrets.yml ├── data ├── brushes.yml └── message_templates.yml ├── db ├── .gitignore ├── migrate │ ├── 1_initial_schema.rb │ ├── 20130125021927_index_occurrences_by_bug_and_redirected.rb │ ├── 20130131002457_track_crashes.rb │ ├── 20130131002503_track_bugs_per_device.rb │ ├── 20130215185809_fix_condition_on_rule_occurrences_set_latest.rb │ ├── 20130221020818_create_blames.rb │ ├── 20130222055524_fix_blame_lru_key.rb │ ├── 20140130012355_add_mapping_to_source_map.rb │ └── 20151126022941_add_hosted_filename_to_source_maps.rb └── seeds.rb ├── doc ├── .gitignore ├── CONTRIBUTING.md ├── MAKING_A_CLIENT_LIBRARY.md └── fdoc │ ├── deobfuscation-POST.fdoc │ ├── deploy-POST.fdoc │ ├── notify-POST.fdoc │ ├── sourcemap-POST.fdoc │ ├── squash.fdoc.service │ └── symbolication-POST.fdoc ├── lib ├── api │ └── errors.rb ├── assets │ ├── .gitkeep │ ├── javascripts │ │ ├── accordion.js.coffee │ │ ├── autocomplete.js.coffee │ │ ├── bug_file_formatter.js.coffee │ │ ├── buttons.js.coffee │ │ ├── configure_squash_client.js.coffee.erb │ │ ├── context.js.coffee │ │ ├── disclosure.js.coffee │ │ ├── dropdown.js.coffee │ │ ├── dynamic_search_field.js.coffee │ │ ├── editor_links.js.coffee │ │ ├── email_alias_form.js.coffee │ │ ├── error_tooltip.js.coffee │ │ ├── feed.js.coffee │ │ ├── form_with_errors.js.coffee │ │ ├── live_update.js.coffee │ │ ├── member_panel.js.coffee │ │ ├── smart_form.js.coffee │ │ ├── sortable_table.js.coffee │ │ ├── tabs.js.coffee │ │ ├── utilities.js.coffee │ │ └── value_inspector.js.coffee │ └── stylesheets │ │ ├── accordion.css.scss │ │ ├── autocomplete.css.scss │ │ ├── grid.css.scss │ │ ├── reset.css │ │ ├── smart_form.css.scss │ │ └── sortable_table.css.scss ├── background_runner.rb ├── background_runner │ ├── job.rb │ ├── multithread.rb │ ├── resque.rb │ ├── sidekiq.rb │ └── tasks │ │ ├── resque.rake │ │ └── sidekiq.rake ├── blamer │ ├── base.rb │ ├── cache.rb │ ├── recency.rb │ └── simple.rb ├── file_mutex.rb ├── known_revision_validator.rb ├── message_template_matcher.rb ├── multithread.rb ├── repo_proxy.rb ├── service.rb ├── service │ ├── jira.rb │ └── pager_duty.rb ├── sidekiq_auth_constraint.rb ├── tasks │ ├── .gitkeep │ ├── concurrency.rake │ ├── doc.rake │ ├── jira.rake │ ├── spec.rake │ ├── statistics.rake │ └── truncation.rake └── workers │ ├── comment_notification_mailer.rb │ ├── deploy_fix_marker.rb │ ├── deploy_notification_mailer.rb │ ├── jira_status_worker.rb │ ├── obfuscation_map_creator.rb │ ├── obfuscation_map_worker.rb │ ├── occurrence_notification_mailer.rb │ ├── occurrences_worker.rb │ ├── pager_duty_acknowledger.rb │ ├── pager_duty_notifier.rb │ ├── pager_duty_resolver.rb │ ├── project_repo_fetcher.rb │ ├── source_map_creator.rb │ ├── source_map_worker.rb │ ├── symbolication_creator.rb │ └── symbolication_worker.rb ├── log └── .gitignore ├── public ├── 400.html ├── 404.html ├── 422.html ├── 500.html ├── favicon.ico └── robots.txt ├── script ├── all_specs.sh ├── jira_oauth.rb ├── mysql_message_templates.rb └── psql_message_templates.rb ├── spec ├── controllers │ ├── account │ │ ├── bugs_controller_spec.rb │ │ ├── events_controller_spec.rb │ │ └── memberships_controller_spec.rb │ ├── accounts_controller_spec.rb │ ├── additions │ │ ├── authentication_helpers_spec.rb │ │ ├── ldap_authentication_helpers_spec.rb │ │ └── password_authentication_helpers_spec.rb │ ├── api │ │ └── v1_controller_spec.rb │ ├── application_controller_spec.rb │ ├── bugs_controller_spec.rb │ ├── comments_controller_spec.rb │ ├── commits_controller_spec.rb │ ├── emails_controller_spec.rb │ ├── environments_controller_spec.rb │ ├── events_controller_spec.rb │ ├── jira │ │ ├── issues_controller_spec.rb │ │ ├── projects_controller_spec.rb │ │ └── statuses_controller_spec.rb │ ├── notification_thresholds_controller_spec.rb │ ├── occurrences_controller_spec.rb │ ├── project │ │ ├── membership_controller_spec.rb │ │ └── memberships_controller_spec.rb │ ├── projects_controller_spec.rb │ ├── search_controller_spec.rb │ ├── sessions_controller_spec.rb │ └── users_controller_spec.rb ├── factories │ ├── blames.rb │ ├── bugs.rb │ ├── comments.rb │ ├── deploys.rb │ ├── device_bugs.rb │ ├── emails.rb │ ├── environments.rb │ ├── events.rb │ ├── memberships.rb │ ├── notification_thresholds.rb │ ├── obfuscation_maps.rb │ ├── occurrences.rb │ ├── projects.rb │ ├── source_maps.rb │ ├── symbolications.rb │ ├── user_events.rb │ ├── users.rb │ └── watches.rb ├── fixtures │ ├── image.jpg │ ├── image.png │ ├── jira_issue.json │ ├── jira_issue_404.json │ ├── jira_issue_resolved.json │ ├── jira_projects.json │ ├── jira_statuses.json │ ├── mapping.json │ └── pagerduty_response.json ├── lib │ ├── blamer │ │ ├── cache_spec.rb │ │ ├── recency_spec.rb │ │ └── simple_spec.rb │ ├── composite_primary_keys_spec.rb │ ├── find_in_batches_spec.rb │ ├── known_revision_validator_spec.rb │ ├── message_template_matcher_spec.rb │ ├── multithread_spec.rb │ ├── service │ │ ├── jira_spec.rb │ │ └── pager_duty_spec.rb │ └── workers │ │ ├── deploy_fix_marker_spec.rb │ │ ├── jira_status_updater_spec.rb │ │ └── occurrences_worker_spec.rb ├── mailers │ └── notification_mailer_spec.rb ├── models │ ├── blame_spec.rb │ ├── bug_spec.rb │ ├── comment_spec.rb │ ├── deploy_spec.rb │ ├── device_bug_spec.rb │ ├── email_spec.rb │ ├── environment_spec.rb │ ├── event_spec.rb │ ├── membership_spec.rb │ ├── notification_threshold_spec.rb │ ├── obfuscation_map_spec.rb │ ├── occurrence_spec.rb │ ├── project_spec.rb │ ├── source_map_spec.rb │ ├── symbolication_spec.rb │ ├── user_event_spec.rb │ ├── user_spec.rb │ └── watch_spec.rb ├── rails_helper.rb ├── routing │ ├── project │ │ └── memberships_spec.rb │ └── users_spec.rb ├── spec_helper.rb └── support │ └── controller_404_examples.rb ├── tmp ├── pids │ └── .gitignore ├── repos │ └── .gitignore ├── sessions │ └── .gitignore ├── sockets │ └── .gitignore └── sourcemaps │ └── .gitignore └── vendor ├── assets ├── javascripts │ ├── .gitkeep │ ├── bootstrap.js │ ├── cubism.js │ ├── flot │ │ ├── categories.js │ │ ├── colorhelpers.js │ │ ├── crosshair.js │ │ ├── errorbars.js │ │ ├── excanvas.js │ │ ├── fillbetween.js │ │ ├── flot.js │ │ ├── image.js │ │ ├── navigate.js │ │ ├── pie.js │ │ ├── resize.js │ │ ├── selection.js │ │ ├── stack.js │ │ ├── symbol.js │ │ ├── threshold.js │ │ └── time.js │ ├── jquery-cookie.js │ ├── jquery-leanModal.js │ ├── jquery-timers.js │ └── sh │ │ ├── shAutoloader.js │ │ ├── shBrushAS3.js │ │ ├── shBrushAppleScript.js │ │ ├── shBrushBash.js │ │ ├── shBrushCSharp.js │ │ ├── shBrushColdFusion.js │ │ ├── shBrushCpp.js │ │ ├── shBrushCss.js │ │ ├── shBrushDelphi.js │ │ ├── shBrushDiff.js │ │ ├── shBrushErlang.js │ │ ├── shBrushGit.js │ │ ├── shBrushGroovy.js │ │ ├── shBrushHaxe.js │ │ ├── shBrushJScript.js │ │ ├── shBrushJava.js │ │ ├── shBrushJavaFX.js │ │ ├── shBrushObjC.js │ │ ├── shBrushPerl.js │ │ ├── shBrushPhp.js │ │ ├── shBrushPlain.js │ │ ├── shBrushPowerShell.js │ │ ├── shBrushPython.js │ │ ├── shBrushRuby.js │ │ ├── shBrushSass.js │ │ ├── shBrushScala.js │ │ ├── shBrushSql.js │ │ ├── shBrushTAP.js │ │ ├── shBrushTypeScript.js │ │ ├── shBrushVb.js │ │ ├── shBrushXml.js │ │ ├── shBrushYaml.js │ │ ├── shCore.js │ │ ├── shCore.min.js │ │ └── shLegacy.js └── stylesheets │ ├── .gitkeep │ ├── bootstrap.css │ └── sh │ ├── shCore.css │ ├── shCoreDefault.css │ ├── shCoreDjango.css │ ├── shCoreEclipse.css │ ├── shCoreEmacs.css │ ├── shCoreFadeToGrey.css │ ├── shCoreMDUltra.css │ ├── shCoreMidnight.css │ ├── shCoreRDark.css │ ├── shThemeDefault.css │ ├── shThemeDjango.css │ ├── shThemeEclipse.css │ ├── shThemeEmacs.css │ ├── shThemeFadeToGrey.css │ ├── shThemeMDUltra.css │ ├── shThemeMidnight.css │ └── shThemeRDark.css ├── configoro ├── base.rb ├── hash.rb └── simple.rb └── plugins └── .gitkeep /.codoopts: -------------------------------------------------------------------------------- 1 | -o doc/js 2 | --title "Squash Front-End JavaScript Documentation" 3 | 4 | lib/assets/javascripts 5 | app/assets/javascripts 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle 2 | .yardoc 3 | node_modules 4 | tmp/cache/* 5 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --require spec_helper 3 | --format documentation 4 | -------------------------------------------------------------------------------- /.ruby-gemset: -------------------------------------------------------------------------------- 1 | squash 2 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.3.0 2 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | doc/CONTRIBUTING.md -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Load all files under the Gemfile.d directory. 4 | 5 | Dir.glob(File.join(File.dirname(__FILE__), 'Gemfile.d', '*.rb')).sort.each do |file| 6 | eval File.read(file), binding, file 7 | end 8 | -------------------------------------------------------------------------------- /Gemfile.d/_before.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Load our frozen Configoro 16 | require File.join(File.dirname(__FILE__), '..', 'vendor', 'configoro', 'simple') 17 | 18 | rails_root = ENV['RAILS_ROOT'] || File.join(File.dirname(__FILE__), '..') 19 | Configoro.paths << File.join(rails_root, 'config', 'environments') 20 | 21 | $_squash_environments = Dir.glob(File.join(rails_root, 'config', 'environments', '*.rb')).map { |f| File.basename f, '.rb' } 22 | 23 | def load_groups(configuration_path, values) 24 | configuration_path = configuration_path.split('.') 25 | 26 | $_squash_environments.select do |env| 27 | settings = Configoro.load_environment(env) 28 | values.include?(traverse_hash(settings, *configuration_path)) 29 | end 30 | end 31 | 32 | def traverse_hash(hsh, *keys) 33 | return nil unless hsh 34 | 35 | if keys.size == 1 36 | hsh[keys.first] 37 | else 38 | traverse_hash hsh[keys.shift], *keys 39 | end 40 | end 41 | 42 | def conditionally(configuration_path, *values, &block) 43 | groups = load_groups(configuration_path, values) 44 | groups.each { |g| group g.to_sym, &block } 45 | end 46 | -------------------------------------------------------------------------------- /Gemfile.d/assets.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | gem 'sass-rails' 16 | gem 'sprockets' # fix nil error 17 | gem 'libv8', platform: :mri 18 | gem 'therubyracer', platform: :mri 19 | gem 'therubyrhino', platform: :jruby 20 | gem 'less-rails' 21 | 22 | gem 'font-awesome-rails' 23 | 24 | gem 'coffee-rails' 25 | gem 'closure-compiler' 26 | gem 'jquery-rails' 27 | -------------------------------------------------------------------------------- /Gemfile.d/authentication.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | conditionally('authentication.strategy', 'ldap') do 16 | gem 'net-ldap', github: 'ruby-ldap/ruby-net-ldap', require: 'net/ldap' 17 | end 18 | -------------------------------------------------------------------------------- /Gemfile.d/concurrency.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | conditionally('concurrency.background_runner', 'Resque') do 16 | gem 'resque' 17 | gem 'resque-pool' 18 | end 19 | 20 | conditionally('concurrency.background_runner', 'Sidekiq') do 21 | gem 'sidekiq' 22 | gem 'capistrano-sidekiq' 23 | 24 | # disable if you don't need Sidekiq monitoring 25 | gem 'slim' 26 | gem 'sinatra' 27 | end 28 | -------------------------------------------------------------------------------- /Gemfile.d/development.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | group :development do 16 | gem 'yard', require: nil 17 | gem 'redcarpet', require: nil, platform: :mri 18 | end 19 | 20 | gem 'sql_origin', groups: [:development, :test] 21 | -------------------------------------------------------------------------------- /Gemfile.d/dogfood.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | gem 'squash_ruby', require: 'squash/ruby' 16 | gem 'squash_rails', require: 'squash/rails' 17 | gem 'squash_ios_symbolicator', require: 'squash/symbolicator' 18 | gem 'squash_javascript', require: 'squash/javascript' 19 | gem 'sourcemap' 20 | gem 'squash_java', require: 'squash/java' 21 | -------------------------------------------------------------------------------- /Gemfile.d/framework.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | gem 'rails', '4.2.5.2' 16 | gem 'responders' 17 | gem 'psych' # fix TypeError: superclass mismatch for class Mark 18 | 19 | gem 'configoro' 20 | gem 'rack-cors', require: 'rack/cors' 21 | -------------------------------------------------------------------------------- /Gemfile.d/integration.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | conditionally('jira.disabled', false, nil) do 16 | gem 'jira-ruby', require: 'jira' 17 | end 18 | -------------------------------------------------------------------------------- /Gemfile.d/mail.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | conditionally('mailer.smtp_settings.authentication', 'ntlm') do 16 | gem 'ruby-ntlm', require: 'ntlm/smtp' 17 | end 18 | 19 | -------------------------------------------------------------------------------- /Gemfile.d/models.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | gem 'pg', platform: :mri 16 | gem 'activerecord-jdbcpostgresql-adapter', platform: :jruby 17 | gem 'has_metadata_column' 18 | gem 'slugalicious' 19 | gem 'email_validation' 20 | gem 'url_validation' 21 | gem 'json_serialize' 22 | gem 'validates_timeliness' 23 | gem 'find_or_create_on_scopes' 24 | gem 'composite_primary_keys' 25 | gem 'rails-observers' 26 | 27 | conditionally('activerecord.cursors', true) do 28 | gem 'activerecord-postgresql-cursors' 29 | end 30 | -------------------------------------------------------------------------------- /Gemfile.d/specs.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | group :test do 16 | gem 'rspec-rails' 17 | gem 'factory_girl_rails' 18 | 19 | gem 'fakeweb' 20 | end 21 | -------------------------------------------------------------------------------- /Gemfile.d/utilities.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | gem 'json' 16 | gem 'git', github: 'RISCfuture/ruby-git' 17 | gem 'user-agent' 18 | 19 | gem 'safe_yaml' 20 | -------------------------------------------------------------------------------- /Gemfile.d/views.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | gem 'erector', github: 'RISCfuture/erector' 16 | gem 'kramdown' 17 | -------------------------------------------------------------------------------- /Gemfile.d/~after.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | if defined?(Configoro) 16 | Configoro.reset_paths # reset configoro 17 | end 18 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | 3 | # Copyright 2014 Square Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # Add your own tasks in files placed in lib/tasks ending in .rake, 18 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 19 | 20 | require File.expand_path('../config/application', __FILE__) 21 | 22 | Squash::Application.load_tasks 23 | -------------------------------------------------------------------------------- /app/assets/images/bug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquareSquash/web/e73f2805f9eb30780a5c213b001f0f4255660fbf/app/assets/images/bug.png -------------------------------------------------------------------------------- /app/assets/images/comment-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquareSquash/web/e73f2805f9eb30780a5c213b001f0f4255660fbf/app/assets/images/comment-arrow.png -------------------------------------------------------------------------------- /app/assets/images/footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquareSquash/web/e73f2805f9eb30780a5c213b001f0f4255660fbf/app/assets/images/footer.png -------------------------------------------------------------------------------- /app/assets/stylesheets/_alerts.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | 3 | .alert { 4 | padding: 10px 20px; 5 | border-radius: 4px; 6 | font-weight: bold; 7 | margin: 20px 0; 8 | 9 | &.error { background-color: $red; } 10 | &.important { background-color: $orange; } 11 | &.warning { background-color: $yellow; } 12 | &.success { background-color: $green; } 13 | &.info { background-color: $blue; } 14 | } 15 | -------------------------------------------------------------------------------- /app/assets/stylesheets/_badges.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | 3 | $badge-padding: 4px; 4 | 5 | span.badge { 6 | background-color: $gray3; 7 | color: white; 8 | padding: $badge-padding; 9 | border-radius: $radius-size; 10 | 11 | &.critical { background-color: $red; } 12 | &.important { background-color: $orange; color: black; } 13 | &.warning { background-color: $yellow; color: black; } 14 | &.success { background-color: $green; color: black; } 15 | &.info { background-color: $blue; color: black; } 16 | } 17 | -------------------------------------------------------------------------------- /app/assets/stylesheets/_breadcrumbs.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | 3 | #breadcrumbs-container .container { 4 | display: -webkit-box; 5 | display: -moz-box; 6 | display: box; 7 | } 8 | 9 | ul.breadcrumb { 10 | background-color: white; 11 | padding: 0 20px; 12 | line-height: $nav-height; 13 | 14 | -webkit-box-flex: 1; 15 | -moz-box-flex: 1; 16 | box-flex: 1; 17 | 18 | li { 19 | display: inline; 20 | 21 | a { text-decoration: none; } 22 | &:last-child { 23 | font-size: 14px; 24 | font-weight: bold; 25 | } 26 | 27 | &.divider { 28 | color: $gray4; 29 | padding: 0 5px; 30 | } 31 | } 32 | } 33 | 34 | div#breadcrumbs-stats { 35 | display: -webkit-box; 36 | display: -moz-box; 37 | display: box; 38 | 39 | div { 40 | margin: 13px 5px; 41 | background-color: $gray5; 42 | padding: 4px 10px; 43 | border-radius: $radius-size; 44 | 45 | strong { 46 | font-size: 14px; 47 | font-weight: bold; 48 | margin: 0; 49 | } 50 | 51 | span { 52 | font-size: 14px; 53 | display: none; 54 | } 55 | 56 | &.shown span { display: inline; } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/assets/stylesheets/_controls.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | 3 | @mixin button($color) { 4 | background: $color; 5 | border: none; 6 | border-radius: $radius-size; 7 | display: inline-block; 8 | color: $gray3; 9 | font-size: $control-font-size; 10 | font-weight: bold; 11 | text-transform: uppercase; 12 | text-decoration: none; 13 | padding: 5px 10px; 14 | 15 | &:hover { cursor: pointer; } 16 | 17 | &:active { 18 | position: relative; 19 | top: 1px; 20 | } 21 | 22 | &[disabled], &.disabled { 23 | background: lighten($color, 15%); 24 | color: $gray5; 25 | } 26 | 27 | &.small { 28 | font-size: 11px; 29 | padding: 2px 5px; 30 | } 31 | } 32 | 33 | input[type=button], input[type=submit], button, .button { 34 | @include button($darkblue); 35 | &.default { @include button($orange); } 36 | &.success { @include button($darkgreen); } 37 | &.warning { @include button($red); } 38 | } 39 | 40 | input[type=text], input[type=email], input[type=password], input[type=search], input[type=tel], input[type=number], textarea { 41 | @include field-options; 42 | width: 100%; 43 | border: none; 44 | border-radius: $radius-size; 45 | } 46 | 47 | select { 48 | font-size: $control-font-size; 49 | width: 100%; 50 | padding: 5px 10px; 51 | } 52 | 53 | input[type=search] { 54 | -webkit-appearance: textfield; 55 | border-radius: $radius-size*2; 56 | width: 100%; // webkit likes to fix these at 125px 57 | } 58 | 59 | input.error, select.error, textarea.error { 60 | background-color: $red !important; 61 | } 62 | 63 | input:invalid, textarea:invalid, select:invalid { border: 1px solid $red !important; } 64 | -------------------------------------------------------------------------------- /app/assets/stylesheets/_footer.scss: -------------------------------------------------------------------------------- 1 | footer { 2 | p { 3 | text-align: center; 4 | color: rgb(159, 159, 159); 5 | margin-top: 20px; 6 | margin-bottom: 10px; 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /app/assets/stylesheets/_modal.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | 3 | #lean_overlay { 4 | position: fixed; 5 | z-index: 100; 6 | top: 0px; 7 | left: 0px; 8 | height: 100%; 9 | width: 100%; 10 | background: black; 11 | display: none; 12 | } 13 | 14 | .modal { 15 | display: none; 16 | 17 | &>a.close { 18 | position: absolute; 19 | top: 0px; 20 | right: 10px; 21 | font-size: 20px; 22 | font-weight: bold; 23 | color: rgba(black, 0.5); 24 | text-decoration: none; 25 | &:hover { color: black; } 26 | } 27 | 28 | &>.modal-body { 29 | background-color: $gray5; 30 | border-bottom-left-radius: $radius-size; 31 | border-bottom-right-radius: $radius-size; 32 | padding: 10px 50px; 33 | 34 | .accordion { 35 | .accordion-pair>h5 { background-color: $gray4; } 36 | 37 | } 38 | } 39 | 40 | h1 { 41 | background-color: white; 42 | padding: 40px 35px 20px 35px; 43 | margin: 0; 44 | } 45 | 46 | p { margin: 5px 10px 15px 10px; } 47 | } 48 | -------------------------------------------------------------------------------- /app/assets/stylesheets/_pills.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | 3 | ul.pills { 4 | margin-top: 30px; 5 | margin-bottom: 20px; 6 | padding-bottom: 10px; 7 | text-align: center; 8 | border-bottom: 1px solid $gray4; 9 | 10 | &:first-child { margin-top: 0; } 11 | 12 | li { 13 | display: inline; 14 | padding-left: 10px; 15 | padding-right: 10px; 16 | border-right: 1px solid black; 17 | margin-top: 30px; 18 | margin-bottom: 10px; 19 | 20 | &:last-child { border-right: none; } 21 | &.active { font-weight: bold; } 22 | 23 | a { text-decoration: none; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/assets/stylesheets/_tables.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | 3 | @mixin table { 4 | th { 5 | font-weight: bold; 6 | font-size: 11px; 7 | color: $gray2; 8 | text-transform: uppercase; 9 | text-align: left; 10 | background-color: $gray6; 11 | padding: 10px 20px; 12 | white-space: nowrap; 13 | } 14 | 15 | tr { background-color: #f4f4f4; } 16 | tbody>tr:hover:not(.no-highlight) { background-color: white; } 17 | 18 | td { 19 | padding: 10px 20px; 20 | border-bottom: 1px solid $gray5; 21 | 22 | &.table-notice { 23 | padding-top: 20px; 24 | color: $gray4; 25 | font-size: 30px; 26 | font-weight: bold; 27 | text-align: center; 28 | cursor: inherit; 29 | background-color: transparent !important; 30 | } 31 | } 32 | 33 | .no-results { 34 | padding-top: 20px; 35 | color: $gray4; 36 | font-size: 30px; 37 | font-weight: bold; 38 | text-align: center; 39 | } 40 | 41 | a.rowlink { 42 | color: inherit; 43 | text-decoration: none; 44 | } 45 | 46 | tr:hover a.rowlink { text-decoration: underline; } 47 | 48 | @include iphone-landscape-and-smaller { 49 | // for small screens, turn the table on its head: stack the cells of a row 50 | // and create a clear division between these groups 51 | 52 | tr { 53 | display: block; 54 | border-bottom: 3px solid $gray4; 55 | } 56 | 57 | thead>tr { 58 | border-top: 3px solid $gray4; 59 | } 60 | 61 | td, th { display: block; } 62 | td { border-bottom: 1px solid $gray5; } 63 | td:last-child { border-bottom: none; } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/assets/stylesheets/accounts.css.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | 3 | body.accounts { 4 | h1 img { 5 | height: $h1-size; 6 | vertical-align: bottom; 7 | margin-right: 10px; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the top of the 9 | * compiled file, but it's generally better to create a new file per style scope. 10 | * 11 | *= require_self 12 | * 13 | *= require reset 14 | *= require grid 15 | * 16 | *= require bootstrap 17 | *= require font-awesome 18 | *= require sh/shCoreDefault 19 | * 20 | *= require accordion 21 | *= require autocomplete 22 | *= require smart_form 23 | *= require sortable_table 24 | * 25 | *= require squash 26 | *= 27 | *= require accounts 28 | *= require bugs 29 | *= require feed 30 | *= require flash 31 | *= require membership 32 | *= require occurrences 33 | *= require projects 34 | *= require sessions 35 | *= require users 36 | */ 37 | -------------------------------------------------------------------------------- /app/assets/stylesheets/flash.css.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | 3 | #flashes { 4 | position: fixed; 5 | bottom: 0; 6 | left: 0; 7 | width: 50%; 8 | } 9 | 10 | @mixin flash($color) { 11 | font-weight: bold; 12 | padding: 10px 20px; 13 | border-top-right-radius: $radius-size; 14 | border-bottom-right-radius: $radius-size; 15 | margin-top: 10px; 16 | margin-bottom: 10px; 17 | background-color: $color; 18 | 19 | // prepare for slide-in animation 20 | position: relative; 21 | left: -100%; 22 | 23 | [class^="fa-"], [class*=" fa-"] { margin-right: 10px; } 24 | a { 25 | float: right; 26 | font-weight: bold; 27 | opacity: 0.5; 28 | &:hover { opacity: 1; } 29 | } 30 | } 31 | 32 | .flash-alert { @include flash($red); } 33 | .flash-notice { @include flash($blue); } 34 | .flash-success { @include flash($green); } 35 | 36 | $flash-animation-duration: 0.5s; 37 | 38 | .flash-shown { 39 | left: 0%; 40 | -webkit-transition: left $flash-animation-duration ease-out; 41 | -moz-transition: left $flash-animation-duration ease-out; 42 | transition: left $flash-animation-duration ease-out; 43 | } 44 | 45 | .flash-hidden { 46 | left: -100%; 47 | -webkit-transition: left $flash-animation-duration ease-in; 48 | -moz-transition: left $flash-animation-duration ease-in; 49 | transition: left $flash-animation-duration ease-in; 50 | } 51 | -------------------------------------------------------------------------------- /app/assets/stylesheets/membership.css.scss: -------------------------------------------------------------------------------- 1 | body#membership-edit { 2 | .row { padding-bottom: 30px; } 3 | 4 | form { 5 | padding-top: 0; 6 | padding-bottom: 0; 7 | } 8 | 9 | #project-owner img { 10 | float: left; 11 | margin-right: 10px; 12 | } 13 | } 14 | 15 | #email-aliases { 16 | input[type=search] { margin-bottom: 10px; } 17 | } 18 | -------------------------------------------------------------------------------- /app/assets/stylesheets/sessions.css.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | 3 | body.sessions { 4 | .modal-container p { font-size: $h5-size; } 5 | 6 | .body-portion { 7 | h3 { margin-top: 50px; } 8 | 9 | form { 10 | &>div { 11 | margin: 10px 0; 12 | &:last-child { margin-bottom: 0; } 13 | } 14 | 15 | .row .columns { 16 | padding: 0 5px; 17 | &:first-child { padding-left: 0; } 18 | &:last-child { padding-right: 0; } 19 | } 20 | input[type=submit] { width: 100%; } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/assets/stylesheets/squash.css.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | 3 | // ----- RESPONSIVE 4 | 5 | @include ipad-and-larger { 6 | .compact-only { display: none; } 7 | } 8 | 9 | @include iphone-landscape-and-smaller { 10 | .full-size-only { display: none; } 11 | } 12 | 13 | // ----- LAYOUT 14 | 15 | // bleed background colors to the bottom of the page 16 | body { 17 | background-color: white; 18 | font-family: "Helvetica Neue", Helvetica, sans-serif; 19 | font-size: $base-font-size; 20 | } 21 | 22 | @import "typography"; 23 | 24 | // ----- PAGE ELEMENTS 25 | 26 | a.favorite { 27 | text-decoration: none; 28 | &:hover { text-decoration: none; } 29 | i { color: $orange; } 30 | } 31 | 32 | .no-results { 33 | padding-top: 20px; 34 | color: $gray4; 35 | font-size: $h2-size; 36 | font-weight: bold; 37 | text-align: center; 38 | } 39 | 40 | img { 41 | max-width: 100%; 42 | height: auto; 43 | } 44 | 45 | // apply to a div containing a gravatar to the left of profile data 46 | .profile-widget img { 47 | width: 40%; 48 | margin-right: 10px; 49 | float: left; 50 | } 51 | 52 | // ----- IMPORTS 53 | 54 | @import "alerts"; 55 | @import "badges"; 56 | @import "breadcrumbs"; 57 | @import "containers"; 58 | @import "controls"; 59 | @import "forms"; 60 | @import "modal"; 61 | @import "navbar"; 62 | @import "pills"; 63 | @import "footer.scss"; 64 | -------------------------------------------------------------------------------- /app/assets/stylesheets/users.css.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | 3 | body#users-show { 4 | h1 img { 5 | height: $h1-size; 6 | vertical-align: bottom; 7 | margin-right: 10px; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /app/controllers/additions/json_detail_responder.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Subclasses `ActionController::Responder` to include a little more detail in 16 | # the JSON response for 422 errors and successful updates. In particular: 17 | # 18 | # * Alters the default response for successful `create` API requests to render 19 | # the resource representation to the response body. 20 | # * Alters the default response for failing `create` and `update` requests to 21 | # render the errors object with the object's class name 22 | # (see {ApplicationController}, section **Typical Responses**). 23 | 24 | class JsonDetailResponder < ActionController::Responder 25 | protected 26 | 27 | # @private 28 | def json_resource_errors 29 | {resource.class.model_name.singular => resource.errors} 30 | end 31 | 32 | # @private 33 | def api_behavior 34 | raise MissingRenderer.new(format) unless has_renderer? 35 | 36 | if put? || patch? 37 | display resource, location: api_location 38 | else 39 | super 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /app/controllers/additions/password_authentication_helpers.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Includes methods for authentication using logins and passwords. Passwords are 16 | # stored as salted, hashed strings in accordance with normal security standards. 17 | 18 | module PasswordAuthenticationHelpers 19 | # Attempts to log in a user, given his/her credentials. If the login fails, 20 | # the reason is logged and tagged with "[AuthenticationHelpers]". If the login 21 | # is successful, the user ID is written to the session. 22 | # 23 | # @param [String] username The username. 24 | # @param [String] password The password. 25 | # @return [true, false] Whether or not the login was successful. 26 | 27 | def log_in(username, password) 28 | user = User.find_by_username(username) 29 | if user && user.authentic?(password) 30 | log_in_user user 31 | return true 32 | else 33 | logger.tagged('AuthenticationHelpers') { logger.info "Denying login to #{username}: Invalid credentials." } 34 | return false 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /app/controllers/jira/issues_controller.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Controller that loads JIRA issues. 16 | 17 | class Jira::IssuesController < ApplicationController 18 | skip_before_filter :login_required 19 | before_filter :find_issue 20 | respond_to :json 21 | 22 | # Returns information about a JIRA issue. 23 | # 24 | # * `GET /jira/issues/:id` 25 | # 26 | # Path Parameters 27 | # --------------- 28 | # 29 | # | | | 30 | # |:-----|----------------------------------------| 31 | # | `id` | The JIRA issue key (e.g., "PROJ-123"). | 32 | 33 | def show 34 | respond_with(@issue) do |format| 35 | format.json { render json: @issue.to_json } 36 | end 37 | end 38 | 39 | private 40 | 41 | def find_issue 42 | @issue = Service::JIRA.issue(params[:id]) || raise(ActiveRecord::RecordNotFound) 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /app/controllers/jira/projects_controller.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Controller that loads JIRA projects. 16 | 17 | class Jira::ProjectsController < ApplicationController 18 | skip_before_filter :login_required 19 | respond_to :json 20 | 21 | # Returns a list of JIRA projects. 22 | # 23 | # * `GET /jira/projects` 24 | 25 | def index 26 | @projects = Service::JIRA.projects 27 | respond_with(@projects) do |format| 28 | format.json { render json: @projects.to_a.sort_by(&:name).map(&:attrs).to_json } 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /app/controllers/jira/statuses_controller.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Controller that loads JIRA issue statuses. 16 | 17 | class Jira::StatusesController < ApplicationController 18 | skip_before_filter :login_required 19 | respond_to :json 20 | 21 | # Returns a list of JIRA statuses. 22 | # 23 | # * `GET /jira/statuses` 24 | 25 | def index 26 | @statuses = Service::JIRA.statuses 27 | respond_with(@statuses) do |format| 28 | format.json { render json: @statuses.to_a.sort_by(&:name).map(&:attrs).to_json } 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /app/mailers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquareSquash/web/e73f2805f9eb30780a5c213b001f0f4255660fbf/app/mailers/.gitkeep -------------------------------------------------------------------------------- /app/middleware/ping.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Rack middleware that responds to a /_status ping before Rack::SSL gets a 16 | # chance to return a redirect to the HTTPS site. 17 | 18 | class Ping 19 | # @private 20 | def initialize(app) 21 | @app = app 22 | end 23 | 24 | # @private 25 | def call(env) 26 | if env['ORIGINAL_FULLPATH'] == '/_status' 27 | [200, {}, ['{"status":"OK"}']] 28 | else 29 | @app.call env 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquareSquash/web/e73f2805f9eb30780a5c213b001f0f4255660fbf/app/models/.gitkeep -------------------------------------------------------------------------------- /app/models/additions/ldap_authentication.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Adds LDAP-based authentication to the {User} model. Mixed in if this 16 | # Squash install is configured to use LDAP-based authentication. 17 | 18 | module LdapAuthentication 19 | extend ActiveSupport::Concern 20 | 21 | # @return [String] This user's LDAP distinguished name (DN). 22 | 23 | def distinguished_name 24 | "#{Squash::Configuration.authentication.ldap.search_key}=#{username},#{Squash::Configuration.authentication.ldap.tree_base}" 25 | end 26 | 27 | private 28 | 29 | def create_primary_email 30 | emails.create!(email: "#{username}@#{Squash::Configuration.mailer.domain}", primary: true) 31 | end 32 | end 33 | 34 | -------------------------------------------------------------------------------- /app/models/device_bug.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | class DeviceBug < ActiveRecord::Base 16 | self.primary_keys = [:bug_id, :device_id] 17 | 18 | belongs_to :bug, inverse_of: :device_bugs 19 | 20 | validates :bug, 21 | presence: true 22 | validates :device_id, 23 | presence: true, 24 | length: {maximum: 126} 25 | end 26 | -------------------------------------------------------------------------------- /app/models/observers/comment_observer.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # This observer on the {Comment} class creates the "comment" {Event} (on {Bug}) 16 | # as necessary. 17 | 18 | class CommentObserver < ActiveRecord::Observer 19 | # @private 20 | def after_create(comment) 21 | create_event comment 22 | watch_bug comment 23 | end 24 | 25 | # @private 26 | def after_commit_on_create(comment) 27 | BackgroundRunner.run CommentNotificationMailer, comment.id 28 | end 29 | 30 | private 31 | 32 | def create_event(comment) 33 | Event.create! do |event| 34 | event.bug_id = comment.bug_id 35 | event.kind = 'comment' 36 | event.data = {'comment_id' => comment.id} 37 | event.user_id = comment.user_id 38 | end 39 | end 40 | 41 | def watch_bug(comment) 42 | comment.user.watches.where(bug_id: comment.bug_id).find_or_create 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /app/models/observers/deploy_observer.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # This observer on the {Deploy} model: 16 | # 17 | # * sets a Project's `uses_releases` attribute if the Deploy has release 18 | # information. 19 | 20 | class DeployObserver < ActiveRecord::Observer 21 | # @private 22 | def after_create(deploy) 23 | update_project_release_setting deploy 24 | end 25 | 26 | private 27 | 28 | def update_project_release_setting(deploy) 29 | return unless deploy.release? 30 | return if deploy.environment.project.uses_releases_override? 31 | deploy.environment.project.update_attribute :uses_releases, true 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /app/models/observers/occurrence_observer.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # This observer on the {Occurrence} model: 16 | # 17 | # * sends an email when a Bug is critical, and 18 | # * creates {DeviceBug DeviceBugs} as necessary. 19 | 20 | class OccurrenceObserver < ActiveRecord::Observer 21 | # @private 22 | def after_commit_on_create(occurrence) 23 | # send emails 24 | BackgroundRunner.run OccurrenceNotificationMailer, occurrence.id 25 | 26 | # notify pagerduty 27 | BackgroundRunner.run PagerDutyNotifier, occurrence.id 28 | end 29 | 30 | # @private 31 | def after_create(occurrence) 32 | if occurrence.device_id.present? 33 | occurrence.bug.device_bugs.where(device_id: occurrence.device_id).find_or_create! 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /app/models/observers/watch_observer.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # This observer pre-fills (or empties) a User's feed (stored in the 16 | # `user_events` table) when a User watches or unwatches a Bug. 17 | 18 | class WatchObserver < ActiveRecord::Observer 19 | # @private 20 | def after_create(watch) 21 | fill_feed watch 22 | end 23 | 24 | # @private 25 | def after_destroy(watch) 26 | empty_feed watch 27 | end 28 | 29 | private 30 | 31 | def fill_feed(watch) 32 | # add the bug's last 10 events to the user's feed 33 | UserEvent.connection.execute <<-SQL 34 | INSERT INTO user_events 35 | (user_id, event_id, created_at) 36 | SELECT #{watch.user_id}, id, created_at 37 | FROM events 38 | WHERE bug_id = #{watch.bug_id} 39 | ORDER BY created_at DESC 40 | LIMIT 10 41 | SQL 42 | end 43 | 44 | def empty_feed(watch) 45 | # remove all events from the user's feed pertaining to that bug 46 | UserEvent.connection.execute <<-SQL 47 | DELETE FROM user_events 48 | USING events 49 | WHERE user_events.event_id = events.id 50 | AND events.bug_id = #{watch.bug_id} 51 | AND user_events.user_id = #{watch.user_id} 52 | SQL 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /app/models/user_event.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Denormalized association between a {User} and the {Event Events} from the 16 | # {Bug Bugs} that that User is {Watch watching}. 17 | # 18 | # Associations 19 | # ============ 20 | # 21 | # | | | 22 | # |:--------|:----------------------------------------------| 23 | # | `user` | The {User} watching the Bug. | 24 | # | `event` | The {Event} for the Bug the User is watching. | 25 | 26 | class UserEvent < ActiveRecord::Base 27 | self.primary_keys = [:user_id, :event_id] 28 | 29 | belongs_to :user, inverse_of: :user_events 30 | belongs_to :event, inverse_of: :user_events 31 | 32 | validates :user, 33 | presence: true 34 | validates :event, 35 | presence: true 36 | end 37 | -------------------------------------------------------------------------------- /app/models/watch.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # An association created when a {User} watches a {Bug}. {Event Events} created 16 | # for that Bug will appear in the User's feed. 17 | # 18 | # Associations 19 | # ============ 20 | # 21 | # | | | 22 | # |:-------|:-----------------------------| 23 | # | `user` | The {User} watching the Bug. | 24 | # | `bug` | The {Bug} being watched. | 25 | 26 | class Watch < ActiveRecord::Base 27 | self.primary_keys = :user_id, :bug_id 28 | 29 | belongs_to :user, inverse_of: :watches 30 | belongs_to :bug, inverse_of: :watches 31 | 32 | validates :user, 33 | presence: true 34 | validates :bug, 35 | presence: true 36 | validate :user_cannot_watch_foreign_bug 37 | 38 | # @private 39 | def as_json(options=nil) 40 | options ||= {} 41 | options[:except] = Array.wrap(options[:except]) + [:user_id, :bug_id] 42 | options[:include] = Array.wrap(options[:include]) + [:user, :bug] 43 | super options 44 | end 45 | 46 | private 47 | 48 | def user_cannot_watch_foreign_bug 49 | errors.add(:bug_id, :no_permission) unless user.role(bug.environment.project) 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /app/views/notification_mailer/assign.text.erb: -------------------------------------------------------------------------------- 1 | <%= @assigner.try!(:name) || "Someone" %> has assigned bug #<%= @bug.number %> on <%= @bug.environment.project.name %> 2 | to you: 3 | 4 | <%= project_environment_bug_url @bug.environment.project, @bug.environment, @bug %> 5 | 6 | Project: <%= @bug.environment.project.name %> 7 | Environment: <%= @bug.environment.name %> 8 | Revision: <%= @bug.revision %> 9 | Blamed Commit: <%= @bug.blamed_revision %> 10 | 11 | <%= @bug.class_name %> 12 | <% if @bug.special_file? %> 13 | in <%= @bug.file %> 14 | <% else %> 15 | in <%= @bug.file %>:<%= @bug.line %> 16 | <% end %> 17 | 18 | <%= @bug.message_template %> 19 | 20 | ---- 21 | 22 | Is it your fault? 23 | 24 | Under "Management," assign it to yourself, then commit the fix. Mark the bug 25 | as fixed when the fix is pushed. 26 | 27 | Is it someone else's fault? 28 | 29 | Under "Management," assign it to that person -- they will receive an email 30 | notification. 31 | 32 | Is this not really a bug? 33 | 34 | Under "Management," mark the bug as "no one will fix this." You will no 35 | longer receive notifications about this non-bug. You can also simply delete 36 | the bug if it was a one-time test. 37 | 38 | You should take one of the above three actions -- don't just let the bug sit 39 | there! 40 | 41 | Yours truly, 42 | Squash 43 | 44 | --- 45 | 46 | If you wish to stop receiving these emails, visit your account page: 47 | <%= account_url %> 48 | -------------------------------------------------------------------------------- /app/views/notification_mailer/blame.text.erb: -------------------------------------------------------------------------------- 1 | A new exception has occurred on <%= @bug.environment.project.name %>, and Squash 2 | suspects that it's your fault. 3 | 4 | <%= project_environment_bug_url @bug.environment.project, @bug.environment, @bug %> 5 | 6 | Project: <%= @bug.environment.project.name %> 7 | Environment: <%= @bug.environment.name %> 8 | Revision: <%= @bug.revision %> 9 | Blamed Commit: <%= @bug.blamed_revision %> 10 | 11 | <%= @bug.class_name %> 12 | <% if @bug.special_file? %> 13 | in <%= @bug.file %> 14 | <% else %> 15 | in <%= @bug.file %>:<%= @bug.line %> 16 | <% end %> 17 | 18 | <%= @bug.message_template %> 19 | 20 | ---- 21 | 22 | Is it your fault? 23 | 24 | Under "Management," assign it to yourself, then commit the fix. Mark the bug 25 | as fixed when the fix is pushed. 26 | 27 | Is it someone else's fault? 28 | 29 | Under "Management," assign it to that person -- they will receive an email 30 | notification. 31 | 32 | Is this not really a bug? 33 | 34 | Under "Management," mark the bug as "no one will fix this." You will no 35 | longer receive notifications about this non-bug. You can also simply delete 36 | the bug if it was a one-time test. 37 | 38 | You should take one of the above three actions -- don't just let the bug sit 39 | there! 40 | 41 | ---- 42 | 43 | <% if @bug.occurrences.first %> 44 | 45 | Stack trace of initial occurrence: 46 | 47 | <%= render_backtrace(@bug.occurrences.first.faulted_backtrace).indent(2) %> 48 | 49 | ---- 50 | <% end %> 51 | 52 | Yours truly, 53 | Squash 54 | -------------------------------------------------------------------------------- /app/views/notification_mailer/comment.text.erb: -------------------------------------------------------------------------------- 1 | <%= @comment.user.name %> has commented on this bug: 2 | 3 | <%= @bug.class_name %> 4 | <% if @bug.special_file? %> 5 | in <%= @bug.file %> 6 | <% else %> 7 | in <%= @bug.file %>:<%= @bug.line %> 8 | <% end %> 9 | 10 | <%= @bug.message_template %> 11 | 12 | His/her comment was: 13 | 14 | <%= email_quote @comment.body %> 15 | 16 | More details at <%= project_environment_bug_url @bug.environment.project, @bug.environment, @bug, anchor: 'comments' %> 17 | 18 | Yours truly, 19 | Squash 20 | --- 21 | 22 | If you wish to stop receiving these emails, visit your account page: 23 | <%= account_url %> 24 | -------------------------------------------------------------------------------- /app/views/notification_mailer/critical.text.erb: -------------------------------------------------------------------------------- 1 | Bug #<%= @bug.number %> on <%= @bug.environment.project.name %> is occurring 2 | a lot. Perhaps someone should look into it. 3 | 4 | <%= project_environment_bug_url @bug.environment.project, @bug.environment, @bug %> 5 | 6 | Project: <%= @bug.environment.project.name %> 7 | Environment: <%= @bug.environment.name %> 8 | Revision: <%= @bug.revision %> 9 | 10 | <%= @bug.class_name %> 11 | <% if @bug.special_file? %> 12 | in <%= @bug.file %> 13 | <% else %> 14 | in <%= @bug.file %>:<%= @bug.line %> 15 | <% end %> 16 | 17 | <%= @bug.message_template %> 18 | 19 | Yours truly, 20 | Squash 21 | -------------------------------------------------------------------------------- /app/views/notification_mailer/deploy.text.erb: -------------------------------------------------------------------------------- 1 | The fix for this bug has just been deployed: 2 | 3 | <%= project_environment_bug_url @bug.environment.project, @bug.environment, @bug %> 4 | 5 | Project: <%= @bug.environment.project.name %> 6 | Environment: <%= @bug.environment.name %> 7 | Revision: <%= @bug.revision %> 8 | Blamed Commit: <%= @bug.blamed_revision %> 9 | Fix Commit: <%= @bug.resolution_revision %> 10 | 11 | <%= @bug.class_name %> 12 | <% if @bug.special_file? %> 13 | in <%= @bug.file %> 14 | <% else %> 15 | in <%= @bug.file %>:<%= @bug.line %> 16 | <% end %> 17 | 18 | <%= @bug.message_template %> 19 | 20 | Yours truly, 21 | Squash 22 | -------------------------------------------------------------------------------- /app/views/notification_mailer/initial.text.erb: -------------------------------------------------------------------------------- 1 | There's a new class of exceptions occurring on <%= @bug.environment.project.name %>: 2 | 3 | <%= project_environment_bug_url @bug.environment.project, @bug.environment, @bug %> 4 | 5 | Project: <%= @bug.environment.project.name %> 6 | Environment: <%= @bug.environment.name %> 7 | Revision: <%= @bug.revision %> 8 | 9 | <%= @bug.class_name %> 10 | <% if @bug.special_file? %> 11 | in <%= @bug.file %> 12 | <% else %> 13 | in <%= @bug.file %>:<%= @bug.line %> 14 | <% end %> 15 | 16 | <%= @bug.message_template %> 17 | 18 | <% if @bug.occurrences.first %> 19 | ---- 20 | 21 | Stack trace of initial occurrence: 22 | 23 | <%= render_backtrace(@bug.occurrences.first.faulted_backtrace).indent(2) %> 24 | 25 | ---- 26 | <% end %> 27 | 28 | Yours truly, 29 | Squash 30 | -------------------------------------------------------------------------------- /app/views/notification_mailer/occurrence.text.erb: -------------------------------------------------------------------------------- 1 | There has been a new occurrence of this bug. 2 | 3 | Bug: <%= project_environment_bug_url @bug.environment.project, @bug.environment, @bug %> 4 | Occurrence: <%= project_environment_bug_occurrence_url @bug.environment.project, @bug.environment, @bug, @occurrence %> 5 | 6 | THE BUG 7 | 8 | <%= @bug.class_name %> 9 | <% if @bug.special_file? %> 10 | in <%= @bug.file %> 11 | <% else %> 12 | in <%= @bug.file %>:<%= @bug.line %> 13 | <% end %> 14 | 15 | THE OCCURRENCE 16 | 17 | <%= @occurrence.message %> 18 | 19 | <% if @occurrence.web? %> 20 | <% if @occurrence.url %> 21 | Request: <%= @occurrence.request_method %> <%= @occurrence.url.to_s %> 22 | <% else %> 23 | Request: <%= @occurrence.request_method %> (invalid URL) 24 | <% end %> 25 | <% end %> 26 | <% if @occurrence.rails? %> 27 | Controller: <%= @occurrence.controller %> 28 | Action: <%= @occurrence.action %> 29 | <% end %> 30 | <% if @occurrence.server? %> 31 | Hostname: <%= @occurrence.hostname %> 32 | PID: <%= @occurrence.pid %> 33 | <% end %> 34 | <% if @occurrence.client? %> 35 | Build: <%= @occurrence.build %> 36 | Device: <%= @occurrence.device_type %> 37 | OS: <%= @occurrence.operating_system %> 38 | <% end %> 39 | <% if @occurrence.mobile? %> 40 | Network Operator: <%= @occurrence.network_operator %> 41 | Network Type: <%= @occurrence.network_type %> 42 | <% end %> 43 | <% if @occurrence.browser? %> 44 | Web Browser: <%= @occurrence.browser_name %> (<%= @occurrence.browser_version %>) 45 | <% end %> 46 | 47 | Stack trace: 48 | 49 | <%= render_backtrace(@occurrence.faulted_backtrace).indent(2) %> 50 | 51 | Yours truly, 52 | Squash 53 | --- 54 | 55 | If you wish to stop receiving these emails, visit the bug page: 56 | <%= project_environment_bug_url @bug.environment.project, @bug.environment, @bug, anchor: 'notifications' %> 57 | -------------------------------------------------------------------------------- /app/views/notification_mailer/reopened.text.erb: -------------------------------------------------------------------------------- 1 | An exception on <%= @bug.environment.project.name %> has reopened this bug, 2 | which was previously marked as fixed and deployed: 3 | 4 | <%= project_environment_bug_url @bug.environment.project, @bug.environment, @bug %> 5 | 6 | Project: <%= @bug.environment.project.name %> 7 | Environment: <%= @bug.environment.name %> 8 | Revision: <%= @bug.revision %> 9 | Fix Commit: <%= @bug.resolution_revision %> 10 | 11 | <%= @bug.class_name %> 12 | <% if @bug.special_file? %> 13 | in <%= @bug.file %> 14 | <% else %> 15 | in <%= @bug.file %>:<%= @bug.line %> 16 | <% end %> 17 | 18 | <%= @bug.message_template %> 19 | 20 | You should revisit the bug and make sure that it was actually fixed. If an 21 | additional fix is required, update the fix commit under the Management page. 22 | 23 | Yours truly, 24 | Squash 25 | -------------------------------------------------------------------------------- /app/views/notification_mailer/resolved.text.erb: -------------------------------------------------------------------------------- 1 | <%= @resolver.try!(:name) || "Someone" %> has <%= @bug.fixed? ? "resolved a bug" : "marked a bug as irrelevant" %> 2 | that you were assigned to: 3 | 4 | <%= project_environment_bug_url @bug.environment.project, @bug.environment, @bug %> 5 | 6 | Project: <%= @bug.environment.project.name %> 7 | Environment: <%= @bug.environment.name %> 8 | Revision: <%= @bug.revision %> 9 | Blamed Commit: <%= @bug.blamed_revision %> 10 | 11 | <%= @bug.class_name %> 12 | <% if @bug.special_file? %> 13 | in <%= @bug.file %> 14 | <% else %> 15 | in <%= @bug.file %>:<%= @bug.line %> 16 | <% end %> 17 | 18 | <%= @bug.message_template %> 19 | 20 | Yours truly, 21 | Squash 22 | --- 23 | 24 | If you wish to stop receiving these emails, visit your account page: 25 | <%= account_url %> 26 | -------------------------------------------------------------------------------- /app/views/notification_mailer/threshold.text.erb: -------------------------------------------------------------------------------- 1 | Bug #<%= @bug.number %> on <%= @bug.environment.project.name %> has been 2 | occurring frequently lately. You set a threshold on how often it should occur, 3 | and this threshold was exceeded. 4 | 5 | <%= project_environment_bug_url @bug.environment.project, @bug.environment, @bug %> 6 | 7 | Project: <%= @bug.environment.project.name %> 8 | Environment: <%= @bug.environment.name %> 9 | Revision: <%= @bug.revision %> 10 | 11 | <%= @bug.class_name %> 12 | <% if @bug.special_file? %> 13 | in <%= @bug.file %> 14 | <% else %> 15 | in <%= @bug.file %>:<%= @bug.line %> 16 | <% end %> 17 | 18 | <%= @bug.message_template %> 19 | 20 | Yours truly, 21 | Squash 22 | -------------------------------------------------------------------------------- /app/views/occurrences/show.js.erb: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Square Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | $(document).ready(function() { 16 | $('#first-occurrence').liveUpdate(); 17 | $('#occurred-at').liveUpdate(); 18 | 19 | $('.complex-object').valueInspector(); 20 | 21 | $('.show-library-files').click(function(e) { 22 | $(e.currentTarget).parent().parent().find('li.lib, li.filtered').slideToggle(); 23 | }); 24 | 25 | $('.backtrace-link').click(function(event) { 26 | $($(event.target).attr('href')).slideToggle(); 27 | return false; 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /app/views/project/membership/edit.js.erb: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Square Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | $(document).ready(function() { 16 | new EmailAliasForm($('#email-aliases'), 17 | "<%= project_my_membership_emails_url format: 'json' %>", 18 | "<%= project_my_membership_emails_url format: 'json' %>"); 19 | }); 20 | -------------------------------------------------------------------------------- /app/views/projects/edit.js.erb: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Square Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | $(document).ready(function() { 16 | new MemberPanel($('#members'), 17 | "<%= escape_javascript @project.name %>", 18 | "<%= @project.to_param %>", 19 | "<%= users_url %>", 20 | "<%= project_memberships_url(@project, format: 'json') %>", 21 | "<%= project_membership_url(@project, 'USERID', format: 'json') %>", 22 | "<%= project_url(@project, format: 'json') %>", 23 | "<%= current_user.role(@project).to_s %>", 24 | false); 25 | 26 | $('#insert-prefab').click(function() { 27 | var lines; 28 | var prefabMenu = $('#prefab'); 29 | 30 | switch(prefabMenu.val()) { 31 | case 'rails': 32 | lines = ["vendor/"]; 33 | break; 34 | default: lines = []; 35 | } 36 | 37 | if (lines) 38 | $('#project_filter_paths_string').val(($('#project_filter_paths_string').val() + "\n" + lines.join("\n")).replace(/^\n/, '')); 39 | 40 | prefabMenu.val(''); 41 | 42 | return false; 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /app/views/users/show.html.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | # Copyright 2014 Square Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | require Rails.root.join('app', 'views', 'layouts', 'application.html.rb') 18 | 19 | module Views 20 | # @private 21 | module Users 22 | # @private 23 | class Show < Views::Layouts::Application 24 | needs :user 25 | 26 | protected 27 | 28 | def page_title() @user.name end 29 | 30 | def body_content 31 | full_width_section do 32 | h1 do 33 | image_tag @user.gravatar 34 | text @user.name 35 | end 36 | 37 | user_info 38 | end 39 | end 40 | 41 | private 42 | 43 | def user_info 44 | dl do 45 | dt "Username" 46 | dd @user.username 47 | dt "Joined" 48 | dd l(@user.created_at, format: :short_date) 49 | dt "Projects" 50 | dd @user.memberships.count 51 | dt "Projects Owned" 52 | dd @user.owned_projects.count 53 | end 54 | end 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path('../../config/application', __FILE__) 3 | require_relative '../config/boot' 4 | require 'rails/commands' 5 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative '../config/boot' 3 | require 'rake' 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # This file is used by Rack-based servers to start the application. 16 | 17 | require ::File.expand_path('../config/environment', __FILE__) 18 | run Squash::Application 19 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Set up gems listed in the Gemfile. 16 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 17 | 18 | require 'bundler/setup' # Set up gems listed in the Gemfile. 19 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: postgresql 3 | encoding: utf8 4 | host: localhost 5 | username: squash 6 | password: 7 | database: squash_development 8 | 9 | test: 10 | adapter: postgresql 11 | encoding: utf8 12 | host: localhost 13 | username: squash 14 | password: 15 | database: squash_test 16 | 17 | production: 18 | adapter: postgresql 19 | encoding: utf8 20 | host: localhost 21 | username: squash 22 | password: 23 | database: squash_production 24 | pool: 30 25 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Load the Rails application. 16 | require File.expand_path('../application', __FILE__) 17 | 18 | # Initialize the Rails application. 19 | Rails.application.initialize! 20 | -------------------------------------------------------------------------------- /config/environments/common/activerecord.yml: -------------------------------------------------------------------------------- 1 | --- 2 | cursors: false 3 | -------------------------------------------------------------------------------- /config/environments/common/authentication.yml: -------------------------------------------------------------------------------- 1 | --- 2 | strategy: password 3 | registration_enabled: true 4 | -------------------------------------------------------------------------------- /config/environments/common/dogfood.yml: -------------------------------------------------------------------------------- 1 | transmit_timeout: 60 2 | ignored_exception_classes: 3 | - ActionController::RoutingError 4 | - ActionController::MethodNotAllowed 5 | - ActionController::ActionNotFound 6 | ignored_exception_messages: 7 | SignalException: 8 | - SIGTERM 9 | "ActiveRecord::StatementInvalid": 10 | - This connection has been closed. 11 | failsafe_log: log/squash.failsafe.log 12 | disabled: true 13 | allowed_origins: [] -------------------------------------------------------------------------------- /config/environments/common/javascript_dogfood.yml: -------------------------------------------------------------------------------- 1 | --- {} 2 | -------------------------------------------------------------------------------- /config/environments/common/jira.yml: -------------------------------------------------------------------------------- 1 | --- 2 | disabled: true 3 | authentication: 4 | strategy: basic 5 | user: YOUR_USERNAME 6 | password: YOUR_PASSWORD 7 | api_host: "https://yourcompany.com" 8 | api_root: "/jira" 9 | create_issue_details: "/secure/CreateIssueDetails!init.jspa" 10 | -------------------------------------------------------------------------------- /config/environments/common/mailer.yml: -------------------------------------------------------------------------------- 1 | --- 2 | from: squash@YOUR_DOMAIN 3 | domain: YOUR_DOMAIN 4 | strategy: sendmail 5 | smtp_settings: 6 | address: 7 | port: 8 | domain: 9 | user_name: 10 | password: 11 | authentication: 12 | enable_starttls_auto: 13 | -------------------------------------------------------------------------------- /config/environments/common/pagerduty.yml: -------------------------------------------------------------------------------- 1 | --- 2 | disabled: true 3 | authentication: 4 | strategy: token 5 | token: YOUR_AUTH_TOKEN 6 | api_url: "https://events.pagerduty.com/generic/2010-04-15/create_event.json" 7 | -------------------------------------------------------------------------------- /config/environments/common/repositories.yml: -------------------------------------------------------------------------------- 1 | --- 2 | directory: tmp/repos 3 | -------------------------------------------------------------------------------- /config/environments/development/dogfood.yml: -------------------------------------------------------------------------------- 1 | --- 2 | disabled: true 3 | -------------------------------------------------------------------------------- /config/environments/development/mailer.yml: -------------------------------------------------------------------------------- 1 | --- 2 | default_url_options: 3 | host: "localhost:3000" 4 | protocol: http 5 | -------------------------------------------------------------------------------- /config/environments/production/dogfood.yml: -------------------------------------------------------------------------------- 1 | --- 2 | disabled: true 3 | api_key: YOUR_PRODUCTION_SQUASH_API_KEY 4 | api_host: YOUR_URL 5 | -------------------------------------------------------------------------------- /config/environments/production/javascript_dogfood.yml: -------------------------------------------------------------------------------- 1 | --- 2 | APIHost: YOUR_URL 3 | -------------------------------------------------------------------------------- /config/environments/production/mailer.yml: -------------------------------------------------------------------------------- 1 | --- 2 | default_url_options: 3 | host: YOUR_HOSTNAME 4 | protocol: https 5 | -------------------------------------------------------------------------------- /config/environments/test/dogfood.yml: -------------------------------------------------------------------------------- 1 | --- 2 | exception_behavior_when_disabled: raise 3 | -------------------------------------------------------------------------------- /config/environments/test/jira.yml: -------------------------------------------------------------------------------- 1 | --- 2 | authentication: 3 | password: obfuscated 4 | -------------------------------------------------------------------------------- /config/environments/test/mailer.yml: -------------------------------------------------------------------------------- 1 | --- 2 | default_url_options: 3 | host: "test.host" 4 | protocol: http 5 | -------------------------------------------------------------------------------- /config/environments/test/people.yml: -------------------------------------------------------------------------------- 1 | --- 2 | url: 3 | -------------------------------------------------------------------------------- /config/environments/test/squash_javascript.yml: -------------------------------------------------------------------------------- 1 | --- 2 | disabled: true 3 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 11 | Rails.application.config.assets.precompile << 'flot/excanvas.js' 12 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Be sure to restart your server when you modify this file. 16 | 17 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 18 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 19 | 20 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 21 | # Rails.backtrace_cleaner.remove_silencers! 22 | -------------------------------------------------------------------------------- /config/initializers/concurrency.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Spawn and stop the thread pool 16 | 17 | if defined?(PhusionPassenger) 18 | PhusionPassenger.on_event(:starting_worker_process) do |forked| 19 | Multithread.start 20 | end 21 | 22 | PhusionPassenger.on_event(:stopping_worker_process) do 23 | Multithread.stop 24 | end 25 | elsif defined?(Unicorn) 26 | Unicorn::HttpServer.class_eval do 27 | old = instance_method(:worker_loop) 28 | define_method(:worker_loop) do |worker| 29 | Multithread.start 30 | old.bind(self).call(worker) 31 | end 32 | end 33 | else 34 | # Not in Passenger at all 35 | Multithread.start 36 | at_exit { Multithread.stop } 37 | end 38 | 39 | # Load concurrency setup 40 | 41 | BackgroundRunner.runner.setup if BackgroundRunner.runner.respond_to?(:setup) 42 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.action_dispatch.cookies_serializer = :marshal 4 | -------------------------------------------------------------------------------- /config/initializers/field_error_proc.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Change the behavior of fields with bad data. This wraps them in a span with 16 | # data-errors attributes listing the errors. JavaScript then creates the 17 | # appropriate visual error display. 18 | 19 | ActionView::Base.field_error_proc = Proc.new do |html, object| 20 | errors = Array.wrap(object.error_message).map { |error| %(data-error="#{error}") }.join(' ') 21 | %(#{html}).html_safe 22 | end 23 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Be sure to restart your server when you modify this file. 16 | 17 | # Configure sensitive parameters which will be filtered from the log file. 18 | Rails.application.config.filter_parameters += [:password] 19 | -------------------------------------------------------------------------------- /config/initializers/html5.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Adds HTML5 support to Erector::Widget. 16 | 17 | class Erector::Widget 18 | tag 'summary' 19 | end 20 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Be sure to restart your server when you modify this file. 16 | 17 | ActiveSupport::Inflector.inflections do |inflect| 18 | inflect.singular 'statuses', 'status' 19 | end 20 | -------------------------------------------------------------------------------- /config/initializers/jira.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | # Copyright 2014 Square Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # @private 18 | module JIRA 19 | 20 | # @private 21 | # 22 | # Adds timeout capability to the JIRA HTTP client. 23 | 24 | class HttpClient 25 | def http_conn_with_timeout(*args) 26 | http_conn = http_conn_without_timeout(*args) 27 | http_conn.open_timeout = @options[:open_timeout] 28 | http_conn.read_timeout = @options[:read_timeout] 29 | http_conn 30 | end 31 | alias_method_chain :http_conn, :timeout 32 | end 33 | end unless Squash::Configuration.jira.disabled? 34 | -------------------------------------------------------------------------------- /config/initializers/load_autoload_paths.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Not sure why this isn't done automatically by Jetty/Jetpack, but oh well. 16 | 17 | if Squash::Application.config.cache_classes 18 | Squash::Application.config.autoload_paths.each do |path| 19 | Dir.glob(path.join('**', '*.rb')).each { |file| require file } 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /config/initializers/mail.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Configure ActionMailer 16 | 17 | if Squash::Configuration.mailer.strategy == 'smtp' 18 | ActionMailer::Base.smtp_settings = Squash::Configuration.mailer.smtp_settings.symbolize_keys 19 | end 20 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Be sure to restart your server when you modify this file. 16 | 17 | # Add new mime types for use in respond_to blocks: 18 | # Mime::Type.register "text/richtext", :rtf 19 | -------------------------------------------------------------------------------- /config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Be sure to restart your server when you modify this file. 16 | 17 | # Your secret key is used for verifying the integrity of signed cookies. 18 | # If you change this key, all old signed cookies will become invalid! 19 | 20 | # Make sure the secret is at least 30 characters and all random, 21 | # no regular words or you'll be exposed to dictionary attacks. 22 | # You can use `rake secret` to generate a secure secret key. 23 | 24 | # Make sure your secret_key_base is kept private 25 | # if you're sharing your code publicly. 26 | Squash::Application.config.secret_key_base = '_SECRET_' 27 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Be sure to restart your server when you modify this file. 16 | 17 | Rails.application.config.session_store :cookie_store, key: '_squash_session' 18 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Be sure to restart your server when you modify this file. 16 | 17 | # This file contains settings for ActionController::ParamsWrapper which 18 | # is enabled by default. 19 | 20 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 21 | ActiveSupport.on_load(:action_controller) do 22 | wrap_parameters format: [] 23 | end 24 | 25 | # To enable root element in JSON for ActiveRecord objects. 26 | # ActiveSupport.on_load(:active_record) do 27 | # self.include_root_in_json = true 28 | # end 29 | -------------------------------------------------------------------------------- /config/preinitializers/jruby.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # JRUBY-6389 16 | 17 | if RUBY_PLATFORM == 'java' 18 | require 'pathname' 19 | 20 | Pathname.class_eval do 21 | def to_str() to_s end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /config/preinitializers/safe_yaml.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Let's make SafeYAML act exactly like YAML by default, to avoid surprising 16 | # behavior. 17 | SafeYAML::OPTIONS[:default_mode] = :unsafe 18 | SafeYAML::OPTIONS[:deserialize_symbols] = true 19 | 20 | # And let's whitelist the things we transmit over YAML 21 | SafeYAML.whitelist! Squash::Java::Namespace 22 | -------------------------------------------------------------------------------- /config/preinitializers/source_maps.rb: -------------------------------------------------------------------------------- 1 | # Ugh. The sourcemap gem defines a module called SourceMap, which shares the name 2 | # of one of our models. So we have to rename it before we load our model. 3 | if ::SourceMap.kind_of?(Module) 4 | ::GemSourceMap = ::SourceMap 5 | Object.send :remove_const, :SourceMap 6 | elsif ::SourceMap.kind_of?(Class) 7 | raise "SourceMap (the model) defined prior to SourceMap (the module) -- see application.rb" 8 | else 9 | raise "SourceMap must be defined -- see application.rb" 10 | end 11 | 12 | # and redefine the methods that use the other SourceMap class 13 | 14 | # @private 15 | class Sprockets::Asset 16 | def sourcemap 17 | relative_path = if pathname.to_s.include?(Rails.root.to_s) 18 | pathname.relative_path_from(Rails.root) 19 | else 20 | pathname 21 | end.to_s 22 | # any extensions after the ".js" can be removed, because they will have 23 | # already been processed 24 | relative_path.gsub! /(?<=\.js)\..*$/, '' 25 | resource_path = [Rails.application.config.assets.prefix, logical_path].join('/') 26 | 27 | mappings = Array.new 28 | to_s.lines.each_with_index do |_, index| 29 | offset = GemSourceMap::Offset.new(index, 0) 30 | mappings << GemSourceMap::Mapping.new(relative_path, offset, offset) 31 | end 32 | GemSourceMap::Map.new(mappings, resource_path) 33 | end 34 | end 35 | 36 | # @private 37 | class Sprockets::BundledAsset < Sprockets::Asset 38 | def sourcemap 39 | to_a.inject(GemSourceMap::Map.new) do |map, asset| 40 | map + asset.sourcemap 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: 14 | secret_key_base: fd1028c1545b8d18bbc63f01c09d98d825002a4c92f275542dc10061b32b5730ca5d1b56a84e9441c23ee5e610365fd923e0a1c594f31915aefadacce67da213 15 | 16 | test: 17 | secret_key_base: 4274eb8fc145b1b8c2b1a461b5a00cd21d96197d8cbefcecf8fd8cada868fdc3e76c8ba814b76ec943280229406b623092a889226671c850b56778b0ff569c9e 18 | 19 | # Do not keep production secrets in the repository, 20 | # instead read values from the environment. 21 | production: 22 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 23 | -------------------------------------------------------------------------------- /data/brushes.yml: -------------------------------------------------------------------------------- 1 | --- 2 | by_extension: 3 | .ant: xml 4 | .applejs: javascript 5 | .as: actionscript3 6 | .as3: actionscript3 7 | .atom: xml 8 | .atom.erb: ! 'ruby; html-script: true' 9 | .bash: shell 10 | .builder: ruby 11 | .c: cpp 12 | .cc: cpp 13 | .cf: coldfusion 14 | .cpp: cpp 15 | .cs: c-sharp 16 | .css: css 17 | .diff: diff 18 | .erl: erlang 19 | .es: actionscript3 20 | .fx: javafx 21 | .gemspec: ruby 22 | .groovy: groovy 23 | .h: obj-c 24 | .hpp: cpp 25 | .htm: xml 26 | .html: xml 27 | .html.erb: ! 'ruby; html-script: true' 28 | .java: java 29 | .jnlp: xml 30 | .jruby: ruby 31 | .js: javascript 32 | .js2: actionscript3 33 | .json: javascript 34 | .m: obj-c 35 | .pas: delphi 36 | .patch: diff 37 | .pch: obj-c 38 | .php: ! 'php; html-script: true' 39 | .pl: perl 40 | .pm: perl 41 | .ps: powershell 42 | .py: python 43 | .rake: ruby 44 | .rb: ruby 45 | .rhtml: ! 'ruby; html-script: true' 46 | .rjs: ruby 47 | .rss: xml 48 | .rss.erb: ! 'ruby; html-script: true' 49 | .ru: ruby 50 | .rxml: ruby 51 | .sass: sass 52 | .scala: scala 53 | .scpt: applescript 54 | .scss: sass 55 | .sh: shell 56 | .shtm: xml 57 | .shtml: xml 58 | .sql: sql 59 | .vb: vb 60 | .wsdl: xml 61 | .xml: xml 62 | .xml.erb: ! 'ruby; html-script: true' 63 | .xsl: xml 64 | .xslt: xml 65 | .yaml: yaml 66 | .yml: yaml 67 | by_filename: 68 | Capfile: ruby 69 | Gemfile: ruby 70 | Rakefile: ruby 71 | default: plain 72 | -------------------------------------------------------------------------------- /db/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite3 -------------------------------------------------------------------------------- /db/migrate/20130125021927_index_occurrences_by_bug_and_redirected.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | class IndexOccurrencesByBugAndRedirected < ActiveRecord::Migration 16 | def up 17 | execute "CREATE INDEX occurrences_bug_redirect ON occurrences(bug_id, redirect_target_id)" 18 | end 19 | 20 | def down 21 | execute "DROP INDEX occurrences_bug_redirect" 22 | end 23 | end 24 | 25 | -------------------------------------------------------------------------------- /db/migrate/20130131002503_track_bugs_per_device.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | class TrackBugsPerDevice < ActiveRecord::Migration 16 | def up 17 | execute <<-SQL 18 | CREATE TABLE device_bugs ( 19 | bug_id INTEGER NOT NULL REFERENCES bugs(id) ON DELETE CASCADE, 20 | device_id CHARACTER VARYING(126) NOT NULL, 21 | PRIMARY KEY (bug_id, device_id) 22 | ) 23 | SQL 24 | end 25 | 26 | def down 27 | drop_table :device_bugs 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /db/migrate/20130215185809_fix_condition_on_rule_occurrences_set_latest.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | class FixConditionOnRuleOccurrencesSetLatest < ActiveRecord::Migration 16 | def up 17 | execute <<-SQL 18 | CREATE OR REPLACE RULE occurrences_set_latest AS 19 | ON INSERT TO occurrences DO 20 | UPDATE bugs 21 | SET latest_occurrence = NEW.occurred_at 22 | WHERE (bugs.id = NEW.bug_id) 23 | AND ((bugs.latest_occurrence IS NULL) 24 | OR (bugs.latest_occurrence < NEW.occurred_at)) 25 | SQL 26 | end 27 | 28 | def down 29 | execute <<-SQL 30 | CREATE OR REPLACE RULE occurrences_set_latest AS 31 | ON INSERT TO occurrences DO 32 | UPDATE bugs 33 | SET latest_occurrence = NEW.occurred_at 34 | WHERE (bugs.id = NEW.bug_id) 35 | AND (bugs.latest_occurrence IS NULL) 36 | OR (bugs.latest_occurrence < NEW.occurred_at) 37 | SQL 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /db/migrate/20130221020818_create_blames.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | class CreateBlames < ActiveRecord::Migration 16 | def up 17 | execute <<-SQL 18 | CREATE UNLOGGED TABLE blames ( 19 | id SERIAL PRIMARY KEY, 20 | repository_hash CHARACTER(40) NOT NULL, 21 | revision CHARACTER(40) NOT NULL, 22 | file CHARACTER VARYING(255) NOT NULL CHECK (CHAR_LENGTH(file) > 0), 23 | line INTEGER NOT NULL CHECK (line > 0), 24 | blamed_revision CHARACTER VARYING(40) NOT NULL, 25 | updated_at TIMESTAMP WITHOUT TIME ZONE 26 | ) 27 | SQL 28 | 29 | execute "CREATE UNIQUE INDEX blames_key ON blames(repository_hash, revision, file, line)" 30 | execute "CREATE UNIQUE INDEX blames_lru ON blames(updated_at)" 31 | end 32 | 33 | def down 34 | drop_table :blames 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /db/migrate/20130222055524_fix_blame_lru_key.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | class FixBlameLruKey < ActiveRecord::Migration 16 | def up 17 | execute "DROP INDEX blames_lru" 18 | execute "CREATE INDEX blames_lru ON blames(updated_at)" 19 | end 20 | 21 | def down 22 | execute "DROP INDEX blames_lru" 23 | execute "CREATE UNIQUE INDEX blames_lru ON blames(updated_at)" 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /db/migrate/20140130012355_add_mapping_to_source_map.rb: -------------------------------------------------------------------------------- 1 | class AddMappingToSourceMap < ActiveRecord::Migration 2 | def up 3 | execute <<-SQL 4 | ALTER TABLE source_maps 5 | ADD COLUMN "from" CHARACTER VARYING(24) NOT NULL DEFAULT 'minified' CHECK (CHAR_LENGTH("from") > 0), 6 | ADD COLUMN "to" CHARACTER VARYING(24) NOT NULL DEFAULT 'original' CHECK (CHAR_LENGTH("to") > 0) 7 | SQL 8 | 9 | execute 'ALTER TABLE source_maps ALTER "from" DROP NOT NULL' 10 | execute 'ALTER TABLE source_maps ALTER "to" DROP NOT NULL' 11 | execute "DROP INDEX source_maps_env_revision" 12 | execute 'CREATE INDEX source_maps_env_revision ON source_maps(environment_id, revision, "from")' 13 | end 14 | 15 | def down 16 | execute 'ALTER TABLE source_maps DROP "from", DROP "to"' 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /db/migrate/20151126022941_add_hosted_filename_to_source_maps.rb: -------------------------------------------------------------------------------- 1 | class AddHostedFilenameToSourceMaps < ActiveRecord::Migration 2 | def up 3 | add_column :source_maps, :filename, :string, limit: 255 4 | 5 | say "Updating existing source maps" 6 | SourceMap.reset_column_information 7 | SourceMap.find_each(batch_size: 50) do |map| 8 | map.update_attribute :filename, map.map.filename 9 | end 10 | 11 | change_column :source_maps, :filename, :string, null: false, limit: 255 12 | 13 | add_index :source_maps, :filename 14 | end 15 | 16 | def down 17 | remove_column :source_maps, :filename 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # This file should contain all the record creation needed to seed the database with its default values. 16 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 17 | # 18 | # Examples: 19 | # 20 | # cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }]) 21 | # Mayor.create(:name => 'Emanuel', :city => cities.first) 22 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | app 2 | js 3 | -------------------------------------------------------------------------------- /doc/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing 2 | ============ 3 | 4 | If you would like to contribute code to Squash, thank you! You can do so through 5 | GitHub by forking one of the repositories and sending a pull request. However, 6 | before your code can be accepted into the project we need you to sign the (super 7 | simple) [Individual Contributor License Agreement (CLA)][1]. 8 | 9 | [1]: https://spreadsheets.google.com/spreadsheet/viewform?formkey=dDViT2xzUHAwRkI3X3k5Z0lQM091OGc6MQ&ndplr=1 10 | -------------------------------------------------------------------------------- /doc/fdoc/deobfuscation-POST.fdoc: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | Upload Java deobfuscation data to Squash. This data typically comes from a 4 | renamelog.xml file generated by yGuard, and is parsed and serialized using the 5 | `squash_java_deobfuscator` gem. 6 | responseCodes: 7 | - status: 422 8 | successful: false 9 | description: | 10 | * Invalid deobfuscation data was provided. 11 | * Missing required API parameter. 12 | - status: 403 13 | successful: false 14 | description: Unknown API key. 15 | - status: 404 16 | successful: false 17 | description: | 18 | * Unknown build number. 19 | * Unknown environment name. 20 | - status: 201 21 | successful: true 22 | requestParameters: 23 | properties: 24 | namespace: 25 | description: | 26 | The `Squash::Java::Namespace` object (generated using the 27 | `squash_java_deobfuscator` gem), YAML-serialized, then gzipped, then base 28 | 64-encoded. 29 | required: true 30 | type: string 31 | example: "eJxj4ci3kgouLE0szvBKLEu0svJLzE0tLkhMTmW3EnAoKMrMzSzJLEstzrfi\nCE4tYbPicsgAKq1msBJ2ACrKTkxPjS/Kzy8pzrdmZ7PmqGYAABwOGY8=\n" 32 | api_key: 33 | description: Your project's API key. 34 | required: true 35 | type: string 36 | example: 22c09d74-1882-4029-9699-af4c57ed060c 37 | environment: 38 | description: The environment name. 39 | required: true 40 | type: string 41 | example: production 42 | build: 43 | description: | 44 | The internal build number of the release this deobfuscation data 45 | pertains to. 46 | required: true 47 | type: string 48 | example: '6314' 49 | -------------------------------------------------------------------------------- /doc/fdoc/sourcemap-POST.fdoc: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | Uploads a JavaScript source map to Squash. This data is generated by your 4 | JavaScript minifier, and then parsed and serialized using the 5 | `squash_javascript` gem. 6 | responseCodes: 7 | - status: 422 8 | successful: false 9 | description: | 10 | * Missing required parameter. 11 | * Invalid parameter value. 12 | - status: 403 13 | successful: false 14 | description: Unknown API key. 15 | - status: 201 16 | successful: true 17 | requestParameters: 18 | properties: 19 | sourcemap: 20 | description: | 21 | A JSON-serialized source map, gzipped, then base 64-encoded. 22 | required: true 23 | type: string 24 | example: "eJxj4ci3UgguLE0szvBKLEssTi7KLCixsgrOLy1KTvVNLGCz4nPITSwoyMxL\nL45mAABqrw+t\n" 25 | api_key: 26 | description: Your project's API key. 27 | required: true 28 | type: string 29 | example: b305d2a6-dc2a-4c01-a345-82e8ce529c26 30 | environment: 31 | description: The name of the environment to which this source map applies. 32 | required: true 33 | type: string 34 | example: production 35 | revision: 36 | description: | 37 | The SHA1 of the Git revision of the code under which this source map was 38 | generated. 39 | required: true 40 | type: string 41 | example: 2dc20c984283bede1f45863b8f3b4dd9b5b554cc 42 | from: 43 | description: | 44 | The type of generated JavaScript code this source map transforms from. 45 | "hosted" should be used for the final hosted JS; other names are 46 | arbitrary. 47 | required: true 48 | type: string 49 | example: hosted 50 | to: 51 | description: | 52 | The type of generated or human-written JavaScript/CoffeeScript code this 53 | source map transforms to. 54 | required: true 55 | type: string 56 | example: concatenated 57 | -------------------------------------------------------------------------------- /doc/fdoc/squash.fdoc.service: -------------------------------------------------------------------------------- 1 | --- 2 | name: Squash 3 | basePath: '/api/1.0' 4 | description: | 5 | The API for Squash allows client libraries to notify Squash of exceptions and 6 | deploys, and upload data that Squash can use to analyze incoming exceptions 7 | (e.g., source maps, symbolication data, etc.). 8 | -------------------------------------------------------------------------------- /doc/fdoc/symbolication-POST.fdoc: -------------------------------------------------------------------------------- 1 | --- 2 | description: | 3 | Upload Objective-C symbolication data to Squash. This data is generated by 4 | your compiler, and then uploaded to Squash using the `squash_ios_symbolicator` 5 | gem. 6 | responseCodes: 7 | - status: 422 8 | successful: false 9 | description: | 10 | * Missing required parameter. 11 | * Invalid symbolication data. 12 | - status: 201 13 | successful: true 14 | requestParameters: 15 | properties: 16 | symbolications: 17 | description: Array of symbolication data. 18 | required: true 19 | type: array 20 | items: 21 | type: hash 22 | properties: 23 | uuid: 24 | description: | 25 | The unique symbolication UUID. This UUID is generated by DWARF for 26 | each new compile, and can be found using `dwarfdump -u`. 27 | required: true 28 | type: string 29 | example: 8817e7da-8c0d-44f0-9eec-24e418425630 30 | symbols: 31 | description: | 32 | A `Squash::Symbolicator::Symbols` object (as generated by 33 | `squash_ios_symbolicator`), YAML-serialized, then gzipped, then base 34 | 64-encoded. 35 | required: false 36 | type: string 37 | example: "eJxj4ci3kgquzE3Kz8lMTizJL7KygvCK2ax4HYohzGgGAP7YDRY=\n" 38 | lines: 39 | description: | 40 | A `Squash::Symbolicator::Lines` object (as generated by 41 | `squash_ios_symbolicator`), YAML-serialized, then gzipped, then base 42 | 64-encoded. 43 | required: false 44 | type: string 45 | example: "eJxj4ci3kgiuzE3Kz8lMTizJL7Ky8snMSy1ms+J2yAExohkAxuwLNg==\n" 46 | -------------------------------------------------------------------------------- /lib/api/errors.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | module API 16 | # Raised when invalid attributes are provided to the worker. 17 | class InvalidAttributesError < StandardError; end 18 | 19 | # Raised when an unknown API key is provided. 20 | class UnknownAPIKeyError < StandardError; end 21 | end 22 | -------------------------------------------------------------------------------- /lib/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquareSquash/web/e73f2805f9eb30780a5c213b001f0f4255660fbf/lib/assets/.gitkeep -------------------------------------------------------------------------------- /lib/assets/javascripts/accordion.js.coffee: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | root = exports ? this 16 | 17 | # Implements accordion behavior. An accordion container must have the class of 18 | # "accordion" and consist of one or more elements of class "accordion-pair". 19 | # Each of these elements must have an `
` (header) and a `
` (body). 20 | # 21 | # Accordion headers must contain an `` element whose `href` is the jQuery 22 | # specifier for the `
` body and whose `rel` is "accordion". 23 | # 24 | $(window).ready -> 25 | $('a[rel=accordion]').click (e) -> 26 | link = $(e.currentTarget) 27 | target = $(link.attr('href')) 28 | 29 | # hide all other items 30 | shown = target.closest('.accordion').find('.accordion-pair.shown') 31 | shown.find('>div').slideUp 'fast', -> shown.removeClass('shown') 32 | 33 | # toggle the target item 34 | if target.hasClass('shown') 35 | target.find('>div').slideUp 'fast', -> target.removeClass('shown') 36 | else 37 | target.addClass('shown') 38 | target.find('>div').slideDown 'fast' 39 | 40 | e.preventDefault() 41 | e.stopPropagation() 42 | return false 43 | -------------------------------------------------------------------------------- /lib/assets/javascripts/bug_file_formatter.js.coffee: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | root = exports ? this 16 | 17 | # Formats a Bug's file name, taking into account special files. 18 | # 19 | # @param [Object] bug The Bug. 20 | # @return [String] The abbreviated file name. 21 | # 22 | root.formatBugFile = (bug) -> 23 | #TODO don't guess, record this information 24 | if bug.file.match(/^\[S\] /) 25 | "" 26 | else 27 | parts = bug.file.split('/') 28 | parts[parts.length - 1] 29 | -------------------------------------------------------------------------------- /lib/assets/javascripts/buttons.js.coffee: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Any buttons with HREF attributes automatically act as links. These buttons can 16 | # also have DATA-SQMETHOD and DATA-SQCONFIRM attributes similar to Rails magic 17 | # links. 18 | # 19 | jQuery.fn.autoButton = -> 20 | for element in this 21 | do (element) -> 22 | $(element).click (e) -> 23 | button = $(e.currentTarget) 24 | 25 | perform = true 26 | if button.data('sqconfirm') 27 | perform = confirm(button.data('sqconfirm')) 28 | unless perform then return false 29 | 30 | if button.data('sqmethod') 31 | form = $('
').attr(action: button.attr('href'), method: 'POST') 32 | $('').attr(type: 'hidden', name: '_method', value: button.data('sqmethod')).appendTo form 33 | $('').attr(type: 'hidden', name: $('meta[name=csrf-param]').attr('content'), value: $('meta[name=csrf-token]').attr('content')).appendTo form 34 | form.submit() 35 | else 36 | window.location = button.attr('href') 37 | return $(this) 38 | 39 | # Applies button behavior to any BUTTON tags already on the page at load time. 40 | $(document).ready -> $('button[href]').autoButton() 41 | -------------------------------------------------------------------------------- /lib/assets/javascripts/configure_squash_client.js.coffee.erb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http: //www.apache.org / licenses / LICENSE - 2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | <% unless Squash::Ruby.configuration :disabled %> 16 | # first the settings imported from the ruby client 17 | SquashJavascript.instance().configure 18 | APIHost: "<%= Squash::Ruby.configuration(:api_host) %>" 19 | APIKey: "<%= Squash::Ruby.configuration(:api_key) %>" 20 | notifyPath: "<%= Squash::Ruby.configuration :notify_path %>" 21 | environment: "<%= Rails.env %>" 22 | revision: "<%= Squash::Ruby.current_revision %>" 23 | 24 | # then the JavaScript-specific overrides 25 | SquashJavascript.instance().configure <%= Squash::Configuration.javascript_dogfood.to_json %> 26 | <% end %> 27 | -------------------------------------------------------------------------------- /lib/assets/javascripts/context.js.coffee: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Finds PRE tags of class "context" and asynchronously loads context data from 16 | # the Git repository. Displays a selected line of code from the repo with 3 17 | # lines of context above and below. 18 | # 19 | jQuery.fn.applyContext = -> 20 | for tag in this 21 | do (tag) -> 22 | element = $(tag) 23 | $.ajax "/projects/#{element.attr 'data-project'}/commits/#{element.data 'revision'}/context.json", 24 | type: 'GET' 25 | data: $.param 26 | file: element.data('file') 27 | line: element.data('line') 28 | context: (element.data('context') || 3) 29 | success: (snippet) -> 30 | element.text(snippet.code).removeClass().addClass("brush: #{snippet.brush}; ruler: true; first-line: #{snippet.first_line}; highlight: #{element.data('line')}; toolbar: false; unindent: false") 31 | SyntaxHighlighter.highlight() 32 | error: (xhr) -> 33 | if xhr && xhr.responseText 34 | element.text JSON.parse(xhr.responseText).error 35 | else 36 | element.text "Couldn’t load context." 37 | this 38 | 39 | # Loads context data for any appropriate PRE tags already on the page at load 40 | # time. 41 | # 42 | $(document).ready -> $('pre.context').applyContext() 43 | -------------------------------------------------------------------------------- /lib/assets/javascripts/disclosure.js.coffee: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Adds disclosure-triangle support to DETAILS/SUMMARY tags in Firefox and 16 | # Safari. (Chrome already has native support.) 17 | # 18 | jQuery.fn.details = -> 19 | for tag in this 20 | do (tag) -> 21 | container = $(tag) 22 | header = container.find('>summary') 23 | container.children(':not(summary)').wrapAll $('
') 24 | content = container.find('>div') 25 | triangle = $('').addClass('fa fa-play').prependTo(header) 26 | shown = false 27 | 28 | if container.data('open') 29 | triangle.css("-#{browser}-transform", "rotate(90deg)") for browser in ['webkit', 'moz', 'o'] 30 | shown = true 31 | else 32 | content.hide() 33 | 34 | triangle.click -> 35 | triangle.css("-#{browser}-transform", "rotate(#{if shown then 0 else 90}deg)") for browser in ['webkit', 'moz', 'o'] 36 | shown = !shown 37 | content.slideToggle() 38 | this 39 | -------------------------------------------------------------------------------- /lib/assets/javascripts/dynamic_search_field.js.coffee: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | root = exports ? this 16 | 17 | # Adds behavior to a search or filter field. The handler is executed when the 18 | # user stops typing for one second. 19 | # 20 | class root.DynamicSearchField 21 | 22 | # Creates a new manager for a dynamic search field. 23 | # 24 | # @param [jQuery element array] element The INPUT field to make dynamic. 25 | # @param [function] handler The handler to execute. 26 | # 27 | constructor: (@element, @handler) -> 28 | @element.keypress (e) => 29 | return false if e.charCode == 13 30 | @element.stopTime() 31 | @element.oneTime 1000, 'search-update', => 32 | @handler(@element.val()) 33 | @element.submit (e) -> 34 | e.stopPropagation() 35 | e.preventDefault() 36 | false 37 | -------------------------------------------------------------------------------- /lib/assets/javascripts/error_tooltip.js.coffee: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | root = exports ? this 16 | 17 | # @private 18 | escape = (str) -> str.replace('&', '&').replace('<', '<').replace('>', '>') 19 | 20 | # Generates appropriate options to send to the Bootstrap tooltip function for a 21 | # tooltip containing the error messages associated with a form field. 22 | # 23 | # @param [Array] errors The error messages for a form field. 24 | # 25 | root.errorTooltipOptions = (errors) -> 26 | { 27 | title: (escape(error) for error in errors).join("
") 28 | html: true 29 | placement: 'right' 30 | trigger: 'focus' 31 | template: '
' 32 | } 33 | -------------------------------------------------------------------------------- /lib/assets/javascripts/form_with_errors.js.coffee: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Works with config/initializers/field_error_proc.rb to properly stylize form 16 | # fields with errors. This is intended for basic HTML forms; smart Ajax-y forms 17 | # are handled by {SmartForm}. 18 | 19 | $(document).ready -> 20 | $('.field-with-errors').each (_, span) -> 21 | element = $(span) 22 | errors = (attr.value for attr in span.attributes when attr.name == 'data-error') 23 | form_element = element.find('input,textarea,select') 24 | element.children().unwrap() 25 | 26 | form_element.addClass 'error' 27 | form_element.tooltip errorTooltipOptions(errors) 28 | -------------------------------------------------------------------------------- /lib/assets/stylesheets/accordion.css.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | 3 | .accordion { 4 | margin: 10px 0; 5 | 6 | &>.accordion-pair { 7 | &>h5 { 8 | background-color: $gray5; 9 | margin: 0; 10 | padding: 10px 20px; 11 | border-radius: $radius-size; 12 | margin-top: 5px; 13 | 14 | a { text-decoration: none; } 15 | } 16 | 17 | &:first-child>h5 { margin-top: 0; } 18 | 19 | &>div { 20 | padding: 10px 20px; 21 | background-color: white; 22 | border-bottom-left-radius: $radius-size; 23 | border-bottom-right-radius: $radius-size; 24 | } 25 | 26 | &.shown { 27 | &>h5 { 28 | border-bottom-left-radius: 0; 29 | border-bottom-right-radius: 0; 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/assets/stylesheets/autocomplete.css.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | 3 | ul.autocomplete { 4 | z-index: 99; 5 | position: absolute; 6 | left: 0; 7 | min-width: 200px; 8 | border: 1px solid $gray4; 9 | box-shadow: 0 4px 4px rgba(black, 0.5); 10 | background-color: white; 11 | display: none; 12 | &.shown { display: block; } 13 | 14 | li { 15 | padding: 5px 10px; 16 | &.selected { background-color: $blue; } 17 | &:hover { cursor: pointer; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/assets/stylesheets/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | 27 | /* HTML5 display-role reset for older browsers */ 28 | article, aside, details, figcaption, figure, 29 | footer, header, hgroup, menu, nav, section { 30 | display: block; 31 | } 32 | 33 | body { 34 | line-height: 1; 35 | } 36 | 37 | ol, ul { 38 | list-style: none; 39 | } 40 | 41 | blockquote, q { 42 | quotes: none; 43 | } 44 | 45 | blockquote:before, blockquote:after, 46 | q:before, q:after { 47 | content: ''; 48 | content: none; 49 | } 50 | 51 | table { 52 | border-collapse: collapse; 53 | border-spacing: 0; 54 | } 55 | 56 | fieldset { 57 | -webkit-margin-start: 0; 58 | -webkit-margin-end: 0; 59 | -webkit-padding-before: 0; 60 | -webkit-padding-start: 0; 61 | -webkit-padding-end: 0; 62 | -webkit-padding-after: 0; 63 | } 64 | -------------------------------------------------------------------------------- /lib/assets/stylesheets/smart_form.css.scss: -------------------------------------------------------------------------------- 1 | .tooltip-error .tooltip-inner { background-color: #700; } 2 | .tooltip-error.top { .tooltip-arrow { border-top-color: #700; } } 3 | .tooltip-error.left { .tooltip-arrow { border-left-color: #700; } } 4 | .tooltip-error.right { .tooltip-arrow { border-right-color: #700; } } 5 | .tooltip-error.bottom { .tooltip-arrow { border-bottom-color: #700; } } 6 | -------------------------------------------------------------------------------- /lib/assets/stylesheets/sortable_table.css.scss: -------------------------------------------------------------------------------- 1 | @import "vars"; 2 | @import "tables"; 3 | 4 | table.sortable { 5 | @include table; 6 | 7 | th { 8 | &.sortable:hover { cursor: pointer; } 9 | &.sorted { background-color: $gray5; } 10 | 11 | i { 12 | margin-left: 5px; 13 | float: right; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/background_runner.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Parent container for the BackgroundRunner module cluster. This module stores 16 | # the modules that encapsulate different strategies for executing long-running 17 | # background tasks outside of the scope of a request-response handler. 18 | # 19 | # @example Running a DeployFixMarker job 20 | # BackgroundRunner.run DeployFixMarker, deploy.id 21 | # 22 | # All `BackgroundRunner` modules should implement a `run` class method that 23 | # takes, as its first argument, the name of a worker class under `lib/workers`. 24 | # It should take any other number of arguments as long as they are serializable. 25 | 26 | module BackgroundRunner 27 | 28 | # @return [Module] The active module that should be used to handle 29 | # background jobs. 30 | 31 | def self.runner 32 | BackgroundRunner.const_get Squash::Configuration.concurrency.background_runner.to_sym, false 33 | end 34 | 35 | # Shortcut for `BackgroundRunner.runner.run`. 36 | 37 | def self.run(*args) 38 | runner.run *args 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/background_runner/job.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | module BackgroundRunner 16 | 17 | # Mixin included into every worker that operates with {BackgroundRunner}. 18 | 19 | module Job 20 | extend ActiveSupport::Concern 21 | 22 | included do 23 | if BackgroundRunner.runner.respond_to?(:extend_job) 24 | # call extend_job for this class... 25 | BackgroundRunner.runner.extend_job self 26 | 27 | # ... and all subclasses ... 28 | subclasses.each { |klass| BackgroundRunner.runner.extend_job klass } 29 | 30 | # ... and all future subclasses 31 | class_eval <<-RUBY 32 | def self.inherited(subclass) 33 | BackgroundRunner.runner.extend_job subclass 34 | end 35 | RUBY 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/background_runner/multithread.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | module BackgroundRunner 16 | 17 | # BackgroundRunner adapter for {::Multithread}. This module generates 18 | # Multithread jobs and assigns them priorities as specified in the 19 | # `concurrency.yml` Configoro file. 20 | 21 | module Multithread 22 | 23 | # Sends a job to {::Multithread.spinoff}. The job's name and priority are 24 | # calculated automatically. 25 | # 26 | # @param [String, Class] job_name The name of the class under `lib/workers` 27 | # to run. 28 | 29 | def self.run(job_name, *arguments) 30 | job_name = job_name.constantize unless job_name.kind_of?(Class) 31 | ::Multithread.spinoff(queue_item_name(job_name, arguments), priority(job_name)) { job_name.perform *arguments } 32 | end 33 | 34 | private 35 | 36 | def self.queue_item_name(job_name, arguments) 37 | return nil if job_name.to_s == 'OccurrencesWorker' 38 | [job_name, arguments.map(&:inspect)].join(':') 39 | end 40 | 41 | def self.priority(job_name) 42 | Squash::Configuration.concurrency.multithread.priority[job_name.to_s] 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/background_runner/tasks/resque.rake: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | require 'resque/tasks' 16 | require 'resque/pool/tasks' 17 | 18 | # We'll override the default pool task in order to use our Squash config 19 | Rake::Task['resque:pool'].clear 20 | 21 | namespace :resque do 22 | task setup: :environment 23 | 24 | task 'pool:setup' do 25 | ActiveRecord::Base.connection.disconnect! 26 | Resque::Pool.after_prefork do |_job| 27 | ActiveRecord::Base.establish_connection 28 | end 29 | end 30 | 31 | desc "Launch a pool of resque workers" 32 | task pool: %w[resque:setup resque:pool:setup] do 33 | require 'resque/pool' 34 | 35 | rails_root = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..' 36 | rails_env = ENV['RAILS_ENV'] || 'development' 37 | 38 | common_file = File.join(rails_root.to_s, 'config', 'environments', 'common', 'concurrency.yml') 39 | env_file = File.join(rails_root.to_s, 'config', 'environments', rails_env, 'concurrency.yml') 40 | 41 | config = YAML.load_file(common_file) 42 | if File.exist?(env_file) 43 | config.merge! YAML.load_file(env_file) 44 | end 45 | 46 | if GC.respond_to?(:copy_on_write_friendly=) 47 | GC.copy_on_write_friendly = true 48 | end 49 | 50 | Resque::Pool.new(config['resque']['pool']).start.join 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /lib/background_runner/tasks/sidekiq.rake: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | namespace :sidekiq do 16 | desc "Writes a Sidekiq configuration file into config/sidekiq.yml" 17 | task configure: :environment do 18 | File.open(Rails.root.join('config', 'sidekiq.yml'), 'w') do |f| 19 | f.puts Squash::Configuration.concurrency.sidekiq.redis.except('url').symbolize_keys.to_yaml 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/blamer/simple.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | require 'digest/sha2' 16 | 17 | module Blamer 18 | 19 | # A simple, Git-free blamer that groups occurrences with identical stack 20 | # traces. While less cool than the {Blamer::Recency Recency} blamer, it has 21 | # the advantage of not requiring access to the Git repository. 22 | 23 | class Simple < Base 24 | 25 | protected 26 | 27 | def bug_search_criteria 28 | @special = true 29 | file = '[S] ' + Digest::SHA2.hexdigest(occurrence.faulted_backtrace.to_json) 30 | 31 | { 32 | class_name: occurrence.bug.class_name, 33 | file: file, 34 | line: 1, 35 | blamed_revision: nil 36 | } 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/service.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Container module for third-party service integrations. 16 | 17 | module Service 18 | end 19 | -------------------------------------------------------------------------------- /lib/sidekiq_auth_constraint.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Authorization constraint, used by the Sidekiq routes, that ensures that there 16 | # exists a current user session. 17 | 18 | module SidekiqAuthConstraint 19 | 20 | # The default `authorized?` implementation if there is no refined 21 | # implementation provided by the authentication strategy. 22 | 23 | module Default 24 | 25 | # Determines whether a user can access the Sidekiq admin page. 26 | # 27 | # @param [ActionDispatch::Request] request A request. 28 | # @return [true, false] Whether the user can access the Sidekiq admin page. 29 | 30 | def authorized?(request) 31 | return false unless request.session[:user_id] 32 | user = User.find(request.session[:user_id]) 33 | !user.nil? 34 | end 35 | end 36 | 37 | # first incorporate the default behavior 38 | extend Default 39 | 40 | # then, if available, incorporate the auth-specific behavior 41 | begin 42 | auth_module = "sidekiq_auth_constraint/#{Squash::Configuration.authentication.strategy}".camelize.constantize 43 | extend auth_module 44 | rescue NameError 45 | # no auth module; ignore 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /lib/tasks/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquareSquash/web/e73f2805f9eb30780a5c213b001f0f4255660fbf/lib/tasks/.gitkeep -------------------------------------------------------------------------------- /lib/tasks/concurrency.rake: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | require 'configoro' 16 | Configoro.initialize 17 | 18 | filename = Squash::Configuration.concurrency.background_runner.underscore + '.rake' 19 | file = Rails.root.join('lib', 'background_runner', 'tasks', filename) 20 | 21 | load(file) if File.exist?(file) 22 | -------------------------------------------------------------------------------- /lib/tasks/doc.rake: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | if Rails.env.development? 16 | require 'yard' 17 | 18 | # bring sexy back (sexy == tables) 19 | module YARD::Templates::Helpers::HtmlHelper 20 | def html_markup_markdown(text) 21 | markup_class(:markdown).new(text, :gh_blockcode, :fenced_code, :autolink, :tables, :no_intraemphasis).to_html 22 | end 23 | end 24 | 25 | YARD::Rake::YardocTask.new do |doc| 26 | doc.options << '-m' << 'markdown' << '-M' << 'redcarpet' 27 | doc.options << '--protected' << '--no-private' 28 | doc.options << '-r' << 'README.md' 29 | doc.options << '-o' << 'doc/app' 30 | doc.options << '--title' << "Squash Documentation" 31 | 32 | doc.files = %w( app/**/*.rb lib/**/*.rb - doc/*.md ) 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /lib/tasks/jira.rake: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | namespace :jira do 16 | desc "Check for closed JIRA issues and update linked bugs accordingly" 17 | task update: :environment do 18 | JiraStatusWorker.perform 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/tasks/spec.rake: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | begin 16 | require 'rspec/core' 17 | require 'rspec/core/rake_task' 18 | 19 | RSpec::Core::RakeTask.new(:spec) do |t| 20 | t.pattern = "./spec/**/*_spec.rb" 21 | end 22 | 23 | task default: :spec 24 | rescue LoadError 25 | # that's ok 26 | end 27 | -------------------------------------------------------------------------------- /lib/tasks/statistics.rake: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | STATS_DIRECTORIES = [ 16 | %w(Controllers app/controllers), 17 | %w(Helpers app/helpers), 18 | %w(Models app/models), 19 | %w(Libraries lib/), 20 | %w(APIs app/apis), 21 | %w(Library \ tests spec/lib), 22 | %w(Controller\ tests spec/controllers), 23 | %w(Model\ tests spec/models) 24 | ].collect { |name, dir| [name, "#{Rails.root}/#{dir}"] }.select { |name, dir| File.directory?(dir) } 25 | 26 | desc "Report code statistics (KLOCs, etc) from the application" 27 | task :stats do 28 | require 'rails/code_statistics' 29 | CodeStatistics::TEST_TYPES = ['Library tests', 'Controller tests', 'Model tests'] 30 | CodeStatistics.new(*STATS_DIRECTORIES).to_s 31 | end 32 | #TODO remove previous stats task 33 | -------------------------------------------------------------------------------- /lib/tasks/truncation.rake: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | namespace :truncate do 16 | desc "Remove metadata from occurrences to free DB space. Specify AGE=n (days)" 17 | task occurrences: :environment do 18 | age = nil 19 | begin 20 | age = Integer(ENV['AGE'].presence || 30) 21 | rescue ArgumentError 22 | $stderr.puts <<-EOF 23 | Specify AGE=n, where `n` is the number of days old an occurrence must be to be 24 | truncated (default 30). 25 | EOF 26 | exit 1 27 | end 28 | 29 | Occurrence.truncate! Occurrence.where('occurred_at < ?', age.days.ago) 30 | end 31 | 32 | desc "Truncate all truncatable records" 33 | task all: :occurrences 34 | end 35 | -------------------------------------------------------------------------------- /lib/workers/comment_notification_mailer.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Simple worker class that emails all relevant Users, informing them of a new 16 | # {Comment} on a {Bug}. 17 | 18 | class CommentNotificationMailer 19 | include BackgroundRunner::Job 20 | 21 | # Creates a new instance and sends notification emails. 22 | # 23 | # @param [Fixnum] comment_id The ID of a Comment that was just posted. 24 | 25 | def self.perform(comment_id) 26 | new(Comment.find(comment_id)).perform 27 | end 28 | 29 | # Creates a new worker instance. 30 | # 31 | # @param [Comment] comment A Comment that was just posted. 32 | 33 | def initialize(comment) 34 | @comment = comment 35 | end 36 | 37 | # Emails all relevant Users about the new Comment. 38 | 39 | def perform 40 | recipients = @comment.bug.comments.select('user_id').uniq.pluck(:user_id) 41 | recipients << @comment.bug.assigned_user_id 42 | recipients.delete @comment.user_id 43 | recipients.uniq! 44 | 45 | User.where(id: recipients).each { |user| NotificationMailer.comment(@comment, user).deliver_now } 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /lib/workers/deploy_notification_mailer.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Simple worker class that emails everyone on a {Bug}'s `notify_on_deploy` list 16 | # of a new Deploy. 17 | 18 | class DeployNotificationMailer 19 | include BackgroundRunner::Job 20 | 21 | # Creates a new instance and sends notification emails. 22 | # 23 | # @param [Fixnum] bug_id The ID of a Bug that a Deploy just fixed. 24 | 25 | def self.perform(bug_id) 26 | new(Bug.find(bug_id)).perform 27 | end 28 | 29 | # Creates a new worker instance. 30 | # 31 | # @param [Bug] bug A Bug that a Deploy just fixed. 32 | 33 | def initialize(bug) 34 | @bug = bug 35 | end 36 | 37 | # Emails all Users who enabled fix-deployed notifications. 38 | 39 | def perform 40 | User.where(id: @bug.notify_on_deploy).each do |user| 41 | NotificationMailer.deploy(@bug, user).deliver_now 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /lib/workers/jira_status_worker.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Worker that finds open bugs linked to JIRA issues, checks if those issues have 16 | # been resolved, and then marks the bug as fixed if so. 17 | # 18 | # You will need to invoke this worker (or the `jira:update` Rake task) in a cron 19 | # task, or otherwise periodically, to fully support JIRA integration. 20 | 21 | class JiraStatusWorker 22 | include BackgroundRunner::Job 23 | 24 | # Creates a new instance and updates bug statuses. 25 | 26 | def self.perform 27 | new.perform 28 | end 29 | 30 | # Iterates through all open bugs that are linked to JIRA issues. Checks the 31 | # JIRA issue status for each such bug, and marks the bug as fixed as 32 | # appropriate. 33 | 34 | def perform 35 | Bug.where(fixed: false).cursor.each do |bug| 36 | next unless bug.jira_issue && bug.jira_status_id 37 | 38 | issue = Service::JIRA.issue(bug.jira_issue) 39 | next unless issue 40 | next unless issue.status.id.to_i == bug.jira_status_id 41 | 42 | bug.modifier = issue 43 | bug.update_attribute :fixed, true 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /lib/workers/obfuscation_map_creator.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Worker that decodes an obfuscation map from parameters given to the API 16 | # controller, and creates the {ObfuscationMap} object. 17 | 18 | class ObfuscationMapCreator 19 | include BackgroundRunner::Job 20 | 21 | # Creates a new instance and creates the ObfuscationMap. 22 | # 23 | # @param [Hash] params Parameters passed to the API controller. 24 | 25 | def self.perform(params) 26 | new(params).perform 27 | end 28 | 29 | # Creates a new instance with the given parameters. 30 | # 31 | # @param [Hash] params Parameters passed to the API controller. 32 | 33 | def initialize(params) 34 | @params = params 35 | end 36 | 37 | # Decodes parameters and creates the ObfuscationMap. 38 | 39 | def perform 40 | map = YAML.load(Zlib::Inflate.inflate(Base64.decode64(@params['namespace'])), safe: true, deserialize_symbols: false) 41 | return unless map.kind_of?(Squash::Java::Namespace) 42 | 43 | project = Project.find_by_api_key(@params['api_key']) or raise(API::UnknownAPIKeyError) 44 | deploy = project. 45 | environments.with_name(@params['environment']).first!. 46 | deploys.find_by_build!(@params['build']) 47 | deploy.obfuscation_map.try! :destroy 48 | deploy.create_obfuscation_map!(namespace: map) 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /lib/workers/obfuscation_map_worker.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Worker that loads Occurrences affected by the addition of a new 16 | # ObfuscationMap, and attempts to deobfuscate them using the new map. 17 | 18 | class ObfuscationMapWorker 19 | include BackgroundRunner::Job 20 | 21 | # Creates a new worker instance and performs a deobfuscation. 22 | # 23 | # @param [Integer] map_id The ID of an {ObfuscationMap}. 24 | 25 | def self.perform(map_id) 26 | new(ObfuscationMap.find(map_id)).perform 27 | end 28 | 29 | # Creates a new worker instance. 30 | # 31 | # @param [ObfuscationMap] map An obfuscation map to process. 32 | 33 | def initialize(map) 34 | @map = map 35 | end 36 | 37 | # Locates relevant Occurrences and attempts to deobfuscate them. 38 | 39 | def perform 40 | @map.deploy.bugs.cursor.each do |bug| 41 | bug.occurrences.cursor.each do |occ| 42 | begin 43 | occ.deobfuscate! @map 44 | occ.recategorize! 45 | rescue => err 46 | # for some reason the cursors gem eats exceptions 47 | Squash::Ruby.notify err, occurrence: occ 48 | end 49 | end 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /lib/workers/pager_duty_resolver.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Tells PagerDuty to resolve the incident associated with a Bug. This occurs 16 | # when a Bug is marked as fixed. 17 | 18 | class PagerDutyResolver < PagerDutyAcknowledger 19 | 20 | # Sends a PagerDuty API call resolving an incident. 21 | 22 | def perform 23 | @bug.environment.project.pagerduty.resolve @bug.pagerduty_incident_key, 24 | description 25 | end 26 | 27 | private 28 | 29 | def description 30 | I18n.t 'workers.pagerduty.resolve.description', 31 | class_name: @bug.class_name, 32 | file_name: File.basename(@bug.file), 33 | locale: @bug.environment.project.locale 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lib/workers/project_repo_fetcher.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Very simple worker that fetches a {Project}'s repository. 16 | 17 | class ProjectRepoFetcher 18 | include BackgroundRunner::Job 19 | 20 | # Creates a new instance and calls {#perform} on it. 21 | # 22 | # @param [Integer] project_id The ID of a {Project} whose repository should be 23 | # updated. 24 | 25 | def self.perform(project_id) 26 | new(Project.find(project_id)).perform 27 | end 28 | 29 | # Creates a new instance. 30 | # 31 | # @param [Project] project A Project whose repository should be updated. 32 | 33 | def initialize(project) 34 | @project = project 35 | end 36 | 37 | # Fetches the Project's repository. 38 | 39 | def perform 40 | @project.repo &:fetch 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /lib/workers/source_map_creator.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Worker that decodes a source map from parameters given to the API controller, 16 | # and creates the {SourceMap} object. 17 | 18 | class SourceMapCreator 19 | include BackgroundRunner::Job 20 | 21 | # Creates a new instance and creates the SourceMap. 22 | # 23 | # @param [Hash] params Parameters passed to the API controller. 24 | 25 | def self.perform(params) 26 | new(params).perform 27 | end 28 | 29 | # Creates a new instance with the given parameters. 30 | # 31 | # @param [Hash] params Parameters passed to the API controller. 32 | 33 | def initialize(params) 34 | @params = params 35 | end 36 | 37 | # Decodes parameters and creates the SourceMap. 38 | 39 | def perform 40 | project = Project.find_by_api_key(@params['api_key']) or raise(API::UnknownAPIKeyError) 41 | project. 42 | environments.with_name(@params['environment']).find_or_create!(name: @params['environment']). 43 | source_maps.create(raw_map: @params['sourcemap'], 44 | revision: @params['revision'], 45 | from: @params['from'], 46 | to: @params['to']) 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /lib/workers/source_map_worker.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Worker that loads Occurrences affected by the addition of a new 16 | # SourceMap, and attempts to sourcemap them using the new map. 17 | 18 | class SourceMapWorker 19 | include BackgroundRunner::Job 20 | 21 | # Creates a new worker instance and performs a sourcemapping. 22 | # 23 | # @param [Integer] map_id The ID of an {SourceMap}. 24 | 25 | def self.perform(map_id) 26 | new(SourceMap.find(map_id)).perform 27 | end 28 | 29 | # Creates a new worker instance. 30 | # 31 | # @param [SourceMap] map A source map to process. 32 | 33 | def initialize(map) 34 | @map = map 35 | end 36 | 37 | # Locates relevant Occurrences and attempts to sourcemap them. 38 | 39 | def perform 40 | @map.environment.bugs.cursor.each do |bug| 41 | bug.occurrences.where(revision: @map.revision).cursor.each do |occurrence| 42 | begin 43 | occurrence.sourcemap! @map 44 | occurrence.recategorize! 45 | rescue => err 46 | # for some reason the cursors gem eats exceptions 47 | Squash::Ruby.notify err, occurrence: occurrence 48 | end 49 | end 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /lib/workers/symbolication_creator.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Worker that decodes a symbolication table from parameters given to the API 16 | # controller, and creates the {Symbolication} object. 17 | 18 | class SymbolicationCreator 19 | include BackgroundRunner::Job 20 | 21 | # Creates a new instance and creates the Symbolication. 22 | # 23 | # @param [Hash] params Parameters passed to the API controller. 24 | 25 | def self.perform(params) 26 | new(params).perform 27 | end 28 | 29 | # Creates a new instance with the given parameters. 30 | # 31 | # @param [Hash] params Parameters passed to the API controller. 32 | 33 | def initialize(params) 34 | @params = params 35 | end 36 | 37 | # Decodes parameters and creates the Symbolication. 38 | 39 | def perform 40 | @params['symbolications'].each do |attrs| 41 | Symbolication.where(uuid: attrs['uuid']).create_or_update do |symbolication| 42 | symbolication.send :write_attribute, :symbols, attrs['symbols'] 43 | symbolication.send :write_attribute, :lines, attrs['lines'] 44 | end 45 | end end 46 | end 47 | -------------------------------------------------------------------------------- /lib/workers/symbolication_worker.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Worker that loads Occurrences affected by the addition of a new 16 | # Symbolication, and attempts to symbolicate them using the new map. 17 | 18 | class SymbolicationWorker 19 | include BackgroundRunner::Job 20 | 21 | # Creates a new worker instance and performs a symbolication. 22 | # 23 | # @param [Integer] uuid The UUID of a {Symbolication}. 24 | 25 | def self.perform(uuid) 26 | new(Symbolication.find_by_uuid!(uuid)).perform 27 | end 28 | 29 | # Creates a new worker instance. 30 | # 31 | # @param [Symbolication] sym A symbolication to process. 32 | 33 | def initialize(sym) 34 | @symbolication = sym 35 | end 36 | 37 | # Locates relevant Occurrences and attempts to symbolicate them. 38 | 39 | def perform 40 | @symbolication.occurrences.cursor.each do |occ| 41 | begin 42 | occ.symbolicate! @symbolication 43 | occ.recategorize! 44 | rescue => err 45 | # for some reason the cursors gem eats exceptions 46 | Squash::Ruby.notify err, occurrence: occ 47 | end 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /log/.gitignore: -------------------------------------------------------------------------------- 1 | *.log -------------------------------------------------------------------------------- /public/400.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was not permitted (400) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The change you wanted was not permitted.

23 |

Maybe you tried to change an attribute you didn't have access to.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The page you were looking for doesn't exist.

23 |

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

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The change you wanted was rejected.

23 |

Maybe one of your attributes had an invalid value.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

We're sorry, but something went wrong.

23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquareSquash/web/e73f2805f9eb30780a5c213b001f0f4255660fbf/public/favicon.ico -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | 3 | User-Agent: * 4 | Disallow: / 5 | -------------------------------------------------------------------------------- /spec/controllers/jira/issues_controller_spec.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | require 'rails_helper' 16 | 17 | RSpec.describe Jira::IssuesController, type: :controller do 18 | describe "#show" do 19 | it "should return information about a JIRA issue" do 20 | FakeWeb.register_uri :get, 21 | jira_url("/rest/api/2/issue/FOO-123"), 22 | response: Rails.root.join('spec', 'fixtures', 'jira_issue.json') 23 | 24 | get :show, id: 'FOO-123', format: 'json' 25 | expect(response.status).to eql(200) 26 | body = JSON.parse(response.body) 27 | expect(body['fields']['summary']).to eql("Double RTs on coffee bar Twitter monitor") 28 | end 29 | 30 | it "should 404 if the JIRA issue is not found" do 31 | FakeWeb.register_uri :get, 32 | jira_url("/rest/api/2/issue/FOO-124"), 33 | response: Rails.root.join('spec', 'fixtures', 'jira_issue_404.json') 34 | 35 | get :show, id: 'FOO-124', format: 'json' 36 | expect(response.status).to eql(404) 37 | end 38 | end 39 | end unless Squash::Configuration.jira.disabled? 40 | -------------------------------------------------------------------------------- /spec/controllers/jira/projects_controller_spec.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | require 'rails_helper' 16 | 17 | RSpec.describe Jira::ProjectsController, type: :controller do 18 | describe "#index" do 19 | it "should a list of known projects" do 20 | FakeWeb.register_uri :get, 21 | jira_url("/rest/api/2/project"), 22 | response: Rails.root.join('spec', 'fixtures', 'jira_projects.json') 23 | 24 | get :index, format: 'json' 25 | expect(response.status).to eql(200) 26 | body = JSON.parse(response.body) 27 | expect(body.map { |st| st['name'] }). 28 | to eql(["Alert", "Android", "Bugs", "Business Intelligence", 29 | "Checker", "Coffee Bar", "Compliance"].sort) 30 | end 31 | end 32 | end unless Squash::Configuration.jira.disabled? 33 | -------------------------------------------------------------------------------- /spec/controllers/jira/statuses_controller_spec.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | require 'rails_helper' 16 | 17 | RSpec.describe Jira::StatusesController, type: :controller do 18 | describe "#index" do 19 | it "should a list of known statuses" do 20 | FakeWeb.register_uri :get, 21 | jira_url("/rest/api/2/status"), 22 | response: Rails.root.join('spec', 'fixtures', 'jira_statuses.json') 23 | 24 | get :index, format: 'json' 25 | expect(response.status).to eql(200) 26 | body = JSON.parse(response.body) 27 | expect(body.map { |st| st['name'] }). 28 | to eql(["Open", "In Progress", "Reopened", "Resolved", "Closed", 29 | "Needs Review", "Approved", "Hold Pending Info", "IceBox", 30 | "Not Yet Started", "Started", "Finished", "Delivered", 31 | "Accepted", "Rejected", "Allocated", "Build", "Verify", 32 | "Pending Review", "Stabilized", "Post Mortem Complete"].sort) 33 | end 34 | end 35 | end unless Squash::Configuration.jira.disabled? 36 | -------------------------------------------------------------------------------- /spec/factories/blames.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :blame do 17 | repository_hash { random_sha } 18 | revision { random_sha } 19 | file "some/file.rb" 20 | line 123 21 | blamed_revision { random_sha } 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/factories/bugs.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :bug do 17 | association :environment 18 | 19 | class_name "ArgumentError" 20 | message_template "wrong number of parameters (1 for 0)" 21 | client 'rails' 22 | 23 | revision '8f29160c367cc3e73c112e34de0ee48c4c323ff7' 24 | file "app/controllers/broken_controller.rb" 25 | line 123 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/factories/comments.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :comment do 17 | association :user 18 | bug do |obj| 19 | membership = FactoryGirl.create(:membership, user: obj.user) 20 | FactoryGirl.create :bug, environment: FactoryGirl.create(:environment, project: membership.project) 21 | end 22 | 23 | body "Brunch occaecat forage, put a bird on it assumenda artisan occupy cardigan laboris marfa. Aliqua authentic aesthetic, dolore carles thundercats odio." 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/factories/deploys.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :deploy do 17 | association :environment 18 | revision '2dc20c984283bede1f45863b8f3b4dd9b5b554cc' 19 | deployed_at { Time.now } 20 | end 21 | 22 | factory :release, class: 'Deploy' do 23 | association :environment 24 | revision '2dc20c984283bede1f45863b8f3b4dd9b5b554cc' 25 | version '1.2.3' 26 | sequence :build, &:to_s 27 | deployed_at { Time.now } 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/factories/device_bugs.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :device_bug do 17 | association :bug 18 | sequence(:device_id) { |i| "device-#{i}" } 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/factories/emails.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :email do 17 | association :user 18 | sequence(:email) { |i| "email-#{i}@example.com" } 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/factories/environments.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :environment do 17 | association :project 18 | sequence(:name) { |i| "env-#{i}" } 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/factories/events.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :event do 17 | association :user 18 | bug do |obj| 19 | membership = FactoryGirl.create(:membership, user: obj.user) 20 | FactoryGirl.create :bug, environment: FactoryGirl.create(:environment, project: membership.project) 21 | end 22 | 23 | kind 'open' 24 | data('status' => 'fixed', 'from' => 'closed', 'revision' => '8f29160c367cc3e73c112e34de0ee48c4c323ff7') 25 | end 26 | 27 | factory :complex_event, parent: :event do 28 | kind 'comment' 29 | data { |obj| {comment_id: FactoryGirl.create(:comment, bug: obj.bug, user: FactoryGirl.create(:user, project: obj.bug.project))} } 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/factories/memberships.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :membership do 17 | association :user 18 | association :project 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/factories/notification_thresholds.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :notification_threshold do 17 | association :user 18 | association :bug 19 | period 1.hour 20 | threshold 100 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /spec/factories/obfuscation_maps.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :obfuscation_map do 17 | association :deploy 18 | namespace { Squash::Java::Namespace.new } 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/factories/projects.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :project do 17 | association :owner, factory: :user 18 | sequence(:name) { |i| "Project #{i}" } 19 | repository_url 'https://github.com/RISCfuture/better_caller.git' 20 | filter_paths %w( vendor/ config/initializers/mysql_connection_fix.rb ) 21 | whitelist_paths %w( vendor/plugins/internal ) 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/factories/source_maps.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :source_map do 17 | association :environment 18 | revision '7f9ef6977510b3487483cf834ea02d3e6d7f6f13' 19 | map GemSourceMap::Map.from_json(Rails.root.join('spec', 'fixtures', 'mapping.json').read) 20 | from 'hosted' 21 | to 'original' 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/factories/symbolications.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :symbolication do 17 | uuid { SecureRandom.uuid } 18 | symbols { Squash::Symbolicator::Symbols.new } 19 | lines { Squash::Symbolicator::Lines.new } 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /spec/factories/user_events.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :user_event do 17 | association :user 18 | association :event 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/factories/users.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :user do 17 | sequence(:username) { |i| "user-#{i}" } 18 | first_name 'Sancho' 19 | last_name 'Sample' 20 | if Squash::Configuration.authentication.strategy == 'password' 21 | sequence(:email_address) { |i| "default-email-#{i}@example.com" } 22 | password 'correct horse battery staple' 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/factories/watches.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FactoryGirl.define do 16 | factory :watch do 17 | association :user 18 | association :bug 19 | after :build do |w| 20 | FactoryGirl.create(:membership, user: w.user, project: w.bug.environment.project) unless w.user.role(w.bug.environment.project) 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/fixtures/image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquareSquash/web/e73f2805f9eb30780a5c213b001f0f4255660fbf/spec/fixtures/image.jpg -------------------------------------------------------------------------------- /spec/fixtures/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquareSquash/web/e73f2805f9eb30780a5c213b001f0f4255660fbf/spec/fixtures/image.png -------------------------------------------------------------------------------- /spec/fixtures/jira_issue_404.json: -------------------------------------------------------------------------------- 1 | HTTP/1.1 404 Not Found 2 | Date: Wed, 14 Nov 2012 22:33:22 GMT 3 | X-AREQUESTID: 1353x39200x1 4 | X-Seraph-LoginReason: OK 5 | X-ASESSIONID: u08r0a 6 | X-AUSERNAME: tim 7 | Cache-Control: no-cache, no-store, no-transform 8 | Content-Type: application/json;charset=UTF-8 9 | Set-Cookie: JSESSIONID=7EEAD8D3F2AE657AF60461E813ADF1B7; Path=/jira; HttpOnly 10 | Set-Cookie: atlassian.xsrf.token=ALMX-0SVV-VVCK-3Y73|b3d297f61c2c261383332a358e39c371759e0f54|lin; Path=/jira 11 | Connection: close 12 | Transfer-Encoding: chunked 13 | 14 | {"errorMessages":["Issue Does Not Exist"],"errors":{}} 15 | -------------------------------------------------------------------------------- /spec/fixtures/mapping.json: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"out.js", 4 | "sourceRoot":"/Documents/Projects/SquareSquash/javascript", 5 | "sources":["/Documents/Projects/SquareSquash/javascript/vendor/assets/foo.js", "/Documents/Projects/SquareSquash/javascript/vendor/assets/bar.js"], 6 | "names":["src", "maps", "are", "fun"], 7 | "mappings":"AAgBC,SAAQ,CAAEA" 8 | } 9 | -------------------------------------------------------------------------------- /spec/fixtures/pagerduty_response.json: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: nginx/1.0.14 3 | Date: Wed, 14 Nov 2012 04:09:11 GMT 4 | Content-Type: application/json; charset=utf-8 5 | Transfer-Encoding: chunked 6 | Connection: keep-alive 7 | Status: 200 OK 8 | X-UA-Compatible: IE=Edge,chrome=1 9 | Cache-Control: no-cache 10 | X-Request-Id: 20436b8395ad658aa642721c14fda3ef 11 | X-Runtime: 0.019127 12 | X-Rack-Cache: invalidate, pass 13 | Set-Cookie: uid=CqQdA1CjGWdd8GH+jTjOAg==; expires=Thu, 31-Dec-37 23:55:55 GMT; domain=pagerduty.com; path=/ 14 | 15 | {"status":"success","message":"You did it!"} 16 | -------------------------------------------------------------------------------- /spec/lib/composite_primary_keys_spec.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | require 'rails_helper' 16 | 17 | RSpec.describe ActiveRecord::Base do 18 | describe "#touch" do 19 | it "should update a single-key record" do 20 | user = FactoryGirl.create(:user, created_at: 1.day.ago, updated_at: 1.day.ago) 21 | expect { expect(user.touch).to eql(true) }.to change(user, :updated_at) 22 | end 23 | 24 | it "should update a multi-key record" do 25 | nt = FactoryGirl.create(:notification_threshold, last_tripped_at: 1.day.ago) 26 | expect { expect(nt.touch(:last_tripped_at)).to eql(true) }.to change(nt, :last_tripped_at) 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/models/blame_spec.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | require 'rails_helper' 16 | 17 | RSpec.describe Blame, type: :model do 18 | end 19 | -------------------------------------------------------------------------------- /spec/models/device_bug_spec.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | require 'rails_helper' 16 | 17 | RSpec.describe DeviceBug, type: :model do 18 | end 19 | -------------------------------------------------------------------------------- /spec/models/membership_spec.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | require 'rails_helper' 16 | 17 | RSpec.describe Membership, type: :model do 18 | # nothing yet 19 | end 20 | -------------------------------------------------------------------------------- /spec/models/notification_threshold_spec.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | require 'rails_helper' 16 | 17 | RSpec.describe NotificationThreshold, type: :model do 18 | describe "#tripped?" do 19 | before :each do 20 | @threshold = FactoryGirl.create(:notification_threshold, threshold: 10, period: 10.minutes, last_tripped_at: 20.minutes.ago) 21 | end 22 | 23 | it "should return false if the threshold has not yet been exceeded within the period" do 24 | FactoryGirl.create_list :rails_occurrence, 9, bug: @threshold.bug 25 | expect(@threshold).not_to be_tripped 26 | end 27 | 28 | it "should return true if the threshold has been exceeded within the period" do 29 | FactoryGirl.create_list :rails_occurrence, 10, bug: @threshold.bug 30 | expect(@threshold).to be_tripped 31 | end 32 | 33 | it "should return false if the threshold was tripped within the last period" do 34 | FactoryGirl.create_list :rails_occurrence, 10, bug: @threshold.bug 35 | @threshold.last_tripped_at = 45.seconds.ago 36 | expect(@threshold).not_to be_tripped 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /spec/models/user_event_spec.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | require 'rails_helper' 16 | 17 | RSpec.describe UserEvent, type: :model do 18 | end 19 | -------------------------------------------------------------------------------- /spec/models/watch_spec.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | require 'rails_helper' 16 | 17 | RSpec.describe Watch, type: :model do 18 | context "[observers]" do 19 | before :all do 20 | @user = FactoryGirl.create(:user) 21 | @unwatched_event = FactoryGirl.create(:event) 22 | @watched_event = FactoryGirl.create(:event) 23 | @unwatched_bug = @unwatched_event.bug 24 | watched_bug = @watched_event.bug 25 | @watch = FactoryGirl.create(:watch, user: @user, bug: watched_bug) 26 | end 27 | 28 | it "should fill a user's feed with events when a bug is watched" do 29 | FactoryGirl.create :watch, user: @user, bug: @unwatched_bug 30 | expect(@user.user_events.pluck(:event_id)).to include(@unwatched_event.id) 31 | end 32 | 33 | it "should remove events from a user's feed when a bug is unwatched" do 34 | @watch.destroy 35 | expect(@user.user_events.pluck(:event_id)).not_to include(@watched_event.id) 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /spec/routing/project/memberships_spec.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | require 'rails_helper' 16 | 17 | RSpec.describe "/projects/:project_id/memberships", type: :routing do 18 | describe "/:id [PATCH]" do 19 | it "should route to usernames with dots in them" do 20 | expect(patch: '/projects/my-project/memberships/user.dot.json'). 21 | to route_to( 22 | controller: 'project/memberships', 23 | action: 'update', 24 | project_id: 'my-project', 25 | id: 'user.dot', 26 | format: 'json' 27 | ) 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /spec/routing/users_spec.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | require 'rails_helper' 16 | 17 | RSpec.describe "/users", type: :routing do 18 | describe "/:id [GET]" do 19 | it "should route to usernames with dots in them" do 20 | expect(get: '/users/user.dot'). 21 | to route_to( 22 | controller: 'users', 23 | action: 'show', 24 | id: 'user.dot' 25 | ) 26 | end 27 | 28 | it "should route to usernames ending in .json" do 29 | expect(get: '/users/user.json'). 30 | to route_to( 31 | controller: 'users', 32 | action: 'show', 33 | id: 'user.json' 34 | ) 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /spec/support/controller_404_examples.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Square Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | RSpec.shared_examples_for "action that 404s at appropriate times" do |method, action, params='{}'| 16 | it "should only allow projects that exist" do 17 | send method, action, eval(params).merge(project_id: 'not-found') 18 | expect(response.status).to eql(404) 19 | end 20 | 21 | it "should only allow environments that actually exist within the project" do 22 | send method, action, eval(params).merge(environment_id: 'not-found') 23 | expect(response.status).to eql(404) 24 | end 25 | end 26 | 27 | RSpec.shared_examples_for "singleton action that 404s at appropriate times" do |method, action, params='{}'| 28 | it "should only find bugs within the current environment" do 29 | send method, action, eval(params).merge(id: 'not-found') 30 | expect(response.status).to eql(404) 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /tmp/pids/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /tmp/repos/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /tmp/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /tmp/sockets/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /tmp/sourcemaps/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquareSquash/web/e73f2805f9eb30780a5c213b001f0f4255660fbf/vendor/assets/javascripts/.gitkeep -------------------------------------------------------------------------------- /vendor/assets/javascripts/sh/shBrushDiff.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (Wed, 12 Feb 2014 03:42:24 GMT) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2013 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null); 21 | 22 | function Brush() 23 | { 24 | this.regexList = [ 25 | { regex: /^\+\+\+ .*$/gm, css: 'color2' }, // new file 26 | { regex: /^\-\-\- .*$/gm, css: 'color2' }, // old file 27 | { regex: /^\s.*$/gm, css: 'color1' }, // unchanged 28 | { regex: /^@@.*@@.*$/gm, css: 'variable' }, // location 29 | { regex: /^\+.*$/gm, css: 'string' }, // additions 30 | { regex: /^\-.*$/gm, css: 'color3' } // deletions 31 | ]; 32 | }; 33 | 34 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 35 | Brush.aliases = ['diff', 'patch']; 36 | 37 | SyntaxHighlighter.brushes.Diff = Brush; 38 | 39 | // CommonJS 40 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 41 | })(); 42 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/sh/shBrushGit.js: -------------------------------------------------------------------------------- 1 | // Git brush for SyntaxHighlighter 2 | 3 | (function() { 4 | // CommonJS 5 | typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; 6 | 7 | function Brush() { 8 | this.regexList = [ 9 | { regex: /^commit (\w+)$/gm, css: 'keyword' } 10 | ] 11 | } 12 | 13 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 14 | Brush.aliases = ['git', 'commit']; 15 | 16 | SyntaxHighlighter.brushes.Git = Brush; 17 | 18 | // CommonJS 19 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 20 | })(); 21 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/sh/shBrushPlain.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/SyntaxHighlighter 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/SyntaxHighlighter/donate.html 7 | * 8 | * @version 9 | * 3.0.83 (Wed, 12 Feb 2014 03:42:24 GMT) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2013 Alex Gorbatchev. 13 | * 14 | * @license 15 | * Dual licensed under the MIT and GPL licenses. 16 | */ 17 | ;(function() 18 | { 19 | // CommonJS 20 | SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null); 21 | 22 | function Brush() 23 | { 24 | }; 25 | 26 | Brush.prototype = new SyntaxHighlighter.Highlighter(); 27 | Brush.aliases = ['text', 'plain']; 28 | 29 | SyntaxHighlighter.brushes.Plain = Brush; 30 | 31 | // CommonJS 32 | typeof(exports) != 'undefined' ? exports.Brush = Brush : null; 33 | })(); 34 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquareSquash/web/e73f2805f9eb30780a5c213b001f0f4255660fbf/vendor/assets/stylesheets/.gitkeep -------------------------------------------------------------------------------- /vendor/configoro/simple.rb: -------------------------------------------------------------------------------- 1 | # A stripped-down version of Configoro that works without any gems. 2 | 3 | require 'erb' 4 | require 'yaml' 5 | 6 | load File.join(File.dirname(__FILE__), 'base.rb') 7 | 8 | # @private 9 | class Configoro::HashWithIndifferentAccess < ::Hash 10 | def deep_merge(other_hash) 11 | dup.deep_merge!(other_hash) 12 | end 13 | 14 | def deep_merge!(other_hash) 15 | other_hash.each_pair do |k, v| 16 | tv = self[k] 17 | self[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? tv.deep_merge(v) : v 18 | end 19 | self 20 | end 21 | end 22 | 23 | load File.join(File.dirname(__FILE__), 'hash.rb') 24 | -------------------------------------------------------------------------------- /vendor/plugins/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquareSquash/web/e73f2805f9eb30780a5c213b001f0f4255660fbf/vendor/plugins/.gitkeep --------------------------------------------------------------------------------