diffend-monitor 0.2.28 → 0.2.34

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.
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Diffend
4
+ # Module for all the components related to setting up the config
5
+ module Configs
6
+ # Class responsible for validating the config from .diffend.yml
7
+ module Validator
8
+ KNOWN_KEYS = {
9
+ project_id: [String],
10
+ shareable_id: [String],
11
+ shareable_key: [String],
12
+ build_path: [String],
13
+ env: [String],
14
+ command: [String],
15
+ ignore_errors?: [TrueClass, FalseClass],
16
+ development?: [TrueClass, FalseClass]
17
+ }.freeze
18
+
19
+ class << self
20
+ # @param config [Diffend::Config]
21
+ def call(config)
22
+ KNOWN_KEYS.each_key do |key|
23
+ if missing?(config, key)
24
+ missing_key_message(key)
25
+ .tap(&config.logger.method(:fatal))
26
+
27
+ raise Diffend::Errors::HandledException
28
+ end
29
+
30
+ if invalid?(config, key)
31
+ invalid_key_message(config, key)
32
+ .tap(&config.logger.method(:fatal))
33
+
34
+ raise Diffend::Errors::HandledException
35
+ end
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ # @param config [Diffend::Config]
42
+ # @param key [String]
43
+ #
44
+ # @return [Boolean] true if we are missing a key, false otherwise
45
+ def missing?(config, key)
46
+ value = config.public_send(key)
47
+
48
+ value.nil? || (value.respond_to?(:empty?) && value.empty?)
49
+ end
50
+
51
+ # @param config [Diffend::Config]
52
+ # @param key [String]
53
+ #
54
+ # @return [Boolean] true if we are missing a key, false otherwise
55
+ def invalid?(config, key)
56
+ !KNOWN_KEYS[key].include?(config.public_send(key).class)
57
+ end
58
+
59
+ # Missing key message
60
+ #
61
+ # @param key [String] missing key
62
+ #
63
+ # @return [String]
64
+ def missing_key_message(key)
65
+ <<~MSG
66
+ \nDiffend configuration is missing #{key} key.\n
67
+ MSG
68
+ end
69
+
70
+ # Invalid key message
71
+ #
72
+ # @param hash [Hash] config hash
73
+ # @param key [String] invalid key
74
+ #
75
+ # @return [String]
76
+ def invalid_key_message(hash, key)
77
+ <<~MSG
78
+ \nDiffend configuration value for #{key} is invalid.\n
79
+ It should be #{KNOWN_KEYS[key].join(' or ')} but is #{hash.public_send(key).class}.\n
80
+ MSG
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -5,10 +5,6 @@ module Diffend
5
5
  module Errors
6
6
  # Base error class from which all the errors should inherit
7
7
  BaseError = Class.new(StandardError)
8
- # Raised when we couldn't find a valid configuration file
9
- MissingConfigurationFile = Class.new(BaseError)
10
- # Raised when configuration file is empty
11
- EmptyConfigurationFile = Class.new(BaseError)
12
8
  # Raised when configuration file is malformed
13
9
  MalformedConfigurationFile = Class.new(BaseError)
14
10
  # Raised when project_id is missing in configuration file
@@ -23,5 +19,7 @@ module Diffend
23
19
  RequestServerError = Class.new(BaseError)
24
20
  # Raised when we had an exception that we know how to handle
25
21
  HandledException = Class.new(BaseError)
22
+ # Raised when we are unable to resolve dependencies
23
+ DependenciesResolveException = Class.new(BaseError)
26
24
  end
27
25
  end
@@ -1,28 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Diffend
4
- # Verifies voting verdicts for gems
5
- module Voting
4
+ # Executes a check for a given command
5
+ module Execute
6
6
  class << self
7
7
  # Build verdict
8
8
  #
