simp-metadata 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +0 -0
- data/Rakefile +69 -0
- data/exe/simp-install +8 -0
- data/exe/simp-media +8 -0
- data/exe/simp-metadata +8 -0
- data/lib/simp/install.rb +0 -0
- data/lib/simp/install/command.rb +70 -0
- data/lib/simp/media.rb +9 -0
- data/lib/simp/media/command.rb +69 -0
- data/lib/simp/media/engine.rb +104 -0
- data/lib/simp/media/type.rb +14 -0
- data/lib/simp/media/type/base.rb +63 -0
- data/lib/simp/media/type/control-repo.rb +211 -0
- data/lib/simp/media/type/internet.rb +38 -0
- data/lib/simp/media/type/iso.rb +9 -0
- data/lib/simp/media/type/local.rb +36 -0
- data/lib/simp/media/type/tar.rb +71 -0
- data/lib/simp/metadata.rb +416 -0
- data/lib/simp/metadata/bootstrap_source.rb +137 -0
- data/lib/simp/metadata/buildinfo.rb +58 -0
- data/lib/simp/metadata/command.rb +92 -0
- data/lib/simp/metadata/commands.rb +21 -0
- data/lib/simp/metadata/commands/base.rb +65 -0
- data/lib/simp/metadata/commands/clone.rb +26 -0
- data/lib/simp/metadata/commands/component.rb +109 -0
- data/lib/simp/metadata/commands/delete.rb +26 -0
- data/lib/simp/metadata/commands/pry.rb +19 -0
- data/lib/simp/metadata/commands/release.rb +47 -0
- data/lib/simp/metadata/commands/releases.rb +24 -0
- data/lib/simp/metadata/commands/save.rb +33 -0
- data/lib/simp/metadata/commands/script.rb +38 -0
- data/lib/simp/metadata/commands/search.rb +65 -0
- data/lib/simp/metadata/commands/set-write-url.rb +19 -0
- data/lib/simp/metadata/commands/set-write.rb +19 -0
- data/lib/simp/metadata/commands/update.rb +46 -0
- data/lib/simp/metadata/component.rb +388 -0
- data/lib/simp/metadata/components.rb +70 -0
- data/lib/simp/metadata/engine.rb +101 -0
- data/lib/simp/metadata/fake_uri.rb +19 -0
- data/lib/simp/metadata/git_ssh_wrapper.sh +6 -0
- data/lib/simp/metadata/location.rb +198 -0
- data/lib/simp/metadata/locations.rb +54 -0
- data/lib/simp/metadata/release.rb +119 -0
- data/lib/simp/metadata/releases.rb +57 -0
- data/lib/simp/metadata/source.rb +204 -0
- data/spec/simp/media/command_spec.rb +12 -0
- data/spec/simp/media/engine_spec.rb +28 -0
- data/spec/simp/media/type/control_repo_spec.rb +23 -0
- data/spec/simp/media/type/internet_spec.rb +29 -0
- data/spec/simp/media/type/iso_spec.rb +15 -0
- data/spec/simp/media/type/local_spec.rb +16 -0
- data/spec/simp/media/type/tar_spec.rb +16 -0
- data/spec/simp/metadata/buildinfo_spec.rb +64 -0
- data/spec/simp/metadata/commands/clone_spec.rb +8 -0
- data/spec/simp/metadata/component_spec.rb +90 -0
- data/spec/simp/metadata/engine_spec.rb +70 -0
- data/spec/simp/metadata/release_spec.rb +104 -0
- data/spec/simp/metadata/source_spec.rb +25 -0
- data/spec/simp/metadata_spec.rb +175 -0
- data/spec/spec_helper.rb +40 -0
- metadata +260 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'simp/media'
|
3
|
+
|
4
|
+
describe Simp::Media::Type::Internet do
|
5
|
+
describe "with edition == 'community'" do
|
6
|
+
it "should run without errors" do
|
7
|
+
tempdir = Dir.mktmpdir("simp-media-rspec")
|
8
|
+
engine = Simp::Media::Engine.new({"version" => "test-stub", "edition" => "community", "output_type" => "tar", "output" => "#{tempdir}/test.tgz"})
|
9
|
+
expect(engine.loaded?).to match(true)
|
10
|
+
engine.run
|
11
|
+
engine.cleanup()
|
12
|
+
engine = nil
|
13
|
+
FileUtils.rmtree(tempdir)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
if (ENV.fetch("SIMP_LICENSE_KEY", nil) != nil)
|
17
|
+
describe "with edition == 'enterprise'" do
|
18
|
+
it "should run without errors" do
|
19
|
+
tempdir = Dir.mktmpdir("simp-media-rspec")
|
20
|
+
engine = Simp::Media::Engine.new({"version" => "test-stub", "edition" => "enterprise", "output_type" => "tar", "output" => "#{tempdir}/test.tgz"})
|
21
|
+
expect(engine.loaded?).to match(true)
|
22
|
+
engine.run
|
23
|
+
engine.cleanup()
|
24
|
+
engine = nil
|
25
|
+
FileUtils.rmtree(tempdir)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'simp/media'
|
3
|
+
|
4
|
+
describe Simp::Media::Type::Iso do
|
5
|
+
xit "should run without errors" do
|
6
|
+
tempdir = Dir.mktmpdir("simp-media-rspec")
|
7
|
+
engine = Simp::Media::Engine.new({"version" => "test-stub", "edition" => "community", "output_type" => "iso", "output" => "#{tempdir}/test.iso"})
|
8
|
+
expect(engine.loaded?).to match(true)
|
9
|
+
engine.run
|
10
|
+
engine.cleanup()
|
11
|
+
engine = nil
|
12
|
+
FileUtils.rmtree(tempdir)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'simp/media'
|
3
|
+
|
4
|
+
describe Simp::Media::Type::Local do
|
5
|
+
|
6
|
+
xit "should run without errors" do
|
7
|
+
tempdir = Dir.mktmpdir("simp-media-rspec")
|
8
|
+
engine = Simp::Media::Engine.new({"version" => "test-stub", "edition" => "community", "output_type" => "local", "output" => "#{tempdir}"})
|
9
|
+
expect(engine.loaded?).to match(true)
|
10
|
+
engine.run
|
11
|
+
engine.cleanup()
|
12
|
+
engine = nil
|
13
|
+
FileUtils.rmtree(tempdir)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'simp/media'
|
3
|
+
|
4
|
+
describe Simp::Media::Type::Tar do
|
5
|
+
|
6
|
+
it "should run without errors" do
|
7
|
+
tempdir = Dir.mktmpdir("simp-media-rspec")
|
8
|
+
engine = Simp::Media::Engine.new({"version" => "test-stub", "edition" => "community", "output_type" => "tar", "output" => "#{tempdir}/test.tgz"})
|
9
|
+
expect(engine.loaded?).to match(true)
|
10
|
+
engine.run
|
11
|
+
engine.cleanup()
|
12
|
+
engine = nil
|
13
|
+
FileUtils.rmtree(tempdir)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'simp/metadata'
|
3
|
+
def test_buildinfo(type)
|
4
|
+
Simp::Metadata::Buildinfo.new(test_component, type)
|
5
|
+
end
|
6
|
+
def diff_buildinfo(type)
|
7
|
+
Simp::Metadata::Buildinfo.new(diff_component, type)
|
8
|
+
end
|
9
|
+
describe Simp::Metadata::Buildinfo do
|
10
|
+
|
11
|
+
describe "#keys" do
|
12
|
+
it 'should return an Array' do
|
13
|
+
expect(test_buildinfo("rpm").keys.class.to_s).to eql("Array")
|
14
|
+
end
|
15
|
+
it "should return an Array of Strings" do
|
16
|
+
expect(test_buildinfo("rpm").keys.all? {|output| output.class.to_s == "String"}).to eql(true)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
describe "#type" do
|
20
|
+
context "when type == 'rpm'" do
|
21
|
+
it 'should return a String' do
|
22
|
+
expect(test_buildinfo("rpm").type.class.to_s).to eql("String")
|
23
|
+
end
|
24
|
+
it "should return 'rpm'" do
|
25
|
+
expect(test_buildinfo("rpm").type).to eql("rpm")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
describe "#['type']" do
|
30
|
+
context "when type == 'rpm'" do
|
31
|
+
it 'should return a String' do
|
32
|
+
expect(test_buildinfo("rpm")['type'].class.to_s).to eql("String")
|
33
|
+
end
|
34
|
+
it "should return 'rpm'" do
|
35
|
+
expect(test_buildinfo("rpm")['type']).to eql("rpm")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
describe "#build_method" do
|
40
|
+
context "when type == 'rpm'" do
|
41
|
+
it 'should return a String' do
|
42
|
+
expect(test_buildinfo("rpm").build_method.class.to_s).to eql("String")
|
43
|
+
end
|
44
|
+
it "should return 'simp-core'" do
|
45
|
+
expect(test_buildinfo("rpm").build_method).to eql("simp-core")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
context "when simp-metadata == 'metadata-build'" do
|
49
|
+
it "should return 'metadata-build'" do
|
50
|
+
expect(diff_buildinfo("rpm").build_method).to eql("metadata-build")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
describe "#['build_method']" do
|
55
|
+
context "when type == 'rpm'" do
|
56
|
+
it 'should return a String' do
|
57
|
+
expect(test_buildinfo("rpm")['build_method'].class.to_s).to eql("String")
|
58
|
+
end
|
59
|
+
it "should return 'simp-core'" do
|
60
|
+
expect(test_buildinfo("rpm")['build_method']).to eql("simp-core")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'simp/metadata'
|
3
|
+
require 'simp/metadata/commands/clone'
|
4
|
+
describe Simp::Metadata::Component do
|
5
|
+
|
6
|
+
describe "#view" do
|
7
|
+
context 'when attribute = nil' do
|
8
|
+
it "should return all information" do
|
9
|
+
release = 'test-stub'
|
10
|
+
component = 'pupmod-simp-activemq'
|
11
|
+
attribute = nil
|
12
|
+
test = component_view_instance(release, component, attribute)
|
13
|
+
expect(test).to eql("asset_name" => "activemq",
|
14
|
+
"authoritative" => "true",
|
15
|
+
"branch" => "master",
|
16
|
+
"component_source" => "simp-metadata",
|
17
|
+
"component_type" => "puppet-module",
|
18
|
+
"extension" => "tgz",
|
19
|
+
"extract" => "false",
|
20
|
+
"format" => "git",
|
21
|
+
"location" => {"extract" => "false", "primary" => "false", "method" => "git", "url" => "https://gitlab.com/simp/simp-activemq"},
|
22
|
+
"method" => "git",
|
23
|
+
"module_name" => "activemq",
|
24
|
+
"ref" => "488f5a0d5b53063c125b93a596626193b71aaa08",
|
25
|
+
"release_source" => "simp-metadata",
|
26
|
+
"tag" => "1.1.1",
|
27
|
+
"url" => "https://github.com/simp/pupmod-simp-activemq",
|
28
|
+
"version" => "1.1.1",
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
context 'when attribute = version' do
|
33
|
+
it "should return only the version" do
|
34
|
+
release = 'test-stub'
|
35
|
+
component = 'pupmod-simp-activemq'
|
36
|
+
attribute = 'version'
|
37
|
+
test = component_view_instance(release, component, attribute)
|
38
|
+
expect(test).to eql("version" => "1.1.1")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#diff" do
|
44
|
+
context 'when attribute = nil' do
|
45
|
+
it "should return all information" do
|
46
|
+
release1 = 'test-stub'
|
47
|
+
release2 = 'test-diff'
|
48
|
+
attribute = nil
|
49
|
+
component = 'pupmod-simp-activemq'
|
50
|
+
test = component_diff_instance(release1, release2, component, attribute)
|
51
|
+
expect(test).to eql("branch" => {"original" => "master", "changed" => "develop"},
|
52
|
+
"ref" => {"original" => "488f5a0d5b53063c125b93a596626193b71aaa08", "changed" => "3987ra0d5b53063f493b93a596626193b71dddd4"},
|
53
|
+
"tag" => {"original" => "1.1.1", "changed" => "1.1.2"},
|
54
|
+
"version" => {"original" => "1.1.1", "changed" => "1.1.2"})
|
55
|
+
end
|
56
|
+
end
|
57
|
+
context 'when attribute = version' do
|
58
|
+
it "should return only the version" do
|
59
|
+
release1 = 'test-stub'
|
60
|
+
release2 = 'test-diff'
|
61
|
+
attribute = 'version'
|
62
|
+
component = 'pupmod-simp-activemq'
|
63
|
+
test = component_diff_instance(release1, release2, component, attribute)
|
64
|
+
expect(test).to eql("version" => {"original" => "1.1.1", "changed" => "1.1.2"})
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
describe "#buildinfo" do
|
69
|
+
context 'when type = nil' do
|
70
|
+
it "should return a Hash" do
|
71
|
+
expect(test_component.buildinfo().class.to_s).to eql("Hash")
|
72
|
+
end
|
73
|
+
it "should contain only Simp::Metadata::Buildinfo objects" do
|
74
|
+
expect(test_component.buildinfo.all? { |buildinfo| buildinfo.class.to_s == "Simp::Metadata::Buildinfo"}).to eql(true)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "when type = 'rpm'" do
|
79
|
+
it "should return a Simp::Metadata::Buildinfo object" do
|
80
|
+
expect(test_component.buildinfo("rpm").class.to_s).to eql("Simp::Metadata::Buildinfo")
|
81
|
+
end
|
82
|
+
it "should be of type 'rpm'" do
|
83
|
+
expect(test_component.buildinfo("rpm").type).to eql("rpm")
|
84
|
+
end
|
85
|
+
it "should be of build_method 'simp-core'" do
|
86
|
+
expect(test_component.buildinfo("rpm").build_method).to eql("simp-core")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'simp/metadata'
|
3
|
+
describe Simp::Metadata::Engine do
|
4
|
+
|
5
|
+
it "should instantiate without errors" do
|
6
|
+
expect {
|
7
|
+
engine = Simp::Metadata::Engine.new
|
8
|
+
|
9
|
+
engine.cleanup()
|
10
|
+
engine = nil
|
11
|
+
}.not_to raise_error()
|
12
|
+
end
|
13
|
+
it "dirty? should return false" do
|
14
|
+
|
15
|
+
engine = Simp::Metadata::Engine.new
|
16
|
+
expect(engine.dirty?).to eql(false)
|
17
|
+
engine.cleanup()
|
18
|
+
engine = nil
|
19
|
+
end
|
20
|
+
it "save should run without errors" do
|
21
|
+
expect {
|
22
|
+
engine = Simp::Metadata::Engine.new
|
23
|
+
|
24
|
+
engine.save()
|
25
|
+
engine.cleanup()
|
26
|
+
engine = nil
|
27
|
+
}.not_to raise_error()
|
28
|
+
end
|
29
|
+
it "cleanup should run without errors" do
|
30
|
+
expect {
|
31
|
+
engine = Simp::Metadata::Engine.new
|
32
|
+
|
33
|
+
engine.cleanup()
|
34
|
+
engine = nil
|
35
|
+
}.not_to raise_error()
|
36
|
+
end
|
37
|
+
describe "components" do
|
38
|
+
it "should run without errors" do
|
39
|
+
expect {
|
40
|
+
engine = Simp::Metadata::Engine.new
|
41
|
+
|
42
|
+
engine.components()
|
43
|
+
engine = nil
|
44
|
+
}.not_to raise_error()
|
45
|
+
end
|
46
|
+
it "should return a Simp::Metadata::Components object" do
|
47
|
+
engine = Simp::Metadata::Engine.new
|
48
|
+
expect(engine.components.class.to_s).to eql("Simp::Metadata::Components")
|
49
|
+
engine.cleanup()
|
50
|
+
engine = nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
describe "releases" do
|
54
|
+
it "should run without errors" do
|
55
|
+
expect {
|
56
|
+
engine = Simp::Metadata::Engine.new
|
57
|
+
|
58
|
+
engine.releases()
|
59
|
+
engine = nil
|
60
|
+
}.not_to raise_error()
|
61
|
+
end
|
62
|
+
it "should return a Simp::Metadata::Releases object" do
|
63
|
+
engine = Simp::Metadata::Engine.new
|
64
|
+
expect(engine.releases.class.to_s).to eql("Simp::Metadata::Releases")
|
65
|
+
engine.cleanup()
|
66
|
+
engine = nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'simp/metadata'
|
3
|
+
require 'simp/metadata/commands/clone'
|
4
|
+
|
5
|
+
describe Simp::Metadata::Release do
|
6
|
+
describe '#puppetfile' do
|
7
|
+
context "when type == nil" do
|
8
|
+
|
9
|
+
it "should return a String" do
|
10
|
+
engine = Simp::Metadata::Engine.new
|
11
|
+
release = engine.releases['test-stub']
|
12
|
+
puppetfile = release.puppetfile()
|
13
|
+
expect(puppetfile.class.to_s).to eql("String")
|
14
|
+
engine.cleanup()
|
15
|
+
engine = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should return a valid Puppetfile" do
|
19
|
+
engine = Simp::Metadata::Engine.new
|
20
|
+
release = engine.releases['test-stub']
|
21
|
+
puppetfile = release.puppetfile()
|
22
|
+
expect(puppetfile.split("\n").size).to be > 2
|
23
|
+
expect(puppetfile).to match(/^mod.*\'.*\',/)
|
24
|
+
expect(puppetfile).to match(/^ :git => .*\'.*\',/)
|
25
|
+
expect(puppetfile).to match(/^ :ref => .*\'.*\'/)
|
26
|
+
engine.cleanup()
|
27
|
+
engine = nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when type == 'simp-core'" do
|
32
|
+
|
33
|
+
it "should return a String" do
|
34
|
+
engine = Simp::Metadata::Engine.new
|
35
|
+
release = engine.releases['test-stub']
|
36
|
+
puppetfile = release.puppetfile('simp-core')
|
37
|
+
expect(puppetfile.class.to_s).to eql("String")
|
38
|
+
engine.cleanup()
|
39
|
+
engine = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should return a valid Puppetfile" do
|
43
|
+
engine = Simp::Metadata::Engine.new
|
44
|
+
release = engine.releases['test-stub']
|
45
|
+
puppetfile = release.puppetfile('simp-core')
|
46
|
+
expect(puppetfile.split("\n").size).to be > 2
|
47
|
+
expect(puppetfile).to match(/^mod.*\'.*\',/)
|
48
|
+
expect(puppetfile).to match(/^ :git => .*\'.*\',/)
|
49
|
+
expect(puppetfile).to match(/^ :ref => .*\'.*\'/)
|
50
|
+
engine.cleanup()
|
51
|
+
engine = nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
describe "#diff" do
|
56
|
+
context 'when attribute is nil' do
|
57
|
+
|
58
|
+
it "should return all differences" do
|
59
|
+
release1 = 'test-stub'
|
60
|
+
release2 = 'test-diff'
|
61
|
+
attribute = nil
|
62
|
+
test = release_diff_instance(release1, release2, attribute)
|
63
|
+
expect(test).to eql(
|
64
|
+
"pupmod-simp-activemq" => {
|
65
|
+
"branch"=>{
|
66
|
+
"original" => "master",
|
67
|
+
"changed"=>"develop"
|
68
|
+
},
|
69
|
+
"tag"=>{
|
70
|
+
"original"=>"1.1.1",
|
71
|
+
"changed"=>"1.1.2"
|
72
|
+
},
|
73
|
+
"ref"=>{
|
74
|
+
"original"=>"488f5a0d5b53063c125b93a596626193b71aaa08",
|
75
|
+
"changed"=>"3987ra0d5b53063f493b93a596626193b71dddd4"
|
76
|
+
},
|
77
|
+
"version"=>{
|
78
|
+
"original"=>"1.1.1",
|
79
|
+
"changed"=>"1.1.2"
|
80
|
+
}
|
81
|
+
}
|
82
|
+
)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
context 'when attribute is "version"' do
|
86
|
+
it "should return only version" do
|
87
|
+
release1 = 'test-stub'
|
88
|
+
release2 = 'test-diff'
|
89
|
+
attribute = 'version'
|
90
|
+
test = release_diff_instance(release1, release2, attribute)
|
91
|
+
expect(test).to eql(
|
92
|
+
"pupmod-simp-activemq" => {
|
93
|
+
"version"=>{
|
94
|
+
"original"=>"1.1.1",
|
95
|
+
"changed"=>"1.1.2"
|
96
|
+
}
|
97
|
+
}
|
98
|
+
)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# vim: set expandtab ts=2 sw=2:
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'simp/metadata'
|
3
|
+
describe Simp::Metadata::Source do
|
4
|
+
it "should require a URL to be specified" do
|
5
|
+
expect {
|
6
|
+
source = Simp::Metadata::Source.new()
|
7
|
+
}.to raise_error(ArgumentError)
|
8
|
+
end
|
9
|
+
# it "should instantiate when passed a valid metadata source" do
|
10
|
+
# expect {
|
11
|
+
# source = Simp::Metadata::Source.new("file://#{File.dirname(__FILE__)}/mock_source")
|
12
|
+
# source.cleanup
|
13
|
+
# source = nil
|
14
|
+
# }.not_to raise_error
|
15
|
+
# end
|
16
|
+
# it "should instantiate when passed a valid metadata source and a cachepath" do
|
17
|
+
# expect {
|
18
|
+
# tempdir = Dir.mktmpdir("simp-metadata-rspec-")
|
19
|
+
# source = Simp::Metadata::Source.new("file://#{File.dirname(__FILE__)}/mock_source", tempdir)
|
20
|
+
# source.cleanup
|
21
|
+
# source = nil
|
22
|
+
# FileUtils.rmtree(tempdir)
|
23
|
+
# }.not_to raise_error
|
24
|
+
# end
|
25
|
+
end
|