kpm 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/kpm.rb +5 -0
- data/lib/kpm/base_artifact.rb +2 -23
- data/lib/kpm/coordinates.rb +40 -0
- data/lib/kpm/formatter.rb +123 -0
- data/lib/kpm/inspector.rb +108 -0
- data/lib/kpm/installer.rb +39 -0
- data/lib/kpm/kaui_artifact.rb +1 -1
- data/lib/kpm/killbill_server_artifact.rb +1 -1
- data/lib/kpm/migrations.rb +94 -0
- data/lib/kpm/plugins_directory.yml +1 -1
- data/lib/kpm/plugins_manager.rb +20 -12
- data/lib/kpm/sha1_checker.rb +6 -1
- data/lib/kpm/tasks.rb +41 -0
- data/lib/kpm/uninstaller.rb +69 -0
- data/lib/kpm/version.rb +1 -1
- data/spec/kpm/remote/migrations_spec.rb +38 -0
- data/spec/kpm/unit/inspector_spec.rb +99 -0
- data/spec/kpm/unit/sha1_checker_spec.rb +16 -0
- data/spec/kpm/unit/uninstaller_spec.rb +108 -0
- data/spec/spec_helper.rb +1 -0
- metadata +13 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 14627c006a8ca097ba3574e2a06329ee1c71b3d4
|
4
|
+
data.tar.gz: 790ba80f029ff28d86d0e91088a0327653cf39cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 45c071a90801caf7a6ec2e8a83d6edd0d1567fc63a2017bf5b7f9be91ec8834ab4cf1b3cc345ddeb8d219281d5697c927367af88367d856b09d14c77aa8e2e1a
|
7
|
+
data.tar.gz: 94dffb5a06040e48f83f70f27cc8d509798848c30b76a5672dbdda12641a4e1fc72ed819b905a8735af44d107da5b72cb85627ddcc70ffea8e1fcba6da08bb9a
|
data/lib/kpm.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
module KPM
|
2
2
|
autoload :Utils, 'kpm/utils'
|
3
3
|
autoload :BaseArtifact, 'kpm/base_artifact'
|
4
|
+
autoload :Coordinates, 'kpm/coordinates'
|
5
|
+
autoload :Formatter, 'kpm/formatter'
|
6
|
+
autoload :Inspector, 'kpm/inspector'
|
4
7
|
autoload :Sha1Checker, 'kpm/sha1_checker'
|
5
8
|
autoload :TomcatManager, 'kpm/tomcat_manager'
|
6
9
|
autoload :KillbillServerArtifact, 'kpm/killbill_server_artifact'
|
@@ -9,9 +12,11 @@ module KPM
|
|
9
12
|
autoload :PluginsManager, 'kpm/plugins_manager'
|
10
13
|
autoload :BaseInstaller, 'kpm/base_installer'
|
11
14
|
autoload :Installer, 'kpm/installer'
|
15
|
+
autoload :Uninstaller, 'kpm/uninstaller'
|
12
16
|
autoload :Tasks, 'kpm/tasks'
|
13
17
|
autoload :Cli, 'kpm/cli'
|
14
18
|
autoload :PluginsDirectory, 'kpm/plugins_directory'
|
19
|
+
autoload :Migrations, 'kpm/migrations'
|
15
20
|
|
16
21
|
class << self
|
17
22
|
def root
|
data/lib/kpm/base_artifact.rb
CHANGED
@@ -65,7 +65,7 @@ module KPM
|
|
65
65
|
|
66
66
|
# Update with resolved version in case 'LATEST' was passed
|
67
67
|
coordinate_map[:version] = artifact_info[:version]
|
68
|
-
coordinates = build_coordinates(coordinate_map)
|
68
|
+
coordinates = KPM::Coordinates.build_coordinates(coordinate_map)
|
69
69
|
|
70
70
|
# Return early if there's nothing to do
|
71
71
|
if !force_download && skip_if_exists(artifact_info, coordinates, sha1_file)
|
@@ -178,7 +178,7 @@ module KPM
|
|
178
178
|
:skipped => false
|
179
179
|
}
|
180
180
|
|
181
|
-
coordinates = build_coordinates(coordinate_map)
|
181
|
+
coordinates = KPM::Coordinates.build_coordinates(coordinate_map)
|
182
182
|
begin
|
183
183
|
nexus_info = nexus_remote(overrides, ssl_verify).get_artifact_info(coordinates)
|
184
184
|
rescue NexusCli::ArtifactMalformedException => e
|
@@ -256,27 +256,6 @@ module KPM
|
|
256
256
|
res
|
257
257
|
end
|
258
258
|
|
259
|
-
def build_coordinates(coordinate_map)
|
260
|
-
group_id = coordinate_map[:group_id]
|
261
|
-
artifact_id = coordinate_map[:artifact_id]
|
262
|
-
packaging = coordinate_map[:packaging]
|
263
|
-
classifier = coordinate_map[:classifier]
|
264
|
-
version = coordinate_map[:version]
|
265
|
-
|
266
|
-
if classifier.nil?
|
267
|
-
if version.nil?
|
268
|
-
"#{group_id}:#{artifact_id}:#{packaging}"
|
269
|
-
else
|
270
|
-
"#{group_id}:#{artifact_id}:#{packaging}:#{version}"
|
271
|
-
end
|
272
|
-
else
|
273
|
-
if version.nil?
|
274
|
-
"#{group_id}:#{artifact_id}:#{packaging}:#{classifier}"
|
275
|
-
else
|
276
|
-
"#{group_id}:#{artifact_id}:#{packaging}:#{classifier}:#{version}"
|
277
|
-
end
|
278
|
-
end
|
279
|
-
end
|
280
259
|
|
281
260
|
# Magic methods...
|
282
261
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module KPM
|
2
|
+
|
3
|
+
class Coordinates
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def build_coordinates(coordinate_map)
|
8
|
+
group_id = coordinate_map[:group_id]
|
9
|
+
artifact_id = coordinate_map[:artifact_id]
|
10
|
+
packaging = coordinate_map[:packaging]
|
11
|
+
classifier = coordinate_map[:classifier]
|
12
|
+
version = coordinate_map[:version]
|
13
|
+
|
14
|
+
if classifier.nil?
|
15
|
+
if version.nil?
|
16
|
+
"#{group_id}:#{artifact_id}:#{packaging}"
|
17
|
+
else
|
18
|
+
"#{group_id}:#{artifact_id}:#{packaging}:#{version}"
|
19
|
+
end
|
20
|
+
else
|
21
|
+
"#{group_id}:#{artifact_id}:#{packaging}:#{classifier}:#{version}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_coordinate_map(entry)
|
26
|
+
parts = entry.split(':')
|
27
|
+
length = parts.size
|
28
|
+
if length == 3
|
29
|
+
{:group_id => parts[0], :artifact_id => parts[1], :packaging => parts[2]}
|
30
|
+
elsif length == 4
|
31
|
+
{:group_id => parts[0], :artifact_id => parts[1], :packaging => parts[2], :version => parts[3]}
|
32
|
+
elsif length == 5
|
33
|
+
{:group_id => parts[0], :artifact_id => parts[1], :packaging => parts[2], :classifier => parts[3], :version => parts[4]}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# Extend String to be able to instantiate a object based on its classname
|
2
|
+
class String
|
3
|
+
def to_class
|
4
|
+
self.split('::').inject(Kernel) do |mod, class_name|
|
5
|
+
mod.const_get(class_name)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module KPM
|
11
|
+
|
12
|
+
class Formatter
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
end
|
16
|
+
|
17
|
+
# Used for normal types where to_s is enough
|
18
|
+
class DefaultFormatter
|
19
|
+
|
20
|
+
def initialize(label, input)
|
21
|
+
@label = label
|
22
|
+
@input = input
|
23
|
+
end
|
24
|
+
|
25
|
+
def size
|
26
|
+
to_s.size
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
@input.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
def label
|
34
|
+
@label.to_s.upcase.gsub(/_/, ' ')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Used for the version map
|
39
|
+
class VersionFormatter
|
40
|
+
|
41
|
+
def initialize(label, versions)
|
42
|
+
@label = label
|
43
|
+
@versions = versions
|
44
|
+
end
|
45
|
+
|
46
|
+
def size
|
47
|
+
to_s.size
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_s
|
51
|
+
@versions.map { |q| sha1=format_sha(q[:sha1]); disabled=""; disabled="(x)" if q[:is_disabled]; default=""; default="(*)" if q[:is_default]; "#{q[:version]}#{sha1}#{default}#{disabled}" }.join(", ")
|
52
|
+
end
|
53
|
+
|
54
|
+
def label
|
55
|
+
"#{@label.to_s.upcase.gsub(/_/, ' ')} sha1=[], def=(*), del=(x)"
|
56
|
+
end
|
57
|
+
|
58
|
+
def format_sha(sha)
|
59
|
+
return "[???]" if sha.nil?
|
60
|
+
"[#{sha[0..5]}..]"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def format(all_plugins)
|
66
|
+
if all_plugins.size == 0
|
67
|
+
return
|
68
|
+
end
|
69
|
+
|
70
|
+
# What we want to output
|
71
|
+
labels = [{:label => :plugin_name},
|
72
|
+
{:label => :plugin_key},
|
73
|
+
{:label => :type},
|
74
|
+
{:label => :group_id},
|
75
|
+
{:label => :artifact_id},
|
76
|
+
{:label => :packaging},
|
77
|
+
{:label => :versions, :formatter => VersionFormatter.name}]
|
78
|
+
|
79
|
+
# Compute label to print along with max size for each label
|
80
|
+
labels_format_argument = []
|
81
|
+
all_plugins.keys.each do |key|
|
82
|
+
v = all_plugins[key]
|
83
|
+
labels.each do |e|
|
84
|
+
# sanitize entry at the same time
|
85
|
+
v[e[:label]] = v[e[:label]] || "???"
|
86
|
+
|
87
|
+
formatter = e[:formatter].nil? ? DefaultFormatter.new(e[:label], v[e[:label]]) : e[:formatter].to_class.new(e[:label], v[e[:label]])
|
88
|
+
prev_size = e.key?(:size) ? e[:size] : formatter.label.size
|
89
|
+
cur_size = formatter.size
|
90
|
+
e[:size] = prev_size < cur_size ? cur_size : prev_size
|
91
|
+
labels_format_argument << formatter.label
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
border = "_"
|
98
|
+
border = (0...labels.size).inject(border) { |res, i| res="#{res}_"; res }
|
99
|
+
border = labels.inject(border) { |res, lbl| (0...lbl[:size] + 2).each { |s| res="#{res}_" }; res }
|
100
|
+
format = "|"
|
101
|
+
format = labels.inject(format) { |res, lbl| res="#{res} %#{lbl[:size]}s |"; res }
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
puts "\n#{border}\n"
|
106
|
+
puts "#{format}\n" % labels_format_argument
|
107
|
+
puts "#{border}\n"
|
108
|
+
|
109
|
+
all_plugins.keys.each do |key|
|
110
|
+
v = all_plugins[key]
|
111
|
+
|
112
|
+
arguments = []
|
113
|
+
labels.inject(arguments) do |res, e|
|
114
|
+
formatter = e[:formatter].nil? ? DefaultFormatter.new(e[:label], v[e[:label]]) : e[:formatter].to_class.new(e[:label], v[e[:label]])
|
115
|
+
res << formatter.to_s
|
116
|
+
end
|
117
|
+
puts "#{format}\n" % arguments
|
118
|
+
end
|
119
|
+
puts "#{border}\n\n"
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module KPM
|
2
|
+
|
3
|
+
class Inspector
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
end
|
7
|
+
|
8
|
+
def inspect(bundles_dir)
|
9
|
+
bundles_dir = Pathname.new(bundles_dir || KPM::BaseInstaller::DEFAULT_BUNDLES_DIR).expand_path
|
10
|
+
plugins= bundles_dir.join('plugins')
|
11
|
+
ruby_plugins_path=bundles_dir.join('plugins/ruby')
|
12
|
+
java_plugins_path=bundles_dir.join('plugins/java')
|
13
|
+
|
14
|
+
all_plugins = {}
|
15
|
+
build_plugins_for_type(ruby_plugins_path, 'ruby', all_plugins)
|
16
|
+
build_plugins_for_type(java_plugins_path, 'java', all_plugins)
|
17
|
+
|
18
|
+
add_plugin_identifier_info(plugins, all_plugins)
|
19
|
+
|
20
|
+
add_sha1_info(bundles_dir, all_plugins)
|
21
|
+
|
22
|
+
all_plugins
|
23
|
+
end
|
24
|
+
|
25
|
+
def format(all_plugins)
|
26
|
+
formatter = KPM::Formatter.new
|
27
|
+
formatter.format(all_plugins)
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def add_sha1_info(bundles_dir, all_plugins)
|
34
|
+
|
35
|
+
sha1_filename = KPM::BaseInstaller::SHA1_FILENAME
|
36
|
+
sha1_file = "#{bundles_dir}/#{sha1_filename}"
|
37
|
+
sha1_checker = Sha1Checker.from_file(sha1_file)
|
38
|
+
|
39
|
+
all_plugins.keys.each do |cur_plugin_name|
|
40
|
+
cur = all_plugins[cur_plugin_name]
|
41
|
+
|
42
|
+
sha1_checker.all_sha1.each do |e|
|
43
|
+
coord, sha1 = e
|
44
|
+
coordinate_map = KPM::Coordinates.get_coordinate_map(coord)
|
45
|
+
|
46
|
+
if coordinate_map[:group_id] == cur[:group_id] &&
|
47
|
+
coordinate_map[:artifact_id] == cur[:artifact_id] &&
|
48
|
+
coordinate_map[:packaging] == cur[:packaging]
|
49
|
+
|
50
|
+
found_version = cur[:versions].select { |v| v[:version] == coordinate_map[:version] }[0]
|
51
|
+
found_version[:sha1] = sha1 if found_version
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_plugin_identifier_info(plugins, all_plugins)
|
59
|
+
plugins_manager = PluginsManager.new(plugins, @logger)
|
60
|
+
all_plugins.keys.each do |cur|
|
61
|
+
plugin_key, entry = plugins_manager.get_identifier_key_and_entry(cur)
|
62
|
+
all_plugins[cur][:plugin_key] = plugin_key
|
63
|
+
all_plugins[cur][:group_id] = entry ? entry['group_id'] : nil
|
64
|
+
all_plugins[cur][:artifact_id] = entry ? entry['artifact_id'] : nil
|
65
|
+
all_plugins[cur][:packaging] = entry ? entry['packaging'] : nil
|
66
|
+
all_plugins[cur][:classifier] = entry ? entry['classifier'] : nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
def build_plugins_for_type(plugins_path, type, res)
|
72
|
+
if !File.exists?(plugins_path)
|
73
|
+
return []
|
74
|
+
end
|
75
|
+
get_entries(plugins_path).inject(res) do |out, e|
|
76
|
+
plugin_map = build_plugin_map(e, plugins_path.join(e), type)
|
77
|
+
out[e] = plugin_map
|
78
|
+
out
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def build_plugin_map(plugin_name, plugin_path, type)
|
83
|
+
|
84
|
+
plugin_map = {:plugin_name => plugin_name, :plugin_path => plugin_path.to_s, :type => type}
|
85
|
+
entries = get_entries(plugin_path)
|
86
|
+
set_default = entries.select { |e| e == "SET_DEFAULT" }[0]
|
87
|
+
default_version = File.basename(File.readlink(plugin_path.join(set_default))) if set_default
|
88
|
+
|
89
|
+
versions = entries.select do |e|
|
90
|
+
e != "SET_DEFAULT"
|
91
|
+
end.inject([]) do |out, e|
|
92
|
+
is_disabled = File.exists?(plugin_path.join(e).join('tmp').join('disabled.txt'))
|
93
|
+
out << {:version => e, :is_default => default_version == e, :is_disabled => is_disabled, :sha1 => nil};
|
94
|
+
out
|
95
|
+
end
|
96
|
+
|
97
|
+
versions.sort! { |a, b| a[:version] <=> b[:version] }
|
98
|
+
plugin_map[:versions] = versions || []
|
99
|
+
|
100
|
+
plugin_map
|
101
|
+
end
|
102
|
+
|
103
|
+
def get_entries(path)
|
104
|
+
Dir.entries(path).select { |entry| entry != '.' && entry != '..' && File.directory?(File.join(path, entry)) }
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
data/lib/kpm/installer.rb
CHANGED
@@ -39,6 +39,7 @@ module KPM
|
|
39
39
|
unless @config['default_bundles'] == false
|
40
40
|
install_default_bundles(@config['plugins_dir'], @config['default_bundles_version'], @config['version'], force_download, verify_sha1)
|
41
41
|
end
|
42
|
+
clean_up_descriptors
|
42
43
|
end
|
43
44
|
|
44
45
|
unless @kaui_config.nil?
|
@@ -99,5 +100,43 @@ module KPM
|
|
99
100
|
|
100
101
|
infos
|
101
102
|
end
|
103
|
+
|
104
|
+
def clean_up_descriptors
|
105
|
+
removed_plugins = clean_up_plugin_identifiers
|
106
|
+
clean_up_sha1s(removed_plugins)
|
107
|
+
end
|
108
|
+
|
109
|
+
def clean_up_plugin_identifiers
|
110
|
+
inspector = KPM::Inspector.new
|
111
|
+
installed_plugins = inspector.inspect(@config['plugins_dir'])
|
112
|
+
|
113
|
+
plugins_installation_path = File.join(@config['plugins_dir'], 'plugins')
|
114
|
+
plugins_manager = KPM::PluginsManager.new(plugins_installation_path, @logger)
|
115
|
+
|
116
|
+
plugin_identifiers = plugins_manager.read_plugin_identifiers
|
117
|
+
removed_identifiers = []
|
118
|
+
plugin_identifiers.each do |plugin_key, plugin|
|
119
|
+
if !installed_plugins.has_key?(plugin['plugin_name'])
|
120
|
+
_, plugin_entry = plugins_manager.get_identifier_key_and_entry(plugin_key)
|
121
|
+
plugins_manager.remove_plugin_identifier_key(plugin_key)
|
122
|
+
removed_identifiers << plugin_entry
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
removed_identifiers
|
127
|
+
end
|
128
|
+
|
129
|
+
def clean_up_sha1s(removed_plugins)
|
130
|
+
sha1checker = KPM::Sha1Checker.from_file(File.join(@config['plugins_dir'], KPM::BaseInstaller::SHA1_FILENAME))
|
131
|
+
removed_plugins.each do |removed|
|
132
|
+
coordinates = KPM::Coordinates.build_coordinates(group_id: removed['group_id'],
|
133
|
+
artifact_id: removed['artifact_id'],
|
134
|
+
packaging: removed['packaging'],
|
135
|
+
classifier: removed['classifier'],
|
136
|
+
version: removed['version'])
|
137
|
+
sha1checker.remove_entry!(coordinates)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
102
141
|
end
|
103
142
|
end
|
data/lib/kpm/kaui_artifact.rb
CHANGED
@@ -8,7 +8,7 @@ module KPM
|
|
8
8
|
|
9
9
|
coordinate_map = {:group_id => KPM::BaseArtifact::KAUI_GROUP_ID, :artifact_id => KPM::BaseArtifact::KAUI_ARTIFACT_ID, :packaging => KPM::BaseArtifact::KAUI_PACKAGING, :classifier => KPM::BaseArtifact::KAUI_CLASSIFIER}
|
10
10
|
|
11
|
-
coordinates = build_coordinates(coordinate_map)
|
11
|
+
coordinates = KPM::Coordinates.build_coordinates(coordinate_map)
|
12
12
|
response = REXML::Document.new nexus_remote(overrides, ssl_verify).search_for_artifacts(coordinates)
|
13
13
|
versions = SortedSet.new
|
14
14
|
response.elements.each('search-results/data/artifact/version') { |element| versions << element.text }
|
@@ -6,7 +6,7 @@ module KPM
|
|
6
6
|
class << self
|
7
7
|
def versions(artifact_id, packaging=KPM::BaseArtifact::KILLBILL_PACKAGING, classifier=KPM::BaseArtifact::KILLBILL_CLASSIFIER, overrides={}, ssl_verify=true)
|
8
8
|
coordinate_map = {:group_id => KPM::BaseArtifact::KILLBILL_GROUP_ID, :artifact_id => artifact_id, :packaging => packaging, :classifier => classifier}
|
9
|
-
coordinates = build_coordinates(coordinate_map)
|
9
|
+
coordinates = KPM::Coordinates.build_coordinates(coordinate_map)
|
10
10
|
response = REXML::Document.new nexus_remote(overrides, ssl_verify).search_for_artifacts(coordinates)
|
11
11
|
versions = SortedSet.new
|
12
12
|
response.elements.each('search-results/data/artifact/version') { |element| versions << element.text }
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'json'
|
3
|
+
require 'logger'
|
4
|
+
require 'open-uri'
|
5
|
+
require 'pathname'
|
6
|
+
|
7
|
+
module KPM
|
8
|
+
class Migrations
|
9
|
+
|
10
|
+
KILLBILL_MIGRATION_PATH = /src\/main\/resources\/org\/killbill\/billing\/[a-z]+\/migration\/(V[0-9a-zA-Z_]+.sql)/
|
11
|
+
JAVA_PLUGIN_MIGRATION_PATH = /src\/main\/resources\/migration\/(V[0-9a-zA-Z_]+.sql)/
|
12
|
+
RUBY_PLUGIN_MIGRATION_PATH = /db\/migrate\/([0-9a-zA-Z_]+.rb)/
|
13
|
+
|
14
|
+
# Go to https://github.com/settings/tokens to generate a token
|
15
|
+
def initialize(from_version, to_version = nil, repository = 'killbill/killbill', oauth_token = nil, logger = Logger.new(STDOUT))
|
16
|
+
@from_version = from_version
|
17
|
+
@to_version = to_version
|
18
|
+
@repository = repository
|
19
|
+
@oauth_token = oauth_token
|
20
|
+
@logger = logger
|
21
|
+
end
|
22
|
+
|
23
|
+
def migrations
|
24
|
+
@migrations ||= begin
|
25
|
+
if @to_version.nil?
|
26
|
+
for_version(@from_version)
|
27
|
+
else
|
28
|
+
migrations_to_skip = Set.new
|
29
|
+
for_version(@from_version, true).each { |migration| migrations_to_skip << migration[:name] }
|
30
|
+
|
31
|
+
for_version(@to_version, false, migrations_to_skip)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def save(dir = nil)
|
37
|
+
return nil if migrations.size == 0
|
38
|
+
|
39
|
+
dir ||= Dir.mktmpdir
|
40
|
+
@logger.debug("Storing migrations to #{dir}")
|
41
|
+
migrations.each do |migration|
|
42
|
+
migration_path = Pathname.new(dir).join(migration[:name])
|
43
|
+
File.open(migration_path, 'w') do |file|
|
44
|
+
@logger.debug("Storing migration #{migration_path}")
|
45
|
+
file.write(migration[:sql])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
dir
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def for_version(version = @from_version, name_only = false, migrations_to_skip = Set.new)
|
54
|
+
@logger.info("Looking for migrations repository=#{@repository}, version=#{version}")
|
55
|
+
metadata = get_as_json("https://api.github.com/repos/#{@repository}/git/trees/#{version}?recursive=1&access_token=#{@oauth_token}")
|
56
|
+
|
57
|
+
migrations = []
|
58
|
+
metadata['tree'].each do |entry|
|
59
|
+
match_data = KILLBILL_MIGRATION_PATH.match(entry['path']) || JAVA_PLUGIN_MIGRATION_PATH.match(entry['path']) || RUBY_PLUGIN_MIGRATION_PATH.match(entry['path'])
|
60
|
+
next unless match_data
|
61
|
+
|
62
|
+
migration_name = match_data[1]
|
63
|
+
@logger.info("Found migration #{migration_name}")
|
64
|
+
next if migrations_to_skip.include?(migration_name)
|
65
|
+
|
66
|
+
sql = nil
|
67
|
+
unless name_only
|
68
|
+
blob_metadata = get_as_json("#{entry['url']}?access_token=#{@oauth_token}")
|
69
|
+
sql = decode(blob_metadata['content'], blob_metadata['encoding'])
|
70
|
+
end
|
71
|
+
|
72
|
+
migrations << {
|
73
|
+
:name => migration_name,
|
74
|
+
:sql => sql
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
migrations
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_as_json(url)
|
82
|
+
raw = URI.parse(url).read
|
83
|
+
JSON.parse(raw)
|
84
|
+
end
|
85
|
+
|
86
|
+
def decode(content, encoding)
|
87
|
+
if encoding == 'base64'
|
88
|
+
Base64.decode64(content)
|
89
|
+
else
|
90
|
+
content
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/kpm/plugins_manager.rb
CHANGED
@@ -111,6 +111,14 @@ module KPM
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
+
def get_identifier_key_and_entry(plugin_name_or_key)
|
115
|
+
identifiers = read_plugin_identifiers
|
116
|
+
identifiers.each_pair do |key, value|
|
117
|
+
return [key, value] if key == plugin_name_or_key || value['plugin_name'] == plugin_name_or_key
|
118
|
+
end
|
119
|
+
nil
|
120
|
+
end
|
121
|
+
|
114
122
|
def guess_plugin_name(artifact_id)
|
115
123
|
return nil if artifact_id.nil?
|
116
124
|
captures = artifact_id.scan(/(.*)-plugin/)
|
@@ -132,6 +140,18 @@ module KPM
|
|
132
140
|
nil
|
133
141
|
end
|
134
142
|
|
143
|
+
def read_plugin_identifiers
|
144
|
+
path = Pathname.new(@plugins_dir).join('plugin_identifiers.json')
|
145
|
+
identifiers = {}
|
146
|
+
begin
|
147
|
+
identifiers = File.open(path, 'r') do |f|
|
148
|
+
JSON.parse(f.read)
|
149
|
+
end
|
150
|
+
rescue Errno::ENOENT
|
151
|
+
end
|
152
|
+
identifiers
|
153
|
+
end
|
154
|
+
|
135
155
|
private
|
136
156
|
|
137
157
|
def validate_plugin_identifier_key_value(plugin_key, value_type, entry_value, coordinate_value)
|
@@ -145,18 +165,6 @@ module KPM
|
|
145
165
|
true
|
146
166
|
end
|
147
167
|
|
148
|
-
def read_plugin_identifiers
|
149
|
-
path = Pathname.new(@plugins_dir).join('plugin_identifiers.json')
|
150
|
-
identifiers = {}
|
151
|
-
begin
|
152
|
-
identifiers = File.open(path, 'r') do |f|
|
153
|
-
JSON.parse(f.read)
|
154
|
-
end
|
155
|
-
rescue Errno::ENOENT
|
156
|
-
end
|
157
|
-
identifiers
|
158
|
-
end
|
159
|
-
|
160
168
|
def write_plugin_identifiers(identifiers)
|
161
169
|
|
162
170
|
path = Pathname.new(@plugins_dir).join('plugin_identifiers.json')
|
data/lib/kpm/sha1_checker.rb
CHANGED
data/lib/kpm/tasks.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'highline'
|
2
2
|
require 'logger'
|
3
3
|
require 'thor'
|
4
|
+
require 'pathname'
|
4
5
|
|
5
6
|
module KPM
|
6
7
|
module Tasks
|
@@ -32,6 +33,19 @@ module KPM
|
|
32
33
|
say help, :green unless help.nil?
|
33
34
|
end
|
34
35
|
|
36
|
+
method_option :destination,
|
37
|
+
:type => :string,
|
38
|
+
:default => nil,
|
39
|
+
:desc => 'A different folder other than the default bundles directory.'
|
40
|
+
method_option :force,
|
41
|
+
:type => :boolean,
|
42
|
+
:default => nil,
|
43
|
+
:desc => 'Don\'t ask for confirmation while deleting multiple versions of a plugin.'
|
44
|
+
desc 'uninstall plugin', 'Uninstall the specified plugin, identified by its name or key, from current deployment'
|
45
|
+
def uninstall(plugin)
|
46
|
+
say 'Done!' if Uninstaller.new(options[:destination]).uninstall_plugin(plugin, options[:force])
|
47
|
+
end
|
48
|
+
|
35
49
|
method_option :destination,
|
36
50
|
:type => :string,
|
37
51
|
:default => nil,
|
@@ -324,6 +338,33 @@ module KPM
|
|
324
338
|
say "Known plugin for KB version #{options[:version]}\n " + (plugins_info.map {|k,v| "#{k} #{v}"}).join("\n "), :green
|
325
339
|
end
|
326
340
|
|
341
|
+
method_option :destination,
|
342
|
+
:type => :string,
|
343
|
+
:default => nil,
|
344
|
+
:desc => 'Folder where to download migration files.'
|
345
|
+
method_option :token,
|
346
|
+
:type => :string,
|
347
|
+
:default => nil,
|
348
|
+
:desc => 'GitHub OAuth token.'
|
349
|
+
desc 'migrations repository from to', 'Download migration files for Kill Bill or a plugin'
|
350
|
+
def migrations(repository, from, to = nil)
|
351
|
+
full_repo = repository.include?('/') ? repository : "killbill/#{repository}"
|
352
|
+
dir = KPM::Migrations.new(from, to, full_repo, options[:token], logger).save(options[:destination])
|
353
|
+
say (dir.nil? ? 'No migration required' : "Migrations can be found at #{dir}"), :green
|
354
|
+
end
|
355
|
+
|
356
|
+
method_option :destination,
|
357
|
+
:type => :string,
|
358
|
+
:default => nil,
|
359
|
+
:desc => 'A different folder other than the default bundles directory.'
|
360
|
+
desc 'inspect', 'Inspect current deployment'
|
361
|
+
def inspect
|
362
|
+
inspector = KPM::Inspector.new
|
363
|
+
all_plugins = inspector.inspect(options[:destination])
|
364
|
+
#puts all_plugins.to_json
|
365
|
+
inspector.format(all_plugins)
|
366
|
+
end
|
367
|
+
|
327
368
|
private
|
328
369
|
|
329
370
|
def logger
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module KPM
|
2
|
+
class Uninstaller
|
3
|
+
def initialize(destination, logger = nil)
|
4
|
+
@logger = logger
|
5
|
+
if @logger.nil?
|
6
|
+
@logger = Logger.new(STDOUT)
|
7
|
+
@logger.level = Logger::INFO
|
8
|
+
end
|
9
|
+
|
10
|
+
destination ||= KPM::BaseInstaller::DEFAULT_BUNDLES_DIR
|
11
|
+
@installed_plugins = Inspector.new.inspect(destination)
|
12
|
+
|
13
|
+
plugins_installation_path = File.join(destination, 'plugins')
|
14
|
+
@plugins_manager = PluginsManager.new(plugins_installation_path, @logger)
|
15
|
+
|
16
|
+
sha1_file_path = File.join(destination, KPM::BaseInstaller::SHA1_FILENAME)
|
17
|
+
@sha1checker = KPM::Sha1Checker.from_file(sha1_file_path, @logger)
|
18
|
+
end
|
19
|
+
|
20
|
+
def uninstall_plugin(plugin, force = false)
|
21
|
+
plugin_info = find_plugin(plugin)
|
22
|
+
raise "No plugin with key/name '#{plugin}' found installed. Try running 'kpm inspect' for more info" unless plugin_info
|
23
|
+
|
24
|
+
remove_all_plugin_versions(plugin_info, force)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def find_plugin(plugin)
|
30
|
+
plugin_info = @installed_plugins[plugin]
|
31
|
+
if plugin_info.nil?
|
32
|
+
@installed_plugins.each do |_, info|
|
33
|
+
if info[:plugin_key] == plugin
|
34
|
+
plugin_info = info
|
35
|
+
break
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
plugin_info
|
41
|
+
end
|
42
|
+
|
43
|
+
def remove_all_plugin_versions(plugin_info, force = false)
|
44
|
+
versions = plugin_info[:versions].map { |artifact| artifact[:version] }
|
45
|
+
KPM.ui.say "Removing the following versions of the #{plugin_info[:plugin_name]} plugin: #{versions.join(', ')}"
|
46
|
+
if !force && versions.length > 1
|
47
|
+
return false unless 'y' == KPM.ui.ask('Are you sure you want to continue?', limited_to: %w(y n))
|
48
|
+
end
|
49
|
+
|
50
|
+
FileUtils.rmtree(plugin_info[:plugin_path])
|
51
|
+
|
52
|
+
@plugins_manager.remove_plugin_identifier_key(plugin_info[:plugin_key])
|
53
|
+
versions.each do |version|
|
54
|
+
remove_sha1_entry(plugin_info, version)
|
55
|
+
end
|
56
|
+
|
57
|
+
true
|
58
|
+
end
|
59
|
+
|
60
|
+
def remove_sha1_entry(plugin_info, version)
|
61
|
+
coordinates = KPM::Coordinates.build_coordinates(group_id: plugin_info[:group_id],
|
62
|
+
artifact_id: plugin_info[:artifact_id],
|
63
|
+
packaging: plugin_info[:packaging],
|
64
|
+
classifier: plugin_info[:classifier],
|
65
|
+
version: version)
|
66
|
+
@sha1checker.remove_entry!(coordinates)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/kpm/version.rb
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe KPM::Migrations do
|
4
|
+
|
5
|
+
context 'plugins' do
|
6
|
+
it 'should be able to find migrations for a java plugin' do
|
7
|
+
migrations = KPM::Migrations.new('master', nil, 'killbill/killbill-analytics-plugin', ENV['TOKEN']).migrations
|
8
|
+
# No migration yet
|
9
|
+
migrations.size.should == 0
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should be able to find migrations for a ruby plugin' do
|
13
|
+
migrations = KPM::Migrations.new('master', nil, 'killbill/killbill-cybersource-plugin', ENV['TOKEN']).migrations
|
14
|
+
# No migration yet
|
15
|
+
migrations.size.should == 0
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'killbill' do
|
20
|
+
it 'should be able to find migrations between two versions' do
|
21
|
+
migrations = KPM::Migrations.new('master', 'work-for-release-0.16.4', 'killbill/killbill', ENV['TOKEN']).migrations
|
22
|
+
|
23
|
+
migrations.size.should == 1
|
24
|
+
migrations.first[:name].should == 'V20160324060345__revisit_payment_methods_indexes_509.sql'
|
25
|
+
migrations.first[:sql].should == "drop index payment_methods_active_accnt on payment_methods;\n"
|
26
|
+
|
27
|
+
KPM::Migrations.new('master', 'master', 'killbill/killbill', ENV['TOKEN']).migrations.size.should == 0
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should be able to find migrations for a given version' do
|
31
|
+
migrations = KPM::Migrations.new('work-for-release-0.16.4', nil, 'killbill/killbill', ENV['TOKEN']).migrations
|
32
|
+
|
33
|
+
migrations.size.should == 1
|
34
|
+
migrations.first[:name].should == 'V20160324060345__revisit_payment_methods_indexes_509.sql'
|
35
|
+
migrations.first[:sql].should == "drop index payment_methods_active_accnt on payment_methods;\n"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe KPM::Inspector do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@logger = Logger.new(STDOUT)
|
7
|
+
@logger.level = Logger::INFO
|
8
|
+
|
9
|
+
tmp_bundles_dir = Dir.mktmpdir
|
10
|
+
@bundles_dir = Pathname.new(tmp_bundles_dir).expand_path
|
11
|
+
@plugins_dir = @bundles_dir.join('plugins')
|
12
|
+
|
13
|
+
FileUtils.mkdir_p(@plugins_dir)
|
14
|
+
|
15
|
+
@ruby_plugins_dir = @plugins_dir.join('ruby')
|
16
|
+
FileUtils.mkdir_p(@ruby_plugins_dir)
|
17
|
+
|
18
|
+
@java_plugins_dir = @plugins_dir.join('java')
|
19
|
+
FileUtils.mkdir_p(@java_plugins_dir)
|
20
|
+
|
21
|
+
@manager = KPM::PluginsManager.new(@plugins_dir, @logger)
|
22
|
+
|
23
|
+
@sha1_file = @bundles_dir.join("sha1.yml")
|
24
|
+
@sha1_checker = KPM::Sha1Checker.from_file(@sha1_file)
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
it 'should parse a correctly setup env' do
|
30
|
+
|
31
|
+
add_plugin('foo', 'plugin_foo', ['1.2.3', '2.0.0', '2.0.1'], 'ruby', 'com.foo', 'foo', 'tar.gz', nil, ['12345', '23456', '34567'], '2.0.1', ['1.2.3'])
|
32
|
+
add_plugin('bar', 'plugin_bar', ['1.0.0'], 'java', 'com.bar', 'bar', 'jar', nil, ['98765'], nil, [])
|
33
|
+
|
34
|
+
inspector = KPM::Inspector.new
|
35
|
+
all_plugins = inspector.inspect(@bundles_dir)
|
36
|
+
all_plugins.size == 2
|
37
|
+
|
38
|
+
all_plugins['plugin_bar']['plugin_key'] == 'bar'
|
39
|
+
all_plugins['plugin_bar']['plugin_path'] == @java_plugins_dir.join('plugin_bar').to_s
|
40
|
+
all_plugins['plugin_bar'][:versions].size == 1
|
41
|
+
all_plugins['plugin_bar'][:versions][0][:version] == '1.0.0'
|
42
|
+
all_plugins['plugin_bar'][:versions][0][:is_default] == true
|
43
|
+
all_plugins['plugin_bar'][:versions][0][:is_disabled] == false
|
44
|
+
all_plugins['plugin_bar'][:versions][0][:sha1] == '98765'
|
45
|
+
|
46
|
+
all_plugins['plugin_foo']['plugin_key'] == 'foo'
|
47
|
+
all_plugins['plugin_foo']['plugin_path'] == @ruby_plugins_dir.join('plugin_foo').to_s
|
48
|
+
all_plugins['plugin_foo'][:versions].size == 3
|
49
|
+
|
50
|
+
all_plugins['plugin_foo'][:versions][0][:version] == '1.2.3'
|
51
|
+
all_plugins['plugin_foo'][:versions][0][:is_default] == false
|
52
|
+
all_plugins['plugin_foo'][:versions][0][:is_disabled] == true
|
53
|
+
all_plugins['plugin_foo'][:versions][0][:sha1] == '12345'
|
54
|
+
|
55
|
+
all_plugins['plugin_foo'][:versions][1][:version] == '2.0.0'
|
56
|
+
all_plugins['plugin_foo'][:versions][1][:is_default] == false
|
57
|
+
all_plugins['plugin_foo'][:versions][1][:is_disabled] == false
|
58
|
+
all_plugins['plugin_foo'][:versions][1][:sha1] == '23456'
|
59
|
+
|
60
|
+
all_plugins['plugin_foo'][:versions][2][:version] == '2.0.1'
|
61
|
+
all_plugins['plugin_foo'][:versions][2][:is_default] == true
|
62
|
+
all_plugins['plugin_foo'][:versions][2][:is_disabled] == false
|
63
|
+
all_plugins['plugin_foo'][:versions][2][:sha1] == '34567'
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def add_plugin(plugin_key, plugin_name, versions, language, group_id, artifact_id, packaging, classifier, sha1, active_version, disabled_versions)
|
71
|
+
|
72
|
+
plugin_dir = language == 'ruby' ? @ruby_plugins_dir.join(plugin_name) : @java_plugins_dir.join(plugin_name)
|
73
|
+
|
74
|
+
versions.each_with_index do |v, idx|
|
75
|
+
|
76
|
+
coordinate_map = {:group_id => group_id, :artifact_id => artifact_id, :version => v, :packaging => packaging, :classifier => classifier}
|
77
|
+
coordinates = KPM::Coordinates.build_coordinates(coordinate_map)
|
78
|
+
|
79
|
+
@manager.add_plugin_identifier_key(plugin_key, plugin_name, language, coordinate_map)
|
80
|
+
@sha1_checker.add_or_modify_entry!(coordinates, sha1[idx])
|
81
|
+
|
82
|
+
|
83
|
+
plugin_dir_version = plugin_dir.join(v)
|
84
|
+
|
85
|
+
FileUtils.mkdir_p(plugin_dir_version)
|
86
|
+
|
87
|
+
# Create some entry to look real
|
88
|
+
some_file = 'ruby' ? 'ROOT' : '#{plugin_name}.jar'
|
89
|
+
FileUtils.touch(plugin_dir_version.join(some_file))
|
90
|
+
end
|
91
|
+
|
92
|
+
@manager.set_active(plugin_dir, active_version) if active_version
|
93
|
+
|
94
|
+
disabled_versions.each do |v|
|
95
|
+
@manager.uninstall(plugin_dir, v)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
@@ -65,6 +65,22 @@ describe KPM::Sha1Checker do
|
|
65
65
|
existing.should == 'bbb068c3fd5f95646ce0d09852f43ff67f06fccc'
|
66
66
|
end
|
67
67
|
|
68
|
+
context 'when removing an entry' do
|
69
|
+
let(:identifier) { 'killbill-plugin-match-1.0.0.tar.gz' }
|
70
|
+
before do
|
71
|
+
@sha1_checker.remove_entry!(identifier)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'does not find the entry' do
|
75
|
+
@sha1_checker.sha1(identifier).should be_nil
|
76
|
+
end
|
77
|
+
|
78
|
+
let(:reloaded_checker) { KPM::Sha1Checker.from_file(@tmp_config) }
|
79
|
+
it 'does not find entry in file system' do
|
80
|
+
reloaded_checker.sha1(identifier).should be_nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
68
84
|
it 'should work with empty config' do
|
69
85
|
|
70
86
|
tmp_destination_dir = Dir.tmpdir()
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe KPM::Uninstaller do
|
4
|
+
|
5
|
+
let(:uninstaller) { KPM::Uninstaller.new(destination) }
|
6
|
+
let(:destination) { 'somedir' }
|
7
|
+
|
8
|
+
let(:plugins_manager_mock) { double(KPM::PluginsManager) }
|
9
|
+
let(:sha1_checker_mock) { double(KPM::Sha1Checker) }
|
10
|
+
before do
|
11
|
+
KPM::Inspector.stub_chain(:new, :inspect).and_return(installed_plugins)
|
12
|
+
KPM::PluginsManager.stub(:new).and_return(plugins_manager_mock)
|
13
|
+
KPM::Sha1Checker.stub(:from_file).and_return(sha1_checker_mock)
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when plugin is not installed' do
|
17
|
+
let(:installed_plugins) { {} }
|
18
|
+
|
19
|
+
it 'raises a plugin not found error' do
|
20
|
+
expect {
|
21
|
+
uninstaller.uninstall_plugin('adyen')
|
22
|
+
}.to raise_error(StandardError, "No plugin with key/name 'adyen' found installed. Try running 'kpm inspect' for more info")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when plugin is installed' do
|
27
|
+
let(:installed_plugins) do
|
28
|
+
{
|
29
|
+
plugin_name => {
|
30
|
+
plugin_key: plugin_key,
|
31
|
+
plugin_path: plugin_path,
|
32
|
+
versions: [{version: version}],
|
33
|
+
group_id: 'group',
|
34
|
+
artifact_id: 'artifact',
|
35
|
+
packaging: 'jar'
|
36
|
+
}
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
let(:plugin_name) { 'plugin-name' }
|
41
|
+
let(:plugin_key) { 'plugin-key' }
|
42
|
+
let(:plugin_path) { 'plugin-path' }
|
43
|
+
let(:version) { '1.0' }
|
44
|
+
|
45
|
+
it 'uninstalls a plugin by name' do
|
46
|
+
FileUtils.should_receive(:rmtree).with(plugin_path)
|
47
|
+
plugins_manager_mock.should_receive(:remove_plugin_identifier_key).with(plugin_key)
|
48
|
+
sha1_checker_mock.should_receive(:remove_entry!).with("group:artifact:jar:#{version}")
|
49
|
+
|
50
|
+
uninstaller.uninstall_plugin(plugin_name).should be_true
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'uninstalls a plugin by key' do
|
54
|
+
FileUtils.should_receive(:rmtree).with(plugin_path)
|
55
|
+
plugins_manager_mock.should_receive(:remove_plugin_identifier_key).with(plugin_key)
|
56
|
+
sha1_checker_mock.should_receive(:remove_entry!).with("group:artifact:jar:#{version}")
|
57
|
+
|
58
|
+
uninstaller.uninstall_plugin(plugin_key).should be_true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'when plugin is installed' do
|
63
|
+
let(:installed_plugins) do
|
64
|
+
{
|
65
|
+
plugin_name => {
|
66
|
+
plugin_key: plugin_key,
|
67
|
+
plugin_path: plugin_path,
|
68
|
+
versions: [{version: version1},{version: version2}],
|
69
|
+
group_id: 'group',
|
70
|
+
artifact_id: 'artifact',
|
71
|
+
packaging: 'jar'
|
72
|
+
}
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
let(:plugin_name) { 'plugin-name' }
|
77
|
+
let(:plugin_key) { 'plugin-key' }
|
78
|
+
let(:plugin_path) { 'plugin-path' }
|
79
|
+
let(:version1) { '1.0' }
|
80
|
+
let(:version2) { '2.0' }
|
81
|
+
|
82
|
+
it 'uninstalls if user confirms action' do
|
83
|
+
KPM.ui.should_receive(:ask).and_return('y')
|
84
|
+
|
85
|
+
FileUtils.should_receive(:rmtree).with(plugin_path)
|
86
|
+
plugins_manager_mock.should_receive(:remove_plugin_identifier_key).with(plugin_key)
|
87
|
+
sha1_checker_mock.should_receive(:remove_entry!).with("group:artifact:jar:#{version1}")
|
88
|
+
sha1_checker_mock.should_receive(:remove_entry!).with("group:artifact:jar:#{version2}")
|
89
|
+
|
90
|
+
uninstaller.uninstall_plugin(plugin_name).should be_true
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'does nothing if user cancels' do
|
94
|
+
KPM.ui.should_receive(:ask).and_return('n')
|
95
|
+
|
96
|
+
uninstaller.uninstall_plugin(plugin_name).should be_false
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'uninstalls without confirmation if the force option is given' do
|
100
|
+
FileUtils.should_receive(:rmtree).with(plugin_path)
|
101
|
+
plugins_manager_mock.should_receive(:remove_plugin_identifier_key).with(plugin_key)
|
102
|
+
sha1_checker_mock.should_receive(:remove_entry!).with("group:artifact:jar:#{version1}")
|
103
|
+
sha1_checker_mock.should_receive(:remove_entry!).with("group:artifact:jar:#{version2}")
|
104
|
+
|
105
|
+
uninstaller.uninstall_plugin(plugin_name, true).should be_true
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kpm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kill Bill core team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: highline
|
@@ -119,16 +119,21 @@ files:
|
|
119
119
|
- lib/kpm/base_artifact.rb
|
120
120
|
- lib/kpm/base_installer.rb
|
121
121
|
- lib/kpm/cli.rb
|
122
|
+
- lib/kpm/coordinates.rb
|
123
|
+
- lib/kpm/formatter.rb
|
124
|
+
- lib/kpm/inspector.rb
|
122
125
|
- lib/kpm/installer.rb
|
123
126
|
- lib/kpm/kaui_artifact.rb
|
124
127
|
- lib/kpm/killbill_plugin_artifact.rb
|
125
128
|
- lib/kpm/killbill_server_artifact.rb
|
129
|
+
- lib/kpm/migrations.rb
|
126
130
|
- lib/kpm/plugins_directory.rb
|
127
131
|
- lib/kpm/plugins_directory.yml
|
128
132
|
- lib/kpm/plugins_manager.rb
|
129
133
|
- lib/kpm/sha1_checker.rb
|
130
134
|
- lib/kpm/tasks.rb
|
131
135
|
- lib/kpm/tomcat_manager.rb
|
136
|
+
- lib/kpm/uninstaller.rb
|
132
137
|
- lib/kpm/utils.rb
|
133
138
|
- lib/kpm/version.rb
|
134
139
|
- spec/kpm/remote/base_artifact_spec.rb
|
@@ -137,12 +142,15 @@ files:
|
|
137
142
|
- spec/kpm/remote/kaui_artifact_spec.rb
|
138
143
|
- spec/kpm/remote/killbill_plugin_artifact_spec.rb
|
139
144
|
- spec/kpm/remote/killbill_server_artifact_spec.rb
|
145
|
+
- spec/kpm/remote/migrations_spec.rb
|
140
146
|
- spec/kpm/remote/tomcat_manager_spec.rb
|
141
147
|
- spec/kpm/unit/base_artifact_spec.rb
|
148
|
+
- spec/kpm/unit/inspector_spec.rb
|
142
149
|
- spec/kpm/unit/plugins_directory_spec.rb
|
143
150
|
- spec/kpm/unit/plugins_manager_spec.rb
|
144
151
|
- spec/kpm/unit/sha1_checker_spec.rb
|
145
152
|
- spec/kpm/unit/sha1_test.yml
|
153
|
+
- spec/kpm/unit/uninstaller_spec.rb
|
146
154
|
- spec/spec_helper.rb
|
147
155
|
homepage: http://kill-bill.org
|
148
156
|
licenses:
|
@@ -177,10 +185,13 @@ test_files:
|
|
177
185
|
- spec/kpm/remote/kaui_artifact_spec.rb
|
178
186
|
- spec/kpm/remote/killbill_plugin_artifact_spec.rb
|
179
187
|
- spec/kpm/remote/killbill_server_artifact_spec.rb
|
188
|
+
- spec/kpm/remote/migrations_spec.rb
|
180
189
|
- spec/kpm/remote/tomcat_manager_spec.rb
|
181
190
|
- spec/kpm/unit/base_artifact_spec.rb
|
191
|
+
- spec/kpm/unit/inspector_spec.rb
|
182
192
|
- spec/kpm/unit/plugins_directory_spec.rb
|
183
193
|
- spec/kpm/unit/plugins_manager_spec.rb
|
184
194
|
- spec/kpm/unit/sha1_checker_spec.rb
|
185
195
|
- spec/kpm/unit/sha1_test.yml
|
196
|
+
- spec/kpm/unit/uninstaller_spec.rb
|
186
197
|
- spec/spec_helper.rb
|