ndr_support 3.3.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 025cbd4a4eaecbac1621d47a68a361d675144a28
4
- data.tar.gz: 48b75b3967ac4fd37736eac5ba4c80423639d029
3
+ metadata.gz: d551092d3ebfd8087efcbfa8321e1a7ead1837e3
4
+ data.tar.gz: 9b6649a2ddae13a5f9f0dacb73cdad200a62c51f
5
5
  SHA512:
6
- metadata.gz: 11b95616713df1d841418503dbbd500308bedc6a792944939539c1891783aa9412cf86ace32aa5a1c792e300143db7fdaa4af9cf86131f6e5ce0b1e54ca21b49
7
- data.tar.gz: 92ab5caca57899c42f2053dfdf06bac3ad55a6da6088641a1e160acb6f4b8e49885b65258aea73ffe202346b1221baec49a89da28cf88f4c5c0ece9491b01b0c
6
+ metadata.gz: 18b986bdcb86d9457514752dd6cbb7a4db9b52daa3814eebd312ef99078d3d2a649e9690f77055189ba89097bc6422c571bfdec94f3872d24c1a4876c1f6a49c
7
+ data.tar.gz: 8acdf5704f9e9b0cdc47fb1b0d31c2051d8eb3ed6a59e23c82ad9975c6d2305b8948443145df8c12e3045885dfcc0dc5e7cee2f3777e57b68a7e3c80046cacbd
data/Guardfile CHANGED
@@ -1,16 +1,24 @@
1
1
  # A sample Guardfile
2
2
  # More info at https://github.com/guard/guard#readme
3
3
 
4
- # directories %(app lib config test spec feature)
5
- guard :rubocop, :all_on_start => false, :keep_failed => false do
6
- watch(/.+\.(gemspec|rake|rb)$/)
7
- watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
8
- end
4
+ # This group allows to skip running rubocop when tests fail.
5
+ group :red_green_refactor, halt_on_fail: true do
6
+ guard :minitest do
7
+ watch(%r{^test/.+_test\.rb$})
8
+ watch('test/test_helper.rb') { 'test' }
9
9
 
