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,34 @@
1
+ module CC
2
+ module CLI
3
+ module Output
4
+ def success(message)
5
+ terminal.say colorize(message, :green)
6
+ end
7
+
8
+ def say(message)
9
+ terminal.say message
10
+ end
11
+
12
+ def warn(message)
13
+ terminal.say colorize("WARNING: #{message}", :yellow)
14
+ end
15
+
16
+ def fatal(message)
17
+ $stderr.puts colorize(message, :red)
18
+ exit 1
19
+ end
20
+
21
+ def colorize(string, *args)
22
+ rainbow.wrap(string).color(*args)
23
+ end
24
+
25
+ def rainbow
26
+ @rainbow ||= Rainbow.new
27
+ end
28
+
29
+ def terminal
30
+ @terminal ||= HighLine.new($stdin, $stdout)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,98 @@
1
+ require "fileutils"
2
+ require "ipaddr"
3
+ require "json"
4
+ require "net/http"
5
+ require "pathname"
6
+ require "uri"
7
+
8
+ require "cc/resolv"
9
+
10
+ module CC
11
+ module CLI
12
+ class Prepare < Command
13
+ ARGUMENT_LIST = "[--allow-internal-ips]".freeze
14
+ SHORT_HELP = "Run the commands in your prepare step.".freeze
15
+ HELP = "#{SHORT_HELP}\n" \
16
+ "\n" \
17
+ " --allow-internal-ips Allow fetching from internal IPs.".freeze
18
+
19
+ InternalHostError = Class.new(StandardError)
20
+ FetchError = Class.new(StandardError)
21
+
22
+ PRIVATE_ADDRESS_SUBNETS = [
23
+ IPAddr.new("10.0.0.0/8"),
24
+ IPAddr.new("172.16.0.0/12"),
25
+ IPAddr.new("192.168.0.0/16"),
26
+ IPAddr.new("fd00::/8"),
27
+ IPAddr.new("127.0.0.1"),
28
+ IPAddr.new("0:0:0:0:0:0:0:1"),
29
+ ].freeze
30
+
31
+ def run
32
+ ::CC::Resolv.with_fixed_dns { fetch_all }
33
+ rescue FetchError, InternalHostError => ex
34
+ fatal(ex.message)
35
+ end
36
+
37
+ private
38
+
39
+ def allow_internal_ips?
40
+ @args.include?("--allow-internal-ips")
41
+ end
42
+
43
+ def fetches
44
+ @fetches ||= config.prepare.fetch
45
+ end
46
+
47
+ def config
48
+ @config ||= CC::Config.load
49
+ end
50
+
51
+ def fetch_all
52
+ fetches.each do |entry|
53
+ fetch(entry.url, entry.path)
54
+ end
55
+ end
56
+
57
+ def fetch(url, target_path)
58
+ ensure_external!(url) unless allow_internal_ips?
59
+
60
+ uri = URI.parse(url)
61
+ http = Net::HTTP.new(uri.host, uri.port)
62
+ http.use_ssl = uri.scheme == "https"
63
+ resp = http.get(uri)
64
+ if resp.code == "200"
65
+ write_file(target_path, resp.body)
66
+ say("Wrote #{url} to #{target_path}")
67
+ else
68
+ raise FetchError, "Failed fetching #{url}: code=#{resp.code} body=#{resp.body}"
69
+ end
70
+ end
71
+
72
+ def write_file(target_path, content)
73
+ FileUtils.mkdir_p(Pathname.new(target_path).parent.to_s)
74
+ File.write(target_path, content)
75
+ end
76
+
77
+ def ensure_external!(url)
78
+ uri = URI.parse(url)
79
+
80
+ if internal?(uri.host)
81
+ raise InternalHostError, "Won't fetch #{url.inspect}: it maps to an internal address"
82
+ end
83
+ end
84
+
85
+ # rubocop:disable Style/CaseEquality
86
+ def internal?(host)
87
+ address = ::Resolv.getaddress(host)
88
+
89
+ PRIVATE_ADDRESS_SUBNETS.any? do |subnet|
90
+ subnet === IPAddr.new(address.to_s)
91
+ end
92
+ rescue ::Resolv::ResolvError
93
+ true # localhost
94
+ end
95
+ # rubocop:enable Style/CaseEquality
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,75 @@
1
+ require "active_support"
2
+ require "active_support/core_ext"
3
+ require "cc/cli/version_checker"
4
+
5
+ module CC
6
+ module CLI
7
+ class Runner
8
+ def self.run(argv)
9
+ new(argv).run
10
+ rescue => ex
11
+ $stderr.puts("error: (#{ex.class}) #{ex.message}")
12
+ CLI.logger.debug("backtrace: #{ex.backtrace.join("\n\t")}")
13
+ exit 1
14
+ end
15
+
16
+ def initialize(args)
17
+ @args = args
18
+ end
19
+
20
+ def run
21
+ VersionChecker.new.check if check_version?
22
+
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
+ command_const = Command[command]
38
+ if command_const.abstract?
39
+ nil
40
+ else
41
+ command_const
42
+ end
43
+ rescue NameError
44
+ nil
45
+ end
46
+
47
+ def command_arguments
48
+ Array(@args[1..-1])
49
+ end
50
+
51
+ def command
52
+ command_name = @args.first
53
+ case command_name
54
+ when nil, "-h", "-?", "--help"
55
+ "help"
56
+ when "-v", "--version"
57
+ "version"
58
+ else
59
+ command_name
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def check_version?
66
+ if ARGV.first == "--no-check-version"
67
+ ARGV.shift
68
+ false
69
+ else
70
+ true
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,84 @@
1
+ module CC
2
+ module CLI
3
+ class ValidateConfig < Command
4
+ NO_CONFIG_MESSAGE = "No checked in config: nothing to validate.".freeze
5
+ TOO_MANY_CONFIG_MESSAGE = "Don't commit both .codeclimate.yml & .codeclimate.json: only the JSON will be used.".freeze
6
+ SHORT_HELP = "Validate your .codeclimate.yml or .codeclimate.json.".freeze
7
+ VALID_CONFIG_MESSAGE = "No errors or warnings found in %s.".freeze
8
+
9
+ def run
10
+ require_json_or_yaml
11
+ process_args
12
+
13
+ if any_issues?
14
+ display_issues
15
+ else
16
+ puts format(VALID_CONFIG_MESSAGE, validator.path)
17
+ end
18
+
19
+ exit 1 unless validator.valid?
20
+ end
21
+
22
+ private
23
+
24
+ attr_reader :config, :registry_path, :registry_prefix, :validator
25
+
26
+ def process_args
27
+ @registry_path = EngineRegistry::DEFAULT_MANIFEST_PATH
28
+ @registry_prefix = ""
29
+
30
+ # Undocumented; we only need these from Builder so we can validate
31
+ # engines/channels against our own registry and prefix.
32
+ while (arg = @args.shift)
33
+ case arg
34
+ when "--registry" then @registry_path = @args.shift
35
+ when "--registry-prefix" then @registry_prefix = @args.shift
36
+ end
37
+ end
38
+ end
39
+
40
+ def any_issues?
41
+ validator.errors.any? ||
42
+ validator.warnings.any?
43
+ end
44
+
45
+ def display_issues
46
+ validator.errors.each do |error|
47
+ puts "#{colorize("ERROR", :red)}: #{error}"
48
+ end
49
+
50
+ validator.warnings.each do |warning|
51
+ puts "#{colorize("WARNING", :yellow)}: #{warning}"
52
+ end
53
+ end
54
+
55
+ def require_json_or_yaml
56
+ if !filesystem.exist?(Config::YAMLAdapter::DEFAULT_PATH) && !filesystem.exist?(Config::JSONAdapter::DEFAULT_PATH)
57
+ puts NO_CONFIG_MESSAGE
58
+ exit 0
59
+ elsif filesystem.exist?(Config::YAMLAdapter::DEFAULT_PATH) && filesystem.exist?(Config::JSONAdapter::DEFAULT_PATH)
60
+ puts "#{colorize("WARNING", :yellow)}: #{TOO_MANY_CONFIG_MESSAGE}"
61
+ end
62
+ end
63
+
64
+ def validator
65
+ @validator =
66
+ if filesystem.exist?(Config::JSONAdapter::DEFAULT_PATH)
67
+ Config::Validation::JSON.new(
68
+ Config::JSONAdapter::DEFAULT_PATH,
69
+ engine_registry,
70
+ )
71
+ elsif filesystem.exist?(Config::YAMLAdapter::DEFAULT_PATH)
72
+ Config::Validation::YAML.new(
73
+ Config::YAMLAdapter::DEFAULT_PATH,
74
+ engine_registry,
75
+ )
76
+ end
77
+ end
78
+
79
+ def engine_registry
80
+ EngineRegistry.new(registry_path, registry_prefix)
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,16 @@
1
+ module CC
2
+ module CLI
3
+ class Version < Command
4
+ SHORT_HELP = "Display the CLI version.".freeze
5
+
6
+ def run
7
+ say version
8
+ end
9
+
10
+ def version
11
+ path = File.expand_path("../../../../VERSION", __FILE__)
12
+ @version ||= File.read(path)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,107 @@
1
+ require "cc/cli/global_config"
2
+ require "cc/cli/global_cache"
3
+
4
+ module CC
5
+ module CLI
6
+ class VersionChecker
7
+ include CC::CLI::Output
8
+
9
+ VERSION_CHECK_TIMEOUT = 60 * 60 # 1 Hour in seconds
10
+ DEFAULT_VERSIONS_URL = "https://versions.codeclimate.com".freeze
11
+
12
+ def check
13
+ return unless global_config.check_version? && version_check_is_due?
14
+
15
+ print_new_version_message if outdated?
16
+
17
+ global_config.save
18
+ rescue => error
19
+ CLI.logger.debug(error)
20
+ end
21
+
22
+ private
23
+
24
+ def version_check_is_due?
25
+ Time.now > global_cache.last_version_check + VERSION_CHECK_TIMEOUT
26
+ end
27
+
28
+ def outdated?
29
+ api_response["outdated"]
30
+ end
31
+
32
+ def latest_version
33
+ api_response["latest"]
34
+ end
35
+
36
+ def print_new_version_message
37
+ warn "A new version (v#{latest_version}) is available. Upgrade instructions are available at: https://github.com/codeclimate/codeclimate#packages"
38
+ end
39
+
40
+ def api_response
41
+ @api_response ||=
42
+ begin
43
+ cache! JSON.parse(api_response_body)
44
+ rescue JSON::ParserError => error
45
+ CLI.logger.debug(error)
46
+ {
47
+ "outdated" => false,
48
+ }
49
+ end
50
+ end
51
+
52
+ def api_response_body
53
+ if http_response.is_a? Net::HTTPSuccess
54
+ http_response.body
55
+ else
56
+ raise Net::HTTPFatalError.new("HTTP Error", http_response)
57
+ end
58
+ rescue Net::HTTPFatalError => error
59
+ CLI.logger.debug(error)
60
+ ""
61
+ end
62
+
63
+ def http_response
64
+ @http_response ||=
65
+ begin
66
+ uri = URI.parse(ENV.fetch("CODECLIMATE_VERSIONS_URL", DEFAULT_VERSIONS_URL))
67
+ uri.query = { version: version, uid: global_config.uuid }.to_query
68
+
69
+ http = Net::HTTP.new(uri.host, uri.port)
70
+ http.open_timeout = 5
71
+ http.read_timeout = 5
72
+ http.ssl_timeout = 5
73
+ http.use_ssl = uri.scheme == "https"
74
+
75
+ http.get(uri, "User-Agent" => user_agent)
76
+ end
77
+ end
78
+
79
+ def cache!(data)
80
+ global_cache.latest_version = data["latest"]
81
+ global_cache.outdated = data["outdated"] == true
82
+ global_cache.last_version_check = Time.now
83
+ data
84
+ end
85
+
86
+ def version
87
+ @version ||= Version.new.version
88
+ end
89
+
90
+ def user_agent
91
+ "Code Climate CLI #{version}"
92
+ end
93
+
94
+ def global_config
95
+ @global_config ||= GlobalConfig.new
96
+ end
97
+
98
+ def global_cache
99
+ @global_cache ||= GlobalCache.new
100
+ end
101
+
102
+ def terminal
103
+ @terminal ||= HighLine.new(nil, $stderr)
104
+ end
105
+ end
106
+ end
107
+ end
data/lib/cc/config.rb ADDED
@@ -0,0 +1,70 @@
1
+ require "cc/config/checks_adapter"
2
+ require "cc/config/default_adapter"
3
+ require "cc/config/engine"
4
+ require "cc/config/engine_set"
5
+ require "cc/config/json_adapter"
6
+ require "cc/config/prepare"
7
+ require "cc/config/validation/hash_validations"
8
+ require "cc/config/validation/check_validator"
9
+ require "cc/config/validation/engine_validator"
10
+ require "cc/config/validation/fetch_validator"
11
+ require "cc/config/validation/file_validator"
12
+ require "cc/config/validation/json"
13
+ require "cc/config/validation/prepare_validator"
14
+ require "cc/config/validation/yaml"
15
+ require "cc/config/yaml_adapter"
16
+
17
+ module CC
18
+ class Config
19
+ attr_reader \
20
+ :analysis_paths,
21
+ :engines,
22
+ :exclude_patterns,
23
+ :prepare
24
+
25
+ attr_writer \
26
+ :development
27
+
28
+ def self.load
29
+ config =
30
+ if File.exist?(JSONAdapter::DEFAULT_PATH)
31
+ JSONAdapter.load.config
32
+ elsif File.exist?(YAMLAdapter::DEFAULT_PATH)
33
+ YAMLAdapter.load.config
34
+ else
35
+ {}
36
+ end
37
+ config = DefaultAdapter.new(config).config
38
+ config = ChecksAdapter.new(config).config
39
+ build(config)
40
+ end
41
+
42
+ def self.build(data)
43
+ new(
44
+ engines: EngineSet.new(data.fetch("plugins", {})).engines,
45
+ exclude_patterns: data.fetch("exclude_patterns", DefaultAdapter::EXCLUDE_PATTERNS),
46
+ prepare: Prepare.from_data(data["prepare"]),
47
+ )
48
+ end
49
+
50
+ def initialize(analysis_paths: [], development: false, engines: [], exclude_patterns: [], prepare: Prepare.new)
51
+ @analysis_paths = analysis_paths
52
+ @development = development
53
+ @engines = engines
54
+ @exclude_patterns = exclude_patterns
55
+ @prepare = prepare
56
+ end
57
+
58
+ def merge(other)
59
+ Merge.new(self, other).run
60
+ end
61
+
62
+ def development?
63
+ @development
64
+ end
65
+
66
+ def disable_plugins!
67
+ @engines.delete_if(&:plugin?)
68
+ end
69
+ end
70
+ end