polishgeeks-dev-tools 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +6 -0
  6. data/Gemfile +2 -0
  7. data/Gemfile.lock +193 -0
  8. data/README.md +112 -0
  9. data/Rakefile +20 -0
  10. data/config/haml-lint.yml +74 -0
  11. data/config/rubocop.yml +35 -0
  12. data/config/yardopts +7 -0
  13. data/lib/polishgeeks-dev-tools.rb +43 -0
  14. data/lib/polishgeeks/dev-tools/command/allowed_extensions.rb +62 -0
  15. data/lib/polishgeeks/dev-tools/command/base.rb +73 -0
  16. data/lib/polishgeeks/dev-tools/command/brakeman.rb +46 -0
  17. data/lib/polishgeeks/dev-tools/command/coverage.rb +43 -0
  18. data/lib/polishgeeks/dev-tools/command/examples_comparator.rb +75 -0
  19. data/lib/polishgeeks/dev-tools/command/expires_in.rb +74 -0
  20. data/lib/polishgeeks/dev-tools/command/haml_lint.rb +28 -0
  21. data/lib/polishgeeks/dev-tools/command/readme.rb +32 -0
  22. data/lib/polishgeeks/dev-tools/command/rspec.rb +38 -0
  23. data/lib/polishgeeks/dev-tools/command/rspec_files_names.rb +58 -0
  24. data/lib/polishgeeks/dev-tools/command/rspec_files_structure.rb +134 -0
  25. data/lib/polishgeeks/dev-tools/command/rubocop.rb +50 -0
  26. data/lib/polishgeeks/dev-tools/command/rubycritic.rb +17 -0
  27. data/lib/polishgeeks/dev-tools/command/simplecov.rb +32 -0
  28. data/lib/polishgeeks/dev-tools/command/tasks_files_names.rb +76 -0
  29. data/lib/polishgeeks/dev-tools/command/yard.rb +35 -0
  30. data/lib/polishgeeks/dev-tools/command/yml_parser.rb +85 -0
  31. data/lib/polishgeeks/dev-tools/config.rb +91 -0
  32. data/lib/polishgeeks/dev-tools/hash.rb +24 -0
  33. data/lib/polishgeeks/dev-tools/logger.rb +63 -0
  34. data/lib/polishgeeks/dev-tools/output_storer.rb +17 -0
  35. data/lib/polishgeeks/dev-tools/runner.rb +27 -0
  36. data/lib/polishgeeks/dev-tools/shell.rb +16 -0
  37. data/lib/polishgeeks/dev-tools/tasks/dev-tools.rake +15 -0
  38. data/lib/polishgeeks/dev-tools/version.rb +8 -0
  39. data/polishgeeks_dev_tools.gemspec +36 -0
  40. data/spec/lib/polishgeeks-dev-tools_spec.rb +35 -0
  41. data/spec/lib/polishgeeks/dev-tools/command/allowed_extensions_spec.rb +66 -0
  42. data/spec/lib/polishgeeks/dev-tools/command/base_spec.rb +127 -0
  43. data/spec/lib/polishgeeks/dev-tools/command/brakeman_spec.rb +95 -0
  44. data/spec/lib/polishgeeks/dev-tools/command/coverage_spec.rb +121 -0
  45. data/spec/lib/polishgeeks/dev-tools/command/examples_comparator_spec.rb +171 -0
  46. data/spec/lib/polishgeeks/dev-tools/command/expires_in_spec.rb +69 -0
  47. data/spec/lib/polishgeeks/dev-tools/command/haml_lint_spec.rb +79 -0
  48. data/spec/lib/polishgeeks/dev-tools/command/readme_spec.rb +38 -0
  49. data/spec/lib/polishgeeks/dev-tools/command/rspec_files_names_spec.rb +91 -0
  50. data/spec/lib/polishgeeks/dev-tools/command/rspec_files_structure_spec.rb +262 -0
  51. data/spec/lib/polishgeeks/dev-tools/command/rspec_spec.rb +63 -0
  52. data/spec/lib/polishgeeks/dev-tools/command/rubocop_spec.rb +127 -0
  53. data/spec/lib/polishgeeks/dev-tools/command/rubycritic_spec.rb +27 -0
  54. data/spec/lib/polishgeeks/dev-tools/command/simplecov_spec.rb +53 -0
  55. data/spec/lib/polishgeeks/dev-tools/command/tasks_files_names_spec.rb +108 -0
  56. data/spec/lib/polishgeeks/dev-tools/command/yard_spec.rb +86 -0
  57. data/spec/lib/polishgeeks/dev-tools/command/yml_parser_spec.rb +104 -0
  58. data/spec/lib/polishgeeks/dev-tools/config_spec.rb +78 -0
  59. data/spec/lib/polishgeeks/dev-tools/hash_spec.rb +37 -0
  60. data/spec/lib/polishgeeks/dev-tools/logger_spec.rb +162 -0
  61. data/spec/lib/polishgeeks/dev-tools/output_storer_spec.rb +20 -0
  62. data/spec/lib/polishgeeks/dev-tools/runner_spec.rb +57 -0
  63. data/spec/lib/polishgeeks/dev-tools/shell_spec.rb +13 -0
  64. data/spec/lib/polishgeeks/dev-tools/version_spec.rb +7 -0
  65. data/spec/spec_helper.rb +28 -0
  66. metadata +330 -0
