codeclimate 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,65 @@
1
+ require "highline"
2
+ require "active_support"
3
+ require "active_support/core_ext"
4
+ require "rainbow"
5
+
6
+ module CC
7
+ module CLI
8
+ class Command
9
+ CODECLIMATE_YAML = ".codeclimate.yml".freeze
10
+
11
+ def initialize(args = [])
12
+ @args = args
13
+ end
14
+
15
+ def run
16
+ $stderr.puts "unknown command #{self.class.name.split('::').last.underscore}"
17
+ end
18
+
19
+ def self.command_name
20
+ name[/[^:]*$/].split(/(?=[A-Z])/).map(&:downcase).join('-')
21
+ end
22
+
23
+ def execute
24
+ run
25
+ end
26
+
27
+ def say(message)
28
+ terminal.say message
29
+ end
30
+
31
+ def warn(message)
32
+ terminal.say(colorize("WARNING: #{message}", :yellow))
33
+ end
34
+
35
+ def fatal(message)
36
+ $stderr.puts colorize(message, :red)
37
+ exit 1
38
+ end
39
+
40
+ def require_codeclimate_yml
41
+ if !filesystem.exist?(CODECLIMATE_YAML)
42
+ fatal("No '.codeclimate.yml' file found. Run 'codeclimate init' to generate a config file.")
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def colorize(string, *args)
49
+ rainbow.wrap(string).color(*args)
50
+ end
51
+
52
+ def rainbow
53
+ @rainbow ||= Rainbow.new
54
+ end
55
+
56
+ def filesystem
57
+ @filesystem ||= CC::Analyzer::Filesystem.new(ENV['FILESYSTEM_DIR'])
58
+ end
59
+
60
+ def terminal
61
+ @terminal ||= HighLine.new($stdin, $stdout)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,12 @@
1
+ module CC
2
+ module CLI
3
+ class Console < Command
4
+
5
+ def run
6
+ require "pry"
7
+ binding.pry(quiet: true, prompt: Pry::SIMPLE_PROMPT, output: $stdout)
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ require "cc/analyzer"
2
+
3
+ module CC
4
+ module CLI
5
+ module Engines
6
+ autoload :Disable, "cc/cli/engines/disable"
7
+ autoload :Enable, "cc/cli/engines/enable"
8
+ autoload :EngineCommand, "cc/cli/engines/engine_command"
9
+ autoload :Install, "cc/cli/engines/install"
10
+ autoload :List, "cc/cli/engines/list"
11
+ autoload :Remove, "cc/cli/engines/remove"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,31 @@
1
+ require "cc/analyzer"
2
+
3
+ module CC
4
+ module CLI
5
+ module Engines
6
+ class Disable < EngineCommand
7
+ def run
8
+ require_codeclimate_yml
9
+
10
+ if !engine_exists?
11
+ say "Engine not found. Run 'codeclimate engines:list' for a list of valid engines."
12
+ elsif !engine_present_in_yaml?
13
+ say "Engine not found in .codeclimate.yml."
14
+ elsif !engine_enabled?
15
+ say "Engine already disabled."
16
+ else
17
+ disable_engine
18
+ update_yaml
19
+ say "Engine disabled."
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def disable_engine
26
+ parsed_yaml.disable_engine(engine_name)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,35 @@
1
+ require "cc/analyzer"
2
+
3
+ module CC
4
+ module CLI
5
+ module Engines
6
+ class Enable < EngineCommand
7
+ def run
8
+ require_codeclimate_yml
9
+
10
+ if !engine_exists?
11
+ say "Engine not found. Run 'codeclimate engines:list' for a list of valid engines."
12
+ elsif engine_enabled?
13
+ say "Engine already enabled."
14
+ pull_docker_images
15
+ else
16
+ enable_engine
17
+ update_yaml
18
+ say "Engine added to .codeclimate.yml."
19
+ pull_docker_images
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def pull_docker_images
26
+ Engines::Install.new.run
27
+ end
28
+
29
+ def enable_engine
30
+ parsed_yaml.enable_engine(engine_name)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,47 @@
1
+ require "cc/analyzer"
2
+
3
+ module CC
4
+ module CLI
5
+ module Engines
6
+ class EngineCommand < Command
7
+ include CC::Analyzer
8
+
9
+ private
10
+
11
+ def engine_name
12
+ @engine_name ||= @args.first
13
+ end
14
+
15
+ def parsed_yaml
16
+ @parsed_yaml ||= CC::Analyzer::Config.new(yaml_content)
17
+ end
18
+
19
+ def yaml_content
20
+ File.read(filesystem.path_for(CODECLIMATE_YAML)).freeze
21
+ end
22
+
23
+ def update_yaml
24
+ File.open(filesystem.path_for(CODECLIMATE_YAML), "w") do |f|
25
+ f.write(parsed_yaml.to_yaml)
26
+ end
27
+ end
28
+
29
+ def engine_present_in_yaml?
30
+ parsed_yaml.engine_present?(engine_name)
31
+ end
32
+
33
+ def engine_enabled?
34
+ parsed_yaml.engine_enabled?(engine_name)
35
+ end
36
+
37
+ def engine_exists?
38
+ engines_registry_list.keys.include?(engine_name)
39
+ end
40
+
41
+ def engines_registry_list
42
+ @engines_registry_list ||= CC::Analyzer::EngineRegistry.new.list
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,49 @@
1
+ require "cc/analyzer"
2
+
3
+ module CC
4
+ module CLI
5
+ module Engines
6
+ class Install < EngineCommand
7
+ ImagePullFailure = Class.new(StandardError)
8
+
9
+ def run
10
+ require_codeclimate_yml
11
+
12
+ say "Pulling docker images."
13
+ pull_docker_images
14
+ end
15
+
16
+ private
17
+
18
+ def pull_docker_images
19
+ engine_names.each do |name|
20
+ if engine_exists?(name)
21
+ image = engine_image(name)
22
+ pull_engine_image(image)
23
+ else
24
+ warn("unknown engine name: #{name}")
25
+ end
26
+ end
27
+ end
28
+
29
+ def engine_names
30
+ @engine_names ||= parsed_yaml.engine_names
31
+ end
32
+
33
+ def engine_exists?(engine_name)
34
+ engines_registry_list.keys.include?(engine_name)
35
+ end
36
+
37
+ def engine_image(engine_name)
38
+ engines_registry_list[engine_name]["image_name"]
39
+ end
40
+
41
+ def pull_engine_image(engine_image)
42
+ if !system("docker pull #{engine_image}")
43
+ raise ImagePullFailure, "unable to pull image #{engine_image}"
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,14 @@
1
+ module CC
2
+ module CLI
3
+ module Engines
4
+ class List < EngineCommand
5
+ def run
6
+ say "Available engines:"
7
+ engines_registry_list.sort_by { |name, _| name }.each do |name, attributes|
8
+ say "- #{name}: #{attributes["description"]}"
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ require "cc/analyzer"
2
+
3
+ module CC
4
+ module CLI
5
+ module Engines
6
+ class Remove < EngineCommand
7
+ def run
8
+ require_codeclimate_yml
9
+
10
+ if !engine_exists?
11
+ say "Engine not found. Run 'codeclimate engines:list' for a list of valid engines."
12
+ elsif !engine_present_in_yaml?
13
+ say "Engine not found in .codeclimate.yml."
14
+ else
15
+ remove_engine
16
+ update_yaml
17
+ say "Engine removed from .codeclimate.yml."
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def remove_engine
24
+ parsed_yaml.remove_engine(engine_name)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,36 @@
1
+ require "rainbow"
2
+
3
+ module CC
4
+ module CLI
5
+ class Help < Command
6
+ def run
7
+ say "Usage: codeclimate COMMAND ...\n\nAvailable commands:\n"
8
+ commands.each do |command|
9
+ say " #{command}"
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def commands
16
+ [
17
+ "analyze [-f format]",
18
+ "console",
19
+ "engines:disable #{underline('engine_name')}",
20
+ "engines:enable #{underline('engine_name')}",
21
+ "engines:install",
22
+ "engines:list",
23
+ "engines:remove #{underline('engine_name')}",
24
+ "help",
25
+ "init",
26
+ "validate-config",
27
+ "version"
28
+ ].freeze
29
+ end
30
+
31
+ def underline(string)
32
+ return Rainbow.new.wrap(string).underline
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,53 @@
1
+ module CC
2
+ module CLI
3
+ class Init < Command
4
+ include CC::Analyzer
5
+
6
+ def run
7
+ if filesystem.exist?(CODECLIMATE_YAML)
8
+ say "Config file .codeclimate.yml already present.\nTry running 'validate-config' to check configuration."
9
+ else
10
+ create_codeclimate_yaml
11
+ say "Config file .codeclimate.yml successfully generated.\nEdit and then try running 'validate-config' to check configuration."
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def create_codeclimate_yaml
18
+ config = { "engines" => {} }
19
+ eligible_engines.each do |engine_name, engine_config|
20
+ config["engines"][engine_name] = {
21
+ "enabled" => true
22
+ }
23
+ config["ratings"] ||= {}
24
+ config["ratings"]["paths"] ||= []
25
+
26
+ config["ratings"]["paths"] |= engine_config["default_ratings_paths"]
27
+ end
28
+
29
+ if filesystem.exist?("vendor")
30
+ config["exclude_paths"] = ["vendor/**/*"]
31
+ end
32
+
33
+ File.write(filesystem.path_for(CODECLIMATE_YAML), config.to_yaml)
34
+ end
35
+
36
+ def engine_eligible?(engine)
37
+ !engine["community"] &&
38
+ engine["enable_regexps"].present? &&
39
+ filesystem.any? do |path|
40
+ engine["enable_regexps"].any? { |re| Regexp.new(re).match(path) }
41
+ end
42
+ end
43
+
44
+ def eligible_engines
45
+ CC::Analyzer::EngineRegistry.new.list.each_with_object({}) do |(engine_name, config), result|
46
+ if engine_eligible?(config)
47
+ result[engine_name] = config
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,60 @@
1
+ require "active_support"
2
+ require "active_support/core_ext"
3
+
4
+ module CC
5
+ module CLI
6
+ class Runner
7
+
8
+ def self.run(argv)
9
+ new(argv).run
10
+ rescue => ex
11
+ $stderr.puts("error: (#{ex.class}) #{ex.message}")
12
+
13
+ if ENV["CODECLIMATE_DEBUG"]
14
+ $stderr.puts("backtrace: #{ex.backtrace.join("\n\t")}")
15
+ end
16
+ end
17
+
18
+ def initialize(args)
19
+ @args = args
20
+ end
21
+
22
+ def run
23
+ if command_class
24
+ command = command_class.new(command_arguments)
25
+ command.execute
26
+ else
27
+ command_not_found
28
+ end
29
+ end
30
+
31
+ def command_not_found
32
+ $stderr.puts "unknown command #{command}"
33
+ exit 1
34
+ end
35
+
36
+ def command_class
37
+ CLI.const_get(command_name)
38
+ rescue NameError
39
+ nil
40
+ end
41
+
42
+ def command_name
43
+ case command
44
+ when nil, '-h', '-?', '--help' then 'Help'
45
+ when '-v', '--version' then 'Version'
46
+ else command.sub(":", "::").underscore.camelize
47
+ end
48
+ end
49
+
50
+ def command_arguments
51
+ @args[1..-1]
52
+ end
53
+
54
+ def command
55
+ @args.first
56
+ end
57
+
58
+ end
59
+ end
60
+ end