diffend-monitor 0.2.34 → 0.2.39

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: f1c739e4cbf06a1ef55576728e684ab0bb639b4889748faa1d688ef1406024c0
4
- data.tar.gz: fe58c9466fe5a532d445e8b5a0a8948b87489fbc9d49974aabb272bfd0ab14ed
3
+ metadata.gz: aad29d6d630d04366e4421991bfdd26d1725878fe5986e240a36e26e9840bab3
4
+ data.tar.gz: 69ac92f632883cf7bcc9e8bf42f3193cc0f034098401e037be143f8b2dce95fd
5
5
  SHA512:
6
- metadata.gz: e44b5cd37e26197b11cb67dd3703984949a15d372b0623c2cc38ef346b47d14aad76ce1956d093304b3cc5cc6f6f952b7b45bce2808afed2fee76fbc124f0f9c
7
- data.tar.gz: 28cb79ac18dc1aad9d535ab80d7c665aadea70cc77b35e6a04c63196a6844c7c62418a28bbdaa4a0e3b7c06480d36b4334fb9ad8023bf512faf1b51b74bdc421
6
+ metadata.gz: 526ee6bc6e464d15bff85944cbec34d072a4a4fce8b3658423526cb7ec60c44413769e2b84b778c9f7e6291ac98afcc2c06f05af385c787198cd3c3798ff30c1
7
+ data.tar.gz: adf72aa9eb79f43aca61022172f2323e0a0f859b4954df63dbe62631b0e9713ff775f712032dda5e65fc04d82ae66b6d37d06a7f4567a5d4f54d5664c47b9d15
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -2,16 +2,23 @@ name: ci
2
2
 
3
3
  jobs:
4
4
  specs:
5
- runs-on: ubuntu-latest
5
+ needs:
6
+ - diffend
7
+ - coditsu
6
8
 
9
+ runs-on: ubuntu-latest
7
10
  strategy:
8
11
  fail-fast: false
9
12
  matrix:
10
13
  ruby:
14
+ - '3.0'
11
15
  - '2.7'
12
16
  - '2.6'
13
17
  - '2.5'
14
- - 'jruby'
18
+ - 'jruby-9.2.14.0'
19
+ bundler:
20
+ - '2.1.4'
21
+ - '2.2.5'
15
22
  include:
16
23
  - ruby: '2.7'
17
24
  coverage: 'true'
@@ -30,19 +37,36 @@ jobs:
30
37
  uses: ruby/setup-ruby@v1
31
38
  with:
32
39
  ruby-version: ${{matrix.ruby}}
33
- - name: Install latest bundler
34
- run: |
35
- gem install bundler --no-document
40
+ bundler: ${{matrix.bundler}}
36
41
  - name: Bundle install
37
42
  env:
38
43
  DIFFEND_DEVELOPMENT: true
39
44
  run: |
40
- bundle config path vendor/bundle
41
- bundle install --jobs 4 --retry 3
45
+ bundle _${{matrix.bundler}}_ config path vendor/bundle
46
+ bundle _${{matrix.bundler}}_ install --jobs 4 --retry 3
42
47
  - name: Run all tests
43
48
  env:
44
49
  GITHUB_COVERAGE: ${{matrix.coverage}}
45
- run: bundle exec rspec
50
+ run: bundle _${{matrix.bundler}}_ exec rspec
51
+
52
+ diffend:
53
+ runs-on: ubuntu-latest
54
+ strategy:
55
+ fail-fast: false
56
+ steps:
57
+ - uses: actions/checkout@v2
58
+ with:
59
+ fetch-depth: 0
60
+ - name: Set up Ruby
61
+ uses: ruby/setup-ruby@v1
62
+ with:
63
+ ruby-version: 3.0
64
+ - name: Install latest bundler
65
+ run: gem install bundler --no-document
66
+ - name: Install Diffend plugin
67
+ run: bundle plugin install diffend
68
+ - name: Bundle Secure
69
+ run: bundle secure
46
70
 
47
71
  coditsu:
48
72
  runs-on: ubuntu-latest
