codeclimate-fede 0.85.23

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 (101) hide show
  1. checksums.yaml +7 -0
  2. data/bin/check +18 -0
  3. data/bin/codeclimate +21 -0
  4. data/bin/prep-release +45 -0
  5. data/bin/release +41 -0
  6. data/bin/validate-release +18 -0
  7. data/config/engines.yml +322 -0
  8. data/lib/cc/analyzer.rb +50 -0
  9. data/lib/cc/analyzer/bridge.rb +106 -0
  10. data/lib/cc/analyzer/composite_container_listener.rb +21 -0
  11. data/lib/cc/analyzer/container.rb +208 -0
  12. data/lib/cc/analyzer/container/result.rb +74 -0
  13. data/lib/cc/analyzer/container_listener.rb +9 -0
  14. data/lib/cc/analyzer/engine.rb +125 -0
  15. data/lib/cc/analyzer/engine_output.rb +74 -0
  16. data/lib/cc/analyzer/engine_output_filter.rb +36 -0
  17. data/lib/cc/analyzer/engine_output_overrider.rb +31 -0
  18. data/lib/cc/analyzer/filesystem.rb +50 -0
  19. data/lib/cc/analyzer/formatters.rb +21 -0
  20. data/lib/cc/analyzer/formatters/formatter.rb +53 -0
  21. data/lib/cc/analyzer/formatters/html_formatter.rb +415 -0
  22. data/lib/cc/analyzer/formatters/json_formatter.rb +38 -0
  23. data/lib/cc/analyzer/formatters/plain_text_formatter.rb +101 -0
  24. data/lib/cc/analyzer/formatters/spinner.rb +35 -0
  25. data/lib/cc/analyzer/issue.rb +69 -0
  26. data/lib/cc/analyzer/issue_sorter.rb +30 -0
  27. data/lib/cc/analyzer/issue_validations.rb +26 -0
  28. data/lib/cc/analyzer/issue_validations/category_validation.rb +32 -0
  29. data/lib/cc/analyzer/issue_validations/check_name_presence_validation.rb +15 -0
  30. data/lib/cc/analyzer/issue_validations/content_validation.rb +21 -0
  31. data/lib/cc/analyzer/issue_validations/description_presence_validation.rb +15 -0
  32. data/lib/cc/analyzer/issue_validations/location_format_validation.rb +72 -0
  33. data/lib/cc/analyzer/issue_validations/other_locations_format_validation.rb +41 -0
  34. data/lib/cc/analyzer/issue_validations/path_existence_validation.rb +15 -0
  35. data/lib/cc/analyzer/issue_validations/path_is_file_validation.rb +15 -0
  36. data/lib/cc/analyzer/issue_validations/path_presence_validation.rb +15 -0
  37. data/lib/cc/analyzer/issue_validations/relative_path_validation.rb +32 -0
  38. data/lib/cc/analyzer/issue_validations/remediation_points_validation.rb +25 -0
  39. data/lib/cc/analyzer/issue_validations/severity_validation.rb +39 -0
  40. data/lib/cc/analyzer/issue_validations/type_validation.rb +15 -0
  41. data/lib/cc/analyzer/issue_validations/validation.rb +35 -0
  42. data/lib/cc/analyzer/issue_validator.rb +11 -0
  43. data/lib/cc/analyzer/location_description.rb +45 -0
  44. data/lib/cc/analyzer/logging_container_listener.rb +24 -0
  45. data/lib/cc/analyzer/measurement.rb +22 -0
  46. data/lib/cc/analyzer/measurement_validations.rb +16 -0
  47. data/lib/cc/analyzer/measurement_validations/name_validation.rb +23 -0
  48. data/lib/cc/analyzer/measurement_validations/type_validation.rb +15 -0
  49. data/lib/cc/analyzer/measurement_validations/validation.rb +27 -0
  50. data/lib/cc/analyzer/measurement_validations/value_validation.rb +21 -0
  51. data/lib/cc/analyzer/measurement_validator.rb +11 -0
  52. data/lib/cc/analyzer/mounted_path.rb +80 -0
  53. data/lib/cc/analyzer/raising_container_listener.rb +32 -0
  54. data/lib/cc/analyzer/source_buffer.rb +47 -0
  55. data/lib/cc/analyzer/source_extractor.rb +79 -0
  56. data/lib/cc/analyzer/source_fingerprint.rb +40 -0
  57. data/lib/cc/analyzer/statsd_container_listener.rb +51 -0
  58. data/lib/cc/analyzer/validator.rb +38 -0
  59. data/lib/cc/cli.rb +39 -0
  60. data/lib/cc/cli/analyze.rb +90 -0
  61. data/lib/cc/cli/analyze/engine_failure.rb +11 -0
  62. data/lib/cc/cli/command.rb +85 -0
  63. data/lib/cc/cli/console.rb +12 -0
  64. data/lib/cc/cli/engines.rb +5 -0
  65. data/lib/cc/cli/engines/engine_command.rb +15 -0
  66. data/lib/cc/cli/engines/install.rb +35 -0
  67. data/lib/cc/cli/engines/list.rb +18 -0
  68. data/lib/cc/cli/file_store.rb +42 -0
  69. data/lib/cc/cli/global_cache.rb +47 -0
  70. data/lib/cc/cli/global_config.rb +35 -0
  71. data/lib/cc/cli/help.rb +51 -0
  72. data/lib/cc/cli/output.rb +34 -0
  73. data/lib/cc/cli/prepare.rb +98 -0
  74. data/lib/cc/cli/runner.rb +75 -0
  75. data/lib/cc/cli/validate_config.rb +84 -0
  76. data/lib/cc/cli/version.rb +16 -0
  77. data/lib/cc/cli/version_checker.rb +107 -0
  78. data/lib/cc/config.rb +70 -0
  79. data/lib/cc/config/checks_adapter.rb +40 -0
  80. data/lib/cc/config/default_adapter.rb +54 -0
  81. data/lib/cc/config/engine.rb +41 -0
  82. data/lib/cc/config/engine_set.rb +47 -0
  83. data/lib/cc/config/json_adapter.rb +17 -0
  84. data/lib/cc/config/prepare.rb +92 -0
  85. data/lib/cc/config/validation/check_validator.rb +34 -0
  86. data/lib/cc/config/validation/engine_validator.rb +93 -0
  87. data/lib/cc/config/validation/fetch_validator.rb +78 -0
  88. data/lib/cc/config/validation/file_validator.rb +112 -0
  89. data/lib/cc/config/validation/hash_validations.rb +52 -0
  90. data/lib/cc/config/validation/json.rb +31 -0
  91. data/lib/cc/config/validation/prepare_validator.rb +40 -0
  92. data/lib/cc/config/validation/yaml.rb +66 -0
  93. data/lib/cc/config/yaml_adapter.rb +73 -0
  94. data/lib/cc/engine_registry.rb +74 -0
  95. data/lib/cc/resolv.rb +39 -0
  96. data/lib/cc/workspace.rb +39 -0
  97. data/lib/cc/workspace/exclusion.rb +34 -0
  98. data/lib/cc/workspace/path_tree.rb +49 -0
  99. data/lib/cc/workspace/path_tree/dir_node.rb +67 -0
  100. data/lib/cc/workspace/path_tree/file_node.rb +31 -0
  101. 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,11 @@
1
+ module CC
2
+ module CLI
3
+ class Analyze < Command
4
+ class EngineFailure < StandardError
5
+ def initialize(message, _engine_name)
6
+ super(message)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ 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,5 @@
1
+ require "cc/analyzer"
2
+
3
+ require "cc/cli/engines/engine_command"
4
+ require "cc/cli/engines/install"
5
+ require "cc/cli/engines/list"
@@ -0,0 +1,15 @@
1
+ require "cc/analyzer"
2
+
3
+ module CC
4
+ module CLI
5
+ module Engines
6
+ class EngineCommand < Command
7
+ abstract!
8
+
9
+ def engine_registry
10
+ @engine_registry ||= EngineRegistry.new
11
+ end
12
+ end
13
+ end
14
+ end
15
+ 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
@@ -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