ndr_support 3.3.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
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'