@@ -1 +1 @@
1
- 2.7.2
1
+ 3.0.0
@@ -2,6 +2,34 @@
2
2
 
3
3
  ## [Unreleased][master]
4
4
 
5
+ ## [0.2.39] (2021-01-18)
6
+ - handle a case if we start to fast and some gems require things it may break the execution ([#101](https://github.com/diffend-io/diffend-ruby/pull/101))
7
+
8
+ ## [0.2.38] (2021-01-15)
9
+ - allow executing `bundle secure` without plugin being present in the Gemfile ([#96](https://github.com/diffend-io/diffend-ruby/pull/96))
10
+ - be explicit about `Bundler` scope ([#97](https://github.com/diffend-io/diffend-ruby/pull/97))
11
+ - switch to exponential backoff in `Diffend::Monitor` ([#98](https://github.com/diffend-io/diffend-ruby/pull/98))
12
+
13
+ ## [0.2.37] (2021-01-05)
14
+ - add support for ENV loaded at runtime ([#92](https://github.com/diffend-io/diffend-ruby/pull/92))
15
+ - allow us to have more control over config errors ([#91](https://github.com/diffend-io/diffend-ruby/pull/91))
16
+ - add `bundle secure` command ([#90](https://github.com/diffend-io/diffend-ruby/pull/90))
17
+ - test against bundler 2.1 and 2.2 ([#83](https://github.com/diffend-io/diffend-ruby/pull/83))
18
+ - test against ruby 3.0.0 ([#89](https://github.com/diffend-io/diffend-ruby/pull/89))
19
+ - simplify how we build full json in specs ([#82](https://github.com/diffend-io/diffend-ruby/pull/82))
20
+ - simplify how we build bundler json in specs ([#84](https://github.com/diffend-io/diffend-ruby/pull/84))
21
+ - simplify how we build diffend json in specs ([#85](https://github.com/diffend-io/diffend-ruby/pull/85))
22
+ - simplify how we build rubygems json in specs ([#86](https://github.com/diffend-io/diffend-ruby/pull/86))
23
+ - simplify how we build packages platforms json in specs ([#87](https://github.com/diffend-io/diffend-ruby/pull/87))
24
+
25
+ ## [0.2.36] (2020-12-06)
26
+ - handle `Bundler::PermissionError` ([#79](https://github.com/diffend-io/diffend-ruby/pull/79))
27
+ - use cache to resolve dependencies in exec mode ([#78](https://github.com/diffend-io/diffend-ruby/pull/78))
28
+
29
+ ## [0.2.35] (2020-11-04)
30
+ - clean command name and title of a process ([#76](https://github.com/diffend-io/diffend-ruby/pull/76))
31
+ - handle `uninitialized constant #<Class:Diffend::Configs::Fetcher>::ERB` ([#75](https://github.com/diffend-io/diffend-ruby/pull/75))
32
+
5
33
  ## [0.2.34] (2020-10-25)
6
34
  - handle `Bundler::GitError` ([#72](https://github.com/diffend-io/diffend-ruby/pull/72))
7
35
 
@@ -94,7 +122,12 @@
94
122
 
95
123
  - initial release
96
124
 
97
- [master]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.34...HEAD
125
+ [master]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.39...HEAD
126
+ [0.2.39]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.38...v0.2.39
127
+ [0.2.38]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.37...v0.2.38
128
+ [0.2.37]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.36...v0.2.37
129
+ [0.2.36]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.35...v0.2.36
130
+ [0.2.35]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.34...v0.2.35
98
131
  [0.2.34]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.33...v0.2.34
99
132
  [0.2.33]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.32...v0.2.33
100
133
  [0.2.32]: https://github.com/diffend-io/diffend-ruby/compare/v0.2.31...v0.2.32
data/Gemfile CHANGED
@@ -7,5 +7,6 @@ plugin 'diffend'
7
7
  gemspec
8
8
 
9
9
  group :development, :test do
10
+ gem 'byebug', platform: :ruby
10
11
  gem 'rspec'
11
12
  end
@@ -1,36 +1,40 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- diffend (0.2.34)
4
+ diffend (0.2.39)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ byebug (11.1.3)
9
10
  diff-lcs (1.4.4)
10
- rake (13.0.1)
11
- rspec (3.9.0)
12
- rspec-core (~> 3.9.0)
13
- rspec-expectations (~> 3.9.0)
14
- rspec-mocks (~> 3.9.0)
15
- rspec-core (3.9.3)
16
- rspec-support (~> 3.9.3)
17
- rspec-expectations (3.9.4)
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)
18
19
  diff-lcs (>= 1.2.0, < 2.0)
19
- rspec-support (~> 3.9.0)
20
- rspec-mocks (3.9.1)
20
+ rspec-support (~> 3.10.0)
21
+ rspec-mocks (3.10.1)
21
22
  diff-lcs (>= 1.2.0, < 2.0)
22
- rspec-support (~> 3.9.0)
23
- rspec-support (3.9.4)
23
+ rspec-support (~> 3.10.0)
24
+ rspec-support (3.10.1)
24
25
 
25
26
  PLATFORMS
26
27
  java
27
28
  ruby
29
+ universal-java-13
30
+ x86_64-darwin-19
28
31
 
29
32
  DEPENDENCIES
30
33
  bundler
34
+ byebug
31
35
  diffend!
32
36
  rake
33
37
  rspec
34
38
 
35
39
  BUNDLED WITH
36
- 2.1.4
40
+ 2.2.5
@@ -10,14 +10,14 @@ module Diffend
10
10
  # @param gemfile [String] path to Gemfile
11
11
  # @param lockfile [String] path to Gemfile.lock
12
12
  #
13
- # @return [Bundler::Definition]
13
+ # @return [::Bundler::Definition]
14
14
  def call(command, gemfile, lockfile)
15
15
  unlock = command == 'update' ? true : nil
16
16
 
17
- Bundler.configure
18
- Bundler::Fetcher.disable_endpoint = nil
17
+ ::Bundler.configure
18
+ ::Bundler::Fetcher.disable_endpoint = nil
19
19
 
20
- Bundler::Definition
20
+ ::Bundler::Definition
21
21
  .build(gemfile, lockfile, unlock)
22
22
  .tap(&:validate_runtime!)
23
23
  end
@@ -0,0 +1,23 @@
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
+ config = Diffend::Config.new(
14
+ command: Diffend::Commands::SECURE,
15
+ severity: Diffend::Logger::INFO
16
+ )
17
+
18
+ Diffend::LatestVersion.call(config)
19
+
20
+ Diffend::Execute.call(config)
21
+ end
22
+ end
23
+ 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,29 +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
  #
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
16
+ #
10
17
  # @return [Diffend::Config]
11
18
  def initialize(command: nil, severity: nil, build_path: nil)
12
19
  @log_level = severity
20
+ @errors = []
13
21
  build(command, build_path)
14
- validate
22
+ Diffend::Configs::Validator.call(self)
15
23
  end
16
24
 
25
+ # Initialize logger
17
26
  def logger
18
27
  @logger ||= Diffend::Logger.new(@log_level)
19
28
  end
20
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
21
36
  def ignore_errors?
22
37
  @ignore_errors
23
38
  end
24
39
 
40
+ # @return [Boolean] true if we are in development mode, false otherwise
25
41
  def development?
26
42
  @development
27
43
  end
28
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
+
29
50
  # Provides diffend commands endpoint url
30
51
  #
31
52
  # @return [String]
@@ -51,19 +72,24 @@ module Diffend
51
72
  "https://my.diffend.io/api/projects/#{project_id}/bundle/#{request_id}/track"
52
73
  end
53
74
 
75
+ # Print config errors
76
+ def print_errors
77
+ @errors.each { |error| logger.fatal(error) }
78
+ end
79
+
54
80
  private
55
81
 
82
+ # @param command [String] command executed via bundler
83
+ # @param build_path [String] path of the current build
56
84
  def build(command, build_path)
57
85
  build_path ||= File.expand_path('..', ::Bundler.bin_path)
58
- hash = Diffend::Configs::Fetcher.call(logger, plugin_path, build_path)
86
+ hash = Diffend::Configs::Fetcher.call(plugin_path, build_path)
59
87
  hash['build_path'] = build_path
60
88
  hash['command'] = command || build_command
61
89
 
62
90
  hash.each { |key, value| instance_variable_set(:"@#{key}", value) }
63
- end
64
-
65
- def validate
66
- Diffend::Configs::Validator.call(self)
91
+ rescue Errors::MalformedConfigurationFile
92
+ @errors << Diffend::Configs::ErrorMessages.malformed_file
67
93
  end
68
94
 
69
95
  # Command that was run with bundle
@@ -73,6 +99,7 @@ module Diffend
73
99
  ARGV.first || ::Bundler.feature_flag.default_cli_command.to_s
74
100
  end
75
101
 
102
+ # @return [String] path to the plugin
76
103
  def plugin_path
77
104
  Pathname.new(File.expand_path('../..', __dir__))
78
105
  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,6 @@ 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]
12
14
  # @param plugin_path [String] path of the plugin
13
15
  # @param build_path [String] path of the current build
14
16
  #
@@ -17,24 +19,9 @@ module Diffend
17
19
  # @example
18
20
  # details = Fetcher.new.call('./')
19
21
  # details.build_path #=> './'
20
- def call(logger, plugin_path, build_path)
21
- build(plugin_path, build_path)
22
- rescue Errors::MalformedConfigurationFile
23
- build_malformed_error_message(build_path)
24
- .tap(&logger.method(:fatal))
25
-
26
- raise Diffend::Errors::HandledException
27
- end
28
-
29
- private
30
-
31
- # @param plugin_path [String] path of the plugin
32
- # @param build_path [String] path of the current build
33
- #
34
- # @return [OpenStruct] open struct with config details
35
- def build(plugin_path, build_path)
22
+ def call(plugin_path, build_path)
36
23
  default_config = File.join(plugin_path, 'config', 'diffend.yml')
37
- project_config = File.join(build_path, '.diffend.yml')
24
+ project_config = File.join(build_path, Diffend::Config::FILENAME)
38
25
 
39
26
  hash = read_file(default_config)
40
27
 
@@ -45,19 +32,18 @@ module Diffend
45
32
  hash
46
33
  end
47
34
 
48
- def read_file(path)
49
- YAML.safe_load(ERB.new(File.read(path)).result)
35
+ private
36
+
37
+ # Load config file
38
+ #
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)
50
44
  rescue Psych::SyntaxError
51
45
  raise Errors::MalformedConfigurationFile
52
46
  end
53
-
54
- # @return [String] malformed configuration file message
55
- def build_malformed_error_message
56
- <<~MSG
57
- \nYour Diffend configuration file is malformed.\n
58
- Please re-setup.\n
59
- MSG
60
- end
61
47
  end
62
48
  end
63
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
@@ -17,12 +17,12 @@ module Diffend
17
17
 
18
18
  # Build bundler definition
19
19
  #
20
- # @return [Bundler::Definition]
20
+ # @return [::Bundler::Definition]
21
21
  def build_definition(command)
22
22
  Diffend::BuildBundlerDefinition.call(
23
23
  command,
24
- Bundler.default_gemfile,
25
- Bundler.default_lockfile
24
+ ::Bundler.default_gemfile,
25
+ ::Bundler.default_lockfile
26
26
  )
27
27
  end
28
28
 
@@ -7,7 +7,7 @@ module Diffend
7
7
  # Build diffend, host, packages, and platform specific information
8
8
  #
9
9
  # @param config [Diffend::Config]
10
- # @param definition [Bundler::Definition] definition for your source
10
+ # @param definition [::Bundler::Definition] definition for your source
11
11
  #
12
12
  # @return [Hash] payload for diffend endpoint
13
13
  def call(config, definition)
@@ -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
@@ -9,8 +9,8 @@ module Diffend
9
9
  ME_PATH = '.'
10
10
  # Sources that we expect to match ourselves too
11
11
  ME_SOURCES = [
12
- Bundler::Source::Gemspec,
13
- Bundler::Source::Path
12
+ ::Bundler::Source::Gemspec,
13
+ ::Bundler::Source::Path
14
14
  ].freeze
15
15
  # List of dependency types
16
16
  DEPENDENCIES_TYPES = {
@@ -32,14 +32,14 @@ module Diffend
32
32
 
33
33
  class << self
34
34
  # @param command [String] command executed via bundler
35
- # @param definition [Bundler::Definition] definition for your source
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 definition [Bundler::Definition] definition for your source
50
+ # @param command [String] command executed via bundler
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
@@ -117,8 +125,8 @@ module Diffend
117
125
 
118
126
  # Build gem versions
119
127
  #
120
- # @param spec [Bundler::StubSpecification, Bundler::LazySpecification, Gem::Specification]
121
- # @param locked_spec [Bundler::LazySpecification, Gem::Specification, NilClass]
128
+ # @param spec [::Bundler::StubSpecification, ::Bundler::LazySpecification, Gem::Specification]
129
+ # @param locked_spec [::Bundler::LazySpecification, Gem::Specification, NilClass]
122
130
  #
123
131
  # @return [Array<String>]
124
132
  def build_versions(spec, locked_spec = nil)
@@ -143,8 +151,8 @@ module Diffend
143
151
 
144
152
  # Build gem platform
145
153
  #
146
- # @param spec [Bundler::StubSpecification, Bundler::LazySpecification, Gem::Specification]
147
- # @param locked_spec [Bundler::LazySpecification, Gem::Specification, NilClass]
154
+ # @param spec [::Bundler::StubSpecification, ::Bundler::LazySpecification, Gem::Specification]
155
+ # @param locked_spec [::Bundler::LazySpecification, Gem::Specification, NilClass]
148
156
  #
149
157
  # @return [String]
150
158
  def build_spec_platform(spec, locked_spec)
@@ -167,18 +175,18 @@ module Diffend
167
175
 
168
176
  # Build gem source type
169
177
  #
170
- # @param source [Bundler::Source] gem source type
178
+ # @param source [::Bundler::Source] gem source type
171
179
  #
172
180
  # @return [Integer] internal gem source type
173
181
  def build_spec_gem_source_type(source)
174
182
  case source
175
- when Bundler::Source::Metadata
183
+ when ::Bundler::Source::Metadata
176
184
  GEM_SOURCES_TYPES[:local]
177
- when Bundler::Source::Rubygems, Bundler::Source::Rubygems::Remote
185
+ when ::Bundler::Source::Rubygems, ::Bundler::Source::Rubygems::Remote
178
186
  GEM_SOURCES_TYPES[:gemfile_source]
179
- when Bundler::Source::Git
187
+ when ::Bundler::Source::Git
180
188
  GEM_SOURCES_TYPES[:gemfile_git]
181
- when Bundler::Source::Path
189
+ when ::Bundler::Source::Path
182
190
  GEM_SOURCES_TYPES[:gemfile_path]
183
191
  else
184
192
  raise ArgumentError, "unknown source #{source.class}"
@@ -187,7 +195,7 @@ module Diffend
187
195
 
188
196
  # Build gem source
189
197
  #
190
- # @param spec [Bundler::StubSpecification, Bundler::LazySpecification, Gem::Specification]
198
+ # @param spec [::Bundler::StubSpecification, ::Bundler::LazySpecification, Gem::Specification]
191
199
  #
192
200
  # @return [Hash]
193
201
  def build_spec_source(spec)
@@ -201,21 +209,16 @@ module Diffend
201
209
 
202
210
  # Figure out source for gem
203
211
  #
204
- # @param spec [Bundler::StubSpecification, Bundler::LazySpecification, Gem::Specification]
212
+ # @param spec [::Bundler::StubSpecification, ::Bundler::LazySpecification, Gem::Specification]
205
213
  #
206
- # @return [Bundler::Source] gem source type
214
+ # @return [::Bundler::Source] gem source type
207
215
  def source_for_spec(spec)
208
216
  return spec.remote if spec.remote
209
217
 
210
218
  case spec.source
211
- 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
218
- when Bundler::Source::Metadata, Bundler::Source::Git, Bundler::Source::Path
219
+ when ::Bundler::Source::Rubygems
220
+ ::Bundler::Source::Rubygems::Remote.new(spec.source.remotes.last)
221
+ when ::Bundler::Source::Metadata, ::Bundler::Source::Git, ::Bundler::Source::Path
219
222
  spec.source
220
223
  else
221
224
  raise ArgumentError, "unknown source #{spec.source.class}"
@@ -224,25 +227,25 @@ module Diffend
224
227
 
225
228
  # Build gem source name
226
229
  #
227
- # @param source [Bundler::Source] gem source type
230
+ # @param source [::Bundler::Source] gem source type
228
231
  #
229
232
  # @return [String]
230
233
  def source_name_from_source(source)
231
234
  case source
232
- when Bundler::Source::Metadata
235
+ when ::Bundler::Source::Metadata
233
236
  ''
234
- when Bundler::Source::Rubygems::Remote
237
+ when ::Bundler::Source::Rubygems::Remote
235
238
  source_name(source.anonymized_uri)
236
- when Bundler::Source::Git
239
+ when ::Bundler::Source::Git
237
240
  source.instance_variable_get(:@safe_uri)
238
- when Bundler::Source::Path
241
+ when ::Bundler::Source::Path
239
242
  source.path
240
243
  else
241
244
  raise ArgumentError, "unknown source #{source.class}"
242
245
  end
243
246
  end
244
247
 
245
- # @param uri [Bundler::URI]
248
+ # @param uri [::Bundler::URI]
246
249
  #
247
250
  # @return [String]
248
251
  def source_name(uri)
@@ -269,7 +272,7 @@ module Diffend
269
272
 
270
273
  # Build gem source type
271
274
  #
272
- # @param remotes [Array<Bundler::URI>]
275
+ # @param remotes [Array<::Bundler::URI>]
273
276
  #
274
277
  # @return [Integer] internal source type
275
278
  def build_source_type(remotes)
@@ -278,7 +281,7 @@ module Diffend
278
281
 
279
282
  # Checks if we should skip a source
280
283
  #
281
- # @param source [Bundler::Source] gem source type
284
+ # @param source [::Bundler::Source] gem source type
282
285
  #
283
286
  # @return [Boolean] true if we should skip this source, false otherwise
284
287
  def skip?(source)
@@ -289,7 +292,7 @@ module Diffend
289
292
 
290
293
  # Checks if it's a self source, this happens for repositories that are a gem
291
294
  #
292
- # @param source [Bundler::Source] gem source type
295
+ # @param source [::Bundler::Source] gem source type
293
296
  #
294
297
  # @return [Boolean] true if it's a self source, false otherwise
295
298
  def me?(source)
@@ -12,7 +12,7 @@ module Diffend
12
12
  def call
13
13
  {
14
14
  'bundler' => {
15
- 'version' => Bundler::VERSION
15
+ 'version' => ::Bundler::VERSION
16
16
  },
17
17
  'environment' => environment,
18
18
  'ruby' => ruby_information,
@@ -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
@@ -55,11 +55,11 @@ module Diffend
55
55
 
56
56
  case severity
57
57
  when INFO
58
- Bundler.ui.confirm(message)
58
+ ::Bundler.ui.confirm(message)
59
59
  when WARN
60
- Bundler.ui.warn(message)
60
+ ::Bundler.ui.warn(message)
61
61
  when ERROR, FATAL
62
- Bundler.ui.error(message)
62
+ ::Bundler.ui.error(message)
63
63
  end
64
64
  end
65
65
  end
@@ -6,6 +6,7 @@
6
6
  errors
7
7
  build_bundler_definition
8
8
  commands
9
+ configs/error_messages
9
10
  config
10
11
  configs/fetcher
11
12
  configs/validator
@@ -25,19 +26,40 @@
25
26
  track
26
27
  ].each { |file| require "diffend/#{file}" }
27
28
 
28
- begin
29
- config = Diffend::Config.new(
30
- command: Diffend::Commands::EXEC,
31
- severity: Diffend::Logger::FATAL
32
- )
33
- rescue Diffend::Errors::HandledException
34
- # we silent exit here because we don't want to break client boot
35
- return
29
+ # Calculate exponential backoff
30
+ #
31
+ # @param retry_count [Integer]
32
+ #
33
+ # @return [Float] backoff value
34
+ def exponential_backoff(retry_count)
35
+ (0.25 * 1.5**retry_count.to_f).round(2)
36
36
  end
37
37
 
38
- return if %w[development test].include?(config.env)
39
-
40
38
  Thread.new do
39
+ config = nil
40
+ retry_count = 0
41
+
42
+ # There is an issue if we start to fast and there are gems that require things,
43
+ # it may break the execution. That's why we want to give the application time to boot.
44
+ sleep(0.5)
45
+
46
+ loop do
47
+ config = Diffend::Config.new(
48
+ command: Diffend::Commands::EXEC,
49
+ severity: Diffend::Logger::FATAL
50
+ )
51
+
52
+ break if config.valid?
53
+ break if retry_count == 12
54
+
55
+ sleep(exponential_backoff(retry_count))
56
+
57
+ retry_count += 1
58
+ end
59
+
60
+ Thread.exit unless config.valid?
61
+ Thread.exit unless config.deployment?
62
+
41
63
  track = Diffend::Track.new(config)
42
64
  track.start
43
65
  end
@@ -7,10 +7,12 @@
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
18
  configs/validator
@@ -42,10 +44,16 @@ module Diffend
42
44
 
43
45
  # Execute diffend plugin
44
46
  def execute
45
- return unless enabled?
47
+ return unless Diffend::Enabled.call
46
48
 
47
49
  config = Diffend::Config.new(severity: Diffend::Logger::INFO)
48
50
 
51
+ unless config.valid?
52
+ config.print_errors
53
+
54
+ exit 255
55
+ end
56
+
49
57
  Diffend::LatestVersion.call(config)
50
58
 
51
59
  Diffend::Execute.call(config)
@@ -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
@@ -7,14 +7,15 @@ module Diffend
7
7
  module RequestVerdict
8
8
  # Exceptions that we handle when there is a resolve issue
9
9
  RESOLVE_EXCEPTIONS = [
10
- Bundler::GemNotFound,
11
- Bundler::VersionConflict,
12
- Bundler::GitError
10
+ ::Bundler::GemNotFound,
11
+ ::Bundler::GitError,
12
+ ::Bundler::PermissionError,
13
+ ::Bundler::VersionConflict
13
14
  ].freeze
14
15
 
15
16
  class << self
16
17
  # @param config [Diffend::Config]
17
- # @param definition [Bundler::Definition] definition for your source
18
+ # @param definition [::Bundler::Definition] definition for your source
18
19
  def call(config, definition)
19
20
  payload = Diffend::LocalContext.call(config, definition)
20
21
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Diffend
4
4
  # Current version
5
- VERSION = '0.2.34'
5
+ VERSION = '0.2.39'
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-monitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.34
4
+ version: 0.2.39
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-30 00:00:00.000000000 Z
37
+ date: 2021-01-18 00:00:00.000000000 Z
38
38
  dependencies:
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: bundler
@@ -94,10 +94,13 @@ files:
94
94
  - diffend.gemspec
95
95
  - lib/diffend.rb
96
96
  - lib/diffend/build_bundler_definition.rb
97
+ - lib/diffend/bundle_secure.rb
97
98
  - lib/diffend/commands.rb
98
99
  - lib/diffend/config.rb
100
+ - lib/diffend/configs/error_messages.rb
99
101
  - lib/diffend/configs/fetcher.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.4
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