diffend 0.2.23 → 0.2.28

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5ce266f8f72de49360adc1e6e1f79c8bf5fa08727ffc990292877c015e1040ee
4
- data.tar.gz: 1a71a4a519b1f2afb9bc993726c045b4db5b87833459ba8f7192c2a2f4232aa6
3
+ metadata.gz: 0c100adca589f5e4e22488ecc8d12a865b2ec8a5bb6be4bf15f3b4bf5d5ad089
4
+ data.tar.gz: 8e5820badb850ee24606874e8de80a8e19114a08276f9fca3933a54e4fb825bc
5
5
  SHA512:
6
- metadata.gz: '08dd6da1d3984200d9ac07fd9fd1f9a0adf6b7746f86a77ab560b77b356dc6fad819513adea6fe2d714b1f06ed8cf5441d796681fd507b64247a2db3560d3138'
7
- data.tar.gz: 2155bbba6da089606b38d36fcec4259054f6cac053bf56eefb303d6d3aa223ba4253ca771249a2543696c636e8c509aa75ceb3ab50f055dd18a2ba9715e5cb9f
6
+ metadata.gz: 70b2798f074676511abc75974db24ee116dcbf9fc87983a4cfc6d9e69246c12b0970c376ced03e08a6fb0a9ba09fa9cd11a3da5d728715c6ec676030bd7ebccd
7
+ data.tar.gz: fd130a1283b65d6487bab7323eb2a7d7c9d3db6cea7c777e4c7a023f77e9b0d0ee4078cd38c9228fe18b1555ee9e9ec9efd0fa1033a7c8ed5e19859cb8e11970
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -34,6 +34,8 @@ jobs:
34
34
  run: |
35
35
  gem install bundler --no-document
36
36
  - name: Bundle install
37
+ env:
38
+ DIFFEND_DEVELOPMENT: true
37
39
  run: |
38
40
  bundle config path vendor/bundle
39
41
  bundle install --jobs 4 --retry 3
@@ -1,6 +1,32 @@
1
1
  # Changelog
2
2
 
3
3
  ## [Unreleased][master]
