polishgeeks-dev-tools 1.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.
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