netsoft-danger 0.3.3 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 834689b35350c36d2d44ddf42e4f4063d6a64669eae0b81622bd75a4a84ad521
4
- data.tar.gz: 60f0dce22bea4f15e6c41dca65b68015117580cf2f6b887b96ea7c5e5cf08e52
3
+ metadata.gz: dfb9db9333ed0616edd6d2650f3d39949842ab95f4226ba641d2829f041e3168
4
+ data.tar.gz: faf45b8bf21ecea1afaf661651579c2b732155979ba15947ba26592f446794bf
5
5
  SHA512:
6
- metadata.gz: ba7dd552680963b240de97848204a8da274fcd62826284bad93a906f0d629de0e41f0fc2a72da71590005392e0415a84d5fd27a4d9b726a997d80da9db4242f3
7
- data.tar.gz: fb9da655dc4673612375ae7b0307fd6add7a01922152f08d1f8728550723df6b725150add8f480b7726756c0f986f797e73ac569e67d1c98673b8f72e67afd9c
6
+ metadata.gz: 503763af26af1a7ad5a88c9b76dd345f4b5de9384111be1aaee93bfb78b4f0f970ab77d98440ca87256f65aac2c3d7e105043ad11514edcfd86ec884ae816c1c
7
+ data.tar.gz: f195d074cdc895ae1031fc326e90b6f718fef0f8e335cf15fd09e1341e4fd45ac652ca2e1343ee71fdee4e367ccde3e26a0b1df5493238b2757482a3dd6493aa
@@ -111,6 +111,10 @@ jobs:
111
111
  name: Build gem
112
112
  command: |-
113
113
  gem build *.gemspec
114
+ - run:
115
+ name: Run rubocop
116
+ command: |-
117
+ bundle exec rubocop
114
118
  - run:
115
119
  name: Run Danger
116
120
  command: |-
@@ -124,7 +128,9 @@ jobs:
124
128
  name: Deploy to gem server
125
129
  command: |-
126
130
  ./bin/tag_check.sh
131
+ ./bin/setup-rubygems.sh
127
132
  rm -rf pkg
128
133
  gem install geminabox
129
134
  rake build
