license-acceptance 1.0.0 → 1.0.5
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
- data/Gemfile.lock +1 -1
- data/config/product_info.toml +17 -10
- data/lib/license_acceptance/acceptor.rb +20 -17
- data/lib/license_acceptance/product.rb +5 -4
- data/lib/license_acceptance/product_reader.rb +12 -12
- data/lib/license_acceptance/strategy/file.rb +6 -5
- data/lib/license_acceptance/strategy/prompt.rb +1 -1
- data/lib/license_acceptance/version.rb +1 -1
- data/spec/license_acceptance/acceptor_spec.rb +59 -6
- data/spec/license_acceptance/product_reader_spec.rb +4 -4
- data/spec/license_acceptance/product_spec.rb +2 -2
- data/spec/license_acceptance/strategy/file_spec.rb +18 -12
- data/spec/license_acceptance/strategy/prompt_spec.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e892e857adb140ddab6c76d173116f248180ced44a2e2ceeeecd9919b1a91b09
|
|
4
|
+
data.tar.gz: ce171bdadb89755fa39e0bd9ce5c5c63901d7949958a0de9a4883a823a35ae9f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0a6c4bb643dc44b5ca0ca0e0f48f6ac22ef590bc7645eea104aa584259d29a911054030749689d2be4424daed5d5a6fd2ace9554a2c7ee9989502d7f63e69d79
|
|
7
|
+
data.tar.gz: c5508cb4655eb0a02ba5c1067b9c58a8c03a08d9ff9eeed7bf0c864df31749ab649901db64c5fc3db6da1fee22f66c81e0bc27d32b02a0fc4899648033c2f408
|
data/Gemfile.lock
CHANGED
data/config/product_info.toml
CHANGED
|
@@ -2,29 +2,36 @@
|
|
|
2
2
|
title = "All known products that require license acceptance, and the mapping of parent to child relationships"
|
|
3
3
|
|
|
4
4
|
[[products]]
|
|
5
|
-
|
|
6
|
-
pretty_name = "Chef Infra"
|
|
5
|
+
id = "infra-client"
|
|
6
|
+
pretty_name = "Chef Infra Client"
|
|
7
7
|
hab_pkg_id = "chef/chef-client"
|
|
8
|
-
filename = "
|
|
8
|
+
filename = "chef_infra_client"
|
|
9
9
|
mixlib_name = "chef"
|
|
10
10
|
license_required_version = "15"
|
|
11
11
|
|
|
12
12
|
[[products]]
|
|
13
|
-
|
|
14
|
-
pretty_name = "InSpec"
|
|
13
|
+
id = "inspec"
|
|
14
|
+
pretty_name = "Chef InSpec"
|
|
15
15
|
hab_pkg_id = "chef/inspec"
|
|
16
16
|
filename = "inspec"
|
|
17
17
|
|
|
18
18
|
[[products]]
|
|
19
|
-
|
|
19
|
+
id = "supermarket"
|
|
20
20
|
pretty_name = "Supermarket"
|
|
21
21
|
filename = "supermarket"
|
|
22
22
|
|
|
23
23
|
[[products]]
|
|
24
|
-
|
|
25
|
-
pretty_name = "Chef Server"
|
|
24
|
+
id = "infra-server"
|
|
25
|
+
pretty_name = "Chef Infra Server"
|
|
26
26
|
hab_pkg_id = "chef/oc_erchef"
|
|
27
|
-
filename = "
|
|
27
|
+
filename = "chef_infra_server"
|
|
28
|
+
|
|
29
|
+
[[products]]
|
|
30
|
+
id = "push-jobs-server"
|
|
31
|
+
pretty_name = "Chef Push Jobs Server"
|
|
32
|
+
filename = "push_jobs_server"
|
|
28
33
|
|
|
29
34
|
[relationships]
|
|
30
|
-
"
|
|
35
|
+
"infra-client" = ["inspec"]
|
|
36
|
+
"infra-server" = ["infra-client"]
|
|
37
|
+
"push-jobs-server" = ["infra-client", "infra-server"]
|
|
@@ -39,21 +39,21 @@ module LicenseAcceptance
|
|
|
39
39
|
# For applications that just need simple logic to handle a failed license acceptance flow we include this small
|
|
40
40
|
# wrapper. Apps with more complex logic (like logging to a logging engine) should call the non-bang version and
|
|
41
41
|
# handle the exception.
|
|
42
|
-
def check_and_persist!(
|
|
43
|
-
check_and_persist(
|
|
44
|
-
rescue LicenseNotAcceptedError
|
|
45
|
-
output.puts "#{
|
|
42
|
+
def check_and_persist!(product_id, version)
|
|
43
|
+
check_and_persist(product_id, version)
|
|
44
|
+
rescue LicenseNotAcceptedError => e
|
|
45
|
+
output.puts "#{e.product.pretty_name} cannot execute without accepting the license"
|
|
46
46
|
exit 172
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
def check_and_persist(
|
|
49
|
+
def check_and_persist(product_id, version)
|
|
50
50
|
if accepted_no_persist?
|
|
51
51
|
logger.debug("Chef License accepted with no persistence")
|
|
52
52
|
@acceptance_value = ACCEPT_NO_PERSIST
|
|
53
53
|
return true
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
product_relationship = product_reader.lookup(
|
|
56
|
+
product_relationship = product_reader.lookup(product_id, version)
|
|
57
57
|
|
|
58
58
|
missing_licenses = file_strategy.accepted?(product_relationship)
|
|
59
59
|
|
|
@@ -87,32 +87,33 @@ module LicenseAcceptance
|
|
|
87
87
|
end
|
|
88
88
|
return true
|
|
89
89
|
else
|
|
90
|
-
raise LicenseNotAcceptedError.new(missing_licenses)
|
|
90
|
+
raise LicenseNotAcceptedError.new(product_relationship.parent, missing_licenses)
|
|
91
91
|
end
|
|
92
92
|
end
|
|
93
93
|
|
|
94
|
-
def self.check_and_persist!(
|
|
95
|
-
new(opts).check_and_persist!(
|
|
94
|
+
def self.check_and_persist!(product_id, version, opts={})
|
|
95
|
+
new(opts).check_and_persist!(product_id, version)
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
def self.check_and_persist(
|
|
99
|
-
new(opts).check_and_persist(
|
|
98
|
+
def self.check_and_persist(product_id, version, opts={})
|
|
99
|
+
new(opts).check_and_persist(product_id, version)
|
|
100
100
|
end
|
|
101
101
|
|
|
102
102
|
# Check whether the specified product requires license acceptance for the given version.
|
|
103
103
|
def license_required?(mixlib_name, version)
|
|
104
104
|
product = product_reader.lookup_by_mixlib(mixlib_name)
|
|
105
105
|
return false if product.nil?
|
|
106
|
-
|
|
106
|
+
# If they don't pass a version we assume they want latest
|
|
107
|
+
return true if version == :latest || version.nil?
|
|
107
108
|
Gem::Version.new(version) >= Gem::Version.new(product.license_required_version)
|
|
108
109
|
end
|
|
109
110
|
|
|
110
111
|
# Some callers only know about mixlib names so we need a way for them to get the product
|
|
111
|
-
#
|
|
112
|
-
def
|
|
112
|
+
# id as this library knows it.
|
|
113
|
+
def id_from_mixlib(mixlib_name)
|
|
113
114
|
product = product_reader.lookup_by_mixlib(mixlib_name)
|
|
114
115
|
return nil if product.nil?
|
|
115
|
-
product.
|
|
116
|
+
product.id
|
|
116
117
|
end
|
|
117
118
|
|
|
118
119
|
# Return the value that was matched ("accept", "accept-no-persist", etc.). Used by callers so they do not
|
|
@@ -159,8 +160,10 @@ module LicenseAcceptance
|
|
|
159
160
|
end
|
|
160
161
|
|
|
161
162
|
class LicenseNotAcceptedError < RuntimeError
|
|
162
|
-
|
|
163
|
-
|
|
163
|
+
attr_reader :product
|
|
164
|
+
def initialize(product, missing_licenses)
|
|
165
|
+
@product = product
|
|
166
|
+
msg = "Missing licenses for the following:\n* " + missing_licenses.map(&:id).join("\n* ")
|
|
164
167
|
super(msg)
|
|
165
168
|
end
|
|
166
169
|
end
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
module LicenseAcceptance
|
|
2
2
|
class Product
|
|
3
3
|
|
|
4
|
-
attr_reader :
|
|
4
|
+
attr_reader :id, :pretty_name, :filename, :mixlib_name, :license_required_version
|
|
5
5
|
|
|
6
|
-
def initialize(
|
|
7
|
-
|
|
6
|
+
def initialize(id, pretty_name, filename, mixlib_name, license_required_version)
|
|
7
|
+
# id is the internal representation of this product as license-acceptance knows it
|
|
8
|
+
@id = id
|
|
8
9
|
@pretty_name = pretty_name
|
|
9
10
|
@filename = filename
|
|
10
11
|
@mixlib_name = mixlib_name
|
|
@@ -13,7 +14,7 @@ module LicenseAcceptance
|
|
|
13
14
|
|
|
14
15
|
def ==(other)
|
|
15
16
|
return false if other.class != Product
|
|
16
|
-
if other.
|
|
17
|
+
if other.id == id &&
|
|
17
18
|
other.pretty_name == pretty_name &&
|
|
18
19
|
other.filename == filename &&
|
|
19
20
|
other.mixlib_name == mixlib_name
|
|
@@ -19,24 +19,24 @@ module LicenseAcceptance
|
|
|
19
19
|
raise InvalidProductInfo.new(location) if toml.empty? || toml["products"].nil? || toml["relationships"].nil?
|
|
20
20
|
|
|
21
21
|
for product in toml["products"]
|
|
22
|
-
products[product["
|
|
23
|
-
product["
|
|
22
|
+
products[product["id"]] = Product.new(
|
|
23
|
+
product["id"], product["pretty_name"],
|
|
24
24
|
product["filename"], product["mixlib_name"],
|
|
25
25
|
product["license_required_version"]
|
|
26
26
|
)
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
for
|
|
30
|
-
parent = products[
|
|
31
|
-
raise UnknownParent.new(
|
|
29
|
+
for parent_id, children in toml["relationships"]
|
|
30
|
+
parent = products[parent_id]
|
|
31
|
+
raise UnknownParent.new(parent_id) if parent.nil?
|
|
32
32
|
# Its fine to not have a relationship entry, but not fine to have
|
|
33
33
|
# a relationship where the children are nil or empty.
|
|
34
34
|
if children.nil? || children.empty? || !children.is_a?(Array)
|
|
35
35
|
raise NoChildRelationships.new(parent)
|
|
36
36
|
end
|
|
37
|
-
children.map! do |
|
|
38
|
-
child = products[
|
|
39
|
-
raise UnknownChild.new(
|
|
37
|
+
children.map! do |child_id|
|
|
38
|
+
child = products[child_id]
|
|
39
|
+
raise UnknownChild.new(child_id) if child.nil?
|
|
40
40
|
child
|
|
41
41
|
end
|
|
42
42
|
relationships[parent] = children
|
|
@@ -55,9 +55,9 @@ module LicenseAcceptance
|
|
|
55
55
|
File.absolute_path(File.join(__FILE__, "../../../config/product_info.toml"))
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
def lookup(
|
|
59
|
-
parent_product = products.fetch(
|
|
60
|
-
raise UnknownProduct.new(
|
|
58
|
+
def lookup(parent_id, parent_version)
|
|
59
|
+
parent_product = products.fetch(parent_id) do
|
|
60
|
+
raise UnknownProduct.new(parent_id)
|
|
61
61
|
end
|
|
62
62
|
children = relationships.fetch(parent_product, [])
|
|
63
63
|
if !parent_version.is_a? String
|
|
@@ -105,7 +105,7 @@ module LicenseAcceptance
|
|
|
105
105
|
|
|
106
106
|
class NoChildRelationships < RuntimeError
|
|
107
107
|
def initialize(product)
|
|
108
|
-
msg = "No child relationships for #{product.
|
|
108
|
+
msg = "No child relationships for #{product.id}, should be removed from product info or fixed"
|
|
109
109
|
super(msg)
|
|
110
110
|
end
|
|
111
111
|
end
|
|
@@ -25,7 +25,7 @@ module LicenseAcceptance
|
|
|
25
25
|
def accepted?(product_relationship)
|
|
26
26
|
searching = [product_relationship.parent] + product_relationship.children
|
|
27
27
|
missing_licenses = searching.clone
|
|
28
|
-
logger.debug("Searching for the following licenses: #{missing_licenses.map(&:
|
|
28
|
+
logger.debug("Searching for the following licenses: #{missing_licenses.map(&:id)}")
|
|
29
29
|
|
|
30
30
|
searching.each do |product|
|
|
31
31
|
found = false
|
|
@@ -40,7 +40,7 @@ module LicenseAcceptance
|
|
|
40
40
|
end
|
|
41
41
|
break if missing_licenses.empty?
|
|
42
42
|
end
|
|
43
|
-
logger.debug("Missing licenses remaining: #{missing_licenses.map(&:
|
|
43
|
+
logger.debug("Missing licenses remaining: #{missing_licenses.map(&:id)}")
|
|
44
44
|
missing_licenses
|
|
45
45
|
end
|
|
46
46
|
|
|
@@ -77,12 +77,13 @@ module LicenseAcceptance
|
|
|
77
77
|
|
|
78
78
|
def persist_license(folder_path, product, parent, parent_version)
|
|
79
79
|
path = ::File.join(folder_path, product.filename)
|
|
80
|
-
logger.info("Persisting a license for #{product.
|
|
80
|
+
logger.info("Persisting a license for #{product.pretty_name} at path #{path}")
|
|
81
81
|
::File.open(path, ::File::WRONLY | ::File::CREAT | ::File::EXCL) do |license_file|
|
|
82
82
|
contents = {
|
|
83
|
-
|
|
83
|
+
id: product.id,
|
|
84
|
+
name: product.pretty_name,
|
|
84
85
|
date_accepted: INVOCATION_TIME.iso8601,
|
|
85
|
-
accepting_product: parent.
|
|
86
|
+
accepting_product: parent.id,
|
|
86
87
|
accepting_product_version: parent_version,
|
|
87
88
|
user: Etc.getlogin,
|
|
88
89
|
file_format: 1,
|
|
@@ -24,7 +24,7 @@ module LicenseAcceptance
|
|
|
24
24
|
CHECK = PASTEL.green("✔")
|
|
25
25
|
|
|
26
26
|
def request(missing_licenses, &persist_callback)
|
|
27
|
-
logger.debug("Requesting a license for #{missing_licenses.map(&:
|
|
27
|
+
logger.debug("Requesting a license for #{missing_licenses.map(&:id)}")
|
|
28
28
|
c = missing_licenses.size
|
|
29
29
|
s = c > 1 ? "s": ""
|
|
30
30
|
|
|
@@ -12,23 +12,28 @@ RSpec.describe LicenseAcceptance::Acceptor do
|
|
|
12
12
|
d
|
|
13
13
|
end
|
|
14
14
|
let(:opts) { { output: output } }
|
|
15
|
+
let(:reader) { instance_double(LicenseAcceptance::ProductReader) }
|
|
15
16
|
let(:acc) { LicenseAcceptance::Acceptor.new(opts) }
|
|
16
|
-
let(:product) { instance_double(LicenseAcceptance::Product,
|
|
17
|
+
let(:product) { instance_double(LicenseAcceptance::Product, id: "foo", pretty_name: "Foo") }
|
|
17
18
|
let(:version) { "version" }
|
|
18
|
-
let(:relationship) { instance_double(LicenseAcceptance::ProductRelationship) }
|
|
19
|
+
let(:relationship) { instance_double(LicenseAcceptance::ProductRelationship, parent: product) }
|
|
19
20
|
let(:missing) { [product] }
|
|
20
21
|
|
|
21
22
|
describe "#check_and_persist!" do
|
|
22
|
-
|
|
23
|
+
before do
|
|
24
|
+
expect(LicenseAcceptance::ProductReader).to receive(:new).and_return(reader)
|
|
25
|
+
expect(reader).to receive(:read)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
let(:err) { LicenseAcceptance::LicenseNotAcceptedError.new(product, [product]) }
|
|
23
29
|
it "outputs an error message to stdout and exits when license acceptance is declined" do
|
|
24
30
|
expect(acc).to receive(:check_and_persist).and_raise(err)
|
|
25
|
-
expect { acc.check_and_persist!(product.
|
|
26
|
-
expect(output.string).to match(/#{product.
|
|
31
|
+
expect { acc.check_and_persist!(product.id, version) }.to raise_error(SystemExit)
|
|
32
|
+
expect(output.string).to match(/#{product.pretty_name}/)
|
|
27
33
|
end
|
|
28
34
|
end
|
|
29
35
|
|
|
30
36
|
describe "#check_and_persist" do
|
|
31
|
-
let(:reader) { instance_double(LicenseAcceptance::ProductReader) }
|
|
32
37
|
let(:file_acc) { instance_double(LicenseAcceptance::Strategy::File) }
|
|
33
38
|
let(:arg_acc) { instance_double(LicenseAcceptance::Strategy::Argument) }
|
|
34
39
|
let(:prompt_acc) { instance_double(LicenseAcceptance::Strategy::Prompt) }
|
|
@@ -235,6 +240,54 @@ RSpec.describe LicenseAcceptance::Acceptor do
|
|
|
235
240
|
expect(acc.acceptance_value).to eq(nil)
|
|
236
241
|
end
|
|
237
242
|
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
describe "#license_required?" do
|
|
246
|
+
let(:reader) { instance_double(LicenseAcceptance::ProductReader) }
|
|
247
|
+
let(:mixlib_name) { "chef" }
|
|
248
|
+
let(:version) { "15.0.0" }
|
|
249
|
+
let(:product) { instance_double(LicenseAcceptance::Product, id: "foo", license_required_version: "15.0.0") }
|
|
250
|
+
|
|
251
|
+
before do
|
|
252
|
+
expect(LicenseAcceptance::ProductReader).to receive(:new).and_return(reader)
|
|
253
|
+
expect(reader).to receive(:read)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
it "returns false if no product can be found" do
|
|
257
|
+
expect(reader).to receive(:lookup_by_mixlib).with(mixlib_name).and_return nil
|
|
258
|
+
expect(acc.license_required?(mixlib_name, version)).to eq(false)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
describe "when version is :latest" do
|
|
262
|
+
let(:version) { :latest }
|
|
263
|
+
it "returns true" do
|
|
264
|
+
expect(reader).to receive(:lookup_by_mixlib).with(mixlib_name).and_return product
|
|
265
|
+
expect(acc.license_required?(mixlib_name, version)).to eq(true)
|
|
266
|
+
end
|
|
267
|
+
end
|
|
238
268
|
|
|
269
|
+
describe "when version is nil" do
|
|
270
|
+
let(:version) { nil }
|
|
271
|
+
it "returns true" do
|
|
272
|
+
expect(reader).to receive(:lookup_by_mixlib).with(mixlib_name).and_return product
|
|
273
|
+
expect(acc.license_required?(mixlib_name, version)).to eq(true)
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
describe "when version is >= than required version" do
|
|
278
|
+
let(:version) { "15.0.0" }
|
|
279
|
+
it "returns true" do
|
|
280
|
+
expect(reader).to receive(:lookup_by_mixlib).with(mixlib_name).and_return product
|
|
281
|
+
expect(acc.license_required?(mixlib_name, version)).to eq(true)
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
describe "when version is < required version" do
|
|
286
|
+
let(:version) { "14.99.99" }
|
|
287
|
+
it "returns false" do
|
|
288
|
+
expect(reader).to receive(:lookup_by_mixlib).with(mixlib_name).and_return product
|
|
289
|
+
expect(acc.license_required?(mixlib_name, version)).to eq(false)
|
|
290
|
+
end
|
|
291
|
+
end
|
|
239
292
|
end
|
|
240
293
|
end
|
|
@@ -7,11 +7,11 @@ RSpec.describe LicenseAcceptance::ProductReader do
|
|
|
7
7
|
let(:version) { "0.1.0" }
|
|
8
8
|
let(:location) { "location" }
|
|
9
9
|
|
|
10
|
-
let(:p1) { {"
|
|
11
|
-
let(:p2) { {"
|
|
10
|
+
let(:p1) { {"id" => "p1", "pretty_name" => "P1", "filename" => "f1", "mixlib_name" => "p1m", "license_required_version" => "p1v"} }
|
|
11
|
+
let(:p2) { {"id" => "p2", "pretty_name" => "P2", "filename" => "f2", "mixlib_name" => "p2m", "license_required_version" => "p2v"} }
|
|
12
12
|
# defined the `==` operator on Product for ease of comparison
|
|
13
|
-
let(:product1) { LicenseAcceptance::Product.new(p1["
|
|
14
|
-
let(:product2) { LicenseAcceptance::Product.new(p2["
|
|
13
|
+
let(:product1) { LicenseAcceptance::Product.new(p1["id"], p1["pretty_name"], p1["filename"], p1["mixlib_name"], p1["license_required_version"]) }
|
|
14
|
+
let(:product2) { LicenseAcceptance::Product.new(p2["id"], p2["pretty_name"], p2["filename"], p2["mixlib_name"], p2["license_required_version"]) }
|
|
15
15
|
let(:r1) { {p1 => p2} }
|
|
16
16
|
let(:toml) { {"products" => [p1, p2], "relationships" => {"p1" => ["p2"]}} }
|
|
17
17
|
|
|
@@ -2,10 +2,10 @@ require "spec_helper"
|
|
|
2
2
|
require "license_acceptance/product"
|
|
3
3
|
|
|
4
4
|
RSpec.describe LicenseAcceptance::Product do
|
|
5
|
-
let(:instance) { LicenseAcceptance::Product.new("
|
|
5
|
+
let(:instance) { LicenseAcceptance::Product.new("id", "Pretty Name", "filename", "mixlib_name", "version") }
|
|
6
6
|
|
|
7
7
|
it "can lookup the product attributes" do
|
|
8
|
-
expect(instance.
|
|
8
|
+
expect(instance.id).to eq("id")
|
|
9
9
|
expect(instance.pretty_name).to eq("Pretty Name")
|
|
10
10
|
expect(instance.filename).to eq("filename")
|
|
11
11
|
expect(instance.mixlib_name).to eq("mixlib_name")
|
|
@@ -12,9 +12,10 @@ RSpec.describe LicenseAcceptance::Strategy::File do
|
|
|
12
12
|
instance_double(LicenseAcceptance::Config, license_locations: [dir1, dir2], persist_location: dir3)
|
|
13
13
|
end
|
|
14
14
|
let(:acc) { LicenseAcceptance::Strategy::File.new(config) }
|
|
15
|
-
let(:
|
|
15
|
+
let(:p1_id) { "foo" }
|
|
16
16
|
let(:p1_filename) { "p1_filename" }
|
|
17
|
-
let(:
|
|
17
|
+
let(:p1_pretty) { "Pretty Name" }
|
|
18
|
+
let(:p1) { instance_double(LicenseAcceptance::Product, id: p1_id, filename: p1_filename, pretty_name: p1_pretty) }
|
|
18
19
|
let(:version) { "0.1.0" }
|
|
19
20
|
let(:product_relationship) { instance_double(LicenseAcceptance::ProductRelationship, parent: p1, children: [], parent_version: version) }
|
|
20
21
|
let(:mode) { File::WRONLY | File::CREAT | File::EXCL }
|
|
@@ -43,17 +44,19 @@ RSpec.describe LicenseAcceptance::Strategy::File do
|
|
|
43
44
|
expect(File).to receive(:open).with(File.join(dir3, p1_filename), mode).and_yield(file)
|
|
44
45
|
expect(file).to receive(:<<) do |yaml|
|
|
45
46
|
yaml = YAML.load(yaml)
|
|
46
|
-
expect(yaml["
|
|
47
|
-
expect(yaml["
|
|
47
|
+
expect(yaml["id"]).to eq(p1_id)
|
|
48
|
+
expect(yaml["name"]).to eq(p1_pretty)
|
|
49
|
+
expect(yaml["accepting_product"]).to eq(p1_id)
|
|
48
50
|
expect(yaml["accepting_product_version"]).to eq(version)
|
|
49
51
|
end
|
|
50
52
|
expect(acc.persist(product_relationship, [p1])).to eq([])
|
|
51
53
|
end
|
|
52
54
|
|
|
53
55
|
describe "when license has children" do
|
|
54
|
-
let(:
|
|
56
|
+
let(:p2_id) { "bar" }
|
|
55
57
|
let(:p2_filename) { "p2_filename" }
|
|
56
|
-
let(:
|
|
58
|
+
let(:p2_pretty) { "Other Pretty Name" }
|
|
59
|
+
let(:p2) { instance_double(LicenseAcceptance::Product, id: p2_id, filename: p2_filename, pretty_name: p2_pretty) }
|
|
57
60
|
let(:product_relationship) {
|
|
58
61
|
instance_double(
|
|
59
62
|
LicenseAcceptance::ProductRelationship,
|
|
@@ -68,15 +71,17 @@ RSpec.describe LicenseAcceptance::Strategy::File do
|
|
|
68
71
|
expect(File).to receive(:open).with(File.join(dir3, p1_filename), mode).and_yield(file)
|
|
69
72
|
expect(file).to receive(:<<) do |yaml|
|
|
70
73
|
yaml = YAML.load(yaml)
|
|
71
|
-
expect(yaml["
|
|
72
|
-
expect(yaml["
|
|
74
|
+
expect(yaml["id"]).to eq(p1_id)
|
|
75
|
+
expect(yaml["name"]).to eq(p1_pretty)
|
|
76
|
+
expect(yaml["accepting_product"]).to eq(p1_id)
|
|
73
77
|
expect(yaml["accepting_product_version"]).to eq(version)
|
|
74
78
|
end
|
|
75
79
|
expect(File).to receive(:open).with(File.join(dir3, p2_filename), mode).and_yield(file)
|
|
76
80
|
expect(file).to receive(:<<) do |yaml|
|
|
77
81
|
yaml = YAML.load(yaml)
|
|
78
|
-
expect(yaml["
|
|
79
|
-
expect(yaml["
|
|
82
|
+
expect(yaml["id"]).to eq(p2_id)
|
|
83
|
+
expect(yaml["name"]).to eq(p2_pretty)
|
|
84
|
+
expect(yaml["accepting_product"]).to eq(p1_id)
|
|
80
85
|
expect(yaml["accepting_product_version"]).to eq(version)
|
|
81
86
|
end
|
|
82
87
|
expect(acc.persist(product_relationship, [p1, p2])).to eq([])
|
|
@@ -88,8 +93,9 @@ RSpec.describe LicenseAcceptance::Strategy::File do
|
|
|
88
93
|
expect(File).to receive(:open).once.with(File.join(dir3, p2_filename), mode).and_yield(file)
|
|
89
94
|
expect(file).to receive(:<<) do |yaml|
|
|
90
95
|
yaml = YAML.load(yaml)
|
|
91
|
-
expect(yaml["
|
|
92
|
-
expect(yaml["
|
|
96
|
+
expect(yaml["id"]).to eq(p2_id)
|
|
97
|
+
expect(yaml["name"]).to eq(p2_pretty)
|
|
98
|
+
expect(yaml["accepting_product"]).to eq(p1_id)
|
|
93
99
|
expect(yaml["accepting_product_version"]).to eq(version)
|
|
94
100
|
end
|
|
95
101
|
expect(acc.persist(product_relationship, [p2])).to eq([])
|
|
@@ -10,7 +10,7 @@ RSpec.describe LicenseAcceptance::Strategy::Prompt do
|
|
|
10
10
|
end
|
|
11
11
|
let(:acc) { LicenseAcceptance::Strategy::Prompt.new(config) }
|
|
12
12
|
let(:prompt) { instance_double(TTY::Prompt) }
|
|
13
|
-
let(:p1) { instance_double(LicenseAcceptance::Product,
|
|
13
|
+
let(:p1) { instance_double(LicenseAcceptance::Product, id: "foo", pretty_name: "Pretty Name") }
|
|
14
14
|
let(:missing_licenses) { [p1] }
|
|
15
15
|
|
|
16
16
|
before do
|
|
@@ -29,7 +29,7 @@ RSpec.describe LicenseAcceptance::Strategy::Prompt do
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
describe "when there are multiple products" do
|
|
32
|
-
let(:p2) { instance_double(LicenseAcceptance::Product,
|
|
32
|
+
let(:p2) { instance_double(LicenseAcceptance::Product, id: "bar", pretty_name: "Other") }
|
|
33
33
|
let(:missing_licenses) { [p1, p2] }
|
|
34
34
|
it "returns true" do
|
|
35
35
|
expect(prompt).to receive(:ask).and_return("yes")
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: license-acceptance
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- tyler-ball
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-
|
|
11
|
+
date: 2019-05-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: pastel
|