codeclimate-fede 0.85.23

Sign up to get free protection for your applications and to get access to all the features.
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