@@ -0,0 +1,35 @@
1
+ AlignParameters:
2
+ Enabled: false
3
+ ClassLength:
4
+ CountComments: false
5
+ Max: 200
6
+ LineLength:
7
+ Max: 99
8
+ MethodLength:
9
+ CountComments: false
10
+ Max: 15
11
+ Metrics/AbcSize:
12
+ Max: 25
13
+ AllCops:
14
+ Exclude:
15
+ - bin/**/*
16
+ - db/**/*
17
+ - .gemspec/**/*
18
+ - .bundle/**/*
19
+ - vendor/**/*
20
+ - config/**/*
21
+ - script/**/*
22
+ - !ruby/regexp /old_and_unused\.rb$/
23
+ - !ruby/regexp /polishgeeks-[^\/]{2,}\.rb/
24
+ Include:
25
+ - '**/Rakefile'
26
+ - config.ru
27
+ - lib/tasks/**/*.rake
28
+ - lib/tasks/**/*.rb
29
+ - lib/capistrano/**/*.rb
30
+ - lib/capistrano/**/*.cap
31
+ Style/MultilineOperationIndentation:
32
+ EnforcedStyle: indented
33
+ SupportedStyles:
34
+ - aligned
35
+ - indented
data/config/yardopts ADDED
@@ -0,0 +1,7 @@
1
+ -o doc/yard
2
+ - doc/*.md
3
+ --title 'PolishGeeks Dev Tools documentation'
4
+ --charset utf-8
5
+ --markup markdown
6
+ --private
7
+ --protected
@@ -0,0 +1,43 @@
1
+ require 'yaml'
2
+ require 'yard'
3
+ require 'pry'
4
+ require 'fileutils'
5
+ require 'timecop'
6
+ require 'faker'
7
+ require 'ostruct'
8
+
9
+ base_path = File.dirname(__FILE__) + '/polishgeeks/dev-tools/*.rb'
10
+ Dir[base_path].each { |file| require file }
11
+
12
+ module PolishGeeks
13
+ module DevTools
14
+ # This is just an alias so we can use it from DevTools directly
15
+ # @return [PolishGeeks::DevTools::Config.config]
16
+ def self.config
17
+ Config.config
18
+ end
19
+
20
+ # @return [String] root path of this gem
21
+ def self.gem_root
22
+ File.expand_path('../..', __FILE__)
23
+ end
24
+
25
+ # @return [String] app root path
26
+ def self.app_root
27
+ File.dirname(ENV['BUNDLE_GEMFILE'])
28
+ end
29
+
30
+ # Sets up the whole configuration
31
+ # @param [Block] block
32
+ def self.setup(&block)
33
+ Config.setup(&block)
34
+ end
35
+ end
36
+ end
37
+
38
+ require 'polishgeeks/dev-tools/command/base'
39
+
40
+ commands_path = File.dirname(__FILE__) + '/polishgeeks/dev-tools/command/*.rb'
41
+ Dir[commands_path].each { |file| require file }
42
+
43
+ load 'polishgeeks/dev-tools/tasks/dev-tools.rake'
@@ -0,0 +1,62 @@
1
+ module PolishGeeks
2
+ module DevTools
3
+ module Command
4
+ # Checking config directory that all files are allowed
5
+ class AllowedExtensions < Base
6
+ self.type = :validator
7
+
8
+ # List of allowed extensions of files
9
+ ALLOWED_EXTENSIONS = %w(
10
+ rb
11
+ yml
12
+ rb.example
13
+ yml.example
14
+ )
15
+
16
+ # Executes this command
17
+ # @return [Array] command output array with list of
18
+ # not allowed files in config directory
19
+ def execute
20
+ results = Dir[config_path]
21
+
22
+ @output = results
23
+ .flatten
24
+ .map { |line| line.gsub!(PolishGeeks::DevTools.app_root + '/config/', '') }
25
+ .uniq
26
+ @output.delete_if do |line|
27
+ ALLOWED_EXTENSIONS.any? { |allow| line =~ /^.*\.#{allow}$/i }
28
+ end
29
+
30
+ @output
31
+ end
32
+
33
+ # @return [String] label with this validator description
34
+ def label
35
+ 'Allowed Extensions'
36
+ end
37
+
38
+ # @return [String] error message that will be displayed if something
39
+ # goes wrong
40
+ def error_message
41
+ err = 'Following files are not allowed in config directory:'
42
+ err << "\n\n"
43
+ err << @output.join("\n")
44
+ err << "\n"
45
+ end
46
+
47
+ # @return [Boolean] true if all files in config directory
48
+ # have correct extension
49
+ def valid?
50
+ @output.empty?
51
+ end
52
+
53
+ private
54
+
55
+ # @return [String] config path with all files included
56
+ def config_path
57
+ "#{File.expand_path(PolishGeeks::DevTools.app_root + '/config')}/*.*"
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,73 @@
1
+ module PolishGeeks
2
+ module DevTools
3
+ # Module encapsulating all the commands that we use to check/verify code
4
+ module Command
5
+ # Base class for all the commands
6
+ # @abstract Subclass and use
7
+ class Base
8
+ # Raised when we specify a framework in which a given command can be executed
9
+ # and it is not present (not detected)
10
+ class MissingFramework < StandardError; end
11
+
12
+ attr_reader :output
13
+ # stored_output [PolishGeeks::DevTools::OutputStorer] storer with results of previous
14
+ # commands (they might use output from previous/other commands)
15
+ attr_accessor :stored_output
16
+
17
+ # Available command types. We have validators that check something
18
+ # and that should have a 'valid?' method and that check for errors, etc
19
+ # and generators that are executed to generate some stats, docs, etc
20
+ TYPES = %i( validator generator )
21
+
22
+ class << self
23
+ attr_accessor :type
24
+ attr_accessor :framework
25
+
26
+ TYPES.each do |type|
27
+ # @return [Boolean] if it is a given type command
28
+ define_method :"#{type}?" do
29
+ self.type == type
30
+ end
31
+ end
32
+ end
33
+
34
+ # When we will try to use a given command, we need to check if it requires
35
+ # a given framework (Rails, Sinatra), if so, then we need to check if it is
36
+ # present, because without it a given command cannot run
37
+ def initialize
38
+ ensure_framework_if_required
39
+ end
40
+
41
+ # @raise [NotImplementedError] this should be implemented in a subclass
42
+ def execute
43
+ fail NotImplementedError
44
+ end
45
+
46
+ # @raise [NotImplementedError] this should be implemented in a subclass
47
+ # if it is a validator type (or no implementation required when
48
+ # it is a validator)
49
+ def valid?
50
+ fail NotImplementedError
51
+ end
52
+
53
+ # @return [String] what message should be printed when error occures
54
+ # @note By default the whole output of an executed command will be printed
55
+ def error_message
56
+ output
57
+ end
58
+
59
+ private
60
+
61
+ # Checks if a framework is required for a given command, and if so, it wont
62
+ # allow to execute this command if it is not present
63
+ # @raise [PolishGeeks::DevTools::Command::Base::MissingFramework] if req framework missing
64
+ def ensure_framework_if_required
65
+ return unless self.class.framework
66
+ return if PolishGeeks::DevTools.config.public_send(:"#{self.class.framework}?")
67
+
68
+ fail MissingFramework, self.class.framework
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,46 @@
1
+ module PolishGeeks
2
+ module DevTools
3
+ module Command
4
+ # A static analysis security vulnerability scanner for Ruby on Rails applications
5
+ # @see https://github.com/presidentbeef/brakeman
6
+ class Brakeman < Base
7
+ self.type = :validator
8
+ self.framework = :rails
9
+
10
+ # Regexps to get some stat info from brakeman output
11
+ REGEXPS = {
12
+ controllers: /Controller.* (\d+)/,
13
+ models: /Model.* (\d+)/,
14
+ templates: /Template.* (\d+)/,
15
+ errors: /Error.* (\d+)/,
16
+ warnings: /Warning.* (\d+)/
17
+ }
18
+
19
+ # Executes this command
20
+ # @return [String] command output
21
+ def execute
22
+ @output = Shell.new.execute('bundle exec brakeman -q')
23
+ end
24
+
25
+ # @return [Boolean] true if we didn't have any vulnerabilities detected
26
+ def valid?
27
+ warnings == 0 && errors == 0
28
+ end
29
+
30
+ # @return [String] label with details bout brakeman scan
31
+ def label
32
+ "Brakeman (#{controllers} con, #{models} mod, #{templates} temp)"
33
+ end
34
+
35
+ REGEXPS.each do |name, regexp|
36
+ # @return [Integer] number of matches for given regexp
37
+ define_method(name) do
38
+ output.scan(regexp).flatten.first.to_i
39
+ end
40
+
41
+ private name
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,43 @@
1
+ module PolishGeeks
2
+ module DevTools
3
+ module Command
4
+ # Command wrapper for Simple code coverage analysing
5
+ # It informs us if we didn't reach a proper code coverage level
6
+ class Coverage < Base
7
+ self.type = :validator
8
+
9
+ # Regexp used to match code coverage level
10
+ MATCH_REGEXP = /\(\d+.\d+\%\) covered/
11
+ # Regexp used to match float number from coverage
12
+ NUMBER_REGEXP = /(\d+[.]\d+)/
13
+
14
+ # @return [Float] code coverage level
15
+ def to_f
16
+ output[*NUMBER_REGEXP].to_f
17
+ end
18
+
19
+ # Executes this command
20
+ # @return [String] command output
21
+ def execute
22
+ @output = stored_output.rspec[*MATCH_REGEXP]
23
+ end
24
+
25
+ # @return [Boolean] true if code coverage level is higher or equal to expected
26
+ def valid?
27
+ to_f >= DevTools.config.simplecov_threshold
28
+ end
29
+
30
+ # @return [String] default label for this command
31
+ def label
32
+ "Coverage #{to_f}% covered - #{DevTools.config.simplecov_threshold}% required"
33
+ end
34
+
35
+ # @return [String] message that should be printed when code coverage level is not met
36
+ def error_message
37
+ threshold = DevTools.config.simplecov_threshold
38
+ "Coverage level should more or equal to #{threshold}%. was: #{to_f}"
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,75 @@
1
+ module PolishGeeks
2
+ module DevTools
3
+ module Command
4
+ # Command wrapper for ExamplesComparator rake task
5
+ # It informs us if our .example files structure is the same as non-example once
6
+ class ExamplesComparator < Base
7
+ self.type = :validator
8
+
9
+ # Executes this command
10
+ # @return [String] command output
11
+ def execute
12
+ @output = "Comparing yaml structure of example files\n\n"
13
+
14
+ Dir[config_path].each do |example_file|
15
+ dedicated_file = example_file.gsub('.example', '')
16
+
17
+ header = compare_header(example_file, dedicated_file)
18
+
19
+ if same_key_structure?(example_file, dedicated_file)
20
+ @output << successful_compare(header)
21
+ else
22
+ @output << failed_compare(header)
23
+ end
24
+ end
25
+ end
26
+
27
+ # @return [Boolean] true if all the example files have the same structure
28
+ # as non-example once, false otherwise
29
+ def valid?
30
+ !output.include?('failed')
31
+ end
32
+
33
+ private
34
+
35
+ # @return [String] config path with all the yml.example files included
36
+ # @note This method is used in Dir[] to get all the example files
37
+ def config_path
38
+ "#{File.expand_path(PolishGeeks::DevTools.app_root + '/config')}/**/*.yml.example"
39
+ end
40
+
41
+ # @param [File] example_file which we compare with dedicated one
42
+ # @param [File] dedicated_file which is compared with example one
43
+ # @return [Boolean] true if the key structure is the same in both files
44
+ # otherwise false
45
+ def same_key_structure?(example_file, dedicated_file)
46
+ yaml1 = PolishGeeks::DevTools::Hash.new
47
+ yaml1.merge!(YAML.load_file(example_file))
48
+ yaml2 = PolishGeeks::DevTools::Hash.new
49
+ yaml2.merge!(YAML.load_file(dedicated_file))
50
+
51
+ yaml1.same_key_structure?(yaml2)
52
+ end
53
+
54
+ # @param [File] example_file which we compare with dedicated one
55
+ # @param [File] dedicated_file which is compared with example one
56
+ # @return [String] success/failure (both) message header
57
+ def compare_header(example_file, dedicated_file)
58
+ "#{File.basename(example_file)} and #{File.basename(dedicated_file)}"
59
+ end
60
+
61
+ # @param [String] compare_header output message
62
+ # @return [String] success message for single file
63
+ def successful_compare(compare_header)
64
+ "\e[32m success\e[0m - #{compare_header}\n"
65
+ end
66
+
67
+ # @param [String] compare_header output message
68
+ # @return [String] failed message for single file
69
+ def failed_compare(compare_header)
70
+ "\e[31m failed\e[0m - #{compare_header} - structure not equal\n"
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,74 @@
1
+ module PolishGeeks
2
+ module DevTools
3
+ module Command
4
+ # Checking Rails cache options especially expires_in
5
+ class ExpiresIn < Base
6
+ self.type = :validator
7
+
8
+ # List of dirs that we will check for
9
+ CHECKED_DIRS = %w(
10
+ app
11
+ lib
12
+ )
13
+
14
+ # Regexp that we want to use to catch invalid things that occur
15
+ # instead of expires_in
16
+ CHECKED_REGEXP = 'expire_in\|expir_in'
17
+
18
+ # Executes this command
19
+ def execute
20
+ results = CHECKED_DIRS.map do |directory|
21
+ path = File.join(PolishGeeks::DevTools.app_root, directory)
22
+ shell_command(path).split("\n")
23
+ end
24
+
25
+ @output = results
26
+ .flatten
27
+ .map { |line| line.split(':').first }
28
+ .map { |line| line.gsub!(PolishGeeks::DevTools.app_root, '') }
29
+ .uniq
30
+
31
+ @output.delete_if do |line|
32
+ excludes.any? { |exclude| line =~ /#{exclude}/ }
33
+ end
34
+ end
35
+
36
+ # @return [String] label with this validator description
37
+ def label
38
+ 'Expires in'
39
+ end
40
+
41
+ # @return [String] error message
42
+ def error_message
43
+ err = 'Following files use expire_in instead of expires_in:'
44
+ err << "\n\n"
45
+ err << @output.join("\n")
46
+ err << "\n"
47
+ end
48
+
49
+ # @return [Boolean] true if not find expire_in
50
+ def valid?
51
+ @output.empty?
52
+ end
53
+
54
+ # @return [Array<String>] list of files/directories that should be excluded from checking
55
+ # @note This should be set in the initializer for this gem in the
56
+ # place where it is going to be used
57
+ def excludes
58
+ DevTools.config.expires_in_files_ignored || []
59
+ end
60
+
61
+ private
62
+
63
+ # @param [String] path in which we want to search
64
+ # @return [String] grep command that should be executed
65
+ # to find what we search for
66
+ # @note Not every path must exist, thats why we redirect errors to /dev/null, that way
67
+ # we can skip all the errors
68
+ def shell_command(path)
69
+ `grep -R \"#{CHECKED_REGEXP}\" #{path}/* 2>/dev/null`
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end