130
135
  gem inabox -g ${HUBSTAFF_GEM_SERVER} pkg/*
136
+ gem push pkg/*.gem
@@ -0,0 +1,15 @@
1
+ inherit_gem:
2
+ netsoft-rubocop:
3
+ - default.yml
4
+
5
+ Style/SignalException:
6
+ Exclude:
7
+ - Dangerfile
8
+
9
+ Style/IfUnlessModifier:
10
+ Exclude:
11
+ - Dangerfile
12
+
13
+ Layout/EmptyLineAfterGuardClause:
14
+ Exclude:
15
+ - Dangerfile
@@ -0,0 +1,34 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Next]
8
+ ### Added
9
+ ### Changed
10
+ ### Fixed
11
+
12
+ ## [0.3.8]
13
+ ### Added
14
+ - auto add/remove some labels
15
+ - allow conventional commit format for our migration, gemfile, and package.json
16
+ - add support for product review labels
17
+ - add support for renamed code review labels
18
+
19
+ ## [0.3.7]
20
+ ### Fixed
21
+ - require English in the netsoft-circle bin
22
+
23
+ ## [0.3.6]
24
+ ### Added
25
+ - rubocop checks for this gem
26
+ ### Changed
27
+ - allow bundler 1.17.3
28
+
29
+ ## [0.3.5]
30
+ ### Added
31
+ - package.json checks
32
+ ### Fixed
33
+ - requie older version of faraday until octokit is fixed (https://github.com/octokit/octokit.rb/pull/1154)
34
+
data/Dangerfile CHANGED
@@ -1,105 +1,153 @@
1
+ # frozen_string_literal: true
2
+
3
+ def toggle_label(github, label, should_set)
4
+ repo_name = github.pr_json['head']['repo']['full_name']
5
+ pr_number = github.pr_json['number']
6
+ has_label = github.pr_labels.include?(label)
7
+ if should_set && !has_label
8
+ github.api.add_labels_to_an_issue(repo_name, pr_number, label)
9
+ elsif !should_set && has_label
10
+ github.api.remove_label(repo_name, pr_number, label)
11
+ end
12
+ end
13
+
1
14
  # Don't let testing shortcuts get into master by accident
2
- if Dir.exists?('spec')
3
- fail("fdescribe left in tests") if `grep -r -e '\\bfdescribe\\b' spec/ |grep -v 'danger ok' `.length > 1
4
- fail("fcontext left in tests") if `grep -r -e '\\bfcontext\\b' spec/ |grep -v 'danger ok' `.length > 1
5
- fail("fit left in tests") if `grep -r -e '\\bfit\\b' spec/ | grep -v 'danger ok' `.length > 1
6
- fail("ap left in tests") if `grep -r -e '\\bap\\b' spec/ | grep -v 'danger ok' `.length > 1
7
- fail("puts left in tests") if `grep -r -e '\\bputs\\b' spec/ | grep -v 'danger ok' `.length > 1
15
+ if Dir.exist?('spec')
16
+ fail('fdescribe left in tests') if `grep -r -e '\\bfdescribe\\b' spec/ |grep -v 'danger ok' `.length > 1
17
+ fail('fcontext left in tests') if `grep -r -e '\\bfcontext\\b' spec/ |grep -v 'danger ok' `.length > 1
18
+ fail('fit left in tests') if `grep -r -e '\\bfit\\b' spec/ | grep -v 'danger ok' `.length > 1
19
+ fail('ap left in tests') if `grep -r -e '\\bap\\b' spec/ | grep -v 'danger ok' `.length > 1
20
+ fail('puts left in tests') if `grep -r -e '\\bputs\\b' spec/ | grep -v 'danger ok' `.length > 1
8
21
  end
9
22
 
10
- if File.exists?('Gemfile')
23
+ if File.exist?('Gemfile')
11
24
  if `grep -r -e "^ *gem 'hubstaff_[a-z]\\+" Gemfile | grep -e ",.\\+[a-zA-Z]" `.length > 1
12
- fail("[gemfile] Beta hubstaff_* gems are not allowed in master/production")
25
+ fail('gemfile: Beta hubstaff_* gems are not allowed in master/production')
13
26
  end
14
27
  if `grep -r -e "^ *gem 'hubstaff_[a-z]\\+" Gemfile | grep -e ",.\\+'[~>=]\\+.\\+[a-zA-Z]" `.length > 1
15
- fail("[gemfile] Beta hubstaff_* gems should be the exact version")
28
+ fail('gemfile: Beta hubstaff_* gems should be the exact version')
16
29
  end
17
30
  if `grep -r -e "^ *gem 'hubstaff_[a-z]\\+" Gemfile | grep -e ",.\\+[' ][0-9.]\\+'" | grep -v '~>' `.length > 1
18
- fail("[gemfile] Release hubstaff_* gems should be using a ~> version")
31
+ fail('gemfile: Release hubstaff_* gems should be using a ~> version')
19
32
  end
20
33
  end
21
34
 
35
+ if github.branch_for_head.start_with?('security')
36
+ toggle_label(github, 'security', true)
37
+ end
38
+
22
39
  git.commits.each do |c|
23
- short = " ( #{c.sha[0..7]} )"
24
- has_migrations = c.diff_parent.any? {|f| f.path =~ /db\/migrate\// }
25
- has_schema_changes = c.diff_parent.any? {|f| f.path =~ /db\/schema\.rb/ }
26
- has_migration_msg = c.message =~ /^\[migration\]/
27
- no_schema_ok = ENV['DANGER_NO_SCHEMA_OK'] || false
40
+ short = " ( #{c.sha[0..7]} )"
41
+ has_migrations = c.diff_parent.any? { |f| f.path =~ %r{db/migrate/} }
42
+ has_schema_changes = c.diff_parent.any? { |f| f.path =~ %r{db/schema\.rb} }
43
+ old_migration_msg = c.message.start_with?('[migration]')
44
+ has_migration_msg = old_migration_msg || c.message.match?(/\Amigration(\([A-Za-z]+\))?:/)
45
+ no_schema_ok = ENV['DANGER_NO_SCHEMA_OK'] || false
28
46
  if has_migrations || has_schema_changes
29
47
  unless has_migration_msg
30
- fail '[migration] Schema migration commits need to be prefixed with [migration]' + short
48
+ fail 'migration: Schema migration commits needs to be tagged with (migration). e.g. migration(Module): ' + short
49
+ end
50
+ if old_migration_msg
51
+ warn 'migration: Please switch to the new conventional commit format.'
31
52
  end
32
53
  if has_migrations && !has_schema_changes && !no_schema_ok
33
- fail '[migration] Please checkin your schema.rb changes with your migration' + short
54
+ fail 'migration: Please checkin your schema.rb changes with your migration' + short
34
55
  end
35
56
  if !has_migrations && has_schema_changes
36
- warn '[migration] Please checkin your migrations with your schema.rb changes' + short
57
+ warn 'migration: Please checkin your migrations with your schema.rb changes' + short
37
58
  end
38
- if c.diff_parent.any? {|f| !( f.path =~ /db\/migrate\// or f.path =~ /db\/schema.rb/ ) }
39
- fail '[migration] Migration commit contains non-migration changes' + short
59
+ if c.diff_parent.any? { |f| f.path !~ %r{db/migrate/|db/schema\.rb} }
60
+ fail 'migration: Migration commit contains non-migration changes' + short
40
61
  end
62
+
63
+ toggle_label(github, 'run migration', true)
41
64
  elsif has_migration_msg
42
65
  fail '[migration] Migration commit with no migrations!' + short
66
+ else
67
+ toggle_label(github, 'run migration', false)
43
68
  end
44
69
 
45
- has_hubstaff_icon_changes = c.diff_parent.any? {|f| f.path =~ /hubstaff(icons|font)/ || f.path =~ /fontcustom-manifest/ }
70
+ has_hubstaff_icon_changes = c.diff_parent.any? { |f| f.path =~ /hubstaff(icons|font)|fontcustom-manifest/ }
46
71
  if has_hubstaff_icon_changes
47
- if c.diff_parent.any? {|f| !( f.path =~ /hubstaff-(icons|font)/ || f.path =~ /fontcustom-manifest/ ) }
48
- fail '[hubstaff-icons] Put hubstaff-icon changes into their own commit' + short
72
+ if c.diff_parent.any? { |f| !(f.path =~ /hubstaff-(icons|font)/ || f.path =~ /fontcustom-manifest/) }
73
+ fail 'hubstaff-icons: Put hubstaff-icon changes into their own commit' + short
49
74
  end
50
75
  end
51
76
 
52
- has_gemfile_changes = c.diff_parent.any? {|f| f.path =~ /Gemfile/ || f.path =~ /gemspec/ }
53
- has_gemfile_msg = c.message =~ /^\[gemfile\]/
77
+ has_gemfile_changes = c.diff_parent.any? { |f| f.path =~ /Gemfile|gemspec/ }
78
+ old_gemfile_msg = c.message.start_with?('[gemfile]')
79
+ has_gemfile_msg = old_gemfile_msg || c.message.match?(/\Agemfile(\([A-Za-z]+\))?:/)
54
80
  if has_gemfile_changes
55
81
  unless has_gemfile_msg
56
- fail '[gemfile] Gemfile commits need to be prefixed with [gemfile] ' + short
82
+ fail 'gemfile: Gemfile commits needs to be tagged with (gemfile). e.g. gemfile(Module): ' + short
57
83
  end
58
- if c.diff_parent.any? {|f| !( f.path =~ /Gemfile/ || f.path =~ /gemspec/ ) }
59
- fail '[gemfile] Gemfile commit contains non-gemfile changes' + short
84
+ if old_migration_msg
85
+ warn 'gemfile: Please switch to the new conventional commit format.'
60
86
  end
61
- if c.diff_parent.any? {|f| f.path == 'Gemfile.lock' }
62
- unless `grep -e '^ 1.15.2$' Gemfile.lock`.length > 1
63
- fail("[gemfile] Gemfile not bundled with bundler 1.15.2")
87
+ if c.diff_parent.any? { |f| f.path !~ /Gemfile|gemspec/ }
88
+ fail 'gemfile: Gemfile commit contains non-gemfile changes' + short
89
+ end
90
+ if c.diff_parent.any? { |f| f.path == 'Gemfile.lock' }
91
+ unless `grep -E -- '^BUNDLED WITH\s*\n\s+(1\\.15\\.2|1\\.17\\.3)$' Gemfile.lock`.length > 1
92
+ fail('gemfile: Gemfile not bundled with bundler 1.15.2 or 1.17.3')
64
93
  end
65
94
  end
66
95
  elsif has_gemfile_msg
67
- fail '[gemfile] Gemfile commit has no gemfile changes!' + short
96
+ fail 'gemfile: Gemfile commit has no gemfile changes!' + short
97
+ end
98
+
99
+ has_package_changes = c.diff_parent.any? { |f| f.path =~ /package\.json|yarn\.lock/ }
100
+ old_package_msg = c.message.start_with?('[package.json]')
101
+ has_package_msg = old_package_msg || c.message.match?(/\Apackage(\([A-Za-z]+\))?:/)
102
+ if has_package_changes
103
+ unless has_package_msg
104
+ fail 'package: Package.json commits needs to be tagged with package. e.g package(Module): ' + short
105
+ end
106
+ if old_package_msg
107
+ warn 'package: Please switch to the new conventional commit format.'
108
+ end
109
+ if c.diff_parent.any? { |f| f.path !~ /package\.json|yarn\.lock/ }
110
+ fail 'package: Package.json commit contains non-package changes' + short
111
+ end
112
+ elsif has_package_msg
113
+ fail 'package: Pacakge.json commit has no package changes!' + short
68
114
  end
69
115
  end
70
116
 
71
- require 'open-uri'
117
+ if ENV['CIRCLE_TOKEN']
118
+ require 'open-uri'
72
119
 
73
- artifact_url = "https://circleci.com/api/v1.1/project/github/#{ENV['CIRCLE_PROJECT_USERNAME']}/#{ENV["CIRCLE_PROJECT_REPONAME"]}/#{ENV['CIRCLE_BUILD_NUM']}/artifacts?circle-token=#{ENV['CIRCLE_TOKEN']}"
74
- artifacts = JSON.load(open(artifact_url).read).map{|a| a["url"]}
120
+ artifact_url = "https://circleci.com/api/v1.1/project/github/#{ENV['CIRCLE_PROJECT_USERNAME']}/#{ENV['CIRCLE_PROJECT_REPONAME']}/#{ENV['CIRCLE_BUILD_NUM']}/artifacts?circle-token=#{ENV['CIRCLE_TOKEN']}"
121
+ artifacts = JSON.parse(URI.parse(artifact_url).read).map { |a| a['url'] }
75
122
 
76
- jest = artifacts.find{ |artifact| artifact.end_with?('jest/index.html') }
77
- coverage = artifacts.find{ |artifact| artifact.end_with?('coverage/index.html') }
78
- rubocop = artifacts.find{ |artifact| artifact.end_with?('rubocop/report.html') }
79
- eslint = artifacts.find{ |artifact| artifact.end_with?('eslint/report.html') }
80
- rspec_files = artifacts.select{ |artifact| artifact =~ /rspec-(.+)\.html$/ }
123
+ jest = artifacts.find { |artifact| artifact.end_with?('jest/index.html') }
124
+ coverage = artifacts.find { |artifact| artifact.end_with?('coverage/index.html') }
125
+ rubocop = artifacts.find { |artifact| artifact.end_with?('rubocop/report.html') }
126
+ eslint = artifacts.find { |artifact| artifact.end_with?('eslint/report.html') }
127
+ rspec_files = artifacts.select { |artifact| artifact =~ /rspec-(.+)\.html$/ }
81
128
 
82
- {}.tap do |hash|
83
- hash['Ruby coverage report'] = coverage if coverage
84
- hash['RSpec test report'] = rspec_files unless rspec_files.empty?
85
- hash['RuboCop inspection report'] = rubocop if rubocop
86
- hash['ESLint inspection report'] = eslint if eslint
87
- hash['Jest coverage report'] = jest if jest
88
- end.each do |msg, links|
89
- links = [*links]
90
- if links.size == 1
91
- message("[#{msg}](#{links[0]})")
92
- else
93
- r = /rspec-(.+)\.html$/
94
- the_links = links.map do |l|
95
- m = r.match(l)
96
- if m
97
- "[#{m[1]}](#{l})"
98
- else
99
- "[link](#{l})"
100
- end
101
- end.join(', ')
129
+ {}.tap do |hash|
130
+ hash['Ruby coverage report'] = coverage if coverage
131
+ hash['RSpec test report'] = rspec_files unless rspec_files.empty?
132
+ hash['RuboCop inspection report'] = rubocop if rubocop
133
+ hash['ESLint inspection report'] = eslint if eslint
134
+ hash['Jest coverage report'] = jest if jest
135
+ end.each do |msg, links|
136
+ links = [*links]
137
+ if links.size == 1
138
+ message("[#{msg}](#{links[0]})")
139
+ else
140
+ r = /rspec-(.+)\.html$/
141
+ the_links = links.map { |l|
142
+ m = r.match(l)
143
+ if m
144
+ "[#{m[1]}](#{l})"
145
+ else
146
+ "[link](#{l})"
147
+ end
148
+ }.join(', ')
102
149
 
103
- message("#{msg} - #{the_links}")
150
+ message("#{msg} - #{the_links}")
151
+ end
104
152
  end
105
153
  end
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  gemspec
data/Rakefile CHANGED
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler'
2
4
  Bundler::GemHelper.install_tasks
3
5
 
4
6
  desc 'Default: run build.'
5
- task :default => :build
7
+ task default: :build
@@ -1,35 +1,36 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'thor'
4
5
  require 'fileutils'
6
+ require 'English'
5
7
 
6
- class NetsoftCircle < Thor
8
+ class NetsoftCircle < Thor # :nodoc:
7
9
  desc 'setup', 'Setup Heroku for deployment'
8
10
  def setup
9
-
10
11
  File.open("#{ENV['HOME']}/.netrc", 'a+') do |file|
11
- file << <<-EOF
12
+ file << <<~CONFIG
12
13
 
13
- machine api.heroku.com
14
- login #{ENV['HEROKU_LOGIN']}
15
- password #{ENV['HEROKU_API_KEY']}
16
- machine git.heroku.com
17
- login #{ENV['HEROKU_LOGIN']}
18
- password #{ENV['HEROKU_API_KEY']}
19
- EOF
14
+ machine api.heroku.com
15
+ login #{ENV['HEROKU_LOGIN']}
16
+ password #{ENV['HEROKU_API_KEY']}
17
+ machine git.heroku.com
18
+ login #{ENV['HEROKU_LOGIN']}
19
+ password #{ENV['HEROKU_API_KEY']}
20
+ CONFIG
20
21
  end
21
22
 
22
- Dir.mkdir("#{ENV['HOME']}/.ssh") unless Dir.exists?("#{ENV['HOME']}/.ssh")
23
+ Dir.mkdir("#{ENV['HOME']}/.ssh") unless Dir.exist?("#{ENV['HOME']}/.ssh")
23
24
  File.open("#{ENV['HOME']}/.ssh/config", 'a+') do |file|
24
- file << <<-EOF
25
+ file << <<~CONFIG
25
26
 
26
- VerifyHostKeyDNS yes
27
- StrictHostKeyChecking no
28
- EOF
27
+ VerifyHostKeyDNS yes
28
+ StrictHostKeyChecking no
29
+ CONFIG
29
30
  end
30
31
 
31
32
  system('git config --global url."https://git.heroku.com/".insteadOf heroku:')
32
- exit(1) unless $?.success?
33
+ exit(1) unless $CHILD_STATUS.success?
33
34
  end
34
35
 
35
36
  desc 'merge', 'Merges several simplecov json result files'
@@ -37,6 +38,7 @@ EOF
37
38
  def merge(*files)
38
39
  require 'simplecov'
39
40
  return if files.empty?
41
+
40
42
  results = []
41
43
 
42
44
  files.each do |file|
@@ -54,7 +56,7 @@ EOF
54
56
 
55
57
  desc 'rspec', 'Run rspec'
56
58
  def rspec
57
- system <<-EOF
59
+ system <<~COMMAND
58
60
  bundle _${BUNDLE_VERSION}_ exec rspec \
59
61
  --color \
60
62
  --format RspecJunitFormatter \
@@ -63,20 +65,20 @@ EOF
63
65
  --out $CIRCLE_ARTIFACTS/rspec.html \
64
66
  --format progress \
65
67
  $(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)
66
- EOF
67
- exit(1) unless $?.success?
68
+ COMMAND
69
+ exit(1) unless $CHILD_STATUS.success?
68
70
  end
69
71
 
70
72
  desc 'rubocop', 'Run rubocop'
71
73
  def rubocop
72
- system <<-EOF
73
- rubocop \
74
+ system <<~COMMAND
75
+ bundle _${BUNDLE_VERSION}_ exec rubocop \
74
76
  --parallel \
75
77
  --format progress \
76
78
  --format html \
77
79
  --out $CIRCLE_ARTIFACTS/rubocop/report.html
78
- EOF
79
- exit(1) unless $?.success?
80
+ COMMAND
81
+ exit(1) unless $CHILD_STATUS.success?
80
82
  end
81
83
 
82
84
  def self.exit_on_failure?
@@ -0,0 +1,3 @@
1
+ mkdir ~/.gem
2
+ echo -e "---\n:rubygems_api_key: $RUBYGEMS_API_KEY" > ~/.gem/credentials
3
+ chmod 0600 ~/.gem/credentials
@@ -15,8 +15,12 @@ if ((danger.github.pr.body || '').length < 5) {
15
15
  fail("Please provide a summary in the Pull Request description");
16
16
  }
17
17
 
18
- if (!labels.includes('review passed')) {
19
- fail("Has not passed code-review");
18
+ if (labels.includes('product review needed')) {
19
+ fail('Has not passed product review');
20
+ }
21
+
22
+ if (!(labels.includes('review passed') || labels.includes('code review passed'))) {
23
+ fail("Has not passed code review");
20
24
  }
21
25
 
22
26
  if (!labels.includes('QA passed')) {
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module NetsoftDanger
2
- VERSION = '0.3.3'.freeze
4
+ VERSION = '0.3.8'
3
5
  end
@@ -1,5 +1,6 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.push File.expand_path('lib', __dir__)
3
4
  require 'netsoft-danger/version'
4
5
 
5
6
  Gem::Specification.new do |s|
@@ -15,11 +16,15 @@ Gem::Specification.new do |s|
15
16
  s.files = `git ls-files`.split("\n")
16
17
  s.require_paths = ['lib']
17
18
 
18
- s.add_development_dependency 'rake'
19
19
  s.add_runtime_dependency 'danger', '~> 5.0'
20
- s.add_runtime_dependency 'rubocop', '~> 0.74.0'
21
- s.add_runtime_dependency 'rubocop-rails', '~> 2.2.1'
22
- s.add_runtime_dependency 'rubocop-performance', '~> 1.4.1'
23
- s.add_runtime_dependency 'rubocop-rspec', '~> 1.35.0'
20
+ s.add_runtime_dependency 'faraday'
24
21
  s.add_runtime_dependency 'thor'
22
+
23
+ s.add_development_dependency 'rake'
24
+
25
+ s.add_development_dependency 'netsoft-rubocop', '= 1.0.1'
26
+ s.add_development_dependency 'rubocop', '= 0.74.0'
27
+ s.add_development_dependency 'rubocop-performance', '= 1.5.2'
28
+ s.add_development_dependency 'rubocop-rails', '= 2.4.2'
29
+ s.add_development_dependency 'rubocop-rspec', '= 1.38.1'
25
30
  end