nexus_cli_sb 4.0.2
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 +7 -0
- data/.gitignore +11 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +42 -0
- data/Guardfile +27 -0
- data/LICENSE +15 -0
- data/README.md +121 -0
- data/Rakefile +1 -0
- data/Thorfile +66 -0
- data/VERSION +1 -0
- data/bin/nexus-cli +10 -0
- data/data/pom.xml.erb +13 -0
- data/features/nexus_oss.feature +251 -0
- data/features/pro/nexus_custom_metadata.feature +116 -0
- data/features/pro/nexus_pro.feature +101 -0
- data/features/step_definitions/cli_steps.rb +105 -0
- data/features/support/env.rb +64 -0
- data/lib/nexus_cli/artifact.rb +44 -0
- data/lib/nexus_cli/base_remote.rb +16 -0
- data/lib/nexus_cli/cli.rb +7 -0
- data/lib/nexus_cli/configuration.rb +102 -0
- data/lib/nexus_cli/connection.rb +84 -0
- data/lib/nexus_cli/errors.rb +259 -0
- data/lib/nexus_cli/mixins/artifact_actions.rb +194 -0
- data/lib/nexus_cli/mixins/global_settings_actions.rb +64 -0
- data/lib/nexus_cli/mixins/logging_actions.rb +45 -0
- data/lib/nexus_cli/mixins/pro/custom_metadata_actions.rb +176 -0
- data/lib/nexus_cli/mixins/pro/smart_proxy_actions.rb +219 -0
- data/lib/nexus_cli/mixins/repository_actions.rb +245 -0
- data/lib/nexus_cli/mixins/user_actions.rb +125 -0
- data/lib/nexus_cli/n3_metadata.rb +77 -0
- data/lib/nexus_cli/remote/oss_remote.rb +11 -0
- data/lib/nexus_cli/remote/pro_remote.rb +59 -0
- data/lib/nexus_cli/remote_factory.rb +30 -0
- data/lib/nexus_cli/tasks.rb +496 -0
- data/lib/nexus_cli/version.rb +6 -0
- data/lib/nexus_cli.rb +44 -0
- data/nexus_cli.gemspec +31 -0
- data/spec/fixtures/metadata_search.xml +10 -0
- data/spec/fixtures/nexus.config +4 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/unit/nexus_cli/artifact_spec.rb +82 -0
- data/spec/unit/nexus_cli/configuration_spec.rb +137 -0
- data/spec/unit/nexus_cli/mixins/pro/custom_metadata_actions_spec.rb +21 -0
- data/spec/unit/nexus_cli/oss_remote_spec.rb +78 -0
- data/spec/unit/nexus_cli/pro_remote_spec.rb +110 -0
- data/spec/unit/nexus_cli/remote_factory_spec.rb +42 -0
- metadata +259 -0
@@ -0,0 +1,116 @@
|
|
1
|
+
Feature: Use the Nexus Pro CLI
|
2
|
+
As a Pro CLI user
|
3
|
+
I need commands to get, update, search, and delete Nexus artifact custom metadata
|
4
|
+
|
5
|
+
Scenario: Push an artifact
|
6
|
+
When I push an artifact with the GAV of "com.test:myprotest:tgz:1.0.0"
|
7
|
+
Then the output should contain:
|
8
|
+
"""
|
9
|
+
Artifact com.test:myprotest:tgz:1.0.0 has been successfully pushed to Nexus.
|
10
|
+
"""
|
11
|
+
And the exit status should be 0
|
12
|
+
|
13
|
+
Scenario: Update an artifact's custom metadata
|
14
|
+
When I call the nexus "update_artifact_custom_info com.test:myprotest:tgz:1.0.0 somekey:somevalue" command
|
15
|
+
Then the output should contain:
|
16
|
+
"""
|
17
|
+
Custom metadata for artifact com.test:myprotest:tgz:1.0.0 has been successfully pushed to Nexus.
|
18
|
+
"""
|
19
|
+
And the exit status should be 0
|
20
|
+
|
21
|
+
Scenario: Update an artifact's custom metadata with multiple parameters
|
22
|
+
When I call the nexus "update_artifact_custom_info com.test:myprotest:tgz:1.0.0 somekey:somevalue_1! \"someotherkey:some other value\" tempkey:tempvalue" command
|
23
|
+
Then the output should contain:
|
24
|
+
"""
|
25
|
+
Custom metadata for artifact com.test:myprotest:tgz:1.0.0 has been successfully pushed to Nexus.
|
26
|
+
"""
|
27
|
+
And the exit status should be 0
|
28
|
+
|
29
|
+
Scenario: Update an artifact's custom metadata and remove a key
|
30
|
+
When I call the nexus "update_artifact_custom_info com.test:myprotest:tgz:1.0.0 tempkey:" command
|
31
|
+
Then the output should contain:
|
32
|
+
"""
|
33
|
+
Custom metadata for artifact com.test:myprotest:tgz:1.0.0 has been successfully pushed to Nexus.
|
34
|
+
"""
|
35
|
+
And the exit status should be 0
|
36
|
+
|
37
|
+
Scenario: Get an artifact's custom metadata
|
38
|
+
When I call the nexus "custom com.test:myprotest:tgz:1.0.0" command
|
39
|
+
Then the output should contain:
|
40
|
+
"""
|
41
|
+
<somekey>somevalue_1!</somekey>
|
42
|
+
"""
|
43
|
+
And the output should contain:
|
44
|
+
"""
|
45
|
+
<someotherkey>some other value</someotherkey>
|
46
|
+
"""
|
47
|
+
And the exit status should be 0
|
48
|
+
|
49
|
+
Scenario: Search for artifacts by custom metadata using matches
|
50
|
+
When I call the nexus "search_custom somekey:matches:*value*" command
|
51
|
+
Then the output should contain:
|
52
|
+
"""
|
53
|
+
<artifactId>myprotest</artifactId>
|
54
|
+
"""
|
55
|
+
And the exit status should be 0
|
56
|
+
|
57
|
+
Scenario: Search for artifacts by custom metadata using equal
|
58
|
+
When I call the nexus "search_custom somekey:equal:somevalue_1!" command
|
59
|
+
Then the output should contain:
|
60
|
+
"""
|
61
|
+
<artifactId>myprotest</artifactId>
|
62
|
+
"""
|
63
|
+
And the exit status should be 0
|
64
|
+
|
65
|
+
Scenario: Search for artifacts by custom metadata using multiple parameters
|
66
|
+
When I call the nexus "search_custom somekey:matches:*value* somekey:equal:somevalue_1!" command
|
67
|
+
Then the output should contain:
|
68
|
+
"""
|
69
|
+
<artifactId>myprotest</artifactId>
|
70
|
+
"""
|
71
|
+
And the exit status should be 0
|
72
|
+
|
73
|
+
Scenario: Search for artifacts by custom metadata that return an empty result set
|
74
|
+
When I call the nexus "search_custom fakekey:equal:fakevalue" command
|
75
|
+
Then the output should contain:
|
76
|
+
"""
|
77
|
+
No search results.
|
78
|
+
"""
|
79
|
+
And the exit status should be 0
|
80
|
+
|
81
|
+
Scenario: Transfer an artifact and ensure its metadata is also copied
|
82
|
+
When I call the nexus "transfer com.test:myprotest:tgz:1.0.0 releases thirdparty" command
|
83
|
+
And I call the nexus "custom com.test:myprotest:tgz:1.0.0" command overriding "repository:thirdparty"
|
84
|
+
Then the output should contain:
|
85
|
+
"""
|
86
|
+
<somekey>somevalue_1!</somekey>
|
87
|
+
"""
|
88
|
+
And the exit status should be 0
|
89
|
+
|
90
|
+
Scenario: Clear an artifact's custom metadata
|
91
|
+
When I call the nexus "clear_artifact_custom_info com.test:myprotest:tgz:1.0.0" command
|
92
|
+
Then the output should contain:
|
93
|
+
"""
|
94
|
+
Custom metadata for artifact com.test:myprotest:tgz:1.0.0 has been successfully cleared.
|
95
|
+
"""
|
96
|
+
And the exit status should be 0
|
97
|
+
|
98
|
+
@delete
|
99
|
+
Scenario: Attempt to delete an artifact
|
100
|
+
When I delete an artifact with the GAV of "com.test:myprotest:tgz:1.0.0"
|
101
|
+
And I call the nexus "info com.test:myprotest:tgz:1.0.0" command
|
102
|
+
Then the output should contain:
|
103
|
+
"""
|
104
|
+
The artifact you requested information for could not be found. Please ensure it exists inside the Nexus.
|
105
|
+
"""
|
106
|
+
And the exit status should be 101
|
107
|
+
|
108
|
+
@delete
|
109
|
+
Scenario: Attempt to delete another artifact
|
110
|
+
When I delete an artifact with the GAV of "com.test:myprotest:tgz:1.0.0" from the "thirdparty" repository
|
111
|
+
And I call the nexus "info com.test:myprotest:tgz:1.0.0" command overriding "repository:thirdparty"
|
112
|
+
Then the output should contain:
|
113
|
+
"""
|
114
|
+
The artifact you requested information for could not be found. Please ensure it exists inside the Nexus.
|
115
|
+
"""
|
116
|
+
And the exit status should be 101
|
@@ -0,0 +1,101 @@
|
|
1
|
+
Feature: Use the Nexus Pro CLI
|
2
|
+
As a Pro CLI user
|
3
|
+
I need commands to get, update, search, and delete Nexus artifact custom metadata
|
4
|
+
|
5
|
+
Scenario: Get Nexus Pro Status
|
6
|
+
When I call the nexus "status" command
|
7
|
+
Then the output should contain:
|
8
|
+
"""
|
9
|
+
Application Name: Sonatype Nexus Professional
|
10
|
+
"""
|
11
|
+
And the exit status should be 0
|
12
|
+
|
13
|
+
Scenario: Set a repository to publish updates
|
14
|
+
When I call the nexus "enable_artifact_publish releases" command
|
15
|
+
And I call the nexus "get_pub_sub releases" command
|
16
|
+
Then the output should contain:
|
17
|
+
"""
|
18
|
+
<publish>true</publish>
|
19
|
+
"""
|
20
|
+
And the exit status should be 0
|
21
|
+
|
22
|
+
Scenario: Set a repository to not publish updates
|
23
|
+
When I call the nexus "disable_artifact_publish releases" command
|
24
|
+
And I call the nexus "get_pub_sub releases" command
|
25
|
+
Then the output should contain:
|
26
|
+
"""
|
27
|
+
<publish>false</publish>
|
28
|
+
"""
|
29
|
+
And the exit status should be 0
|
30
|
+
|
31
|
+
Scenario: Set a repository to subscribe to updates
|
32
|
+
When I call the nexus "enable_artifact_subscribe central" command
|
33
|
+
And I call the nexus "get_pub_sub central" command
|
34
|
+
Then the output should contain:
|
35
|
+
"""
|
36
|
+
<subscribe>true</subscribe>
|
37
|
+
"""
|
38
|
+
And the exit status should be 0
|
39
|
+
|
40
|
+
Scenario: Set a repository to not subscribe to updates
|
41
|
+
When I call the nexus "disable_artifact_subscribe central" command
|
42
|
+
And I call the nexus "get_pub_sub central" command
|
43
|
+
Then the output should contain:
|
44
|
+
"""
|
45
|
+
<subscribe>false</subscribe>
|
46
|
+
"""
|
47
|
+
And the exit status should be 0
|
48
|
+
|
49
|
+
Scenario: Enable Smart Proxy on the Server
|
50
|
+
When I call the nexus "enable_smart_proxy" command
|
51
|
+
And I call the nexus "get_smart_proxy_settings" command
|
52
|
+
Then the output should contain:
|
53
|
+
"""
|
54
|
+
"enabled": true
|
55
|
+
"""
|
56
|
+
And the exit status should be 0
|
57
|
+
|
58
|
+
Scenario: Enable Smart Proxy and set the host
|
59
|
+
When I call the nexus "enable_smart_proxy --host=0.0.0.1" command
|
60
|
+
And I call the nexus "get_smart_proxy_settings" command
|
61
|
+
Then the output should contain:
|
62
|
+
"""
|
63
|
+
"host": "0.0.0.1"
|
64
|
+
"""
|
65
|
+
And the exit status should be 0
|
66
|
+
|
67
|
+
Scenario: Enable Smart Proxy and set the host
|
68
|
+
When I call the nexus "enable_smart_proxy --port=1234" command
|
69
|
+
And I call the nexus "get_smart_proxy_settings" command
|
70
|
+
Then the output should contain:
|
71
|
+
"""
|
72
|
+
"port": 1234
|
73
|
+
"""
|
74
|
+
And the exit status should be 0
|
75
|
+
|
76
|
+
Scenario: Disable Smart Proxy on the Server
|
77
|
+
When I call the nexus "disable_smart_proxy" command
|
78
|
+
And I call the nexus "get_smart_proxy_settings" command
|
79
|
+
Then the output should contain:
|
80
|
+
"""
|
81
|
+
"enabled": false
|
82
|
+
"""
|
83
|
+
And the exit status should be 0
|
84
|
+
|
85
|
+
Scenario: Add a trusted key
|
86
|
+
When I add a trusted key to nexus
|
87
|
+
And I call the nexus "get_trusted_keys" command
|
88
|
+
Then the output should contain:
|
89
|
+
"""
|
90
|
+
cucumber
|
91
|
+
"""
|
92
|
+
And the exit status should be 0
|
93
|
+
|
94
|
+
Scenario: Delete a trusted key
|
95
|
+
When I delete a trusted key in nexus
|
96
|
+
And I call the nexus "get_trusted_keys" command
|
97
|
+
Then the output should not contain:
|
98
|
+
"""
|
99
|
+
cucumber
|
100
|
+
"""
|
101
|
+
And the exit status should be 0
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'aruba/api'
|
2
|
+
require 'json'
|
3
|
+
require 'jsonpath'
|
4
|
+
World(Aruba::Api)
|
5
|
+
|
6
|
+
When /^I call the nexus "(.*?)" command$/ do |command|
|
7
|
+
step "I run `nexus-cli #{command} --overrides=#{get_overrides_string}`"
|
8
|
+
end
|
9
|
+
|
10
|
+
When /^I call the nexus "(.*?)" command overriding "(.*?)"$/ do |command, overrides|
|
11
|
+
|
12
|
+
step "I run `nexus-cli #{command} --overrides=#{create_step_overrides(overrides)}`"
|
13
|
+
end
|
14
|
+
|
15
|
+
When /^I call the nexus "(.*?)" command as the "(.*?)" user with password "(.*?)"$/ do |command, username, password|
|
16
|
+
overrides = get_overrides_string.gsub('username:admin', "username:#{username}")
|
17
|
+
overrides.gsub!('password:admin123', "password:#{password}")
|
18
|
+
step "I run `nexus-cli #{command} --overrides=#{overrides}`"
|
19
|
+
end
|
20
|
+
|
21
|
+
When /^I push an artifact with the GAV of "(.*)"$/ do |coordinates|
|
22
|
+
groupId, artifact_id, extension, version = coordinates.split(":")
|
23
|
+
file = File.new(File.join(temp_dir, "#{artifact_id}-#{version}.#{extension}"), 'w')
|
24
|
+
file.puts "some data"
|
25
|
+
file.close
|
26
|
+
step "I run `nexus-cli push #{coordinates} #{file.path} --overrides=#{get_overrides_string}`"
|
27
|
+
end
|
28
|
+
|
29
|
+
When /^I pull an artifact with the GAV of "(.*?)" to a temp directory$/ do |coordinates|
|
30
|
+
step "I run `nexus-cli pull #{coordinates} --destination #{temp_dir} --overrides=#{get_overrides_string}`"
|
31
|
+
end
|
32
|
+
|
33
|
+
Then /^I should have a copy of the "(.*?)" artifact in a temp directory$/ do |fileName|
|
34
|
+
File.exists?(File.join(temp_dir, fileName)).should == true
|
35
|
+
end
|
36
|
+
|
37
|
+
When /^I delete an artifact with the GAV of "(.*)"$/ do |coordinates|
|
38
|
+
nexus_remote.delete_artifact(coordinates)
|
39
|
+
end
|
40
|
+
|
41
|
+
When /^I delete an artifact with the GAV of "(.*?)" from the "(.*?)" repository$/ do |coordinates, repository|
|
42
|
+
nexus_remote.configuration["repository"] = repository
|
43
|
+
nexus_remote.delete_artifact(coordinates)
|
44
|
+
end
|
45
|
+
|
46
|
+
When /^I edit the "(.*?)" files "(.*?)" field to true$/ do |file, field|
|
47
|
+
Dir.chdir('tmp/aruba') do
|
48
|
+
json = JSON.parse(File.read(File.join(File.expand_path("~/.nexus"), file)))
|
49
|
+
File.open(File.join(File.expand_path("~/.nexus"), file), "w+") do |opened|
|
50
|
+
json["data"]["globalRestApiSettings"][field] = true
|
51
|
+
opened.write(JSON.pretty_generate(json))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
When /^I update global settings uiTimeout to (\d+) and upload the json string$/ do |value|
|
57
|
+
json = JSON.parse(nexus_remote.get_global_settings_json)
|
58
|
+
edited_json = JsonPath.for(json).gsub("$..uiTimeout") {|v| value.to_i}.to_hash
|
59
|
+
nexus_remote.upload_global_settings(JSON.dump(edited_json))
|
60
|
+
end
|
61
|
+
|
62
|
+
When /^I add a trusted key to nexus$/ do
|
63
|
+
Dir.chdir(temp_dir) do
|
64
|
+
File.open("cert.txt", "w+") do |opened|
|
65
|
+
opened.write("-----BEGIN CERTIFICATE-----
|
66
|
+
MIICiTCCAfICCQDIKBRH7YO5mTANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
|
67
|
+
VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFTATBgNVBAcTDFNhbnRhIE1vbmljYTET
|
68
|
+
MBEGA1UEChMKUmlvdCBHYW1lczETMBEGA1UEAxMKS3lsZSBBbGxhbjEjMCEGCSqG
|
69
|
+
SIb3DQEJARYUa2FsbGFuQHJpb3RnYW1lcy5jb20wHhcNMTIwNjIwMjMxOTQ1WhcN
|
70
|
+
MTMwNjIwMjMxOTQ1WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3Ju
|
71
|
+
aWExFTATBgNVBAcTDFNhbnRhIE1vbmljYTETMBEGA1UEChMKUmlvdCBHYW1lczET
|
72
|
+
MBEGA1UEAxMKS3lsZSBBbGxhbjEjMCEGCSqGSIb3DQEJARYUa2FsbGFuQHJpb3Rn
|
73
|
+
YW1lcy5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM8Yz96KDxzv7eEt
|
74
|
+
DQNLV/3ipXJ5U/lQOQ2BrjSB6qrAHP2u4f+tzJtANXHcRrhXI3oOE993fg82adZg
|
75
|
+
XpWLl9wcPHDKP8s5l4TUxMjVJ4UYLJeINwOh/s3cpFq/ni/Klb+QWKG8Vyp6ossF
|
76
|
+
VGOc0IiU4ZaC38+jlqvCkHwdCQ4hAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAG6Eh
|
77
|
+
2QO0D69W+9wFvMQAC8YvHNMW9S9A+YRDa5vOeWzUZpeAYuawFSVfjT3fof2ovCU8
|
78
|
+
/AR2PyVwJvXRp0Yon2sUfaaFVP4x0BFAwWHk4vLBtqviBhKRdF1D/rR1g4KRowsh
|
79
|
+
P5KVneepzhtEt9G/uO4MU89cdUR0IMyUwdhq2dg=
|
80
|
+
-----END CERTIFICATE-----
|
81
|
+
")
|
82
|
+
end
|
83
|
+
step "I run `nexus-cli add_trusted_key --certificate=#{File.join(temp_dir, "cert.txt")} --description=cucumber --overrides=#{get_overrides_string}`"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
When /^I delete a trusted key in nexus$/ do
|
88
|
+
json = JSON.parse(nexus_remote.get_trusted_keys)
|
89
|
+
key_id = json["data"].first["id"]
|
90
|
+
step "I run `nexus-cli delete_trusted_key #{key_id} --overrides=#{get_overrides_string}`"
|
91
|
+
end
|
92
|
+
|
93
|
+
Then /^a file named "(.*?)" should exist in my nexus folder$/ do |file|
|
94
|
+
path = File.join(File.expand_path("~/.nexus"), file)
|
95
|
+
step "a file named \"#{path}\" should exist"
|
96
|
+
end
|
97
|
+
|
98
|
+
Then /^the file "(.*?)" in my nexus folder should contain:$/ do |file, partial_content|
|
99
|
+
path = File.join(File.expand_path("~/.nexus"), file)
|
100
|
+
check_file_content(path, partial_content, true)
|
101
|
+
end
|
102
|
+
|
103
|
+
Then /^the file "([^"]*)" should contain:$/ do |file, partial_content|
|
104
|
+
check_file_content(file, partial_content, true)
|
105
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
require 'spork'
|
4
|
+
|
5
|
+
module ArubaOverrides
|
6
|
+
def detect_ruby(cmd)
|
7
|
+
processor, platform, *rest = RUBY_PLATFORM.split("-")
|
8
|
+
if platform =~ /w32$/ && cmd =~ /^nexus-cli /
|
9
|
+
"ruby -I../../lib -S ../../bin/#{cmd}"
|
10
|
+
else
|
11
|
+
"#{cmd}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Spork.prefork do
|
17
|
+
require 'aruba/cucumber'
|
18
|
+
require 'nexus_cli'
|
19
|
+
require 'rspec'
|
20
|
+
|
21
|
+
World(ArubaOverrides)
|
22
|
+
|
23
|
+
Before do
|
24
|
+
@aruba_timeout_seconds = 10
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_overrides_string
|
28
|
+
@overrides_string ||= "url:http://localhost:8081/nexus repository:releases username:admin password:admin123"
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_overrides
|
32
|
+
@overrides ||= {'url' => 'http://localhost:8081/nexus', 'repository' => 'releases', 'username' => 'admin', 'password' => 'admin123'}
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_step_overrides(overrides)
|
36
|
+
overrides_hash = overrides.split(" ").inject({}) do |overrides_hash, override|
|
37
|
+
key, value = override.split(":")
|
38
|
+
overrides_hash[key] = value
|
39
|
+
overrides_hash
|
40
|
+
end
|
41
|
+
|
42
|
+
step_overrides = get_overrides.merge(overrides_hash)
|
43
|
+
step_overrides.to_a.inject("") do |overrides_string, pair|
|
44
|
+
overrides_string << pair.join(":")
|
45
|
+
overrides_string << " "
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def temp_dir
|
50
|
+
@tmpdir ||= Dir.mktmpdir
|
51
|
+
end
|
52
|
+
|
53
|
+
def nexus_remote
|
54
|
+
@nexus_remote ||= NexusCli::RemoteFactory.create(get_overrides)
|
55
|
+
end
|
56
|
+
|
57
|
+
at_exit do
|
58
|
+
FileUtils.rm_rf(temp_dir)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
Spork.each_run do
|
63
|
+
require 'nexus_cli'
|
64
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module NexusCli
|
2
|
+
class Artifact
|
3
|
+
attr_reader :group_id, :artifact_id, :extension, :classifier
|
4
|
+
attr_accessor :version
|
5
|
+
|
6
|
+
# Constructs an artifact object from Maven co-ordinates
|
7
|
+
# See http://maven.apache.org/pom.html#Maven_coordinatess
|
8
|
+
# for more information on maven coordinatess
|
9
|
+
#
|
10
|
+
# @param coordinates [String] the Maven identifier
|
11
|
+
#
|
12
|
+
# @return [Array<String>] an Array with four elements
|
13
|
+
def initialize(coordinates)
|
14
|
+
@group_id, @artifact_id, @extension, @classifier, @version = parse_coordinates(coordinates)
|
15
|
+
end
|
16
|
+
|
17
|
+
def file_name
|
18
|
+
if classifier.nil?
|
19
|
+
"#{artifact_id}-#{version}.#{extension}"
|
20
|
+
else
|
21
|
+
"#{artifact_id}-#{version}-#{classifier}.#{extension}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def parse_coordinates(coordinates)
|
28
|
+
split_coordinates = coordinates.split(":")
|
29
|
+
if(split_coordinates.size < 3 or split_coordinates.size > 5)
|
30
|
+
raise ArtifactMalformedException
|
31
|
+
end
|
32
|
+
|
33
|
+
group_id = split_coordinates[0]
|
34
|
+
artifact_id = split_coordinates[1]
|
35
|
+
extension = split_coordinates.size > 3 ? split_coordinates[2] : "jar"
|
36
|
+
classifier = split_coordinates.size > 4 ? split_coordinates[3] : nil
|
37
|
+
version = split_coordinates[-1]
|
38
|
+
|
39
|
+
version.upcase! if version == "latest"
|
40
|
+
|
41
|
+
return group_id, artifact_id, extension, classifier, version
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module NexusCli
|
2
|
+
class BaseRemote
|
3
|
+
attr_reader :configuration
|
4
|
+
attr_reader :connection
|
5
|
+
|
6
|
+
extend Forwardable
|
7
|
+
def_delegators :@connection, :status, :nexus_url, :nexus, :sanitize_for_id, :running_nexus_pro?
|
8
|
+
|
9
|
+
# @param [Hash] overrides
|
10
|
+
# @param [Boolean] ssl_verify
|
11
|
+
def initialize(overrides, ssl_verify=true)
|
12
|
+
@configuration = overrides ? Configuration.from_overrides(overrides) : Configuration.from_file
|
13
|
+
@connection = Connection.new(configuration, ssl_verify)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module NexusCli
|
4
|
+
class Configuration
|
5
|
+
DEFAULT_FILE = (ENV['HOME'] ? "~/.nexus_cli" : "/root/.nexus_cli").freeze
|
6
|
+
|
7
|
+
class << self
|
8
|
+
# The filepath to the nexus cli configuration file
|
9
|
+
#
|
10
|
+
# @return [String]
|
11
|
+
def file_path
|
12
|
+
File.expand_path(ENV['NEXUS_CONFIG'] || File.expand_path(DEFAULT_FILE))
|
13
|
+
end
|
14
|
+
|
15
|
+
# Creates a new instance of the Configuration object based on some overrides
|
16
|
+
#
|
17
|
+
# @param [Hash] overrides
|
18
|
+
#
|
19
|
+
# @return [NexusCli::Configuration]
|
20
|
+
def from_overrides(overrides)
|
21
|
+
raise MissingSettingsFileException unless overrides
|
22
|
+
overrides = overrides.with_indifferent_access
|
23
|
+
|
24
|
+
configuration = (load_config || Hash.new).with_indifferent_access
|
25
|
+
configuration.merge!(overrides)
|
26
|
+
new(configuration)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Creates a new instance of the Configuration object from the config file
|
30
|
+
#
|
31
|
+
#
|
32
|
+
# @return [NexusCli::Configuration]
|
33
|
+
def from_file
|
34
|
+
config = load_config
|
35
|
+
raise MissingSettingsFileException unless config
|
36
|
+
config = config.with_indifferent_access
|
37
|
+
new(config)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Validates an instance of the Configuration object and raises when there
|
41
|
+
# is an error with it
|
42
|
+
#
|
43
|
+
# @param config [NexusCli::Configuration]
|
44
|
+
#
|
45
|
+
# @raise [NexusCli::InvalidSettingsException]
|
46
|
+
def validate!(config)
|
47
|
+
unless config.valid?
|
48
|
+
raise InvalidSettingsException.new(config.errors)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# Loads the config file
|
55
|
+
#
|
56
|
+
# @return [Hash]
|
57
|
+
def load_config
|
58
|
+
begin
|
59
|
+
config = YAML.load_file(file_path)
|
60
|
+
rescue Errno::ENOENT
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def validate!
|
67
|
+
self.class.validate!(self)
|
68
|
+
end
|
69
|
+
|
70
|
+
def valid?
|
71
|
+
errors.empty?
|
72
|
+
end
|
73
|
+
|
74
|
+
def errors
|
75
|
+
result = Hash.new
|
76
|
+
result[:url] = ["url required"] unless url.is_a?(String) && url.size > 0
|
77
|
+
result[:repository] = ["repository required"] unless repository.is_a?(String) && repository.size > 0
|
78
|
+
result
|
79
|
+
end
|
80
|
+
|
81
|
+
attr_accessor :url
|
82
|
+
attr_accessor :repository
|
83
|
+
attr_accessor :username
|
84
|
+
attr_accessor :password
|
85
|
+
|
86
|
+
def initialize(options)
|
87
|
+
@url = options[:url]
|
88
|
+
@repository = options[:repository]
|
89
|
+
@username = options[:username]
|
90
|
+
@password = options[:password]
|
91
|
+
|
92
|
+
if @repository.is_a?(String)
|
93
|
+
@repository = @repository.gsub(' ', '_')
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def [](attr)
|
98
|
+
self.instance_variable_get('@' + attr.to_s)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module NexusCli
|
2
|
+
class Connection
|
3
|
+
attr_reader :nexus
|
4
|
+
attr_reader :configuration
|
5
|
+
attr_reader :ssl_verify
|
6
|
+
|
7
|
+
def initialize(configuration, ssl_verify)
|
8
|
+
@configuration = configuration
|
9
|
+
@ssl_verify = ssl_verify
|
10
|
+
@nexus = setup_nexus(configuration)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Joins a given url to the current url stored in the configuraiton
|
14
|
+
# and returns the combined String.
|
15
|
+
#
|
16
|
+
# @param [String] url
|
17
|
+
#
|
18
|
+
# @return [String]
|
19
|
+
def nexus_url(url)
|
20
|
+
File.join(configuration['url'], url)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Gets that current status of the Nexus server. On a non-error
|
24
|
+
# status code, returns a Hash of values from the server.
|
25
|
+
#
|
26
|
+
# @return [Hash]
|
27
|
+
def status
|
28
|
+
response = nexus.get(nexus_url("service/local/status"))
|
29
|
+
case response.status
|
30
|
+
when 200
|
31
|
+
doc = REXML::Document.new(response.content).elements["/status/data"]
|
32
|
+
data = Hash.new
|
33
|
+
data['app_name'] = doc.elements["appName"].text
|
34
|
+
data['version'] = doc.elements["version"].text
|
35
|
+
data['edition_long'] = doc.elements["editionLong"].text
|
36
|
+
data['state'] = doc.elements["state"].text
|
37
|
+
data['started_at'] = doc.elements["startedAt"].text
|
38
|
+
data['base_url'] = doc.elements["baseUrl"].text
|
39
|
+
return data
|
40
|
+
when 401
|
41
|
+
raise PermissionsException
|
42
|
+
when 503
|
43
|
+
raise CouldNotConnectToNexusException
|
44
|
+
else
|
45
|
+
raise UnexpectedStatusCodeException.new(response.status)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Transforms a given [String] into a sanitized version by
|
50
|
+
# replacing spaces with underscores and downcasing.
|
51
|
+
#
|
52
|
+
# @param unsanitized_string [String] the String to sanitize
|
53
|
+
#
|
54
|
+
# @return [String] the sanitized String
|
55
|
+
def sanitize_for_id(unsanitized_string)
|
56
|
+
unsanitized_string.gsub(" ", "_").downcase
|
57
|
+
end
|
58
|
+
|
59
|
+
# Determines whether or not the Nexus server being
|
60
|
+
# connected to is running Nexus Pro.
|
61
|
+
def running_nexus_pro?
|
62
|
+
status['edition_long'] == "Professional"
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# Returns an HTTPClient instance with settings to connect
|
68
|
+
# to a Nexus server.
|
69
|
+
#
|
70
|
+
# @return [HTTPClient]
|
71
|
+
def setup_nexus(configuration)
|
72
|
+
client = HTTPClient.new
|
73
|
+
client.send_timeout = 6000
|
74
|
+
client.receive_timeout = 6000
|
75
|
+
if configuration['username'] and configuration['password']
|
76
|
+
# https://github.com/nahi/httpclient/issues/63
|
77
|
+
client.set_auth(nil, configuration['username'], configuration['password'])
|
78
|
+
client.www_auth.basic_auth.challenge(configuration['url'])
|
79
|
+
end
|
80
|
+
client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE unless ssl_verify
|
81
|
+
client
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|