supercop 0.2.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a69ce9a6b65284cfe4c831111c5eee5e7361d91d
4
+ data.tar.gz: c3ca2a2d82a22bd5acedaa22033a700f26ee7d4e
5
+ SHA512:
6
+ metadata.gz: ec097698283f997ae6b1f0b1c66b1428c428c774b6ddb85ac1f525cee6b5599bfd0555d868c964595fa4f91a6037f7b4478445ec3c6cc84a0cf54ab1a593bba3
7
+ data.tar.gz: 7bbe552029a0dcaa38000c06db531f0d8441411327f3b5f8add50b192a643369af54e592f9ed50f7586b0305b739af83bc717ae6b74de3d82f384d51d8a5065a
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.2.3
5
+ - 2.3.1
6
+ - 2.3.3
7
+ before_install:
8
+ - gem install bundler -v 1.13.1
9
+ - gem install rubocop
10
+ before_script:
11
+ - bundle exec rake supercop:generate_config
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in supercop.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Artem Kuznetsov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # Supercop
2
+ [![Build Status](https://travis-ci.org/artemasmith/supercop.svg?branch=master)](https://travis-ci.org/artemasmith/supercop)
3
+
4
+ This gem allows you to combine multiple linters with their configs in one place and run all checks by one command with tabled-view summary report (see below).
5
+ You should specify which linters you would like to use, for example rubocop, reek,
6
+ scss_linter etc. Gem would load them if they are not installed and run checks.
7
+
8
+ One gem for rule them all:)
9
+
10
+ ### Versions
11
+
12
+ It works for 2.2.3, 2.3.1, 2.3.3 versions of Ruby MRI.
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ ```ruby
19
+ gem 'supercop'
20
+ ```
21
+
22
+ And then execute:
23
+
24
+ $ bundle
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install supercop
29
+
30
+ ### Install into another gem
31
+
32
+ Add supercop tasks to the Rakefile:
33
+
34
+ ```ruby
35
+ spec = Gem::Specification.find_by_name 'supercop'
36
+ load "#{spec.gem_dir}/lib/tasks/manage_settings.rake"
37
+ load "#{spec.gem_dir}/lib/tasks/check.rake"
38
+ ```
39
+
40
+ ## Usage
41
+
42
+ After install, you should modify supercop.yml and specify prefered linters.
43
+ After that run
44
+
45
+ $ rake supercop:generate_config
46
+
47
+ for non-rails project (like gem) or
48
+
49
+ $ rails g supercop:config
50
+
51
+ for rails project
52
+
53
+ After that, please modify your supercop.yml config file, adding linters you want to use and run
54
+
55
+ $ rake supercop:load_dependencies
56
+
57
+ or you can do it manually by adding gems to your Gemfile (for other gems - to the end of file) and running bundle install.
58
+
59
+ `Note:` You should do it once.
60
+
61
+ Now you can run checks.
62
+
63
+ ### Clean up
64
+
65
+ If you want to restore all affected files and clean up supercop remnants, please run
66
+
67
+ $ rake supercop:cleanup
68
+
69
+ This will delete config file and erase changes made by Supercop to your Gemfile and bundle.
70
+
71
+ ### Running check
72
+
73
+ $ rake supercop:check
74
+
75
+ | linter | alerts | max | status |
76
+ | ------------------ |:------------------:|:------------------:|:------------------:|
77
+ | rubocop | 48 | 99 | ok |
78
+ | reek | 45 | 99 | ok |
79
+ | slim_lint | none | 99 | ok |
80
+ | scss_lint | none | 99 | ok |
81
+
82
+ 'none' - means linter did not work correctly. To figured out why - change 'verbose' option to true
83
+
84
+ ## Development
85
+
86
+ After checking out the repo, run bundle install and make your changes. After commit, create Pull Request and notify me.
87
+
88
+ ## Contributing
89
+
90
+ Bug reports and pull requests are welcome on GitHub at https://github.com/artemasmith/supercop.
91
+
92
+ ## License
93
+
94
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ import './lib/tasks/manage_settings.rake'
5
+ import './lib/tasks/check.rake'
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "supercop"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/supercop.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext'
3
+ require 'active_support/core_ext/hash/indifferent_access'
4
+
5
+ require 'supercop/cop'
6
+ require 'supercop/version'
7
+ require 'supercop/checker'
8
+ require 'supercop/configuration'
9
+ require 'supercop/table_formatter'
10
+ require 'supercop/actions/config_copier'
11
+ require 'supercop/actions/file_injector'
12
+ require 'supercop/actions/clean'
13
+ require 'supercop/actions/loaders/base'
14
+ require 'supercop/actions/loaders/dependency'
15
+ require 'supercop/parsers/base'
16
+ require 'supercop/parsers/proxy'
17
+ require 'supercop/parsers/scss_lint'
18
+ require 'supercop/parsers/rubocop'
19
+
20
+ require 'json'
21
+ require 'yaml'
22
+
23
+ if defined?(Rails)
24
+ require 'supercop/railtie'
25
+ require 'rails/generators'
26
+ end
27
+
28
+ module Supercop
29
+ class << self
30
+ attr_accessor :configuration
31
+ end
32
+
33
+ def self.configuration
34
+ @configuration ||= Configuration.new
35
+ end
36
+ end
@@ -0,0 +1,93 @@
1
+ module Supercop
2
+ module Actions
3
+ class Clean
4
+ class << self
5
+ def call
6
+ if clean_gemfile[:changed]
7
+ restore_gemfile
8
+
9
+ update_bundle
10
+ else
11
+ notify_nothing_changed
12
+ end
13
+
14
+ remove_config
15
+ end
16
+
17
+ private
18
+
19
+ def notify_nothing_changed
20
+ puts 'Your Gemfile was not changed. Nothing to restore.'
21
+ end
22
+
23
+ def restore_gemfile
24
+ puts 'Restoring your Gemfile'
25
+
26
+ temp_file = "#{gemfile}.tmp"
27
+
28
+ File.open(temp_file, 'w') do |f|
29
+ f.print(clean_gemfile[:gemfile])
30
+ end
31
+
32
+ FileUtils.mv temp_file, gemfile
33
+ end
34
+
35
+ def update_bundle
36
+ puts 'Updating your bundle, please wait'
37
+
38
+ Bundler.with_clean_env do
39
+ `bundle install`
40
+ end
41
+ end
42
+
43
+ def clean_gemfile
44
+ clean_gemfile = []
45
+ changed = false
46
+
47
+ File.open(gemfile, 'r') do |f|
48
+ until (line = f.gets).nil?
49
+ if line.include?(start_comment)
50
+ changed = true
51
+ until (line = f.gets).nil?
52
+ if line.include?(end_comment)
53
+ line = f.gets
54
+ break
55
+ end
56
+ end
57
+ end
58
+
59
+ clean_gemfile << line
60
+ end
61
+ end
62
+ @_clean_gemfile = { gemfile: clean_gemfile.join, changed: changed }
63
+ end
64
+
65
+ def remove_config
66
+ if File.file?(supercop_config)
67
+ puts 'Removing your supercop.yml'
68
+
69
+ FileUtils.rm(supercop_config)
70
+ end
71
+ end
72
+
73
+ def gemfile
74
+ @_gemfile ||= File.join(Dir.pwd, 'Gemfile')
75
+ end
76
+
77
+ def supercop_config
78
+ root = defined?(Rails) ? File.join(Dir.pwd, 'config') : Dir.pwd
79
+
80
+ @_supercop_config ||= File.join(root, 'supercop.yml')
81
+ end
82
+
83
+ def start_comment
84
+ Supercop::Actions::Loaders::Dependency::START_COMMENT
85
+ end
86
+
87
+ def end_comment
88
+ Supercop::Actions::Loaders::Dependency::END_COMMENT
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,46 @@
1
+ module Supercop
2
+ module Actions
3
+ class ConfigCopier
4
+ require 'fileutils'
5
+ CONFIG_PATH = %w[lib supercop templates].freeze
6
+
7
+ def initialize(args)
8
+ @filename = args.fetch(:filename, 'supercop.yml')
9
+ @destination = args.fetch(:destination)
10
+ @options = args.fetch(:options, {})
11
+ @source = args.fetch(:source, 'supercop.yml')
12
+ end
13
+
14
+ def call
15
+ return "There is no destination #{destination}" if invalid_destination?
16
+ return "#{destination_file} already exists" if File.file?(destination_file)
17
+
18
+ FileUtils.copy(source_file, destination_file, options)
19
+
20
+ "file #{destination_file} was created"
21
+ rescue => e
22
+ "Could not create file. #{e.message}"
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :filename, :destination, :source, :options
28
+
29
+ def invalid_destination?
30
+ destination.empty? || !Dir.exist?(destination)
31
+ end
32
+
33
+ def source_file
34
+ File.join(root, CONFIG_PATH, source)
35
+ end
36
+
37
+ def destination_file
38
+ File.join(destination, filename)
39
+ end
40
+
41
+ def root
42
+ Gem.loaded_specs['supercop'].full_gem_path
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,35 @@
1
+ module Supercop
2
+ module Actions
3
+ class FileInjector
4
+ attr_reader :filename, :line
5
+
6
+ def initialize(filename:, line:)
7
+ @filename = filename
8
+ @line = line
9
+ end
10
+
11
+ def call
12
+ return if file_include?
13
+
14
+ insert_into_file
15
+ end
16
+
17
+ def file_include?
18
+ File.foreach(filename).grep(sanitized).present?
19
+ end
20
+
21
+ private
22
+
23
+
24
+ def insert_into_file
25
+ File.open(filename, 'a') do |f|
26
+ f.write(line)
27
+ end
28
+ end
29
+
30
+ def sanitized
31
+ line.sub(/\s\n$/, '')
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,58 @@
1
+ module Supercop
2
+ module Actions
3
+ module Loaders
4
+ class Base
5
+ BUNDLE_REQUIRED = :bundle_required
6
+
7
+ attr_reader :gem_name, :config, :injector, :file
8
+
9
+ def initialize(gem_name)
10
+ @gem_name = gem_name
11
+ @config = Supercop.configuration.public_send(gem_name)
12
+ @injector = Supercop::Actions::FileInjector
13
+ @file = Supercop.configuration.path('Gemfile')
14
+ end
15
+
16
+ def installed?
17
+ load_gem
18
+ true
19
+ rescue LoadError
20
+ false
21
+ end
22
+
23
+ def call
24
+ add_gem
25
+
26
+ puts "'#{gem_name}' was added as dependency.\n"
27
+ BUNDLE_REQUIRED
28
+ end
29
+
30
+ private
31
+
32
+ def load_gem
33
+ require gem_name.to_s
34
+ end
35
+
36
+ def add_gem
37
+ puts "Inserting into #{file} \n"
38
+ puts "gem config #{gem_config}\n"
39
+
40
+ injector.new(filename: file, line: gem_config).call
41
+ end
42
+
43
+ def gem_config
44
+ result = ["gem '#{gem_name}'"]
45
+ result << ", #{config[:version]}" if option?(:version)
46
+ result << ", path: '#{config[:path]}'" if option?(:path)
47
+ result << ", git: '#{config[:git]}'" if option?(:git) && !option?(:path)
48
+ result << "\n"
49
+ result.join(' ')
50
+ end
51
+
52
+ def option?(option)
53
+ config.keys.include?(option)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,65 @@
1
+ module Supercop
2
+ module Actions
3
+ module Loaders
4
+ class Dependency
5
+ BUNDLE_REQUIRED = :bundle_required
6
+ START_COMMENT = "####### SUPERCOP #######\n".freeze
7
+ END_COMMENT = "#### ENDOF SUPERCOP ####\n".freeze
8
+
9
+ attr_reader :gem_list, :loader, :file_injector
10
+
11
+ def initialize(loader = nil)
12
+ @gem_list = Supercop.configuration.cops_settings.keys
13
+ @loader = loader || Base
14
+ @file_injector = Supercop::Actions::FileInjector
15
+ end
16
+
17
+ def call
18
+ puts 'Loading dependecies, please wait..'
19
+
20
+ if gems_to_add.empty?
21
+ say_nothing_needed
22
+ else
23
+ wrap_for_gemfile do
24
+ gems_to_add.each { |gem_name| loader.new(gem_name).call }
25
+ end
26
+
27
+ install
28
+ end
29
+ end
30
+
31
+ alias load_dependencies call
32
+
33
+ private
34
+
35
+ def gems_to_add
36
+ gem_list.select { |gem_name| !loaded?(gem_name) }
37
+ end
38
+
39
+ def loaded?(gem_name)
40
+ loader.new(gem_name).installed? ? true : false
41
+ end
42
+
43
+ def install
44
+ puts 'Updating your bundle, please wait'
45
+ Bundler.with_clean_env do
46
+ `bundle install`
47
+ end
48
+ end
49
+
50
+ def say_nothing_needed
51
+ puts 'No need to install anything.'
52
+ end
53
+
54
+ def wrap_for_gemfile(&_block)
55
+ file = Supercop.configuration.path('Gemfile')
56
+ file_injector.new(filename: file, line: START_COMMENT).call
57
+
58
+ yield
59
+
60
+ file_injector.new(filename: file, line: END_COMMENT).call
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,16 @@
1
+ module Supercop
2
+ class Checker
3
+ attr_reader :linters, :printer, :cop
4
+ def initialize(printer = TableFormatter)
5
+ @linters = Supercop.configuration.cops_settings.keys
6
+ @printer = printer
7
+ @cop = Cop
8
+ end
9
+
10
+ def call
11
+ checks_result = linters.map { |linter| cop.new(linter).handle }
12
+
13
+ printer.new.print_table(checks_result)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,61 @@
1
+ module Supercop
2
+ class Configuration
3
+ attr_accessor :cops_settings, :verbose, :file_path
4
+
5
+ def initialize
6
+ @cops_settings = config_file.fetch(:config)
7
+ @verbose = config_file.fetch(:verbose)
8
+ @file_path = config_path
9
+ end
10
+
11
+ def path(file_path)
12
+ defined?(Rails) ? Rails.root.join(file_path) : File.join(Dir.pwd, file_path)
13
+ end
14
+
15
+ private
16
+
17
+ def config_file
18
+ @_config_file ||= YAML.load_file(config_path).with_indifferent_access
19
+ rescue => e
20
+ puts "Can't find or read config file, did you run initialize command? #{e.message}"
21
+ end
22
+
23
+ def config_path
24
+ @_config_path ||= defined?(Rails) ? rails_path : other_path
25
+ end
26
+
27
+ def rails_path
28
+ Rails.root.join('config', 'supercop.yml')
29
+ end
30
+
31
+ def other_path
32
+ File.join(Dir.pwd, 'supercop.yml')
33
+ end
34
+
35
+ def method_missing(m, *args, &block)
36
+ define_dig unless cops_settings.methods.include?(:dig)
37
+
38
+ cops_settings.dig(m) || super
39
+ end
40
+
41
+ # FYI: dirty hack for ruby < 2.3
42
+ def define_dig
43
+ new_method = <<-NEW
44
+ class ::Hash
45
+ def dig(*path)
46
+ path.inject(self) do |location, key|
47
+ location.is_a?(Hash) ? location[key] : nil
48
+ end
49
+ end
50
+ end
51
+ NEW
52
+
53
+ eval(new_method)
54
+ end
55
+
56
+ # https://robots.thoughtbot.com/always-define-respond-to-missing-when-overriding
57
+ def respond_to_missing?(method_name, include_private = false)
58
+ cops_settings.keys.include?(method_name) || super
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,43 @@
1
+ module Supercop
2
+ class Cop
3
+ attr_reader :linter, :cop_config, :parser, :config
4
+
5
+ def initialize(linter)
6
+ @linter = linter
7
+ @parser = Supercop::Parsers::Proxy
8
+ @config = Supercop.configuration
9
+ @cop_config = config.public_send(linter)
10
+ end
11
+
12
+ def handle
13
+ result = parse_cop_config
14
+
15
+ output = %i[linter warnings_actual warnings_max].map { |key| result[key] }
16
+ output << linter_status(result[:warnings_actual], result[:warnings_max])
17
+ end
18
+
19
+ private
20
+
21
+ def linter_status(actual, max)
22
+ actual.to_i < max ? 'ok' : 'fail'
23
+ end
24
+
25
+ def actual_warnings_count
26
+ output = `#{cop_config.fetch('cmd')} #{cop_config.fetch('options')}`
27
+
28
+ parser.new(output, linter).parse.to_s
29
+ end
30
+
31
+ def parse_cop_config
32
+ return if linter.blank?
33
+
34
+ { warnings_actual: actual_warnings_count,
35
+ warnings_max: cop_config.fetch('max'),
36
+ linter: linter }
37
+ rescue => e
38
+ puts "Problems with linter config load. #{e.message}" if config.verbose
39
+
40
+ { linter: linter, warnings_actual: 0, warnings_max: 0 }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,17 @@
1
+ module Supercop
2
+ module Generators
3
+ class ConfigGenerator < ::Rails::Generators::Base
4
+ source_root File.expand_path('../templates', __dir__)
5
+
6
+ puts '=> Creates a Supercop idefault config for your application.'
7
+
8
+ def copy_config_file
9
+ destination = 'config/supercop.yml'
10
+
11
+ puts "=> Copy config file to #{destination}"
12
+
13
+ copy_file 'supercop.yml', destination
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,38 @@
1
+ module Supercop
2
+ module Parsers
3
+ class Base
4
+ attr_reader :json, :config
5
+
6
+ def initialize(json)
7
+ @json = json
8
+ @config = Supercop.configuration
9
+ end
10
+
11
+ def call
12
+ warnings_count
13
+ end
14
+
15
+ private
16
+
17
+ def parse
18
+ JSON.parse(json).count
19
+ end
20
+
21
+ def warnings_count
22
+ parse
23
+ rescue => e
24
+ parse_error(e)
25
+
26
+ 'none'
27
+ end
28
+
29
+ def parse_error(e)
30
+ msg = %Q[Wrong configuration for linter,
31
+ please check the path and options provided.
32
+ Error: #{e.message}]
33
+
34
+ puts msg if config.verbose
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,33 @@
1
+ module Supercop
2
+ module Parsers
3
+ class Proxy
4
+ RUBOCOP = %w[SlimLint HamlLint].freeze
5
+
6
+ attr_reader :json, :linter, :parser
7
+
8
+ def initialize(json, linter)
9
+ @linter = linter
10
+ @json = json
11
+ @parser = find_parser
12
+ end
13
+
14
+ def parse
15
+ parser.call
16
+ end
17
+
18
+ private
19
+
20
+ def find_parser
21
+ return Rubocop.new(json) if rubocop_like_parser?
22
+
23
+ ('Supercop::Parsers::' + linter.classify).constantize.new(json)
24
+ rescue NameError
25
+ Base.new(json)
26
+ end
27
+
28
+ def rubocop_like_parser?
29
+ RUBOCOP.include?(linter.classify)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ module Supercop
2
+ module Parsers
3
+ class Rubocop < Base
4
+ private
5
+
6
+ def parse
7
+ JSON.parse(json).fetch('summary').fetch('offense_count')
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module Supercop
2
+ module Parsers
3
+ class ScssLint < Base
4
+ private
5
+
6
+ def parse
7
+ output = JSON.parse(json)
8
+
9
+ output.keys.inject(0) { |warnings, key| warnings + output[key].count }
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module Supercop
2
+ # FYI: Here we defined rake tasks and generators for Rails use
3
+ require 'rails/railtie'
4
+ class Railtie < ::Rails::Railtie
5
+ rake_tasks do
6
+ load 'tasks/manage_settings.rake'
7
+ load 'tasks/check.rake'
8
+ end
9
+
10
+ generators do
11
+ require_relative 'generators/config_generator'
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,42 @@
1
+ module Supercop
2
+ class TableFormatter
3
+ CELL_WIDTH = 20
4
+ DEFAULT_COLUMNS = %w[linter alerts max status].freeze
5
+
6
+ def initialize(columns = nil)
7
+ @columns = columns || DEFAULT_COLUMNS
8
+ end
9
+
10
+ def print_table(lines)
11
+ puts header
12
+
13
+ lines.each { |elements| puts line(elements) }
14
+
15
+ puts footer
16
+ end
17
+
18
+ private
19
+
20
+ def header
21
+ dash_line + "\n" + line(@columns) + "\n" + dash_line
22
+ end
23
+
24
+ def dash_line
25
+ line = '+'
26
+ @columns.count.times { line += Array.new(CELL_WIDTH, '-').join + '+' }
27
+ line
28
+ end
29
+
30
+ def footer
31
+ dash_line
32
+ end
33
+
34
+ def line(elements)
35
+ '|' + elements.map { |element| cell(element.to_s) }.join
36
+ end
37
+
38
+ def cell(word)
39
+ word.center(word.length + (CELL_WIDTH - word.length).abs) + '|'
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,86 @@
1
+ # FYI: 'cmd', 'options' and 'max' are required.
2
+ # 'path', 'git', 'version' and 'path' are optional params for installation.
3
+ # 'version' would not work with 'path' param.
4
+ # 'path' option is more priority and overrides 'git' option.
5
+ #
6
+ # File Format:
7
+ #
8
+ # linter: - gem name of linter to download
9
+ # cmd*: - command that run in command line
10
+ # option*: - options for cmd command to run. Please spcify here json output for normal parsing
11
+ # version: - version of gem to install
12
+ # git: - repo for gem download
13
+ # path: - local file system path to gem. It overrides git option
14
+ # max*: - maximum errors for linter to define ok or fail status of check
15
+ #
16
+ # * - required
17
+ #
18
+ # `Please note`, that you should specify JSON output param for correct parsing
19
+ #
20
+ # Example:
21
+ #
22
+ # rubocop:
23
+ # cmd: 'rubocop'
24
+ # options: '--jormat default'
25
+ # path: '/home/developer/rubocopgem/'
26
+ # version: '1.0.1'
27
+ # max: 20
28
+ #
29
+ # With git param:
30
+ #
31
+ # rubocop:
32
+ # cmd: 'rubocop'
33
+ # options: '--jormat default'
34
+ # git: 'git@github.com/developer/rubocop.git'
35
+ # version: '1.0.1'
36
+ #
37
+ # `Important!`
38
+ #
39
+ # Please use gem names for the configuration keys, like you add it to your gemfile
40
+ # For example:
41
+ # Correct:
42
+ #
43
+ # sccs_lint:
44
+ # cmd: 'scss-lint'
45
+ # version: '0.69'
46
+ #
47
+ # Incorrect - it wouldn't work
48
+ #
49
+ # scss-lint:
50
+ # cmd: 'scss-lint'
51
+ # version: '0.69'
52
+ #
53
+ # Template config fo rails project with slim
54
+ # max: &max_quantity
55
+ # max: 99
56
+ # verbose: false
57
+ # config:
58
+ # rubocop:
59
+ # cmd: 'rubocop'
60
+ # options: '--format json'
61
+ # git: 'git@github.com:bbatsov/rubocop.git'
62
+ # version: '~0.49'
63
+ # <<: *max_quantity
64
+ # slim_lint:
65
+ # cmd: 'slim-lint'
66
+ # options: 'app/views --reporter json'
67
+ # version: '~> 0.13.0'
68
+ # <<: *max_quantity
69
+ # scss_lint:
70
+ # cmd: 'scss-lint'
71
+ # options: 'app/assets --format JSON'
72
+ # <<: *max_quantity
73
+
74
+ max: &max_quantity
75
+ max: 99
76
+ verbose: false
77
+ config:
78
+ rubocop:
79
+ cmd: 'rubocop'
80
+ options: '--format json'
81
+ git: 'git@github.com:bbatsov/rubocop.git'
82
+ <<: *max_quantity
83
+ reek:
84
+ cmd: 'reek'
85
+ options: '--format json'
86
+ <<: *max_quantity
@@ -0,0 +1,3 @@
1
+ module Supercop
2
+ VERSION = '0.2.1'
3
+ end
@@ -0,0 +1,8 @@
1
+ require 'supercop'
2
+
3
+ desc 'Cops your code with configured linters and prints table report'
4
+ namespace :supercop do
5
+ task :check do
6
+ Supercop::Checker.new.call
7
+ end
8
+ end
@@ -0,0 +1,42 @@
1
+ require 'supercop'
2
+
3
+ namespace :supercop do
4
+ desc 'Create config file in your project, and load dependecies'
5
+ task :generate_config do
6
+ if defined?(Rails)
7
+ generate_for_rails
8
+ else
9
+ generate_for_other
10
+ end
11
+ end
12
+
13
+ desc 'Add missing dependencies to your Gemfile and run bundle install'
14
+ task :load_dependencies do
15
+ loader.load_dependencies
16
+ end
17
+
18
+ desc 'Clean up changes made by supercop: config, gems'
19
+ task :cleanup do
20
+ cleaner.call
21
+ end
22
+
23
+ def generate_for_rails
24
+ puts 'Please, use rails generator instead!'
25
+ end
26
+
27
+ def generate_for_other
28
+ puts 'Generate config for your supercop linters'
29
+
30
+ destination = Dir.pwd
31
+
32
+ puts Supercop::Actions::ConfigCopier.new(destination: destination).call
33
+ end
34
+
35
+ def loader
36
+ Supercop::Actions::Loaders::Dependency.new
37
+ end
38
+
39
+ def cleaner
40
+ Supercop::Actions::Clean
41
+ end
42
+ end
data/supercop.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'supercop/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'supercop'
8
+ spec.version = Supercop::VERSION
9
+ spec.authors = ['Artem Kuznetsov']
10
+ spec.email = ['artemasmith@gmailcom']
11
+
12
+ spec.summary = %q{Utility for get easy and simple code quality report
13
+ based on different linters, like rubocop or reek}
14
+ spec.description = %q{This gem allows you to use multiply lnters to check
15
+ your code quality and get nice table-view report}
16
+ spec.homepage = 'http://github.com/artemasmith/supercop'
17
+ spec.license = 'MIT'
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
+ f.match(%r{^(test|spec|features)/})
21
+ end
22
+ spec.bindir = 'exe'
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ['lib']
25
+
26
+ spec.add_development_dependency 'bundler', '>= 1.13'
27
+ spec.add_development_dependency 'rake', '>= 10.0'
28
+ spec.add_development_dependency 'rspec', '>= 3.0'
29
+ spec.add_development_dependency 'rspec-its'
30
+ spec.add_development_dependency 'pry'
31
+ spec.add_development_dependency 'fakefs'
32
+ spec.add_development_dependency 'activesupport'
33
+ spec.add_development_dependency 'json'
34
+ end
metadata ADDED
@@ -0,0 +1,189 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: supercop
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Artem Kuznetsov
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-09-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-its
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: fakefs
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: activesupport
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: json
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: |-
126
+ This gem allows you to use multiply lnters to check
127
+ your code quality and get nice table-view report
128
+ email:
129
+ - artemasmith@gmailcom
130
+ executables: []
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - ".gitignore"
135
+ - ".rspec"
136
+ - ".travis.yml"
137
+ - Gemfile
138
+ - LICENSE.txt
139
+ - README.md
140
+ - Rakefile
141
+ - bin/console
142
+ - bin/setup
143
+ - lib/supercop.rb
144
+ - lib/supercop/actions/clean.rb
145
+ - lib/supercop/actions/config_copier.rb
146
+ - lib/supercop/actions/file_injector.rb
147
+ - lib/supercop/actions/loaders/base.rb
148
+ - lib/supercop/actions/loaders/dependency.rb
149
+ - lib/supercop/checker.rb
150
+ - lib/supercop/configuration.rb
151
+ - lib/supercop/cop.rb
152
+ - lib/supercop/generators/config_generator.rb
153
+ - lib/supercop/parsers/base.rb
154
+ - lib/supercop/parsers/proxy.rb
155
+ - lib/supercop/parsers/rubocop.rb
156
+ - lib/supercop/parsers/scss_lint.rb
157
+ - lib/supercop/railtie.rb
158
+ - lib/supercop/table_formatter.rb
159
+ - lib/supercop/templates/supercop.yml
160
+ - lib/supercop/version.rb
161
+ - lib/tasks/check.rake
162
+ - lib/tasks/manage_settings.rake
163
+ - supercop.gemspec
164
+ homepage: http://github.com/artemasmith/supercop
165
+ licenses:
166
+ - MIT
167
+ metadata: {}
168
+ post_install_message:
169
+ rdoc_options: []
170
+ require_paths:
171
+ - lib
172
+ required_ruby_version: !ruby/object:Gem::Requirement
173
+ requirements:
174
+ - - ">="
175
+ - !ruby/object:Gem::Version
176
+ version: '0'
177
+ required_rubygems_version: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ requirements: []
183
+ rubyforge_project:
184
+ rubygems_version: 2.5.2
185
+ signing_key:
186
+ specification_version: 4
187
+ summary: Utility for get easy and simple code quality report based on different linters,
188
+ like rubocop or reek
189
+ test_files: []