diffend 0.2.32 → 0.2.37

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e0efaea5a8bb4c724e24057821578b6c257a5eb313c472ac17dd60747fe10e4
4
- data.tar.gz: af3b702fa128eabcc8f6f054895c0e64097f38672b650697e292ab705b749b69
3
+ metadata.gz: 6882244ccac8c68c4b0eef0e1ffceeda710c6202b28a7608e7b6502dc9c8f694
4
+ data.tar.gz: efd83185b8af53f813204f3265567ed2ed44b6d9e40328d13f613254e3865857
5
5
  SHA512:
6
- metadata.gz: 00e60e3f610e03cad43a65b11c1b7f17d839d4b43009dde4436b9eebd96b82bdbf0035860eb85fb0e57c7042221403894a1aaf5f89cb606a86dd15e94f65bc58
7
- data.tar.gz: f45b310e0e376b50e27b7a1876f3704a3f282dbadac5c868b4548a4a6a2d582632aeb3f204e47fda5545f47807446e648b0bf2fe70b4a0abdefb17ea40cf1ff1
6
+ metadata.gz: 82509d763d303aad433d329c761d1c36e422314dfb0f55999793829a5c1d1e0a9bdcc4e23a3b4b47dd340fd97129eef567eee23320a5249c0cea956a5fd05468
7
+ data.tar.gz: bfff54f76c8d02c108c4416756be710991948cd3cebf35143c8ecd98e0a13777a8d445963d2986388db5a480a31094250a2ef9334bd3e58558acdd36bb12e0a7
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -8,10 +8,14 @@ jobs:
8
8
  fail-fast: false
9
9
  matrix:
10
10
  ruby:
11
+ - '3.0'
11
12
  - '2.7'
12
13
  - '2.6'
13
14
  - '2.5'
14
- - 'jruby'
15
+ - 'jruby-9.2.13.0'
16
+ bundler:
17
+ - '2.1.4'
18
+ - '2.2.4'
15
19
  include:
16
20
  - ruby: '2.7'
17
21
  coverage: 'true'
@@ -30,19 +34,17 @@ jobs:
30
34
  uses: ruby/setup-ruby@v1
31
35
  with:
32
36
  ruby-version: ${{matrix.ruby}}
33
- - name: Install latest bundler
34
- run: |
35
- gem install bundler --no-document
37
+ bundler: ${{matrix.bundler}}
36
38
  - name: Bundle install
37
39
  env:
38
40
  DIFFEND_DEVELOPMENT: true
39
41
  run: |
40
- bundle config path vendor/bundle
41
- bundle install --jobs 4 --retry 3
42
+ bundle _${{matrix.bundler}}_ config path vendor/bundle
43
+ bundle _${{matrix.bundler}}_ install --jobs 4 --retry 3
42
44
  - name: Run all tests
43
45
  env:
44
46
  GITHUB_COVERAGE: ${{matrix.coverage}}
45
- run: bundle exec rspec
47
+ run: bundle _${{matrix.bundler}}_ exec rspec
46
48
 
47
49
  coditsu:
48
50
  runs-on: ubuntu-latest
@@ -1 +1 @@
1
- 2.7.1
1
+ 3.0.0
@@ -2,6 +2,35 @@
2
2
 
3
3
  ## [Unreleased][master]
4
4
 
