Created
April 29, 2013 01:46
-
-
Save tommeier/5479260 to your computer and use it in GitHub Desktop.
Check for timezone aware rails code (using Cane: https://github.com/square/cane)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require 'set' | |
| require 'cane/file' | |
| require 'cane/task_runner' | |
| module CaneExt | |
| # Creates violations for files that do not meet code requirements. | |
| class CodeCheck < Struct.new(:opts) | |
| include Cane::CLI | |
| def initialize(*args) | |
| options = args.first.merge!(defaults(self.class)) | |
| super(options) | |
| end | |
| def self.key; :code; end | |
| def self.name; "code checking"; end | |
| def self.options | |
| { | |
| code_glob: [ 'Glob to run code checks over', | |
| default: '{app,lib,spec}/**/*.rb', | |
| variable: 'GLOB', | |
| clobber: :no_code | |
| ], | |
| code_exclude: [ 'Exclude from code check', | |
| variable: 'GLOB', | |
| default: ['lib/cane_ext/*'], | |
| clobber: :no_code | |
| ], | |
| code_timezones: [ 'Time zone aware commands', | |
| default: { | |
| 'Date.today' => 'Time.zone.today', | |
| 'Time.now' => 'Time.zone.now', | |
| 'DateTime.now' => 'Time.zone.now', | |
| 'Time.at' => 'Time.zone.at', | |
| 'Time.parse' => 'Time.zone.parse', | |
| 'Time.new' => 'Time.zone.local', | |
| 'DateTime.new' => 'Time.zone.local', | |
| 'DateTime.strptime' => 'Time.zone.strptime' | |
| }, | |
| variable: 'FILE', | |
| clobber: :no_zone | |
| ], | |
| no_code: ['Disable code checking', cast: ->(x) { !x }] | |
| } | |
| end | |
| def violations | |
| return [] if opts[:no_code] | |
| worker.map(file_list) do |file_path| | |
| map_lines(file_path) do |line, line_number| | |
| violations_for_line(line.chomp).map {|message| { | |
| file: file_path, | |
| line: line_number + 1, | |
| label: message, | |
| description: "Lines violated code requirements" | |
| }} | |
| end | |
| end.flatten | |
| end | |
| protected | |
| def violations_for_line(line) | |
| result = [] | |
| matched_zone_violation = /#{escaped_timezone_aware_violations.join('|')}/i.match(line) | |
| result << "Line contains code that is not timezone aware: '#{matched_zone_violation}' should be '#{timezone_aware_violations[matched_zone_violation.to_s]}'" if matched_zone_violation | |
| result | |
| end | |
| def timezone_aware_violations | |
| opts.fetch(:code_timezones) | |
| end | |
| def escaped_timezone_aware_violations | |
| timezone_aware_violations.keys.map { |violation| Regexp.escape(violation) } | |
| end | |
| def file_list | |
| Dir[opts.fetch(:code_glob)].reject {|f| excluded?(f) } | |
| end | |
| def exclusions | |
| @exclusions ||= opts.fetch(:code_exclude, []).flatten.map do |i| | |
| Dir[i] | |
| end.flatten.to_set | |
| end | |
| def excluded?(file) | |
| exclusions.include?(file) | |
| end | |
| def map_lines(file_path, &block) | |
| Cane::File.iterator(file_path).map.with_index(&block) | |
| end | |
| def worker | |
| Cane.task_runner(opts) | |
| end | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment