codeclimate-fede 0.85.23
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/check +18 -0
- data/bin/codeclimate +21 -0
- data/bin/prep-release +45 -0
- data/bin/release +41 -0
- data/bin/validate-release +18 -0
- data/config/engines.yml +322 -0
- data/lib/cc/analyzer.rb +50 -0
- data/lib/cc/analyzer/bridge.rb +106 -0
- data/lib/cc/analyzer/composite_container_listener.rb +21 -0
- data/lib/cc/analyzer/container.rb +208 -0
- data/lib/cc/analyzer/container/result.rb +74 -0
- data/lib/cc/analyzer/container_listener.rb +9 -0
- data/lib/cc/analyzer/engine.rb +125 -0
- data/lib/cc/analyzer/engine_output.rb +74 -0
- data/lib/cc/analyzer/engine_output_filter.rb +36 -0
- data/lib/cc/analyzer/engine_output_overrider.rb +31 -0
- data/lib/cc/analyzer/filesystem.rb +50 -0
- data/lib/cc/analyzer/formatters.rb +21 -0
- data/lib/cc/analyzer/formatters/formatter.rb +53 -0
- data/lib/cc/analyzer/formatters/html_formatter.rb +415 -0
- data/lib/cc/analyzer/formatters/json_formatter.rb +38 -0
- data/lib/cc/analyzer/formatters/plain_text_formatter.rb +101 -0
- data/lib/cc/analyzer/formatters/spinner.rb +35 -0
- data/lib/cc/analyzer/issue.rb +69 -0
- data/lib/cc/analyzer/issue_sorter.rb +30 -0
- data/lib/cc/analyzer/issue_validations.rb +26 -0
- data/lib/cc/analyzer/issue_validations/category_validation.rb +32 -0
- data/lib/cc/analyzer/issue_validations/check_name_presence_validation.rb +15 -0
- data/lib/cc/analyzer/issue_validations/content_validation.rb +21 -0
- data/lib/cc/analyzer/issue_validations/description_presence_validation.rb +15 -0
- data/lib/cc/analyzer/issue_validations/location_format_validation.rb +72 -0
- data/lib/cc/analyzer/issue_validations/other_locations_format_validation.rb +41 -0
- data/lib/cc/analyzer/issue_validations/path_existence_validation.rb +15 -0
- data/lib/cc/analyzer/issue_validations/path_is_file_validation.rb +15 -0
- data/lib/cc/analyzer/issue_validations/path_presence_validation.rb +15 -0
- data/lib/cc/analyzer/issue_validations/relative_path_validation.rb +32 -0
- data/lib/cc/analyzer/issue_validations/remediation_points_validation.rb +25 -0
- data/lib/cc/analyzer/issue_validations/severity_validation.rb +39 -0
- data/lib/cc/analyzer/issue_validations/type_validation.rb +15 -0
- data/lib/cc/analyzer/issue_validations/validation.rb +35 -0
- data/lib/cc/analyzer/issue_validator.rb +11 -0
- data/lib/cc/analyzer/location_description.rb +45 -0
- data/lib/cc/analyzer/logging_container_listener.rb +24 -0
- data/lib/cc/analyzer/measurement.rb +22 -0
- data/lib/cc/analyzer/measurement_validations.rb +16 -0
- data/lib/cc/analyzer/measurement_validations/name_validation.rb +23 -0
- data/lib/cc/analyzer/measurement_validations/type_validation.rb +15 -0
- data/lib/cc/analyzer/measurement_validations/validation.rb +27 -0
- data/lib/cc/analyzer/measurement_validations/value_validation.rb +21 -0
- data/lib/cc/analyzer/measurement_validator.rb +11 -0
- data/lib/cc/analyzer/mounted_path.rb +80 -0
- data/lib/cc/analyzer/raising_container_listener.rb +32 -0
- data/lib/cc/analyzer/source_buffer.rb +47 -0
- data/lib/cc/analyzer/source_extractor.rb +79 -0
- data/lib/cc/analyzer/source_fingerprint.rb +40 -0
- data/lib/cc/analyzer/statsd_container_listener.rb +51 -0
- data/lib/cc/analyzer/validator.rb +38 -0
- data/lib/cc/cli.rb +39 -0
- data/lib/cc/cli/analyze.rb +90 -0
- data/lib/cc/cli/analyze/engine_failure.rb +11 -0
- data/lib/cc/cli/command.rb +85 -0
- data/lib/cc/cli/console.rb +12 -0
- data/lib/cc/cli/engines.rb +5 -0
- data/lib/cc/cli/engines/engine_command.rb +15 -0
- data/lib/cc/cli/engines/install.rb +35 -0
- data/lib/cc/cli/engines/list.rb +18 -0
- data/lib/cc/cli/file_store.rb +42 -0
- data/lib/cc/cli/global_cache.rb +47 -0
- data/lib/cc/cli/global_config.rb +35 -0
- data/lib/cc/cli/help.rb +51 -0
- data/lib/cc/cli/output.rb +34 -0
- data/lib/cc/cli/prepare.rb +98 -0
- data/lib/cc/cli/runner.rb +75 -0
- data/lib/cc/cli/validate_config.rb +84 -0
- data/lib/cc/cli/version.rb +16 -0
- data/lib/cc/cli/version_checker.rb +107 -0
- data/lib/cc/config.rb +70 -0
- data/lib/cc/config/checks_adapter.rb +40 -0
- data/lib/cc/config/default_adapter.rb +54 -0
- data/lib/cc/config/engine.rb +41 -0
- data/lib/cc/config/engine_set.rb +47 -0
- data/lib/cc/config/json_adapter.rb +17 -0
- data/lib/cc/config/prepare.rb +92 -0
- data/lib/cc/config/validation/check_validator.rb +34 -0
- data/lib/cc/config/validation/engine_validator.rb +93 -0
- data/lib/cc/config/validation/fetch_validator.rb +78 -0
- data/lib/cc/config/validation/file_validator.rb +112 -0
- data/lib/cc/config/validation/hash_validations.rb +52 -0
- data/lib/cc/config/validation/json.rb +31 -0
- data/lib/cc/config/validation/prepare_validator.rb +40 -0
- data/lib/cc/config/validation/yaml.rb +66 -0
- data/lib/cc/config/yaml_adapter.rb +73 -0
- data/lib/cc/engine_registry.rb +74 -0
- data/lib/cc/resolv.rb +39 -0
- data/lib/cc/workspace.rb +39 -0
- data/lib/cc/workspace/exclusion.rb +34 -0
- data/lib/cc/workspace/path_tree.rb +49 -0
- data/lib/cc/workspace/path_tree/dir_node.rb +67 -0
- data/lib/cc/workspace/path_tree/file_node.rb +31 -0
- metadata +277 -0
@@ -0,0 +1,90 @@
|
|
1
|
+
require "cc/cli/command"
|
2
|
+
|
3
|
+
module CC
|
4
|
+
module CLI
|
5
|
+
class Analyze < Command
|
6
|
+
ARGUMENT_LIST = "[-f format] [-e engine[:channel]] [path]".freeze
|
7
|
+
SHORT_HELP = "Run analysis with the given arguments".freeze
|
8
|
+
HELP = "#{SHORT_HELP}\n" \
|
9
|
+
"\n" \
|
10
|
+
" -f <format>, --format <format> Format of output. Possible values: #{CC::Analyzer::Formatters::FORMATTERS.keys.join ", "}\n" \
|
11
|
+
" -e <engine[:channel]> Engine to run. Can be specified multiple times.\n" \
|
12
|
+
" --dev Run in development mode. Engines installed locally that are not in the manifest will be run.\n" \
|
13
|
+
" path Path to check. Can be specified multiple times.".freeze
|
14
|
+
|
15
|
+
autoload :EngineFailure, "cc/cli/analyze/engine_failure"
|
16
|
+
|
17
|
+
include CC::Analyzer
|
18
|
+
|
19
|
+
def run
|
20
|
+
# Load config here so it sees ./.codeclimate.yml
|
21
|
+
@config = Config.load
|
22
|
+
|
23
|
+
# process args after, so it modifies loaded configuration
|
24
|
+
process_args
|
25
|
+
|
26
|
+
bridge = Bridge.new(
|
27
|
+
config: config,
|
28
|
+
formatter: formatter,
|
29
|
+
listener: CompositeContainerListener.new(
|
30
|
+
LoggingContainerListener.new(Analyzer.logger),
|
31
|
+
RaisingContainerListener.new(EngineFailure),
|
32
|
+
),
|
33
|
+
registry: EngineRegistry.new,
|
34
|
+
)
|
35
|
+
|
36
|
+
bridge.run
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
attr_reader :config, :engines_disabled, :listener, :registry
|
42
|
+
|
43
|
+
def process_args
|
44
|
+
while (arg = @args.shift)
|
45
|
+
case arg
|
46
|
+
when "-f", "--format"
|
47
|
+
@formatter = Formatters.resolve(@args.shift).new(filesystem)
|
48
|
+
when "-e", "--engine"
|
49
|
+
disable_all_engines!
|
50
|
+
name, channel = @args.shift.split(":", 2)
|
51
|
+
enable_engine(name, channel)
|
52
|
+
when "--dev"
|
53
|
+
config.development = true
|
54
|
+
when "--no-plugins"
|
55
|
+
config.disable_plugins!
|
56
|
+
else
|
57
|
+
config.analysis_paths << arg
|
58
|
+
end
|
59
|
+
end
|
60
|
+
rescue Formatters::Formatter::InvalidFormatterError => ex
|
61
|
+
fatal(ex.message)
|
62
|
+
end
|
63
|
+
|
64
|
+
def formatter
|
65
|
+
@formatter ||= Formatters::PlainTextFormatter.new(filesystem)
|
66
|
+
end
|
67
|
+
|
68
|
+
def disable_all_engines!
|
69
|
+
unless engines_disabled
|
70
|
+
config.engines.each { |e| e.enabled = false }
|
71
|
+
@engines_disabled = true
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def enable_engine(name, channel)
|
76
|
+
existing_engine = config.engines.detect { |e| e.name == name }
|
77
|
+
if existing_engine.present?
|
78
|
+
existing_engine.enabled = true
|
79
|
+
existing_engine.channel = channel if channel.present?
|
80
|
+
else
|
81
|
+
config.engines << Config::Engine.new(
|
82
|
+
name,
|
83
|
+
channel: channel,
|
84
|
+
enabled: true,
|
85
|
+
)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require "highline"
|
2
|
+
require "active_support"
|
3
|
+
require "active_support/core_ext"
|
4
|
+
require "rainbow"
|
5
|
+
require "cc/cli/output"
|
6
|
+
|
7
|
+
module CC
|
8
|
+
module CLI
|
9
|
+
class Command
|
10
|
+
include CC::CLI::Output
|
11
|
+
|
12
|
+
CODECLIMATE_YAML = ".codeclimate.yml".freeze
|
13
|
+
NAMESPACE = name.split("::")[0..-2].join("::").freeze
|
14
|
+
|
15
|
+
def self.abstract!
|
16
|
+
@abstract = true
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.abstract?
|
20
|
+
@abstract == true
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.all
|
24
|
+
@@subclasses.reject(&:abstract?)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.[](name)
|
28
|
+
all.find { |command| command.name == "#{NAMESPACE}::#{name}" || command.command_name == name }
|
29
|
+
end
|
30
|
+
|
31
|
+
# rubocop: disable Style/ClassVars
|
32
|
+
def self.inherited(subclass)
|
33
|
+
@@subclasses ||= []
|
34
|
+
@@subclasses << subclass
|
35
|
+
end
|
36
|
+
# rubocop: enable Style/ClassVars
|
37
|
+
|
38
|
+
def self.synopsis
|
39
|
+
"#{command_name} #{self::ARGUMENT_LIST if const_defined?(:ARGUMENT_LIST)}".strip
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.short_help
|
43
|
+
if const_defined? :SHORT_HELP
|
44
|
+
self::SHORT_HELP
|
45
|
+
else
|
46
|
+
""
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.help
|
51
|
+
if const_defined? :HELP
|
52
|
+
self::HELP
|
53
|
+
else
|
54
|
+
short_help
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def initialize(args = [])
|
59
|
+
@args = args
|
60
|
+
end
|
61
|
+
|
62
|
+
def run
|
63
|
+
$stderr.puts "unknown command #{self.class.name.split("::").last.underscore}"
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.command_name
|
67
|
+
name.gsub(/^#{NAMESPACE}::/, "").split("::").map do |part|
|
68
|
+
part.split(/(?=[A-Z])/).map(&:downcase).join("-")
|
69
|
+
end.join(":")
|
70
|
+
end
|
71
|
+
|
72
|
+
def execute
|
73
|
+
run
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def filesystem
|
79
|
+
@filesystem ||= CC::Analyzer::Filesystem.new(
|
80
|
+
CC::Analyzer::MountedPath.code.container_path,
|
81
|
+
)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module CC
|
2
|
+
module CLI
|
3
|
+
class Console < Command
|
4
|
+
SHORT_HELP = "Open a ruby console for the CLI. Useful for developing against the CLI.".freeze
|
5
|
+
|
6
|
+
def run
|
7
|
+
require "pry"
|
8
|
+
binding.pry(quiet: true, prompt: Pry::SIMPLE_PROMPT, output: $stdout)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module CC
|
2
|
+
module CLI
|
3
|
+
module Engines
|
4
|
+
class Install < EngineCommand
|
5
|
+
SHORT_HELP = "Pull the latest images for enabled engines in your configuration".freeze
|
6
|
+
|
7
|
+
ImagePullFailure = Class.new(StandardError)
|
8
|
+
|
9
|
+
def run
|
10
|
+
say "Pulling docker images."
|
11
|
+
pull_docker_images
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def config
|
17
|
+
@config ||= CC::Config.load
|
18
|
+
end
|
19
|
+
|
20
|
+
def pull_docker_images
|
21
|
+
config.engines.each(&method(:pull_engine))
|
22
|
+
end
|
23
|
+
|
24
|
+
def pull_engine(engine)
|
25
|
+
metadata = engine_registry.fetch_engine_details(engine)
|
26
|
+
unless system("docker pull #{metadata.image}")
|
27
|
+
raise ImagePullFailure, "unable to pull image #{metadata.image}"
|
28
|
+
end
|
29
|
+
rescue EngineRegistry::EngineDetailsNotFoundError
|
30
|
+
warn("unknown engine <#{engine.name}:#{engine.channel}>")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module CC
|
2
|
+
module CLI
|
3
|
+
module Engines
|
4
|
+
class List < EngineCommand
|
5
|
+
SHORT_HELP = "List all available engines".freeze
|
6
|
+
|
7
|
+
def run
|
8
|
+
say "Available engines:"
|
9
|
+
engine_registry.
|
10
|
+
sort_by { |engine, _| engine.name }.
|
11
|
+
each do |engine, metadata|
|
12
|
+
say "- #{engine.name}: #{metadata.description}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "yaml"
|
3
|
+
|
4
|
+
module CC
|
5
|
+
module CLI
|
6
|
+
class FileStore
|
7
|
+
# This class is not supposed to be directly used. It should be sublcassed
|
8
|
+
# and a few constants need to be defined on the sublass to be usable.
|
9
|
+
#
|
10
|
+
# FILE_NAME is the name of the file this class wraps.
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
load_data
|
14
|
+
end
|
15
|
+
|
16
|
+
def save
|
17
|
+
return false unless File.exist? self.class::FILE_NAME
|
18
|
+
|
19
|
+
File.open(self.class::FILE_NAME, "w") do |f|
|
20
|
+
YAML.dump data, f
|
21
|
+
end
|
22
|
+
|
23
|
+
true
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :data
|
29
|
+
|
30
|
+
def load_data
|
31
|
+
@data =
|
32
|
+
if File.exist? self.class::FILE_NAME
|
33
|
+
File.open(self.class::FILE_NAME, "r:bom|utf-8") do |f|
|
34
|
+
YAML.safe_load(f, [Time], [], false, self.class::FILE_NAME) || {}
|
35
|
+
end
|
36
|
+
else
|
37
|
+
{}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "cc/cli/file_store"
|
2
|
+
|
3
|
+
module CC
|
4
|
+
module CLI
|
5
|
+
class GlobalCache < FileStore
|
6
|
+
FILE_NAME = "/cache.yml".freeze
|
7
|
+
|
8
|
+
# Cache entries
|
9
|
+
|
10
|
+
def last_version_check
|
11
|
+
data["last-version-check"] || Time.at(0)
|
12
|
+
end
|
13
|
+
|
14
|
+
def last_version_check=(value)
|
15
|
+
data["last-version-check"] =
|
16
|
+
if value.is_a? Time
|
17
|
+
value
|
18
|
+
else
|
19
|
+
Time.at(0)
|
20
|
+
end
|
21
|
+
save
|
22
|
+
value
|
23
|
+
end
|
24
|
+
|
25
|
+
def latest_version
|
26
|
+
data["latest-version"]
|
27
|
+
end
|
28
|
+
|
29
|
+
def latest_version=(value)
|
30
|
+
data["latest-version"] = value
|
31
|
+
save
|
32
|
+
value
|
33
|
+
end
|
34
|
+
|
35
|
+
def outdated
|
36
|
+
data["outdated"] == true
|
37
|
+
end
|
38
|
+
alias outdated? outdated
|
39
|
+
|
40
|
+
def outdated=(value)
|
41
|
+
data["outdated"] = value == true
|
42
|
+
save
|
43
|
+
value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "cc/cli/file_store"
|
2
|
+
require "uuid"
|
3
|
+
|
4
|
+
module CC
|
5
|
+
module CLI
|
6
|
+
class GlobalConfig < FileStore
|
7
|
+
FILE_NAME = "/config.yml".freeze
|
8
|
+
|
9
|
+
DEFAULT_CONFIG = {
|
10
|
+
"check-version" => true,
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
# Config entries
|
14
|
+
|
15
|
+
def check_version
|
16
|
+
data["check-version"]
|
17
|
+
end
|
18
|
+
alias check_version? check_version
|
19
|
+
|
20
|
+
def check_version=(value)
|
21
|
+
data["check-version"] = value == true
|
22
|
+
end
|
23
|
+
|
24
|
+
def uuid
|
25
|
+
data["uuid"] ||= UUID.new.generate
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def load_data
|
31
|
+
@data = DEFAULT_CONFIG.merge(super)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/cc/cli/help.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require "rainbow"
|
2
|
+
|
3
|
+
module CC
|
4
|
+
module CLI
|
5
|
+
class Help < Command
|
6
|
+
ARGUMENT_LIST = "[command]".freeze
|
7
|
+
SHORT_HELP = "Display help information.".freeze
|
8
|
+
HELP = "#{SHORT_HELP}\n" \
|
9
|
+
"\n" \
|
10
|
+
" no arguments Show help summary for all commands.\n" \
|
11
|
+
" [command] Show help for specific commands. Can be specified multiple times.".freeze
|
12
|
+
|
13
|
+
def run
|
14
|
+
if @args.any?
|
15
|
+
@args.each do |command|
|
16
|
+
show_help(command)
|
17
|
+
end
|
18
|
+
else
|
19
|
+
show_help_summary
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def show_help(command_name)
|
26
|
+
if (command = Command[command_name])
|
27
|
+
say "Usage: codeclimate #{command.synopsis}\n"
|
28
|
+
say "\n"
|
29
|
+
say "#{command.help}\n"
|
30
|
+
say "\n\n"
|
31
|
+
else
|
32
|
+
say "Unknown command: #{command_name}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def show_help_summary
|
37
|
+
short_helps =
|
38
|
+
Command.all.sort_by(&:command_name).map do |command|
|
39
|
+
[command.synopsis, command.short_help]
|
40
|
+
end.compact.to_h
|
41
|
+
|
42
|
+
longest_command_length = short_helps.keys.map(&:length).max
|
43
|
+
|
44
|
+
say "Usage: codeclimate COMMAND ...\n\nAvailable commands:\n"
|
45
|
+
short_helps.each do |command, help|
|
46
|
+
say format(" %-#{longest_command_length}s %s\n", command, help)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|