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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.github/workflows/ci.yml +9 -7
- data/.ruby-version +1 -1
- data/CHANGELOG.md +36 -1
- data/Gemfile +0 -1
- data/Gemfile.lock +16 -24
- data/config/diffend.yml +6 -0
- data/lib/diffend/bundle_secure.rb +25 -0
- data/lib/diffend/commands.rb +2 -0
- data/lib/diffend/config.rb +38 -12
- data/lib/diffend/configs/error_messages.rb +38 -0
- data/lib/diffend/configs/fetcher.rb +19 -58
- data/lib/diffend/configs/validator.rb +4 -34
- data/lib/diffend/enabled.rb +22 -0
- data/lib/diffend/errors.rb +0 -4
- data/lib/diffend/local_context/host.rb +10 -2
- data/lib/diffend/local_context/packages.rb +13 -10
- data/lib/diffend/logger.rb +6 -6
- data/lib/diffend/monitor.rb +21 -7
- data/lib/diffend/plugin.rb +11 -17
- data/lib/diffend/request.rb +2 -1
- data/lib/diffend/request_verdict.rb +9 -1
- data/lib/diffend/version.rb +1 -1
- data/plugins.rb +1 -0
- metadata +7 -4
- metadata.gz.sig +0 -0
- data/lib/diffend/configs/file_finder.rb +0 -38
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6882244ccac8c68c4b0eef0e1ffceeda710c6202b28a7608e7b6502dc9c8f694
|
|
4
|
+
data.tar.gz: efd83185b8af53f813204f3265567ed2ed44b6d9e40328d13f613254e3865857
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 82509d763d303aad433d329c761d1c36e422314dfb0f55999793829a5c1d1e0a9bdcc4e23a3b4b47dd340fd97129eef567eee23320a5249c0cea956a5fd05468
|
|
7
|
+
data.tar.gz: bfff54f76c8d02c108c4416756be710991948cd3cebf35143c8ecd98e0a13777a8d445963d2986388db5a480a31094250a2ef9334bd3e58558acdd36bb12e0a7
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data.tar.gz.sig
CHANGED
|
Binary file
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -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
|
-
|
|
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
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
3.0.0
|
data/CHANGELOG.md
CHANGED
|
@@ -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.
|
|
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
data/Gemfile.lock
CHANGED
|
@@ -1,48 +1,40 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
diffend (0.2.
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
rspec (3.
|
|
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.
|
|
28
|
-
rspec-mocks (3.
|
|
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.
|
|
31
|
-
rspec-support (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.
|
|
40
|
+
2.2.4
|
data/config/diffend.yml
ADDED
|
@@ -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
|
data/lib/diffend/commands.rb
CHANGED
data/lib/diffend/config.rb
CHANGED
|
@@ -3,31 +3,50 @@
|
|
|
3
3
|
module Diffend
|
|
4
4
|
# Diffend config object
|
|
5
5
|
class Config
|
|
6
|
-
|
|
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
|
-
# @
|
|
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
|
-
# @
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
.tap(&logger.method(:fatal))
|
|
28
|
+
if File.exist?(project_config)
|
|
29
|
+
hash.merge!(read_file(project_config) || {})
|
|
30
|
+
end
|
|
34
31
|
|
|
35
|
-
|
|
32
|
+
hash
|
|
36
33
|
end
|
|
37
34
|
|
|
38
35
|
private
|
|
39
36
|
|
|
40
|
-
#
|
|
37
|
+
# Load config file
|
|
41
38
|
#
|
|
42
|
-
# @
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
25
|
-
|
|
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
|
data/lib/diffend/errors.rb
CHANGED
|
@@ -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
|
-
|
|
37
|
+
instance = new(command, definition)
|
|
38
38
|
|
|
39
|
-
instance
|
|
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
|
data/lib/diffend/logger.rb
CHANGED
|
@@ -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
|
|
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
|
data/lib/diffend/monitor.rb
CHANGED
|
@@ -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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
)
|
|
29
|
+
Thread.new do
|
|
30
|
+
config = nil
|
|
31
|
+
config_iterations = 0
|
|
33
32
|
|
|
34
|
-
|
|
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
|
data/lib/diffend/plugin.rb
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
data/lib/diffend/request.rb
CHANGED
|
@@ -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
|
|
27
|
+
rescue *RESOLVE_EXCEPTIONS
|
|
20
28
|
raise ::Diffend::Errors::DependenciesResolveException
|
|
21
29
|
rescue StandardError => e
|
|
22
30
|
Diffend::HandleErrors::Report.call(
|
data/lib/diffend/version.rb
CHANGED
data/plugins.rb
CHANGED
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.
|
|
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:
|
|
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.
|
|
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
|