9
- # @param command [String] either install or update
10
- # @param config [OpenStruct] diffend config
11
- # @param definition [Bundler::Definition] definition for your source
12
- def call(command, config, definition)
13
- Versions::Remote
14
- .call(command, config, definition)
15
- .tap { |response| build_message(command, config, response) }
9
+ # @param config [Diffend::Config]
10
+ def call(config)
11
+ Diffend::RequestVerdict
12
+ .call(config, build_definition(config.command))
13
+ .tap { |response| build_message(config, response) }
14
+ rescue Diffend::Errors::DependenciesResolveException
15
+ # We are unable to resolve dependencies, no message will be printed
16
16
  end
17
17
 
18
- # @param command [String] either install or update
19
- # @param config [OpenStruct] diffend config
18
+ # Build bundler definition
19
+ #
20
+ # @return [Bundler::Definition]
21
+ def build_definition(command)
22
+ Diffend::BuildBundlerDefinition.call(
23
+ command,
24
+ Bundler.default_gemfile,
25
+ Bundler.default_lockfile
26
+ )
27
+ end
28
+
29
+ # @param config [Diffend::Config]
20
30
  # @param response [Hash] response from diffend API
21
- def build_message(command, config, response)
31
+ def build_message(config, response)
22
32
  if response.key?('error')
23
- build_error(response)
33
+ build_error(config, response)
24
34
  elsif response.key?('action')
25
- build_verdict(command, config, response)
35
+ build_verdict(config, response)
26
36
  else