4
+
5
+ ## [0.2.28] (2020-09-19)
6
+ - start `Diffend::Monitor` only if not in development or test ([#44](https://github.com/diffend-io/diffend-ruby/pull/44))
7
+ - better host command expose ([#45](https://github.com/diffend-io/diffend-ruby/pull/45))
8
+
9
+ ## [0.2.27] (2020-09-16)
10
+ - introduce `Diffend::RequestObject` ([#40](https://github.com/diffend-io/diffend-ruby/pull/40))
11
+ - clean up error codes and introduce `DIFFEND_INGORE_EXCEPTIONS` ([#41](https://github.com/diffend-io/diffend-ruby/pull/41))
12
+ - introduce `Diffend::Monitor` and `Diffend::Track` ([#15](https://github.com/diffend-io/diffend-ruby/pull/15))
13
+
14
+ ## [0.2.26] (2020-09-10)
15
+ - introduce `DIFFEND_DEVELOPMENT` environment variable ([#36](https://github.com/diffend-io/diffend-ruby/pull/36))
16
+ - adjust message for allow verdict ([#37](https://github.com/diffend-io/diffend-ruby/pull/37))
17
+ - do not run the plugin when it is not enabled ([#38](https://github.com/diffend-io/diffend-ruby/pull/38))
18
+
19
+ ## [0.2.25] (2020-09-09)
20
+ - add support for a warn verdict ([#34](https://github.com/diffend-io/diffend-ruby/pull/34))
21
+
22
+ ## [0.2.24] (2020-09-08)
23
+ - better error handling of response ([#28](https://github.com/diffend-io/diffend-ruby/pull/28))
24
+ - fix jruby specs ([#29](https://github.com/diffend-io/diffend-ruby/pull/29))
25
+ - handle request server errors ([#30](https://github.com/diffend-io/diffend-ruby/pull/30))
26
+ - better detection of gem source ([#31](https://github.com/diffend-io/diffend-ruby/pull/31))
27
+ - detect if we are running outdated version of the plugin ([#32](https://github.com/diffend-io/diffend-ruby/pull/32))
28
+
29
+ ## [0.2.23] (2020-09-06)
4
30
  - fix how we build gem platform ([#26](https://github.com/diffend-io/diffend-ruby/pull/26))
5
31
  - test against jruby, ruby-2.5 and ruby-2.6 ([#25](https://github.com/diffend-io/diffend-ruby/pull/25))
6
32
 
@@ -38,7 +64,13 @@
38
64
 
39
65
  - initial release
40
66
 
41
- [master]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.22...HEAD
67
+ [master]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.28...HEAD
68
+ [0.2.28]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.27...v0.2.28
69
+ [0.2.27]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.26...v0.2.27
70
+ [0.2.26]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.25...v0.2.26
71
+ [0.2.25]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.24...v0.2.25
72
+ [0.2.24]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.23...v0.2.24
73
+ [0.2.23]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.22...v0.2.23
42
74
  [0.2.22]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.21...v0.2.22
43
75
  [0.2.21]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.20...v0.2.21
44
76
  [0.2.20]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.19...v0.2.20
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- diffend (0.2.23)
4
+ diffend (0.2.28)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -15,8 +15,10 @@
15
15
  handle_errors/build_exception_payload
16
16
  handle_errors/display_to_stdout
17
17
  handle_errors/report
18
+ request_object
18
19
  request
19
20
  voting
21
+ track
20
22
  ].each { |file| require "diffend/#{file}" }
21
23
 
22
24
  %w[
@@ -27,7 +29,7 @@
27
29
  # Diffend main namespace
28
30
  module Diffend
29
31
  # Current plugin version
30
- VERSION = '0.2.23'
32
+ VERSION = '0.2.28'
31
33
  # Diffend homepage
32
34
  HOMEPAGE = 'https://diffend.io'
33
35
 
@@ -41,23 +43,82 @@ module Diffend
41
43
 
42
44
  # Execute diffend plugin
43
45
  def execute
46
+ return unless enabled?
47
+
48
+ verify_version
49
+
44
50
  config = fetch_config
45
51
 
46
52
  Diffend::Voting.call(
47
53
  command,
54
+ config,
48
55
  Diffend::BuildBundlerDefinition.call(
49
56
  command,
50
57
  Bundler.default_gemfile,
51
58
  Bundler.default_lockfile
52
59
  )
53
60
  )
61
+ rescue Diffend::Errors::HandledException
62
+ return if ENV['DIFFEND_IGNORE_ERRORS'] == 'true'
63
+
64
+ exit 255
54
65
  rescue StandardError => e
55
66
  Diffend::HandleErrors::Report.call(
56
67
  exception: e,
57
68
  config: config,
58
69
  message: :unhandled_exception,
59
- report: true
70
+ report: true,
71
+ raise_exception: false
60
72
  )
73
+
74
+ return if ENV['DIFFEND_IGNORE_ERRORS'] == 'true'
75
+
76
+ exit 255
77
+ end
78
+
79
+ def verify_version
80
+ return if ENV['DIFFEND_DEVELOPMENT'] == 'true'
81
+ return if installed_version == VERSION
82
+
83
+ build_outdated_version_message(installed_version)
84
+ .tap(&Bundler.ui.method(:error))
85
+
86
+ exit 2
87
+ end
88
+
89
+ # @return [String] installed plugin version
90
+ def installed_version
91
+ Bundler::Plugin
92
+ .index
93
+ .plugin_path('diffend')
94
+ .basename
95
+ .to_s
96
+ .split('-')
97
+ .last
98
+ end
99
+
100
+ # Checks if plugin is enabled
101
+ #
102
+ # @return [Boolean] true if enabled, false otherwise
103
+ def enabled?
104
+ Bundler
105
+ .default_gemfile
106
+ .read
107
+ .split("\n")
108
+ .reject(&:empty?)
109
+ .map(&:strip)
110
+ .select { |line| line.start_with?('plugin') }
111
+ .any? { |line| line.include?('diffend') }
112
+ end
113
+
114
+ # @param version [Hash] installed version
115
+ #
116
+ # @return [String]
117
+ def build_outdated_version_message(version)
118
+ <<~MSG
119
+ \nYou are running an outdated version (#{version}) of the plugin, which will lead to issues.
120
+ \nPlease upgrade to the latest one (#{VERSION}) by executing "rm -rf .bundle/plugin".\n
121
+ MSG
61
122
  end
62
123
 
63
124
  # Command that was run with bundle
@@ -3,9 +3,11 @@
3
3
  module Diffend
4
4
  # Modules grouping supported bundler commands
5
5
  module Commands
6
- # Install bundler command
6
+ # Bundler install command
7
7
  INSTALL = 'install'
8
- # Update bundler command
8
+ # Bundler update command
9
9
  UPDATE = 'update'
10
+ # Bundler exec command
11
+ EXEC = 'exec'
10
12
  end
11
13
  end
@@ -27,16 +27,20 @@ module Diffend
27
27
  build(build_path)
28
28
  rescue Errors::MissingConfigurationFile
29
29
  Bundler.ui.error(build_missing_error_message(build_path))
30
- exit 1
30
+
31
+ raise Diffend::Errors::HandledException
31
32
  rescue Errors::EmptyConfigurationFile
32
33
  Bundler.ui.error(build_empty_error_message(build_path))
33
- exit 1
34
+
35
+ raise Diffend::Errors::HandledException
34
36
  rescue Errors::MalformedConfigurationFile
35
37
  Bundler.ui.error(build_malformed_error_message(build_path))
36
- exit 1
38
+
39
+ raise Diffend::Errors::HandledException
37
40
  rescue *MISSING_KEY_ERRORS => e
38
41
  Bundler.ui.error(build_missing_key_error_message(e))
39
- exit 1
42
+
43
+ raise Diffend::Errors::HandledException
40
44
  end
41
45
 
42
46
  private
@@ -19,9 +19,9 @@ module Diffend
19
19
  ShareableKeyMissingInConfigurationFile = Class.new(BaseError)
20
20
  # Raised when build_path is missing in configuration file
21
21
  BuildPathMissingInConfigurationFile = Class.new(BaseError)
22
- # When unsupported response returned from the endpoint
23
- UnsupportedResponse = Class.new(BaseError)
24
- # When unsupported action returned from the endpoint
25
- UnsupportedAction = Class.new(BaseError)
22
+ # Raised when server-side error occurs
23
+ RequestServerError = Class.new(BaseError)
24
+ # Raised when we had an exception that we know how to handle
25
+ HandledException = Class.new(BaseError)
26
26
  end
27
27
  end
@@ -9,7 +9,7 @@ module Diffend
9
9
  class << self
10
10
  # Build exception payload
11
11
  #
12
- # @param exception [Exception] expection that was raised
12
+ # @param exception [Exception, NilClass] expection that was raised
13
13
  # @param payload [Hash] with versions to check
14
14
  #
15
15
  # @return [Hash]
@@ -18,9 +18,9 @@ module Diffend
18
18
  request_id: SecureRandom.uuid,
19
19
  payload: payload,
20
20
  exception: {
21
- class: exception.class,
22
- message: exception.message,
23
- backtrace: exception.backtrace
21
+ class: exception&.class,
22
+ message: exception&.message,
23
+ backtrace: exception&.backtrace
24
24
  }
25
25
  }.freeze
26
26
  end
@@ -9,6 +9,16 @@ module Diffend
9
9
  This is a bug, don't hesitate.\n
10
10
  Create an issue at https://github.com/diffend-io/diffend-ruby/issues\n
11
11
  MSG
12
+ UNSUPPORTED_RESPONSE = <<~MSG
13
+ \nAPI returned an unsupported response. We recorded this incident in our system and will review it.\n
14
+ This is a bug, don't hesitate.\n
15
+ Create an issue at https://github.com/diffend-io/diffend-ruby/issues\n
16
+ MSG
17
+ UNSUPPORTED_VERDICT = <<~MSG
18
+ \nAPI returned an unsupported verdict. We recorded this incident in our system and will review it.\n
19
+ This is a bug, don't hesitate.\n
20
+ Create an issue at https://github.com/diffend-io/diffend-ruby/issues\n
21
+ MSG
12
22
  REQUEST_ERROR = <<~MSG
13
23
  \nWe were unable to process your request at this time. We recorded this incident in our system and will review it.\n
14
24
  If you think that this is a bug, don't hesitate.\n
@@ -12,9 +12,10 @@ module Diffend
12
12
  # @param config [OpenStruct] Diffend config
13
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
+ # @param raise_exception [Boolean] if true we will raise an exception
15
16
  #
16
17
  # @return [Net::HTTPResponse] response from Diffend
17
- def call(exception:, payload: {}, config:, message:, report: false)
18
+ def call(config:, message:, exception: nil, payload: {}, report: false, raise_exception: true)
18
19
  exception_payload = prepare_exception_payload(exception, payload)
19
20
 
20
21
  Bundler.ui.error(Diffend::HandleErrors::Messages::PAYLOAD_DUMP)
@@ -22,13 +23,24 @@ module Diffend
22
23
 
23
24
  if report
24
25
  Diffend::Request.call(
25
- config,
26
- errors_url(config.project_id),
27
- exception_payload
26
+ build_request_object(config, exception_payload)
28
27
  )
29
28
  end
30
29
 
31
- exit 1
30
+ raise Diffend::Errors::HandledException if raise_exception
31
+ end
32
+
33
+ # @param config [OpenStruct] diffend config
34
+ # @param payload [Hash]
35
+ #
36
+ # @return [Diffend::RequestObject]
37
+ def build_request_object(config, payload)
38
+ Diffend::RequestObject.new(
39
+ config: config,
40
+ url: errors_url(config.project_id),
41
+ payload: payload,
42
+ request_method: :post
43
+ )
32
44
  end
33
45
 
34
46
  # Prepare exception payload and display it to stdout
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ %w[
4
+ build_bundler_definition
5
+ errors
6
+ config/fetcher
7
+ config/file_finder
8
+ config/validator
9
+ commands
10
+ handle_errors/messages
11
+ handle_errors/build_exception_payload
12
+ handle_errors/display_to_stdout
13
+ handle_errors/report
14
+ request_object
15
+ request
16
+ voting
17
+ track
18
+ ].each { |file| require "diffend/#{file}" }
19
+
20
+ %w[
21
+ versions/local
22
+ versions/remote
23
+ ].each { |file| require "diffend/voting/#{file}" }
24
+
25
+ unless %w[development test].include?(ENV['DIFFEND_ENV'])
26
+ Thread.new do
27
+ track = Diffend::Track.new
28
+ track.start
29
+ end
30
+ end
@@ -23,6 +23,15 @@ module Diffend
23
23
  Net::OpenTimeout,
24
24
  Net::ReadTimeout
25
25
  ].freeze
26
+ # Message displayed when server issue occured and we will retry
27
+ SERVER_ERROR_MESSAGE = 'We experienced a server-side issue, retrying...'
28
+ # List of server issues
29
+ #
30
+ # 500 - Internal Server Error
31
+ # 502 - Bad Gateway
32
+ # 503 - Service Unavailable
33
+ # 504 - Gateway Timeout
34
+ SERVER_ERRORS = [500, 502, 503, 504].freeze
26
35
  # Number of retries
27
36
  RETRIES = 3
28
37
  # Request headers
@@ -33,17 +42,39 @@ module Diffend
33
42
  class << self
34
43
  # Execute request
35
44
  #
36
- # @param config [OpenStruct] diffend config
37
- # @param endpoint_url [String]
38
- # @param payload [Hash]
45
+ # @param request_object [Diffend::RequestObject]
39
46
  #
40
47
  # @return [Net::HTTPResponse] response from Diffend
41
- def call(config, endpoint_url, payload)
48
+ def call(request_object)
42
49
  retry_count ||= -1
43
50
 
44
- build_http(endpoint_url) do |http, uri|
45
- http.request(build_request(uri, config, payload))
51
+ build_http(request_object.url) do |http, uri|
52
+ response = http.request(
53
+ build_request(
54
+ uri,
55
+ request_object.request_method,
56
+ request_object.config,
57
+ request_object.payload
58
+ )
59
+ )
60
+
61
+ if SERVER_ERRORS.include?(response.code.to_i)
62
+ raise Diffend::Errors::RequestServerError, response.code.to_i
63
+ end
64
+
65
+ response
46
66
  end
67
+ rescue Diffend::Errors::RequestServerError => e
68
+ retry_count += 1
69
+
70
+ retry if handle_retry(SERVER_ERROR_MESSAGE, retry_count)
71
+
72
+ Diffend::HandleErrors::Report.call(
73
+ exception: e,
74
+ payload: request_object.payload,
75
+ config: request_object.config,
76
+ message: :request_error
77
+ )
47
78
  rescue *CONNECTION_EXCEPTIONS => e
48
79
  retry_count += 1
49
80
 
@@ -51,8 +82,8 @@ module Diffend
51
82
 
52
83
  Diffend::HandleErrors::Report.call(
53
84
  exception: e,
54
- payload: payload,
55
- config: config,
85
+ payload: request_object.payload,
86
+ config: request_object.config,
56
87
  message: :request_error
57
88
  )
58
89
  rescue *TIMEOUT_EXCEPTIONS => e
@@ -62,8 +93,8 @@ module Diffend
62
93
 
63
94
  Diffend::HandleErrors::Report.call(
64
95
  exception: e,
65
- payload: payload,
66
- config: config,
96
+ payload: request_object.payload,
97
+ config: request_object.config,
67
98
  message: :request_error
68
99
  )
69
100
  end
@@ -100,17 +131,32 @@ module Diffend
100
131
  # Build http post request and assigns headers and payload
101
132
  #
102
133
  # @param uri [URI::HTTPS]
134
+ # @param request_method [Symbol]
103
135
  # @param config [OpenStruct] Diffend config
104
136
  # @param payload [Hash] with versions to check
105
137
  #
106
- # @return [Net::HTTP::Post]
107
- def build_request(uri, config, payload)
108
- Net::HTTP::Post
138
+ # @return [Net::HTTP::Post, Net::HTTP::Put]
139
+ def build_request(uri, request_method, config, payload)
140
+ pick_request_method(request_method)
109
141
  .new(uri.request_uri, HEADERS)
110
142
  .tap { |request| assign_auth(request, config) }
111
143
  .tap { |request| assign_payload(request, payload) }
112
144
  end
113
145
 
146
+ # Pick request method
147
+ #
148
+ # @param request_method [Symbol]
149
+ #
150
+ # @return [Net::HTTP::Post, Net::HTTP::Put]
151
+ def pick_request_method(request_method)
152
+ case request_method
153
+ when :post
154
+ Net::HTTP::Post
155
+ when :put
156
+ Net::HTTP::Put
157
+ end
158
+ end
159
+
114
160
  # Assigns basic authorization if provided in the config
115
161
  #
116
162
  # @param request [Net::HTTP::Post] prepared http post
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Diffend
4
+ # Class responsible for preparing diffend request object
5
+ RequestObject = Struct.new(:config, :url, :payload, :request_method, keyword_init: true)
6
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Diffend
4
+ # Track what is run in production
5
+ class Track
6
+ # Time that we want to wait between track requests
7
+ TRACK_SLEEP = 15
8
+ # Time that we want to wait before we retry
9
+ RETRY_SLEEP = 15
10
+
11
+ # Initialize tracking
12
+ def initialize
13
+ @mutex = Mutex.new
14
+ @config = fetch_config
15
+ end
16
+
17
+ # Start tracking
18
+ def start
19
+ response = exec_request
20
+
21
+ perform(response['id'])
22
+ rescue Diffend::Errors::HandledException
23
+ sleep(RETRY_SLEEP)
24
+
25
+ retry
26
+ rescue StandardError => e
27
+ Diffend::HandleErrors::Report.call(
28
+ exception: e,
29
+ config: @config,
30
+ message: :unhandled_exception,
31
+ report: true,
32
+ raise_exception: false
33
+ )
34
+
35
+ sleep(RETRY_SLEEP)
36
+
37
+ retry
38
+ end
39
+
40
+ # @param request_id [String]
41
+ def perform(request_id)
42
+ loop do
43
+ @mutex.synchronize do
44
+ track_request(request_id)
45
+ end
46
+
47
+ sleep(TRACK_SLEEP)
48
+ end
49
+ end
50
+
51
+ # Perform an exec request
52
+ def exec_request
53
+ Diffend::Voting.call(
54
+ Diffend::Commands::EXEC,
55
+ @config,
56
+ Diffend::BuildBundlerDefinition.call(
57
+ Diffend::Commands::EXEC,
58
+ Bundler.default_gemfile,
59
+ Bundler.default_lockfile
60
+ )
61
+ )
62
+ end
63
+
64
+ # Perform a track request
65
+ #
66
+ # @param request_id [String]
67
+ def track_request(request_id)
68
+ Diffend::Request.call(
69
+ build_request_object(request_id)
70
+ )
71
+ end
72
+
73
+ # @param request_id [String]
74
+ #
75
+ # @return [Diffend::RequestObject]
76
+ def build_request_object(request_id)
77
+ Diffend::RequestObject.new(
78
+ config: @config,
79
+ url: track_url(@config.project_id, request_id),
80
+ payload: { id: request_id }.freeze,
81
+ request_method: :put
82
+ ).freeze
83
+ end
84
+
85
+ # Fetch diffend config file
86
+ #
87
+ # @return [OpenStruct, nil] configuration object
88
+ #
89
+ # @raise [Errors::MissingConfigurationFile] when no config file
90
+ def fetch_config
91
+ Config::Fetcher.call(
92
+ File.expand_path('..', Bundler.bin_path)
93
+ )
94
+ end
95
+
96
+ # @param project_id [String] diffend project_id
97
+ # @param request_id [String]
98
+ #
99
+ # @return [String]
100
+ def track_url(project_id, request_id)
101
+ "https://my.diffend.io/api/projects/#{project_id}/bundle/#{request_id}/track"
102
+ end
103
+ end
104
+ end
@@ -7,45 +7,69 @@ module Diffend
7
7
  # Build verdict
8
8
  #
9
9
  # @param command [String] either install or update
10
+ # @param config [OpenStruct] diffend config
10
11
  # @param definition [Bundler::Definition] definition for your source
11
- def call(command, definition)
12
+ def call(command, config, definition)
12
13
  Versions::Remote
13
- .call(command, definition)
14
- .tap { |response| build_message(command, response) }
14
+ .call(command, config, definition)
15
+ .tap { |response| build_message(command, config, response) }
15
16
  end
16
17
 
17
- def build_message(command, response)
18
+ # @param command [String] either install or update
19
+ # @param config [OpenStruct] diffend config
20
+ # @param response [Hash] response from diffend API
21
+ def build_message(command, config, response)
18
22
  if response.key?('error')
19
23
  build_error(response)
20
24
  elsif response.key?('action')
21
- build_verdict(command, response)
25
+ build_verdict(command, config, response)
22
26
  else
23
- raise UnsupportedResponse, response['action']
27
+ Diffend::HandleErrors::Report.call(
28
+ config: config,
29
+ message: :unsupported_response,
30
+ payload: response,
31
+ report: true
32
+ )
24
33
  end
25
34
  end
26
35
 
36
+ # @param response [Hash] response from diffend API
27
37
  def build_error(response)
28
38
  build_error_message(response)
29
39
  .tap(&Bundler.ui.method(:error))
30
40
 
31
- exit 1
41
+ raise Diffend::Errors::HandledException
32
42
  end
33
43
 
34
- def build_verdict(command, response)
44
+ # @param command [String] either install or update
45
+ # @param config [OpenStruct] diffend config
46
+ # @param response [Hash] response from diffend API
47
+ def build_verdict(command, config, response)
35
48
  case response['action']
36
49
  when 'allow'
37
50
  build_allow_message(command, response)
38
51
  .tap(&Bundler.ui.method(:confirm))
52
+ when 'warn'
53
+ build_warn_message(command, response)
54
+ .tap(&Bundler.ui.method(:warn))
39
55
  when 'deny'
40
56
  build_deny_message(command, response)
41
57
  .tap(&Bundler.ui.method(:error))
42
58
 
43
59
  exit 1
44
60
  else
45
- raise UnsupportedAction, response['action']
61
+ Diffend::HandleErrors::Report.call(
62
+ config: config,
63
+ message: :unsupported_verdict,
64
+ payload: response,
65
+ report: true
66
+ )
46
67
  end
47
68
  end
48
69
 
70
+ # @param response [Hash] response from diffend API
71
+ #
72
+ # @return [String]
49
73
  def build_error_message(response)
50
74
  <<~MSG
51
75
  \nDiffend returned an error for your request.\n
@@ -53,21 +77,56 @@ module Diffend
53
77
  MSG
54
78
  end
55
79
 
80
+ # @param command [String] either install or update
81
+ # @param response [Hash] response from diffend API
82
+ #
83
+ # @return [String]
56
84
  def build_allow_message(command, response)
57
85
  <<~MSG
58
- \nDiffend reported an allow verdict for #{command} command for this project.\n
59
- All of our #{response['allows_count'] + response['denies_count']} checks succeeded.\n
86
+ #{build_message_header('an allow', command)}
87
+ #{build_message_info(response)}\n
60
88
  #{response['review_url']}\n
61
89
  MSG
62
90
  end
63
91
 
92
+ # @param command [String] either install or update
93
+ # @param response [Hash] response from diffend API
94
+ #
95
+ # @return [String]
96
+ def build_warn_message(command, response)
97
+ <<~MSG
98
+ #{build_message_header('a warn', command)}
99
+ #{build_message_info(response)} Please go to the url below and review the issues.\n
100
+ #{response['review_url']}\n
101
+ MSG
102
+ end
103
+
104
+ # @param command [String] either install or update
105
+ # @param response [Hash] response from diffend API
106
+ #
107
+ # @return [String]
64
108
  def build_deny_message(command, response)
65
109
  <<~MSG
66
- \nDiffend reported a deny verdict for #{command} command for this project.\n
67
- #{response['denies_count']} out of our #{response['allows_count'] + response['denies_count']} checks failed. Please go to the url below and review the issues.\n
110
+ #{build_message_header('a deny', command)}
111
+ #{build_message_info(response)} Please go to the url below and review the issues.\n
68
112
  #{response['review_url']}\n
69
113
  MSG
70
114
  end
115
+
116
+ # @param type [String] verdict type
117
+ # @param command [String] either install or update
118
+ #
119
+ # @return [String]
120
+ def build_message_header(type, command)
121
+ "\nDiffend reported #{type} verdict for #{command} command for this project."
122
+ end
123
+
124
+ # @param response [Hash] response from diffend API
125
+ #
126
+ # @return [String]
127
+ def build_message_info(response)
128
+ "\nQuality score: #{response['quality_score']}, allows: #{response['allows_count']}, warnings: #{response['warns_count']}, denies: #{response['denies_count']}."
129
+ end
71
130
  end
72
131
  end
73
132
  end
@@ -40,7 +40,7 @@ module Diffend
40
40
  instance = new(definition)
41
41
 
42
42
  case command
43
- when Commands::INSTALL then instance.build_install
43
+ when Commands::INSTALL, Commands::EXEC then instance.build_install
44
44
  when Commands::UPDATE then instance.build_update
45
45
  else
46
46
  raise ArgumentError, "invalid command: #{command}"
@@ -54,7 +54,6 @@ module Diffend
54
54
  def initialize(definition)
55
55
  @definition = definition
56
56
  @direct_dependencies = Hash[definition.dependencies.map { |val| [val.name, val] }]
57
- @main_source = definition.send(:sources).rubygems_sources.last
58
57
  # Support case without Gemfile.lock
59
58
  @locked_specs = @definition.locked_gems ? @definition.locked_gems.specs : []
60
59
  end
@@ -150,17 +149,17 @@ module Diffend
150
149
  #
151
150
  # @return [String]
152
151
  def build_spec_platform(spec, locked_spec)
153
- spec.platform || locked_spec&.platform || build_spec_generic_platform(spec)
152
+ parse_platform(
153
+ spec.platform || locked_spec&.platform || spec.send(:generic_local_platform)
154
+ )
154
155
  end
155
156
 
156
- # Build gem generic platform
157
+ # Parse gem platform
157
158
  #
158
- # @param spec [Bundler::StubSpecification, Bundler::LazySpecification, Gem::Specification]
159
+ # @param platform [String, Gem::Platform]
159
160
  #
160
161
  # @return [String]
161
- def build_spec_generic_platform(spec)
162
- platform = spec.send(:generic_local_platform)
163
-
162
+ def parse_platform(platform)
164
163
  case platform
165
164
  when String then platform
166
165
  when Gem::Platform then platform.os
@@ -176,7 +175,7 @@ module Diffend
176
175
  case source
177
176
  when Bundler::Source::Metadata
178
177
  GEM_SOURCES_TYPES[:local]
179
- when Bundler::Source::Rubygems
178
+ when Bundler::Source::Rubygems, Bundler::Source::Rubygems::Remote
180
179
  GEM_SOURCES_TYPES[:gemfile_source]
181
180
  when Bundler::Source::Git
182
181
  GEM_SOURCES_TYPES[:gemfile_git]
@@ -207,10 +206,20 @@ module Diffend
207
206
  #
208
207
  # @return [Bundler::Source] gem source type
209
208
  def source_for_spec(spec)
210
- if @direct_dependencies.key?(spec.name)
211
- @direct_dependencies[spec.name].source || @main_source
212
- else
209
+ return spec.remote if spec.remote
210
+
211
+ case spec.source
212
+ when Bundler::Source::Rubygems
213
+ spec
214
+ .source
215
+ .send(:remote_specs)
216
+ .search(Bundler::Dependency.new(spec.name, spec.version))
217
+ .last
218
+ .remote
219
+ when Bundler::Source::Metadata, Bundler::Source::Git, Bundler::Source::Path
213
220
  spec.source
221
+ else
222
+ raise ArgumentError, "unknown source #{spec.source.class}"
214
223
  end
215
224
  end
216
225
 
@@ -223,10 +232,10 @@ module Diffend
223
232
  case source
224
233
  when Bundler::Source::Metadata
225
234
  ''
226
- when Bundler::Source::Rubygems
227
- source_name(source.remotes.first)
235
+ when Bundler::Source::Rubygems::Remote
236
+ source_name(source.anonymized_uri)
228
237
  when Bundler::Source::Git
229
- source.uri
238
+ source.instance_variable_get(:@safe_uri)
230
239
  when Bundler::Source::Path
231
240
  source.path
232
241
  else
@@ -234,11 +243,11 @@ module Diffend
234
243
  end
235
244
  end
236
245
 
237
- # @param name [Bundler::URI]
246
+ # @param uri [Bundler::URI]
238
247
  #
239
- # @return [String] cleaned source name
240
- def source_name(name)
241
- name.to_s[0...-1]
248
+ # @return [String]
249
+ def source_name(uri)
250
+ uri.to_s[0...-1]
242
251
  end
243
252
 
244
253
  # Build sources used in the Gemfile
@@ -20,28 +20,39 @@ module Diffend
20
20
  class << self
21
21
  # @param command [String] either install or update
22
22
  # @param definition [Bundler::Definition] definition for your source
23
- def call(command, definition)
24
- config = fetch_config
25
-
23
+ # @param config [OpenStruct] diffend config
24
+ def call(command, config, definition)
26
25
  payload = payload(command, config.project_id, definition)
27
26
 
28
27
  response = Diffend::Request.call(
29
- config,
30
- commands_url(command, config.project_id),
31
- payload
28
+ build_request_object(command, config, payload)
32
29
  )
33
30
 
34
31
  JSON.parse(response.body)
35
32
  rescue StandardError => e
36
33
  Diffend::HandleErrors::Report.call(
37
34
  exception: e,
38
- payload: payload,
35
+ payload: payload || {},
39
36
  config: config,
40
37
  message: :unhandled_exception,
41
38
  report: true
42
39
  )
43
40
  end
44
41
 
42
+ # @param command [String] either install or update
43
+ # @param config [OpenStruct] diffend config
44
+ # @param payload [Hash]
45
+ #
46
+ # @return [Diffend::RequestObject]
47
+ def build_request_object(command, config, payload)
48
+ Diffend::RequestObject.new(
49
+ config: config,
50
+ url: commands_url(command, config.project_id),
51
+ payload: payload,
52
+ request_method: :post
53
+ )
54
+ end
55
+
45
56
  # Build diffend, host, packages, and platform specific information
46
57
  #
47
58
  # @param command [String] either install or update
@@ -151,10 +162,16 @@ module Diffend
151
162
  #
152
163
  # @return [Hash]
153
164
  def build_host_command
154
- {
155
- 'name' => $PROGRAM_NAME.split('/').last.strip,
156
- 'options' => ARGV.join(' ')
157
- }
165
+ if File.exist?($PROGRAM_NAME)
166
+ array = `ps -p #{Process.pid} -o command=`.strip.split(' ')
167
+ array.shift if array.first.end_with?('bin/ruby')
168
+ name = array.shift.split('/').last.strip
169
+ command = "#{name} #{array.join(' ')}"
170
+
171
+ { 'name' => command, 'title' => '' }
172
+ else
173
+ { 'name' => ARGV.join(' '), 'title' => $PROGRAM_NAME }
174
+ end
158
175
  end
159
176
 
160
177
  # Build host ips, except localhost and loopback
@@ -187,17 +204,6 @@ module Diffend
187
204
  tags
188
205
  end
189
206
 
190
- # Fetch diffend config file
191
- #
192
- # @return [OpenStruct, nil] configuration object
193
- #
194
- # @raise [Errors::MissingConfigurationFile] when no config file
195
- def fetch_config
196
- Config::Fetcher.call(
197
- File.expand_path('..', Bundler.bin_path)
198
- )
199
- end
200
-
201
207
  # Provides diffend command endpoint url
202
208
  #
203
209
  # @param command [String] either install or update
@@ -10,6 +10,6 @@ project_id = nil
10
10
  gemfile = ARGV[0]
11
11
  lockfile = ARGV[1]
12
12
 
13
- definition = Bundler::Definition.build(gemfile, lockfile, true)
13
+ definition = Diffend::BuildBundlerDefinition.call(command, gemfile lockfile)
14
14
 
15
15
  pp Diffend::Voting::Versions::Remote.payload(command, project_id, definition)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diffend
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.23
4
+ version: 0.2.28
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomasz Pajor
@@ -34,7 +34,7 @@ cert_chain:
34
34
  9MmF6uCQa1EjK2p8tYT0MnbHrFkoehxdX4VO9y99GAkhZyJNKPYPtyAUFV27sT2V
35
35
  LfCJRk4ifKIN/FUCwDSn8Cz0m6oH265q0p6wdzI6qrWOjP8tGOMBTA==
36
36
  -----END CERTIFICATE-----
37
- date: 2020-09-06 00:00:00.000000000 Z
37
+ date: 2020-09-19 00:00:00.000000000 Z
38
38
  dependencies:
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: bundler
@@ -102,7 +102,10 @@ files:
102
102
  - lib/diffend/handle_errors/display_to_stdout.rb
103
103
  - lib/diffend/handle_errors/messages.rb
104
104
  - lib/diffend/handle_errors/report.rb
105
+ - lib/diffend/monitor.rb
105
106
  - lib/diffend/request.rb
107
+ - lib/diffend/request_object.rb
108
+ - lib/diffend/track.rb
106
109
  - lib/diffend/voting.rb
107
110
  - lib/diffend/voting/versions/local.rb
108
111
  - lib/diffend/voting/versions/remote.rb
metadata.gz.sig CHANGED
Binary file