5
+ ## [0.2.37] (2021-01-05)
6
+ - add support for ENV loaded at runtime ([#92](https://github.com/diffend-io/diffend-ruby/pull/92))
7
+ - allow us to have more control over config errors ([#91](https://github.com/diffend-io/diffend-ruby/pull/91))
8
+ - add `bundle secure` command ([#90](https://github.com/diffend-io/diffend-ruby/pull/90))
9
+ - test against bundler 2.1 and 2.2 ([#83](https://github.com/diffend-io/diffend-ruby/pull/83))
10
+ - test against ruby 3.0.0 ([#89](https://github.com/diffend-io/diffend-ruby/pull/89))
11
+ - simplify how we build full json in specs ([#82](https://github.com/diffend-io/diffend-ruby/pull/82))
12
+ - simplify how we build bundler json in specs ([#84](https://github.com/diffend-io/diffend-ruby/pull/84))
13
+ - simplify how we build diffend json in specs ([#85](https://github.com/diffend-io/diffend-ruby/pull/85))
14
+ - simplify how we build rubygems json in specs ([#86](https://github.com/diffend-io/diffend-ruby/pull/86))
15
+ - simplify how we build packages platforms json in specs ([#87](https://github.com/diffend-io/diffend-ruby/pull/87))
16
+
17
+ ## [0.2.36] (2020-12-06)
18
+ - handle `Bundler::PermissionError` ([#79](https://github.com/diffend-io/diffend-ruby/pull/79))
19
+ - use cache to resolve dependencies in exec mode ([#78](https://github.com/diffend-io/diffend-ruby/pull/78))
20
+
21
+ ## [0.2.35] (2020-11-04)
22
+ - clean command name and title of a process ([#76](https://github.com/diffend-io/diffend-ruby/pull/76))
23
+ - handle `uninitialized constant #<Class:Diffend::Configs::Fetcher>::ERB` ([#75](https://github.com/diffend-io/diffend-ruby/pull/75))
24
+
25
+ ## [0.2.34] (2020-10-25)
26
+ - handle `Bundler::GitError` ([#72](https://github.com/diffend-io/diffend-ruby/pull/72))
27
+
28
+ ## [0.2.33] (2020-10-25)
29
+ - fix an exception when configuration file is missing ([#65](https://github.com/diffend-io/diffend-ruby/pull/65))
30
+ - silently exit when configuration file is missing in `Diffend::Monitor` ([#66](https://github.com/diffend-io/diffend-ruby/pull/66))
31
+ - introduce default config ([#67](https://github.com/diffend-io/diffend-ruby/pull/67))
32
+ - handle `SocketError` ([#68](https://github.com/diffend-io/diffend-ruby/pull/68))
33
+
5
34
  ## [0.2.32] (2020-10-02)
6
35
  - fix how we build platform from `Gem::Platform` ([#56](https://github.com/diffend-io/diffend-ruby/pull/56))
7
36
  - introduce `Diffend::LatestVersion` ([#57](https://github.com/diffend-io/diffend-ruby/pull/57))
@@ -85,7 +114,13 @@
85
114
 
86
115
  - initial release
87
116
 
88
- [master]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.30...HEAD
117
+ [master]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.36...HEAD
118
+ [0.2.36]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.35...v0.2.36
119
+ [0.2.35]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.34...v0.2.35
120
+ [0.2.34]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.33...v0.2.34
121
+ [0.2.33]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.32...v0.2.33
122
+ [0.2.32]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.31...v0.2.32
123
+ [0.2.31]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.30...v0.2.31
89
124
  [0.2.30]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.29...v0.2.30
90
125
  [0.2.29]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.28...v0.2.29
91
126
  [0.2.28]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.27...v0.2.28
data/Gemfile CHANGED
@@ -8,6 +8,5 @@ gemspec
8
8
 
9
9
  group :development, :test do
10
10
  gem 'byebug', platform: :ruby
11
- gem 'pry', platform: :jruby
12
11
  gem 'rspec'
13
12
  end
@@ -1,48 +1,40 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- diffend (0.2.32)
4
+ diffend (0.2.37)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  byebug (11.1.3)
10
- coderay (1.1.3)
11
10
  diff-lcs (1.4.4)
12
- ffi (1.13.1-java)
13
- method_source (1.0.0)
14
- pry (0.13.1-java)
15
- coderay (~> 1.1)
16
- method_source (~> 1.0)
17
- spoon (~> 0.0)
18
- rake (13.0.1)
19
- rspec (3.9.0)
20
- rspec-core (~> 3.9.0)
21
- rspec-expectations (~> 3.9.0)
22
- rspec-mocks (~> 3.9.0)
23
- rspec-core (3.9.2)
24
- rspec-support (~> 3.9.3)
25
- rspec-expectations (3.9.2)
11
+ rake (13.0.3)
12
+ rspec (3.10.0)
13
+ rspec-core (~> 3.10.0)
14
+ rspec-expectations (~> 3.10.0)
15
+ rspec-mocks (~> 3.10.0)
16
+ rspec-core (3.10.1)
17
+ rspec-support (~> 3.10.0)
18
+ rspec-expectations (3.10.1)
26
19
  diff-lcs (>= 1.2.0, < 2.0)
27
- rspec-support (~> 3.9.0)
28
- rspec-mocks (3.9.1)
20
+ rspec-support (~> 3.10.0)
21
+ rspec-mocks (3.10.1)
29
22
  diff-lcs (>= 1.2.0, < 2.0)
30
- rspec-support (~> 3.9.0)
31
- rspec-support (3.9.3)
32
- spoon (0.0.6)
33
- ffi
23
+ rspec-support (~> 3.10.0)
24
+ rspec-support (3.10.1)
34
25
 
35
26
  PLATFORMS
36
27
  java
37
28
  ruby
29
+ universal-java-13
30
+ x86_64-darwin-19
38
31
 
39
32
  DEPENDENCIES
40
33
  bundler
41
34
  byebug
42
35
  diffend!
43
- pry
44
36
  rake
45
37
  rspec
46
38
 
47
39
  BUNDLED WITH
48
- 2.1.4
40
+ 2.2.4
@@ -0,0 +1,6 @@
1
+ project_id: <%= ENV['DIFFEND_PROJECT_ID'] %>
2
+ shareable_id: <%= ENV['DIFFEND_SHAREABLE_ID'] %>
3
+ shareable_key: <%= ENV['DIFFEND_SHAREABLE_KEY'] %>
4
+ env: <%= ENV['DIFFEND_ENV'] || 'development' %>
5
+ ignore_errors: <%= ENV['DIFFEND_IGNORE_ERRORS'] || 'true' %>
6
+ development: <%= ENV['DIFFEND_DEVELOPMENT'] || 'true' %>
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Diffend
4
+ # Extend bundler with a new secure command to be able to run Diffend separately
5
+ class BundleSecure
6
+ Bundler::Plugin::API.command(Diffend::Commands::SECURE, self)
7
+
8
+ # Execute diffend check
9
+ #
10
+ # @param _name [String] command name
11
+ # @param _args [Array] arguments from ARGV
12
+ def exec(_name, _args)
13
+ return unless Diffend::Enabled.call
14
+
15
+ config = Diffend::Config.new(
16
+ command: Diffend::Commands::SECURE,
17
+ severity: Diffend::Logger::INFO
18
+ )
19
+
20
+ Diffend::LatestVersion.call(config)
21
+
22
+ Diffend::Execute.call(config)
23
+ end
24
+ end
25
+ end
@@ -9,5 +9,7 @@ module Diffend
9
9
  UPDATE = 'update'
10
10
  # Bundler exec command
11
11
  EXEC = 'exec'
12
+ # Bundler secure command introduced by diffend plugin
13
+ SECURE = 'secure'
12
14
  end
13
15
  end
@@ -3,31 +3,50 @@
3
3
  module Diffend
4
4
  # Diffend config object
5
5
  class Config
6
- attr_reader :project_id, :shareable_id, :shareable_key, :build_path, :env, :command
6
+ # Name of the diffend config file
7
+ FILENAME = '.diffend.yml'
8
+
9
+ attr_reader :project_id, :shareable_id, :shareable_key, :build_path, :env, :command, :errors
7
10
 
8
11
  # Build diffend config object
9
12
  #
10
- # @return [Diffend::Config]
13
+ # @param command [String] command executed via bundler
14
+ # @param severity [Integer] logging severity threshold
15
+ # @param build_path [String] path of the current build
11
16
  #
12
- # @raise [Errors::MissingConfigurationFile] when no config file
17
+ # @return [Diffend::Config]
13
18
  def initialize(command: nil, severity: nil, build_path: nil)
14
19
  @log_level = severity
20
+ @errors = []
15
21
  build(command, build_path)
16
- validate
22
+ Diffend::Configs::Validator.call(self)
17
23
  end
18
24
 
25
+ # Initialize logger
19
26
  def logger
20
27
  @logger ||= Diffend::Logger.new(@log_level)
21
28
  end
22
29
 
30
+ # @return [Boolean] true if config is valid, false otherwise
31
+ def valid?
32
+ @errors.empty?
33
+ end
34
+
35
+ # @return [Boolean] true if we want to ignore errors, false otherwise
23
36
  def ignore_errors?
24
37
  @ignore_errors
25
38
  end
26
39
 
40
+ # @return [Boolean] true if we are in development mode, false otherwise
27
41
  def development?
28
42
  @development
29
43
  end
30
44
 
45
+ # @return [Boolean] true if we are in deployment mode, false otherwise
46
+ def deployment?
47
+ !%w[development test].include?(env)
48
+ end
49
+
31
50
  # Provides diffend commands endpoint url
32
51
  #
33
52
  # @return [String]
@@ -53,22 +72,24 @@ module Diffend
53
72
  "https://my.diffend.io/api/projects/#{project_id}/bundle/#{request_id}/track"
54
73
  end
55
74
 
75
+ # Print config errors
76
+ def print_errors
77
+ @errors.each { |error| logger.fatal(error) }
78
+ end
79
+
56
80
  private
57
81
 
82
+ # @param command [String] command executed via bundler
83
+ # @param build_path [String] path of the current build
58
84
  def build(command, build_path)
59
85
  build_path ||= File.expand_path('..', ::Bundler.bin_path)
60
- hash = Diffend::Configs::Fetcher.call(logger, build_path)
86
+ hash = Diffend::Configs::Fetcher.call(plugin_path, build_path)
61
87
  hash['build_path'] = build_path
62
- hash['env'] = ENV['DIFFEND_ENV'] || 'development'
63
- hash['ignore_errors'] = ENV['DIFFEND_IGNORE_ERRORS'] == 'true'
64
- hash['development'] = ENV['DIFFEND_DEVELOPMENT'] == 'true'
65
88
  hash['command'] = command || build_command
66
89
 
67
90
  hash.each { |key, value| instance_variable_set(:"@#{key}", value) }
68
- end
69
-
70
- def validate
71
- Diffend::Configs::Validator.call(self)
91
+ rescue Errors::MalformedConfigurationFile
92
+ @errors << Diffend::Configs::ErrorMessages.malformed_file
72
93
  end
73
94
 
74
95
  # Command that was run with bundle
@@ -77,5 +98,10 @@ module Diffend
77
98
  def build_command
78
99
  ARGV.first || ::Bundler.feature_flag.default_cli_command.to_s
79
100
  end
101
+
102
+ # @return [String] path to the plugin
103
+ def plugin_path
104
+ Pathname.new(File.expand_path('../..', __dir__))
105
+ end
80
106
  end
81
107
  end
@@ -0,0 +1,38 @@
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 config error messages
7
+ module ErrorMessages
8
+ class << self
9
+ # @return [String] malformed configuration file message
10
+ def malformed_file
11
+ 'Your Diffend configuration file is malformed. Please re-setup.'
12
+ end
13
+
14
+ # Missing key message
15
+ #
16
+ # @param key [String] missing key
17
+ #
18
+ # @return [String]
19
+ def missing_key(key)
20
+ "Diffend configuration is missing #{key} key"
21
+ end
22
+
23
+ # Invalid key message
24
+ #
25
+ # @param config [Diffend::Config]
26
+ # @param key [String] invalid key
27
+ #
28
+ # @return [String]
29
+ def invalid_key(config, key)
30
+ <<~MSG
31
+ Diffend configuration value for #{key} is invalid.
32
+ Expected #{Validator::KNOWN_KEYS[key].join(' or ')}, was #{config.public_send(key).class}.
33
+ MSG
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'yaml'
3
+ %w[
4
+ erb
5
+ yaml
6
+ ].each(&method(:require))
4
7
 
5
8
  module Diffend
6
9
  # Module for all the components related to setting up the config
@@ -8,7 +11,7 @@ module Diffend
8
11
  # Class responsible for fetching the config from .diffend.yml
9
12
  module Fetcher
10
13
  class << self
11
- # @param logger [Diffend::Logger]
14
+ # @param plugin_path [String] path of the plugin
12
15
  # @param build_path [String] path of the current build
13
16
  #
14
17
  # @return [Hash] details from configuration file
@@ -16,73 +19,31 @@ module Diffend
16
19
  # @example
17
20
  # details = Fetcher.new.call('./')
18
21
  # details.build_path #=> './'
19
- def call(logger, build_path)
20
- build(build_path)
21
- rescue Errors::MissingConfigurationFile
22
- build_missing_error_message(build_path)
23
- .tap(&logger.method(:fatal))
22
+ def call(plugin_path, build_path)
23
+ default_config = File.join(plugin_path, 'config', 'diffend.yml')
24
+ project_config = File.join(build_path, Diffend::Config::FILENAME)
24
25
 
25
- raise Diffend::Errors::HandledException
26
- rescue Errors::EmptyConfigurationFile
27
- build_empty_error_message(build_path)
28
- .tap(&logger.method(:fatal))
26
+ hash = read_file(default_config)
29
27
 
30
- raise Diffend::Errors::HandledException
31
- rescue Errors::MalformedConfigurationFile
32
- build_malformed_error_message(build_path)
33
- .tap(&logger.method(:fatal))
28
+ if File.exist?(project_config)
29
+ hash.merge!(read_file(project_config) || {})
30
+ end
34
31
 
35
- raise Diffend::Errors::HandledException
32
+ hash
36
33
  end
37
34
 
38
35
  private
39
36
 
40
- # @param build_path [String] path of the current build
37
+ # Load config file
41
38
  #
42
- # @return [OpenStruct] open struct with config details
43
- def build(build_path)
44
- content = ERB.new(
45
- File.read(
46
- FileFinder.call(build_path)
47
- )
48
- ).result
49
-
50
- raise Errors::EmptyConfigurationFile if content.empty?
51
-
52
- parse_file(content)
53
- end
54
-
55
- def parse_file(content)
56
- YAML.safe_load(content)
39
+ # @param file_path [String]
40
+ #
41
+ # @return [Hash]
42
+ def read_file(file_path)
43
+ YAML.safe_load(ERB.new(File.read(file_path)).result)
57
44
  rescue Psych::SyntaxError
58
45
  raise Errors::MalformedConfigurationFile
59
46
  end
60
-
61
- # @param build_path [String] path of the current build
62
- #
63
- # @return [String] missing configuration file message
64
- def build_missing_error_message(build_path)
65
- <<~MSG
66
- \nWe were unable to locate Diffend configuration file.\n
67
- Please make sure that .diffend.yml is present in #{build_path} folder.\n
68
- MSG
69
- end
70
-
71
- # @return [String] empty configuration file message
72
- def build_empty_error_message
73
- <<~MSG
74
- \nYour Diffend configuration file is empty.\n
75
- Please re-setup.\n
76
- MSG
77
- end
78
-
79
- # @return [String] malformed configuration file message
80
- def build_malformed_error_message
81
- <<~MSG
82
- \nYour Diffend configuration file is malformed.\n
83
- Please re-setup.\n
84
- MSG
85
- end
86
47
  end
87
48
  end
88
49
  end
@@ -5,6 +5,7 @@ module Diffend
5
5
  module Configs
6
6
  # Class responsible for validating the config from .diffend.yml
7
7
  module Validator
8
+ # List of known config keys
8
9
  KNOWN_KEYS = {
9
10
  project_id: [String],
10
11
  shareable_id: [String],
@@ -21,18 +22,11 @@ module Diffend
21
22
  def call(config)
22
23
  KNOWN_KEYS.each_key do |key|
23
24
  if missing?(config, key)
24
- missing_key_message(key)
25
- .tap(&config.logger.method(:fatal))
26
-
27
- raise Diffend::Errors::HandledException
25
+ config.errors << ErrorMessages.missing_key(key)
26
+ next
28
27
  end
29
28
 
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
29
+ config.errors << ErrorMessages.invalid_key(config, key) if invalid?(config, key)
36
30
  end
37
31
  end
38
32
 
@@ -55,30 +49,6 @@ module Diffend
55
49
  def invalid?(config, key)
56
50
  !KNOWN_KEYS[key].include?(config.public_send(key).class)
57
51
  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
52
  end
83
53
  end
84
54
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Diffend
4
+ # Verify if the plugin is enabled
5
+ module Enabled
6
+ class << self
7
+ # Checks if plugin is enabled
8
+ #
9
+ # @return [Boolean] true if enabled, false otherwise
10
+ def call
11
+ ::Bundler
12
+ .default_gemfile
13
+ .read
14
+ .split("\n")
15
+ .reject(&:empty?)
16
+ .map(&:strip)
17
+ .select { |line| line.start_with?('plugin') }
18
+ .any? { |line| line.include?('diffend') }
19
+ end
20
+ end
21
+ end
22
+ 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
@@ -47,9 +47,9 @@ module Diffend
47
47
  command = "#{name} #{array.join(' ')}"
48
48
  end
49
49
 
50
- { 'name' => command, 'title' => '' }
50
+ { 'name' => clean(command), 'title' => '' }
51
51
  else
52
- { 'name' => ARGV.join(' '), 'title' => $PROGRAM_NAME }
52
+ { 'name' => clean(ARGV.join(' ')), 'title' => clean($PROGRAM_NAME) }
53
53
  end
54
54
  end
55
55
 
@@ -82,6 +82,14 @@ module Diffend
82
82
 
83
83
  tags
84
84
  end
85
+
86
+ # @param str [String] that we want to clean and truncate
87
+ def clean(str)
88
+ str
89
+ .dup
90
+ .gsub(/[[:space:]]+/, ' ')
91
+ .strip[0...255]
92
+ end
85
93
  end
86
94
  end
87
95
  end
@@ -34,12 +34,12 @@ module Diffend
34
34
  # @param command [String] command executed via bundler
35
35
  # @param definition [Bundler::Definition] definition for your source
36
36
  def call(command, definition)
37
- Bundler.ui.silence { definition.resolve_remotely! }
37
+ instance = new(command, definition)
38
38
 
39
- instance = new(definition)
39
+ Bundler.ui.silence { instance.resolve }
40
40
 
41
41
  case command
42
- when Commands::INSTALL, Commands::EXEC then instance.build_install
42
+ when Commands::INSTALL, Commands::EXEC, Commands::SECURE then instance.build_install
43
43
  when Commands::UPDATE then instance.build_update
44
44
  else
45
45
  raise ArgumentError, "invalid command: #{command}"
@@ -47,14 +47,22 @@ module Diffend
47
47
  end
48
48
  end
49
49
 
50
+ # @param command [String] command executed via bundler
50
51
  # @param definition [Bundler::Definition] definition for your source
51
52
  #
52
53
  # @return [Hash] local dependencies
53
- def initialize(definition)
54
+ def initialize(command, definition)
55
+ @command = command
54
56
  @definition = definition
55
57
  @direct_dependencies = Hash[definition.dependencies.map { |val| [val.name, val] }]
56
58
  # Support case without Gemfile.lock
57
59
  @locked_specs = @definition.locked_gems ? @definition.locked_gems.specs : []
60
+ @cached = command == Commands::EXEC
61
+ end
62
+
63
+ # Resolve definition
64
+ def resolve
65
+ @cached ? @definition.resolve_with_cache! : @definition.resolve_remotely!
58
66
  end
59
67
 
60
68
  # Build install specification
@@ -209,12 +217,7 @@ module Diffend
209
217
 
210
218
  case spec.source
211
219
  when Bundler::Source::Rubygems
212
- spec
213
- .source
214
- .send(:remote_specs)
215
- .search(Bundler::Dependency.new(spec.name, spec.version))
216
- .last
217
- .remote
220
+ Bundler::Source::Rubygems::Remote.new(spec.source.remotes.last)
218
221
  when Bundler::Source::Metadata, Bundler::Source::Git, Bundler::Source::Path
219
222
  spec.source
220
223
  else
@@ -3,17 +3,17 @@
3
3
  module Diffend
4
4
  # Diffend logging
5
5
  class Logger
6
- # Low-level information, mostly for developers.
6
+ # Low-level information, mostly for developers
7
7
  DEBUG = 0
8
- # Generic (useful) information about system operation.
8
+ # Generic (useful) information about system operation
9
9
  INFO = 1
10
- # A warning.
10
+ # A warning
11
11
  WARN = 2
12
- # A handleable error condition.
12
+ # A handleable error condition
13
13
  ERROR = 3
14
- # An unhandleable error that results in a program crash.
14
+ # An error that we are unable to handle that results in a program crash
15
15
  FATAL = 4
16
- # An unknown message that should always be logged.
16
+ # An unknown message that should always be logged
17
17
  UNKNOWN = 5
18
18
 
19
19
  # @param level [Integer] logging severity threshold
@@ -6,9 +6,9 @@
6
6
  errors
7
7
  build_bundler_definition
8
8
  commands
9
+ configs/error_messages
9
10
  config
10
11
  configs/fetcher
11
- configs/file_finder
12
12
  configs/validator
13
13
  handle_errors/messages
14
14
  handle_errors/build_exception_payload
@@ -26,14 +26,28 @@
26
26
  track
27
27
  ].each { |file| require "diffend/#{file}" }
28
28
 
29
- config = Diffend::Config.new(
30
- command: Diffend::Commands::EXEC,
31
- severity: Diffend::Logger::FATAL
32
- )
29
+ Thread.new do
30
+ config = nil
31
+ config_iterations = 0
33
32
 
34
- return if %w[development test].include?(config.env)
33
+ loop do
34
+ config = Diffend::Config.new(
35
+ command: Diffend::Commands::EXEC,
36
+ severity: Diffend::Logger::FATAL
37
+ )
38
+
39
+ break if config.valid?
40
+
41
+ config_iterations += 1
42
+
43
+ break if config_iterations == 12
44
+
45
+ sleep 5
46
+ end
47
+
48
+ Thread.exit unless config.valid?
49
+ Thread.exit unless config.deployment?
35
50
 
36
- Thread.new do
37
51
  track = Diffend::Track.new(config)
38
52
  track.start
39
53
  end
@@ -7,13 +7,14 @@
7
7
  %w[
8
8
  version
9
9
  logger
10
+ enabled
10
11
  latest_version
11
12
  errors
12
13
  build_bundler_definition
13
14
  commands
15
+ configs/error_messages
14
16
  config
15
17
  configs/fetcher
16
- configs/file_finder
17
18
  configs/validator
18
19
  handle_errors/messages
19
20
  handle_errors/build_exception_payload
@@ -43,15 +44,22 @@ module Diffend
43
44
 
44
45
  # Execute diffend plugin
45
46
  def execute
46
- return unless enabled?
47
+ return unless Diffend::Enabled.call
47
48
 
48
49
  config = Diffend::Config.new(severity: Diffend::Logger::INFO)
49
50
 
51
+ unless config.valid?
52
+ config.print_errors
53
+
54
+ exit 255
55
+ end
56
+
50
57
  Diffend::LatestVersion.call(config)
51
58
 
52
59
  Diffend::Execute.call(config)
53
60
  rescue Diffend::Errors::HandledException
54
- return if config.ignore_errors?
61
+ # config will not be initialized when configuration file is missing
62
+ return if config&.ignore_errors?
55
63
 
56
64
  exit 255
57
65
  rescue StandardError => e
@@ -67,20 +75,6 @@ module Diffend
67
75
 
68
76
  exit 255
69
77
  end
70
-
71
- # Checks if plugin is enabled
72
- #
73
- # @return [Boolean] true if enabled, false otherwise
74
- def enabled?
75
- ::Bundler
76
- .default_gemfile
77
- .read
78
- .split("\n")
79
- .reject(&:empty?)
80
- .map(&:strip)
81
- .select { |line| line.start_with?('plugin') }
82
- .any? { |line| line.include?('diffend') }
83
- end
84
78
  end
85
79
  end
86
80
  end
@@ -14,7 +14,8 @@ module Diffend
14
14
  Errno::ECONNRESET,
15
15
  Errno::ENETUNREACH,
16
16
  Errno::EHOSTUNREACH,
17
- Errno::ECONNREFUSED
17
+ Errno::ECONNREFUSED,
18
+ SocketError
18
19
  ].freeze
19
20
  # Message displayed when timeout occured and we will retry
20
21
  TIMEOUT_MESSAGE = 'We experienced a connection issue, retrying...'
@@ -5,6 +5,14 @@ require 'json'
5
5
  module Diffend
6
6
  # Module responsible for fetching diffend verdict on local context
7
7
  module RequestVerdict
8
+ # Exceptions that we handle when there is a resolve issue
9
+ RESOLVE_EXCEPTIONS = [
10
+ Bundler::GemNotFound,
11
+ Bundler::GitError,
12
+ Bundler::PermissionError,
13
+ Bundler::VersionConflict
14
+ ].freeze
15
+
8
16
  class << self
9
17
  # @param config [Diffend::Config]
10
18
  # @param definition [Bundler::Definition] definition for your source
@@ -16,7 +24,7 @@ module Diffend
16
24
  )
17
25
 
18
26
  JSON.parse(response.body)
19
- rescue Bundler::GemNotFound, Bundler::VersionConflict
27
+ rescue *RESOLVE_EXCEPTIONS
20
28
  raise ::Diffend::Errors::DependenciesResolveException
21
29
  rescue StandardError => e
22
30
  Diffend::HandleErrors::Report.call(
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Diffend
4
4
  # Current version
5
- VERSION = '0.2.32'
5
+ VERSION = '0.2.37'
6
6
  end
data/plugins.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'diffend/plugin'
4
+ require 'diffend/bundle_secure'
4
5
 
5
6
  Diffend::Plugin.register
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.32
4
+ version: 0.2.37
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-10-02 00:00:00.000000000 Z
37
+ date: 2021-01-05 00:00:00.000000000 Z
38
38
  dependencies:
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: bundler
@@ -90,14 +90,17 @@ files:
90
90
  - bin/rspec
91
91
  - certs/mensfeld.pem
92
92
  - certs/tomaszpajor.pem
93
+ - config/diffend.yml
93
94
  - diffend.gemspec
94
95
  - lib/diffend.rb
95
96
  - lib/diffend/build_bundler_definition.rb
97
+ - lib/diffend/bundle_secure.rb
96
98
  - lib/diffend/commands.rb
97
99
  - lib/diffend/config.rb
100
+ - lib/diffend/configs/error_messages.rb
98
101
  - lib/diffend/configs/fetcher.rb
99
- - lib/diffend/configs/file_finder.rb
100
102
  - lib/diffend/configs/validator.rb
103
+ - lib/diffend/enabled.rb
101
104
  - lib/diffend/errors.rb
102
105
  - lib/diffend/execute.rb
103
106
  - lib/diffend/handle_errors/build_exception_payload.rb
@@ -139,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
142
  - !ruby/object:Gem::Version
140
143
  version: '0'
141
144
  requirements: []
142
- rubygems_version: 3.1.2
145
+ rubygems_version: 3.2.3
143
146
  signing_key:
144
147
  specification_version: 4
145
148
  summary: OSS supply chain security and management platform
metadata.gz.sig CHANGED
Binary file
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Diffend
4
- module Configs
5
- # Class used to figure out the file from which we should load the settings
6
- module FileFinder
7
- # Names of the files or paths where we will look for the settings
8
- #
9
- # @note We do the double dot trick, to look outside of the current dir because when
10
- # executed from a docker container, we copy the local uncommitted settings into the
11
- # dir above the app location not to pollute the reset state of the git repo
12
- #
13
- # @note Order is important, as for local env we should load from
14
- # local file (if present first)
15
- FILE_NAMES = %w[
16
- .diffend.yml
17
- ].map { |name| ["../#{name}", name] }.tap(&:flatten!).freeze
18
-
19
- private_constant :FILE_NAMES
20
-
21
- class << self
22
- # Looks for Diffend settings file for a given env
23
- #
24
- # @param build_path [String] path of the current build
25
- #
26
- # @return [String] path to the file from which we should load all the settings
27
- def call(build_path)
28
- FILE_NAMES
29
- .map { |name| File.join(build_path, name) }
30
- .map { |name| Dir[name] }
31
- .find { |selection| !selection.empty? }
32
- .tap { |path| path || raise(Errors::MissingConfigurationFile) }
33
- .first
34
- end
35
- end
36
- end
37
- end
38
- end