27
37
  Diffend::HandleErrors::Report.call(
28
38
  config: config,
@@ -36,25 +46,24 @@ module Diffend
36
46
  # @param response [Hash] response from diffend API
37
47
  def build_error(response)
38
48
  build_error_message(response)
39
- .tap(&Bundler.ui.method(:error))
49
+ .tap(&config.logger.method(:error))
40
50
 
41
51
  raise Diffend::Errors::HandledException
42
52
  end
43
53
 
44
- # @param command [String] either install or update
45
- # @param config [OpenStruct] diffend config
54
+ # @param config [Diffend::Config]
46
55
  # @param response [Hash] response from diffend API
47
- def build_verdict(command, config, response)
56
+ def build_verdict(config, response)
48
57
  case response['action']
49
58
  when 'allow'
50
- build_allow_message(command, response)
51
- .tap(&Bundler.ui.method(:confirm))
59
+ build_allow_message(config.command, response)
60
+ .tap(&config.logger.method(:info))
52
61
  when 'warn'
53
- build_warn_message(command, response)
54
- .tap(&Bundler.ui.method(:warn))
62
+ build_warn_message(config.command, response)
63
+ .tap(&config.logger.method(:warn))
55
64
  when 'deny'
56
- build_deny_message(command, response)
57
- .tap(&Bundler.ui.method(:error))
65
+ build_deny_message(config.command, response)
66
+ .tap(&config.logger.method(:error))
58
67
 
59
68
  exit 1
60
69
  else
@@ -77,7 +86,7 @@ module Diffend
77
86
  MSG
78
87
  end
79
88
 
80
- # @param command [String] either install or update
89
+ # @param command [String] command executed via bundler
81
90
  # @param response [Hash] response from diffend API
82
91
  #
83
92
  # @return [String]
@@ -89,7 +98,7 @@ module Diffend
89
98
  MSG
90
99
  end
91
100
 
92
- # @param command [String] either install or update
101
+ # @param command [String] command executed via bundler
93
102
  # @param response [Hash] response from diffend API
94
103
  #
95
104
  # @return [String]
@@ -101,7 +110,7 @@ module Diffend
101
110
  MSG
102
111
  end
103
112
 
104
- # @param command [String] either install or update
113
+ # @param command [String] command executed via bundler
105
114
  # @param response [Hash] response from diffend API
106
115
  #
107
116
  # @return [String]
@@ -114,7 +123,7 @@ module Diffend
114
123
  end
115
124
 
116
125
  # @param type [String] verdict type
117
- # @param command [String] either install or update
126
+ # @param command [String] command executed via bundler
118
127
  #
119
128
  # @return [String]
120
129
  def build_message_header(type, command)
@@ -7,10 +7,10 @@ module Diffend
7
7
  class << self
8
8
  # Execute request to Diffend
9
9
  #
10
+ # @param config [Diffend::Config]
11
+ # @param message [Symbol] message that we want to display
10
12
  # @param exception [Exception] expection that was raised
11
13
  # @param payload [Hash] with versions to check
12
- # @param config [OpenStruct] Diffend config
13
- # @param message [Symbol] message that we want to display
14
14
  # @param report [Boolean] if true we will report the issue to diffend
15
15
  # @param raise_exception [Boolean] if true we will raise an exception
16
16
  #
@@ -18,8 +18,11 @@ module Diffend
18
18
  def call(config:, message:, exception: nil, payload: {}, report: false, raise_exception: true)
19
19
  exception_payload = prepare_exception_payload(exception, payload)
20
20
 
21
- Bundler.ui.error(Diffend::HandleErrors::Messages::PAYLOAD_DUMP)
22
- Bundler.ui.error(Diffend::HandleErrors::Messages.const_get(message.to_s.upcase))
21
+ Diffend::HandleErrors::Messages::PAYLOAD_DUMP
22
+ .tap(&config.logger.method(:error))
23
+ Diffend::HandleErrors::Messages
24
+ .const_get(message.to_s.upcase)
25
+ .tap(&config.logger.method(:error))
23
26
 
24
27
  if report
25
28
  Diffend::Request.call(
@@ -30,14 +33,14 @@ module Diffend
30
33
  raise Diffend::Errors::HandledException if raise_exception
31
34
  end
32
35
 
33
- # @param config [OpenStruct] diffend config
36
+ # @param config [Diffend::Config]
34
37
  # @param payload [Hash]
35
38
  #
36
39
  # @return [Diffend::RequestObject]
37
40
  def build_request_object(config, payload)
38
41
  Diffend::RequestObject.new(
39
42
  config: config,
40
- url: errors_url(config.project_id),
43
+ url: config.errors_url,
41
44
  payload: payload,
42
45
  request_method: :post
43
46
  )
@@ -54,17 +57,6 @@ module Diffend
54
57
  .call(exception, payload)
55
58
  .tap(&Diffend::HandleErrors::DisplayToStdout.method(:call))
56
59
  end
57
-
58
- # Provides diffend errors endpoint url
59
- #
60
- # @param project_id [String] diffend project_id
61
- #
62
- # @return [String] diffend endpoint
63
- def errors_url(project_id)
64
- return ENV['DIFFEND_ERROR_URL'] if ENV.key?('DIFFEND_ERROR_URL')
65
-
66
- "https://my.diffend.io/api/projects/#{project_id}/errors"
67
- end
68
60
  end
69
61
  end
70
62
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Diffend
4
+ # Verify if we are running latest version of the plugin
5
+ module LatestVersion
6
+ class << self
7
+ # Verify if we are running latest version of the plugin
8
+ #
9
+ # @param config [Diffend::Config]
10
+ def call(config)
11
+ return if config.development?
12
+ return if installed_version == Diffend::VERSION
13
+
14
+ print_message(config, installed_version)
15
+
16
+ exit 2
17
+ end
18
+
19
+ private
20
+
21
+ # @return [String] installed plugin version
22
+ def installed_version
23
+ ::Bundler::Plugin
24
+ .index
25
+ .plugin_path('diffend')
26
+ .basename
27
+ .to_s
28
+ .split('-')
29
+ .last
30
+ end
31
+
32
+ # @param config [Diffend::Config]
33
+ # @param version [Hash] installed version
34
+ def print_message(config, version)
35
+ build_message(version)
36
+ .tap(&config.logger.method(:error))
37
+ end
38
+
39
+ # @param version [Hash] installed version
40
+ #
41
+ # @return [String]
42
+ def build_message(version)
43
+ <<~MSG
44
+ \nYou are running an outdated version (#{version}) of the plugin, which will lead to issues.
45
+ \nPlease upgrade to the latest one (#{Diffend::VERSION}) by executing "rm -rf .bundle/plugin".\n
46
+ MSG
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Diffend
4
+ # Module responsible for building local context
5
+ module LocalContext
6
+ class << self
7
+ # Build diffend, host, packages, and platform specific information
8
+ #
9
+ # @param config [Diffend::Config]
10
+ # @param definition [Bundler::Definition] definition for your source
11
+ #
12
+ # @return [Hash] payload for diffend endpoint
13
+ def call(config, definition)
14
+ {
15
+ 'diffend' => Diffend.call(config),
16
+ 'host' => Host.call,
17
+ 'packages' => Packages.call(config.command, definition),
18
+ 'platform' => Platform.call
19
+ }.freeze
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Diffend
4
+ # Module responsible for building local context
5
+ module LocalContext
6
+ # Module responsible for building diffend information from local context
7
+ module Diffend
8
+ # API version
9
+ API_VERSION = '0.1'
10
+ # Platform type ruby
11
+ PLATFORM_TYPE = 0
12
+
13
+ private_constant :API_VERSION, :PLATFORM_TYPE
14
+
15
+ class << self
16
+ # Build diffend information
17
+ #
18
+ # @param config [Diffend::Config]
19
+ #
20
+ # @return [Hash]
21
+ def call(config)
22
+ {
23
+ 'api_version' => API_VERSION,
24
+ 'environment' => config.env,
25
+ 'project_id' => config.project_id,
26
+ 'type' => PLATFORM_TYPE,
27
+ 'version' => ::Diffend::VERSION
28
+ }.freeze
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'etc'
4
+
5
+ module Diffend
6
+ # Module responsible for building local context
7
+ module LocalContext
8
+ # Module responsible for building host information from local context
9
+ module Host
10
+ class << self
11
+ # Build host information
12
+ #
13
+ # @return [Hash]
14
+ def call
15
+ uname = Etc.uname
16
+
17
+ {
18
+ 'command' => command,
19
+ 'ips' => ips,
20
+ 'name' => uname[:nodename],
21
+ 'system' => {
22
+ 'machine' => uname[:machine],
23
+ 'name' => uname[:sysname],
24
+ 'release' => uname[:release],
25
+ 'version' => uname[:version]
26
+ },
27
+ 'tags' => tags,
28
+ 'user' => Etc.getpwuid(Process.uid).name,
29
+ 'pid' => Process.pid
30
+ }.freeze
31
+ end
32
+
33
+ private
34
+
35
+ # Build host command information
36
+ #
37
+ # @return [Hash]
38
+ def command
39
+ if File.exist?($PROGRAM_NAME)
40
+ if defined?(JRUBY_VERSION)
41
+ name = $PROGRAM_NAME.split('/').last.strip
42
+ command = "#{name} #{ARGV.join(' ')}"
43
+ else
44
+ array = `ps -p #{Process.pid} -o command=`.strip.split(' ')
45
+ array.shift if array.first.end_with?('bin/ruby')
46
+ name = array.shift.split('/').last.strip
47
+ command = "#{name} #{array.join(' ')}"
48
+ end
49
+
50
+ { 'name' => command, 'title' => '' }
51
+ else
52
+ { 'name' => ARGV.join(' '), 'title' => $PROGRAM_NAME }
53
+ end
54
+ end
55
+
56
+ # Build host ips, except localhost and loopback
57
+ #
58
+ # @return [Array<String>]
59
+ def ips
60
+ Socket.ip_address_list.map do |ip|
61
+ next if ip.ipv4_loopback? || ip.ipv6_loopback? || ip.ipv6_linklocal?
62
+
63
+ ip.ip_address
64
+ end.compact
65
+ end
66
+
67
+ # Build host tags
68
+ #
69
+ # @return [Array]
70
+ def tags
71
+ tags = []
72
+
73
+ if ENV.key?('GITHUB_ACTIONS')
74
+ tags << 'ci'
75
+ tags << 'ci-github'
76
+ end
77
+
78
+ if ENV.key?('CIRCLECI')
79
+ tags << 'ci'
80
+ tags << 'ci-circle'
81
+ end
82
+
83
+ tags
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end