10
- guard :minitest do
11
- watch(%r{^test/.+_test\.rb$})
12
- watch('test/test_helper.rb') { 'test' }
10
+ # Non-rails
11
+ watch(%r{^lib/ndr_support/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
12
+ end
13
13
 
14
- # Non-rails
15
- watch(%r{^lib/ndr_support/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
14
+ # automatically check Ruby code style with Rubocop when files are modified
15
+ guard :shell do
16
+ watch(/.+\.(rb|rake)$/) do |m|
17
+ unless system("bundle exec rake rubocop:diff #{m[0]}")
18
+ Notifier.notify "#{File.basename(m[0])} inspected, offenses detected",
19
+ title: 'RuboCop results (partial)', image: :failed
20
+ end
21
+ nil
22
+ end
23
+ end
16
24
  end
data/README.md CHANGED
@@ -3,8 +3,7 @@
3
3
  This is the Public Health England (PHE) National Disease Registers (NDR) Support ruby gem, providing:
4
4
 
5
5
  1. core ruby class extensions;
6
- 2. additional time, regular expression, file security and encoding classes; and
7
- 3. rake tasks to manage code auditing of ruby based projects.
6
+ 2. additional time, regular expression, file security and encoding classes.
8
7
 
9
8
  ## Installation
10
9
 
@@ -54,26 +53,6 @@ To enable this add the following line to your code:
54
53
  include NdrSupport::YAML::SerializationMigration
55
54
  ```
56
55
 
57
- ### Code Auditing Rake Tasks
58
-
59
- ndr_support also provides a mechanism to manage the state of routine code quality and security peer reviews. It should be used as part of wider quality and security policies.
60
-
61
- It provides rake tasks to help manage the process of persisting the state of security reviews.
62
-
63
- Once files have been reviewed as secure, the revision number for that file is stored in code_safety.yml. If used within a Rails app, this file is stored in the config/ folder, otherwise it is kept in the project's root folder.
64
-
65
- Note: This feature works with svn and git repositories and svn, git-svn and git working copies.
66
-
67
- To add code auditing to your project add this line to your application's Rakefile:
68
-
69
- ```ruby
70
- require 'ndr_support/tasks'
71
- ```
72
-
73
- For more details of the tasks available, execute:
74
-
75
- $ rake -T audit
76
-
77
56
  ## Contributing
78
57
 
79
58
  1. Fork it ( https://github.com/PublicHealthEngland/ndr_support/fork )
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'rake/testtask'
3
- require 'ndr_support/tasks'
3
+ require 'ndr_dev_support/tasks'
4
4
 
5
5
  Rake::TestTask.new do |t|
6
6
  t.libs << 'test'
data/code_safety.yml CHANGED
@@ -27,19 +27,19 @@ file safety:
27
27
  Guardfile:
28
28
  comments:
29
29
  reviewed_by: timgentry
30
- safe_revision: 506a317e59d0ccb5b32d813b74d822f35a55cea9
30
+ safe_revision: e33e9dae7f38bc449ce9276515a539836dbbbd53
31
31
  LICENSE.txt:
32
32
  comments:
33
33
  reviewed_by: timgentry
34
34
  safe_revision: 90328cca8494539257e192a63b240a91c89f0616
35
35
  README.md:
36
36
  comments:
37
- reviewed_by: brian.shand
38
- safe_revision: 63cff701a1740a3bfa04330c21f1262dd49a7c31
37
+ reviewed_by: timgentry
38
+ safe_revision: e33e9dae7f38bc449ce9276515a539836dbbbd53
39
39
  Rakefile:
40
40
  comments:
41
41
  reviewed_by: timgentry
42
- safe_revision: 2a5d30674dc9dde336e1dbbbf3c8a98905647432
42
+ safe_revision: e33e9dae7f38bc449ce9276515a539836dbbbd53
43
43
  gemfiles/Gemfile.rails32:
44
44
  comments:
45
45
  reviewed_by: pauleves
@@ -159,19 +159,15 @@ file safety:
159
159
  lib/ndr_support/version.rb:
160
160
  comments:
161
161
  reviewed_by: timgentry
162
- safe_revision: f625404bd69bb1b233f7a7b1a043d52e916da743
162
+ safe_revision: 04c7617a6cc63d614e53cd6bc053dec46cc15786
163
163
  lib/ndr_support/yaml/serialization_migration.rb:
164
164
  comments:
165
165
  reviewed_by: timgentry
166
166
  safe_revision: 29595e6431587ff9b7db6e3ad3abbb3577bff99c
167
- lib/tasks/audit_code.rake:
168
- comments:
169
- reviewed_by: josh.pencheon
170
- safe_revision: 20cde082ee86a547de7b21a97a695bb307ac9f64
171
167
  ndr_support.gemspec:
172
168
  comments:
173
169
  reviewed_by: timgentry
174
- safe_revision: 41cea330c8de42e4080c40143eaa15a225be7c5a
170
+ safe_revision: e33e9dae7f38bc449ce9276515a539836dbbbd53
175
171
  test/array_test.rb:
176
172
  comments:
177
173
  reviewed_by: timgentry
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This defines the NdrSupport version. If you change it, rebuild and commit the gem.
2
- # Use "rake build" to build the gem, see rake -T for all bundler rake tasks (and our own).
4
+ # Use "rake build" to build the gem, see rake -T for all bundler rake tasks.
3
5
  module NdrSupport
4
- VERSION = '3.3.0'
6
+ VERSION = '4.0.0'
5
7
  end
data/ndr_support.gemspec CHANGED
@@ -31,8 +31,10 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency 'minitest', '>= 5.0.0'
32
32
  spec.add_development_dependency 'mocha', '~> 1.1'
33
33
 
34
+ spec.add_development_dependency 'ndr_dev_support', '~> 1.1', '>= 1.1.1'
34
35
  spec.add_development_dependency 'guard'
35
36
  spec.add_development_dependency 'guard-rubocop'
37
+ spec.add_development_dependency 'guard-shell'
36
38
  spec.add_development_dependency 'guard-minitest'
37
39
  spec.add_development_dependency 'terminal-notifier-guard' if RUBY_PLATFORM =~ /darwin/
38
40
  spec.add_development_dependency 'simplecov'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ndr_support
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - NCRS Development Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-29 00:00:00.000000000 Z
11
+ date: 2016-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -106,6 +106,26 @@ dependencies:
106
106
  - - ~>
107
107
  - !ruby/object:Gem::Version
108
108
  version: '1.1'
109
+ - !ruby/object:Gem::Dependency
110
+ name: ndr_dev_support
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ~>
114
+ - !ruby/object:Gem::Version
115
+ version: '1.1'
116
+ - - '>='
117
+ - !ruby/object:Gem::Version
118
+ version: 1.1.1
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: '1.1'
126
+ - - '>='
127
+ - !ruby/object:Gem::Version
128
+ version: 1.1.1
109
129
  - !ruby/object:Gem::Dependency
110
130
  name: guard
111
131
  requirement: !ruby/object:Gem::Requirement
@@ -134,6 +154,20 @@ dependencies:
134
154
  - - '>='
135
155
  - !ruby/object:Gem::Version
136
156
  version: '0'
157
+ - !ruby/object:Gem::Dependency
158
+ name: guard-shell
159
+ requirement: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ type: :development
165
+ prerelease: false
166
+ version_requirements: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - '>='
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
137
171
  - !ruby/object:Gem::Dependency
138
172
  name: guard-minitest
139
173
  requirement: !ruby/object:Gem::Requirement
@@ -224,7 +258,6 @@ files:
224
258
  - lib/ndr_support/utf8_encoding/object_support.rb
225
259
  - lib/ndr_support/version.rb
226
260
  - lib/ndr_support/yaml/serialization_migration.rb
227
- - lib/tasks/audit_code.rake
228
261
  - ndr_support.gemspec
229
262
  - test/array_test.rb
230
263
  - test/concerns/working_days_test.rb
@@ -1,475 +0,0 @@
1
- SAFETY_FILE =
2
- if File.exist?('code_safety.yml')
3
- 'code_safety.yml'
4
- elsif defined?(Rails)
5
- Rails.root.join('config', 'code_safety.yml')
6
- else
7
- 'code_safety.yml'
8
- end
9
-
10
- # Temporary overrides to only audit external access files
11
- SAFETY_REPOS = [['/svn/era', '/svn/extra/era/external-access']]
12
-
13
- require 'yaml'
14
-
15
- # Parameter max_print is number of entries to print before truncating output
16
- # (negative value => print all)
17
- def audit_code_safety(max_print = 20, ignore_new = false, show_diffs = false, show_in_priority = false, user_name = 'usr')
18
- puts 'Running source code safety audit script.'
19
- puts
20
-
21
- max_print = 1_000_000 if max_print < 0
22
- safety_cfg = File.exist?(SAFETY_FILE) ? YAML.load_file(SAFETY_FILE) : {}
23
- file_safety = safety_cfg['file safety']
24
- if file_safety.nil?
25
- puts "Creating new 'file safety' block in #{SAFETY_FILE}"
26
- safety_cfg['file safety'] = file_safety = {}
27
- end
28
- file_safety.each do |_k, v|
29
- rev = v['safe_revision']
30
- v['safe_revision'] = rev.to_s if rev.is_a?(Integer)
31
- end
32
- orig_count = file_safety.size
33
-
34
- safety_repo = trunk_repo = get_trunk_repo
35
-
36
- # TODO: below is broken for git-svn
37
- # Is it needed?
38
-
39
- SAFETY_REPOS.each do |suffix, alt|
40
- # Temporarily override to only audit a different file list
41
- if safety_repo.end_with?(suffix)
42
- safety_repo = safety_repo[0...-suffix.length] + alt
43
- break
44
- end
45
- end
46
-
47
- if ignore_new
48
- puts "Not checking for new files in #{safety_repo}"
49
- else
50
- puts "Checking for new files in #{safety_repo}"
51
- new_files = get_new_files(safety_repo)
52
- # Ignore subdirectories, and exclude code_safety.yml by default.
53
- new_files.delete_if { |f| f =~ /[\/\\]$/ || f == SAFETY_FILE }
54
- new_files.each do |f|
55
- next if file_safety.key?(f)
56
- file_safety[f] = {
57
- 'comments' => nil,
58
- 'reviewed_by' => nil,
59
- 'safe_revision' => nil }
60
- end
61
- File.open(SAFETY_FILE, 'w') do |file|
62
- # Consistent file diffs, as ruby preserves Hash insertion order since v1.9
63
- safety_cfg['file safety'] = Hash[file_safety.sort]
64
- YAML.dump(safety_cfg, file) # Save changes before checking latest revisions
65
- end
66
- end
67
- puts "Updating latest revisions for #{file_safety.size} files"
68
- set_last_changed_revision(trunk_repo, file_safety, file_safety.keys)
69
- puts "\nSummary:"
70
- puts "Number of files originally in #{SAFETY_FILE}: #{orig_count}"
71
- puts "Number of new files added: #{file_safety.size - orig_count}"
72
-
73
- # Now generate statistics:
74
- unknown = file_safety.values.select { |x| x['safe_revision'].nil? }
75
- unsafe = file_safety.values.select do |x|
76
- !x['safe_revision'].nil? && x['safe_revision'] != -1 &&
77
- x['last_changed_rev'] != x['safe_revision'] &&
78
- !(x['last_changed_rev'] =~ /^[0-9]+$/ && x['safe_revision'] =~ /^[0-9]+$/ &&
79
- x['last_changed_rev'].to_i < x['safe_revision'].to_i)
80
- end
81
- puts "Number of files with no safe version: #{unknown.size}"
82
- puts "Number of files which are no longer safe: #{unsafe.size}"
83
- puts
84
- printed = []
85
- # We also print a third category: ones which are no longer in the repository
86
- file_list =
87
- if show_in_priority
88
- file_safety.sort_by { |_k, v| v.nil? ? -100 : v['last_changed_rev'].to_i }.map(&:first)
89
- else
90
- file_safety.keys.sort
91
- end
92
-
93
- file_list.each do |f|
94
- if print_file_safety(file_safety, trunk_repo, f, false, printed.size >= max_print)
95
- printed << f
96
- end
97
- end
98
- puts "... and #{printed.size - max_print} others" if printed.size > max_print
99
- if show_diffs
100
- puts
101
- printed.each do |f|
102
- print_file_diffs(file_safety, trunk_repo, f, user_name)
103
- end
104
- end
105
-
106
- # Returns `true` unless there are pending reviews:
107
- unsafe.length.zero? && unknown.length.zero?
108
- end
109
-
110
- # Print summary details of a file's known safety
111
- # If not verbose, only prints details for unsafe files
112
- # Returns true if anything printed (or would have been printed if silent),
113
- # or false otherwise.
114
- def print_file_safety(file_safety, repo, fname, verbose = false, silent = false)
115
- msg = "#{fname}\n "
116
- entry = file_safety[fname]
117
- msg += 'File not in audit list' if entry.nil?
118
-
119
- if entry['safe_revision'].nil?
120
- msg += 'No safe revision known'
121
- msg += ", last changed #{entry['last_changed_rev']}" unless entry['last_changed_rev'].nil?
122
- else
123
- repolatest = entry['last_changed_rev'] # May have been prepopulated en mass
124
- msg += 'Not in repository: ' if entry['last_changed_rev'] == -1
125
- if (repolatest != entry['safe_revision']) &&
126
- !(repolatest =~ /^[0-9]+$/ && entry['safe_revision'] =~ /^[0-9]+$/ &&
127
- repolatest.to_i < entry['safe_revision'].to_i)
128
- # (Allow later revisions to be treated as safe for svn)
129
- msg += "No longer safe since revision #{repolatest}: "
130
- else
131
- return false unless verbose
132
- msg += 'Safe: '
133
- end
134
- msg += "revision #{entry['safe_revision']} reviewed by #{entry['reviewed_by']}"
135
- end
136
- msg += "\n Comments: #{entry['comments']}" if entry['comments']
137
- puts msg unless silent
138
- true
139
- end
140
-
141
- def flag_file_as_safe(release, reviewed_by, comments, f)
142
- safety_cfg = YAML.load_file(SAFETY_FILE)
143
- file_safety = safety_cfg['file safety']
144
-
145
- unless File.exist?(f)
146
- abort("Error: Unable to flag non-existent file as safe: #{f}")
147
- end
148
- unless file_safety.key?(f)
149
- file_safety[f] = {
150
- 'comments' => nil,
151
- 'reviewed_by' => :dummy, # dummy value, will be overwritten
152
- 'safe_revision' => nil }
153
- end
154
- entry = file_safety[f]
155
- entry_orig = entry.dup
156
- if comments.to_s.length > 0 && entry['comments'] != comments
157
- entry['comments'] = if entry['comments'].to_s.empty?
158
- comments
159
- else
160
- "#{entry['comments']}#{'.' unless entry['comments'].end_with?('.')} Revision #{release}: #{comments}"
161
- end
162
- end
163
- if entry['safe_revision']
164
- unless release
165
- abort("Error: File already has safe revision #{entry['safe_revision']}: #{f}")
166
- end
167
- if release.is_a?(Integer) && release < entry['safe_revision']
168
- puts("Warning: Rolling back safe revision from #{entry['safe_revision']} to #{release} for #{f}")
169
- end
170
- end
171
- entry['safe_revision'] = release
172
- entry['reviewed_by'] = reviewed_by
173
- if entry == entry_orig
174
- puts "No changes when updating safe_revision to #{release || '[none]'} for #{f}"
175
- else
176
- File.open(SAFETY_FILE, 'w') do |file|
177
- # Consistent file diffs, as ruby preserves Hash insertion order since v1.9
178
- safety_cfg['file safety'] = Hash[file_safety.sort]
179
- YAML.dump(safety_cfg, file) # Save changes before checking latest revisions
180
- end
181
- puts "Updated safe_revision to #{release || '[none]'} for #{f}"
182
- end
183
- end
184
-
185
- # Determine the type of repository
186
- def repository_type
187
- @repository_type ||= if Dir.exist?('.svn') || system("svn info . > /dev/null 2>&1")
188
- 'svn'
189
- elsif Dir.exist?('.git') && open('.git/config').grep(/svn/).any?
190
- 'git-svn'
191
- elsif Dir.exist?('.git') && open('.git/config').grep(/git/).any?
192
- 'git'
193
- else
194
- 'not known'
195
- end
196
- end
197
-
198
- def get_trunk_repo
199
- case repository_type
200
- when 'svn'
201
- repo_info = %x[svn info]
202
- puts 'svn case'
203
- return repo_info.split("\n").select { |x| x =~ /^URL: / }.collect { |x| x[5..-1] }.first
204
- when 'git-svn'
205
- puts 'git-svn case'
206
- repo_info = %x[git svn info]
207
- return repo_info.split("\n").select { |x| x =~ /^URL: / }.collect { |x| x[5..-1] }.first
208
- when 'git'
209
- puts 'git case'
210
- repo_info = %x[git remote -v]
211
- return repo_info.split("\n").first[7..-9]
212
- else
213
- return 'Information not available. Unknown repository type'
214
- end
215
- end
216
-
217
- def get_new_files(safety_repo)
218
- case repository_type
219
- when 'svn', 'git-svn'
220
- %x[svn ls -R "#{safety_repo}"].split("\n")
221
- when 'git'
222
- #%x[git ls-files --modified].split("\n")
223
- %x[git ls-files].split("\n")
224
-
225
- # TODO: Below is for remote repository - for testing use local files
226
- #new_files = %x[git ls-files --modified #{safety_repo}].split("\n")
227
- # TODO: Do we need the --modified option?
228
- #new_files = %x[git ls-files --modified].split("\n")
229
- else
230
- []
231
- end
232
- end
233
-
234
- # Fill in the latest changed revisions in a file safety map.
235
- # (Don't write this data to the YAML file, as it is intrinsic to the SVN
236
- # repository.)
237
- def set_last_changed_revision(repo, file_safety, fnames)
238
- dot_freq = (file_safety.size / 40.0).ceil # Print up to 40 progress dots
239
- case repository_type
240
- when 'git'
241
- fnames = file_safety.keys if fnames.nil?
242
-
243
- fnames.each_with_index do |f, i|
244
- info = %x[git log -n 1 #{f}].split("\n").first[7..-1]
245
- if info.nil? || info.empty?
246
- file_safety[f]['last_changed_rev'] = -1
247
- else
248
- file_safety[f]['last_changed_rev'] = info
249
- end
250
- # Show progress
251
- print '.' if (i % dot_freq) == 0
252
- end
253
- puts
254
- when 'git-svn', 'svn'
255
- fnames = file_safety.keys if fnames.nil?
256
-
257
- fnames.each_with_index do |f, i|
258
- last_revision = get_last_changed_revision(repo, f)
259
- if last_revision.nil? || last_revision.empty?
260
- file_safety[f]['last_changed_rev'] = -1
261
- else
262
- file_safety[f]['last_changed_rev'] = last_revision
263
- end
264
- # Show progress
265
- print '.' if (i % dot_freq) == 0
266
- end
267
- puts
268
- # NOTE: Do we need the following for retries?
269
- # if retries && result.size != fnames.size && fnames.size > 1
270
- # # At least one invalid (deleted file --> subsequent arguments ignored)
271
- # # Try each file individually
272
- # # (It would probably be safe to continue from the extra_info.size argument)
273
- # puts "Retrying (got #{result.size}, expected #{fnames.size})" if debug >= 2
274
- # result = []
275
- # fnames.each{ |f|
276
- # result += svn_info_entries([f], repo, false, debug)
277
- # }
278
- # end
279
- end
280
- end
281
-
282
- # Return the last changed revision
283
- def get_last_changed_revision(repo, fname)
284
- case repository_type
285
- when 'git'
286
- %x[git log -n 1 "#{fname}"].split("\n").first[7..-1]
287
- when 'git-svn', 'svn'
288
- begin
289
- svn_info = %x[svn info -r head "#{repo}/#{fname}"]
290
- rescue
291
- puts 'we have an error in the svn info line'
292
- end
293
- begin
294
- svn_info.match('Last Changed Rev: ([0-9]*)').to_a[1]
295
- rescue
296
- puts 'We have an error in getting the revision'
297
- end
298
- end
299
- end
300
-
301
- # Get mime type. Note that Git does not have this information
302
- def get_mime_type(repo, fname)
303
- case repository_type
304
- when 'git'
305
- 'Git does not provide mime types'
306
- when 'git-svn', 'svn'
307
- %x[svn propget svn:mime-type "#{repo}/#{fname}"].chomp
308
- end
309
- end
310
-
311
- # # Print file diffs, for code review
312
- def print_file_diffs(file_safety, repo, fname, user_name)
313
- entry = file_safety[fname]
314
- repolatest = entry['last_changed_rev']
315
- safe_revision = entry['safe_revision']
316
-
317
- if safe_revision.nil?
318
- first_revision = set_safe_revision
319
- print_repo_file_diffs(repolatest, repo, fname, user_name, first_revision)
320
- else
321
-
322
- rev = get_last_changed_revision(repo, fname)
323
- if rev
324
- mime = get_mime_type(repo, fname)
325
- end
326
-
327
- print_repo_file_diffs(repolatest, repo, fname, user_name, safe_revision) if repolatest != safe_revision
328
- end
329
- end
330
-
331
- # Returns first commit for git and 0 for svn in order to be used to display
332
- # new files. Called from print_file_diffs
333
- def set_safe_revision
334
- case repository_type
335
- when 'git'
336
- %x[git rev-list --max-parents=0 HEAD].chomp
337
- when 'git-svn', 'svn'
338
- 0
339
- end
340
- end
341
-
342
- def print_repo_file_diffs(repolatest, repo, fname, user_name, safe_revision)
343
- require 'open3'
344
- cmd = nil
345
- case repository_type
346
- when 'git'
347
- cmd = ['git', '--no-pager', 'diff', '-b', "#{safe_revision}..#{repolatest}", fname]
348
- when 'git-svn', 'svn'
349
- cmd = ['svn', 'diff', '-r', "#{safe_revision.to_i}:#{repolatest.to_i}", '-x', '-b', "#{repo}/#{fname}"]
350
- end
351
- if cmd
352
- puts(cmd.join(' '))
353
- stdout_and_err_str, status = Open3.capture2e(*cmd)
354
- puts(stdout_and_err_str)
355
- else
356
- puts 'Unknown repo'
357
- end
358
-
359
- puts %(To flag the changes to this file as safe, run:)
360
- puts %( rake audit:safe release=#{repolatest} file=#{fname} reviewed_by=#{user_name} comments="")
361
- puts
362
- end
363
-
364
- def release_valid?(release)
365
- case repository_type
366
- when 'svn', 'git-svn'
367
- release =~ /\A[0-9][0-9]*\Z/
368
- when 'git'
369
- release =~ /\A[0-9a-f]{40}\Z/
370
- else
371
- false
372
- end
373
- end
374
-
375
- def get_release
376
- release = ENV['release']
377
- release = nil if release == '0'
378
- case repository_type
379
- when 'svn', 'git-svn'
380
- release.to_i
381
- when 'git'
382
- release
383
- else
384
- ''
385
- end
386
- release
387
- end
388
-
389
- def clean_working_copy?
390
- case repository_type
391
- when 'svn'
392
- system('svn status | grep -q [^AMCDG]')
393
- when 'git', 'git-svn'
394
- system('git diff --quiet HEAD')
395
- end
396
- end
397
-
398
- namespace :audit do
399
- desc "Audit safety of source code.
400
- Usage: audit:code [max_print=n] [ignore_new=false|true] [show_diffs=false|true] [reviewed_by=usr]
401
-
402
- File #{SAFETY_FILE} lists the safety and revision information
403
- of the era source code. This task updates the list, and [TODO] warns about
404
- files which have changed since they were last verified as safe."
405
- task(:code) do
406
- puts 'Usage: audit:code [max_print=n] [ignore_new=false|true] [show_diffs=false|true] [show_in_priority=false|true] [reviewed_by=usr]'
407
- puts "This is a #{repository_type} repository"
408
-
409
- ignore_new = (ENV['ignore_new'].to_s =~ /\Atrue\Z/i)
410
- show_diffs = (ENV['show_diffs'].to_s =~ /\Atrue\Z/i)
411
- show_in_priority = (ENV['show_in_priority'].to_s =~ /\Atrue\Z/i)
412
- max_print = ENV['max_print'] =~ /\A-?[0-9][0-9]*\Z/ ? ENV['max_print'].to_i : 20
413
- reviewer = ENV['reviewed_by']
414
-
415
- all_safe = audit_code_safety(max_print, ignore_new, show_diffs, show_in_priority, reviewer)
416
-
417
- unless show_diffs
418
- puts 'To show file diffs, run: rake audit:code max_print=-1 show_diffs=true'
419
- end
420
-
421
- exit(1) unless all_safe
422
- end
423
-
424
- desc "Flag a source file as safe.
425
-
426
- Usage:
427
- Flag as safe: rake audit:safe release=revision reviewed_by=usr [comments=...] file=f
428
- Needs review: rake audit:safe release=0 [comments=...] file=f"
429
- task(:safe) do
430
- release = get_release
431
-
432
- required_fields = %w(release file)
433
- required_fields << 'reviewed_by' if release # 'Needs review' doesn't need a reviewer
434
- missing = required_fields.collect { |f| (f if ENV[f].to_s.empty? || (f == 'reviewed_by' && ENV[f] == 'usr')) }.compact # Avoid accidental missing username
435
- unless missing.empty?
436
- puts 'Usage: rake audit:safe release=revision reviewed_by=usr [comments=...] file=f'
437
- puts 'or, to flag a file for review: rake audit:safe release=0 [comments=...] file=f'
438
- abort("Error: Missing required argument(s): #{missing.join(', ')}")
439
- end
440
-
441
- unless release.nil? || release_valid?(release)
442
- puts 'Usage: rake audit:safe release=revision reviewed_by=usr [comments=...] file=f'
443
- puts 'or, to flag a file for review: rake audit:safe release=0 [comments=...] file=f'
444
- abort("Error: Invalid release: #{ENV['release']}")
445
- end
446
-
447
- flag_file_as_safe(release, ENV['reviewed_by'], ENV['comments'], ENV['file'])
448
- end
449
-
450
- desc 'Wraps audit:code, and stops if any review is pending/stale.'
451
- task(:ensure_safe) do
452
- abort('You have local changes, cannot verify code safety!') unless clean_working_copy?
453
-
454
- puts 'Checking code safety...'
455
-
456
- begin
457
- begin
458
- $stdout = $stderr = StringIO.new
459
- Rake::Task['audit:code'].invoke
460
- ensure
461
- $stdout, $stderr = STDOUT, STDERR
462
- end
463
- rescue SystemExit => ex
464
- puts '=============================================================='
465
- puts 'Code safety review of some files are not up-to-date; aborting!'
466
- puts ' - to review the files in question, run: rake audit:code'
467
- puts '=============================================================='
468
-
469
- raise ex
470
- end
471
- end
472
- end
473
-
474
- # Prevent building of un-reviewed gems:
475
- task build: :'audit:ensure_safe'