nexus_cli 0.1.2 → 0.2.0
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.
- data/.gitignore +3 -0
- data/VERSION +1 -1
- data/lib/nexus_cli/errors.rb +12 -5
- data/lib/nexus_cli/remote.rb +56 -42
- data/lib/nexus_cli/tasks.rb +71 -14
- data/spec/remote_spec.rb +5 -0
- metadata +4 -4
data/.gitignore
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/nexus_cli/errors.rb
CHANGED
@@ -25,16 +25,16 @@ module NexusCli
|
|
25
25
|
def initialize(key)
|
26
26
|
@missing_setting = key
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def message
|
30
|
-
"The .nexus_cli file
|
30
|
+
"The .nexus_cli file or your overrides are missing the value: #{@missing_setting}"
|
31
31
|
end
|
32
32
|
status_code(102)
|
33
33
|
end
|
34
34
|
|
35
35
|
class MissingSettingsFileException < NexusCliError
|
36
36
|
def message
|
37
|
-
"The .nexus_cli file is missing or corrupt."
|
37
|
+
"The .nexus_cli file is missing or corrupt. You can either fix the .nexus_cli file or pass the --overrides hash."
|
38
38
|
end
|
39
39
|
status_code(103)
|
40
40
|
end
|
@@ -48,7 +48,7 @@ module NexusCli
|
|
48
48
|
|
49
49
|
class CouldNotConnectToNexusException < NexusCliError
|
50
50
|
def message
|
51
|
-
"Could not connect to Nexus. Please ensure the url
|
51
|
+
"Could not connect to Nexus. Please ensure the url you are using is reachable."
|
52
52
|
end
|
53
53
|
status_code(105)
|
54
54
|
end
|
@@ -65,8 +65,15 @@ module NexusCli
|
|
65
65
|
%{Your request was denied by the Nexus server due to a bad request and your artifact has not been uploaded.
|
66
66
|
This could mean several things:
|
67
67
|
Your .nexus_cli['repository'] is invalid.
|
68
|
-
The artifact with this identifier
|
68
|
+
The artifact with this identifier already exists inside the repository and that repository does not allow multiple deployments.}
|
69
69
|
end
|
70
70
|
status_code(107)
|
71
71
|
end
|
72
|
+
|
73
|
+
class NotNexusProException < NexusCliError
|
74
|
+
def message
|
75
|
+
"You cannot use this feature unless you are using Nexus Professional."
|
76
|
+
end
|
77
|
+
status_code(108)
|
78
|
+
end
|
72
79
|
end
|
data/lib/nexus_cli/remote.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'restclient'
|
2
|
+
require 'rexml/document'
|
2
3
|
require 'yaml'
|
3
4
|
require 'open3'
|
4
5
|
|
@@ -7,38 +8,42 @@ module NexusCli
|
|
7
8
|
class << self
|
8
9
|
|
9
10
|
def configuration=(config = {})
|
10
|
-
validate_config(config)
|
11
11
|
@configuration = config
|
12
12
|
end
|
13
13
|
|
14
14
|
def configuration
|
15
15
|
return @configuration if @configuration
|
16
|
-
begin
|
17
|
-
config = YAML::load_file(File.expand_path("~/.nexus_cli"))
|
18
|
-
rescue Errno::ENOENT
|
19
|
-
raise MissingSettingsFileException
|
20
|
-
end
|
21
|
-
validate_config(config)
|
22
|
-
@configuration = config
|
23
16
|
end
|
24
17
|
|
25
18
|
def nexus
|
26
19
|
@nexus ||= RestClient::Resource.new configuration["url"], :user => configuration["username"], :password => configuration["password"]
|
27
20
|
end
|
28
21
|
|
22
|
+
def status
|
23
|
+
doc = REXML::Document.new(nexus['service/local/status'].get).elements['status/data']
|
24
|
+
data = Hash.new
|
25
|
+
data['app_name'] = doc.elements['appName'].text
|
26
|
+
data['version'] = doc.elements['version'].text
|
27
|
+
data['edition_long'] = doc.elements['editionLong'].text
|
28
|
+
data['state'] = doc.elements['state'].text
|
29
|
+
data['started_at'] = doc.elements['startedAt'].text
|
30
|
+
data['base_url'] = doc.elements['baseUrl'].text
|
31
|
+
return data
|
32
|
+
end
|
33
|
+
|
29
34
|
def pull_artifact(artifact, destination, overrides)
|
30
|
-
parse_overrides(overrides)
|
31
35
|
split_artifact = artifact.split(":")
|
32
36
|
if(split_artifact.size < 4)
|
33
37
|
raise ArtifactMalformedException
|
34
38
|
end
|
39
|
+
group_id, artifact_id, version, extension = split_artifact
|
35
40
|
begin
|
36
|
-
fileData = nexus['service/local/artifact/maven/redirect'].get ({params: {r: configuration['repository'], g:
|
41
|
+
fileData = nexus['service/local/artifact/maven/redirect'].get ({params: {r: configuration['repository'], g: group_id, a: artifact_id, v: version, e: extension}})
|
37
42
|
rescue RestClient::ResourceNotFound
|
38
43
|
raise ArtifactNotFoundException
|
39
44
|
end
|
40
45
|
artifact = nil
|
41
|
-
destination = File.join(File.expand_path(destination || "."), "#{
|
46
|
+
destination = File.join(File.expand_path(destination || "."), "#{artifact_id}-#{version}.#{extension}")
|
42
47
|
artifact = File.open(destination, 'w')
|
43
48
|
artifact.write(fileData)
|
44
49
|
artifact.close()
|
@@ -46,29 +51,21 @@ module NexusCli
|
|
46
51
|
end
|
47
52
|
|
48
53
|
def push_artifact(artifact, file, insecure, overrides)
|
49
|
-
#Build up the pieces that will make up the PUT request
|
50
|
-
parse_overrides(overrides)
|
51
54
|
split_artifact = artifact.split(":")
|
52
55
|
if(split_artifact.size < 4)
|
53
56
|
raise ArtifactMalformedException
|
54
57
|
end
|
55
|
-
artifact_id = split_artifact
|
56
|
-
group_id
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
Open3.popen3("curl -I #{insecure ? "-k" : ""} -T #{file} #{File.join(configuration['url'], put_string)} -u #{configuration['username']}:#{configuration['password']}") do |stdin, stdout, stderr, wait_thr|
|
61
|
-
exit_code = wait_thr.value.exitstatus
|
62
|
-
standard_out = stdout.read
|
63
|
-
if (standard_out.match('403 Forbidden') || standard_out.match('401 Unauthorized'))
|
64
|
-
raise PermissionsException
|
65
|
-
elsif standard_out.match('400 Bad Request')
|
58
|
+
group_id, artifact_id, version, extension = split_artifact
|
59
|
+
nexus['service/local/artifact/maven/content'].post hasPom: false, g: group_id, a: artifact_id, v: version, e: extension, p: extension, r: configuration['repository'],
|
60
|
+
file: File.new(file) do |response, request, result, &block|
|
61
|
+
case response.code
|
62
|
+
when 400
|
66
63
|
raise BadUploadRequestException
|
67
|
-
|
68
|
-
|
69
|
-
when
|
70
|
-
raise
|
71
|
-
when
|
64
|
+
when 401
|
65
|
+
raise PermissionsException
|
66
|
+
when 403
|
67
|
+
raise PermissionsException
|
68
|
+
when 404
|
72
69
|
raise CouldNotConnectToNexusException
|
73
70
|
end
|
74
71
|
end
|
@@ -79,16 +76,15 @@ module NexusCli
|
|
79
76
|
if(split_artifact.size < 4)
|
80
77
|
raise ArtifactMalformedException
|
81
78
|
end
|
82
|
-
|
83
|
-
|
79
|
+
group_id = split_artifact[0].gsub(".", "/")
|
80
|
+
artifact_id = split_artifact[1].gsub(".", "/")
|
84
81
|
version = split_artifact[2]
|
85
82
|
|
86
|
-
delete_string = "content/repositories/releases/#{
|
83
|
+
delete_string = "content/repositories/releases/#{group_id}/#{artifact_id}/#{version}"
|
87
84
|
Kernel.quietly {`curl --request DELETE #{File.join(configuration['url'], delete_string)} -u #{configuration['username']}:#{configuration['password']}`}
|
88
85
|
end
|
89
86
|
|
90
87
|
def get_artifact_info(artifact, overrides)
|
91
|
-
parse_overrides(overrides)
|
92
88
|
split_artifact = artifact.split(":")
|
93
89
|
if(split_artifact.size < 4)
|
94
90
|
raise ArtifactMalformedException
|
@@ -99,19 +95,37 @@ module NexusCli
|
|
99
95
|
raise ArtifactNotFoundException
|
100
96
|
end
|
101
97
|
end
|
98
|
+
|
99
|
+
def get_artifact_custom_info(artifact, overrides)
|
100
|
+
raise NotNexusProException unless running_nexus_pro?
|
101
|
+
split_artifact = artifact.split(":")
|
102
|
+
if(split_artifact.size < 4)
|
103
|
+
raise ArtifactMalformedException
|
104
|
+
end
|
105
|
+
group_id, artifact_id, version, extension = split_artifact
|
106
|
+
file_name = "#{artifact_id}-#{version}.#{extension}"
|
107
|
+
get_string = "content/repositories/#{configuration['repository']}/.meta/#{group_id.gsub(".", "/")}/#{artifact_id.gsub(".", "/")}/#{version}/#{file_name}.n3"
|
108
|
+
begin
|
109
|
+
n3_data = nexus[get_string].get
|
110
|
+
parse_n3(n3_data)
|
111
|
+
rescue RestClient::ResourceNotFound => e
|
112
|
+
raise ArtifactNotFoundException
|
113
|
+
end
|
114
|
+
end
|
102
115
|
|
103
116
|
private
|
104
|
-
|
105
|
-
|
106
|
-
["url", "repository", "username","password"].each do |key|
|
107
|
-
raise InvalidSettingsException.new(key) unless configuration.has_key?(key)
|
108
|
-
end
|
117
|
+
def running_nexus_pro?
|
118
|
+
return status['edition_long'] == "Professional" ? true : false
|
109
119
|
end
|
110
120
|
|
111
|
-
def
|
112
|
-
|
113
|
-
|
114
|
-
|
121
|
+
def parse_n3(data)
|
122
|
+
result = ""
|
123
|
+
data.each_line { |item|
|
124
|
+
tag = item.match(/#(\w*)>/) ? "#{$1}" : ""
|
125
|
+
value = item.match(/"([^"]*)"/) ? "#{$1}" : ""
|
126
|
+
result += " <#{tag}>#{value}</#{tag}>\n" unless tag.empty? && value.empty?
|
127
|
+
}
|
128
|
+
return "<artifact-resolution>\n <data>\n" + result + " </data>\n</artifact-resolution>"
|
115
129
|
end
|
116
130
|
end
|
117
131
|
end
|
data/lib/nexus_cli/tasks.rb
CHANGED
@@ -6,14 +6,32 @@ module NexusCli
|
|
6
6
|
base.send :include, ::Thor::Actions
|
7
7
|
base.class_eval do
|
8
8
|
|
9
|
+
map 'pull' => :pull_artifact
|
10
|
+
map 'push' => :push_artifact
|
11
|
+
map 'info' => :get_artifact_info
|
12
|
+
map 'custom' => :get_artifact_custom_info
|
13
|
+
map 'config' => :get_nexus_configuration
|
14
|
+
map 'status' => :get_nexus_status
|
15
|
+
|
16
|
+
class_option :overrides,
|
17
|
+
:type => :hash,
|
18
|
+
:default => {},
|
19
|
+
:desc => "A hashed list of overrides. Available options are 'url', 'repository', 'username', and 'password'."
|
20
|
+
|
21
|
+
def initialize(*args)
|
22
|
+
super
|
23
|
+
begin
|
24
|
+
set_remote_configuration(options[:overrides])
|
25
|
+
rescue NexusCliError => e
|
26
|
+
say e.message, :red
|
27
|
+
exit e.status_code
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
9
31
|
method_option :destination,
|
10
32
|
:type => :string,
|
11
33
|
:default => nil,
|
12
34
|
:desc => "A different folder other than the current working directory."
|
13
|
-
method_option :overrides,
|
14
|
-
:type => :hash,
|
15
|
-
:default => {},
|
16
|
-
:desc => "A hashed list of overrides. Available options are 'url', 'repository', 'username', and 'password'."
|
17
35
|
desc "pull_artifact artifact", "Pulls an artifact from Nexus and places it on your machine."
|
18
36
|
def pull_artifact(artifact)
|
19
37
|
begin
|
@@ -29,10 +47,6 @@ module NexusCli
|
|
29
47
|
:type => :boolean,
|
30
48
|
:default => false,
|
31
49
|
:desc => "Overrides any failures because of an 'insecure' SSL conncetion."
|
32
|
-
method_option :overrides,
|
33
|
-
:type => :hash,
|
34
|
-
:default => {},
|
35
|
-
:desc => "A hashed list of overrides. Available options are 'url', 'repository', 'username', and 'password'."
|
36
50
|
desc "push_artifact artifact file", "Pushes an artifact from your machine onto the Nexus."
|
37
51
|
def push_artifact(artifact, file)
|
38
52
|
begin
|
@@ -44,11 +58,7 @@ module NexusCli
|
|
44
58
|
end
|
45
59
|
end
|
46
60
|
|
47
|
-
|
48
|
-
:type => :hash,
|
49
|
-
:default => {},
|
50
|
-
:desc => "A hashed list of overrides. Available options are 'url', 'repository', 'username', and 'password'."
|
51
|
-
desc "get_artifact_info artifact", "Gets and returns the XML information about a particular artifact."
|
61
|
+
desc "get_artifact_info artifact", "Gets and returns the metadata in XML format about a particular artifact."
|
52
62
|
def get_artifact_info(artifact)
|
53
63
|
begin
|
54
64
|
say Remote.get_artifact_info(artifact, options[:overrides]), :green
|
@@ -58,11 +68,21 @@ module NexusCli
|
|
58
68
|
end
|
59
69
|
end
|
60
70
|
|
71
|
+
desc "get_artifact_custom_info artifact", "Gets and returns the custom metadata in XML format about a particular artifact."
|
72
|
+
def get_artifact_custom_info(artifact)
|
73
|
+
begin
|
74
|
+
say Remote.get_artifact_custom_info(artifact, options[:overrides]), :green
|
75
|
+
rescue NexusCliError => e
|
76
|
+
say e.message, :red
|
77
|
+
exit e.status_code
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
61
81
|
desc "get_nexus_configuration", "Prints out configuration from the .nexus_cli file that helps inform where artifacts will be uploaded."
|
62
82
|
def get_nexus_configuration
|
63
83
|
begin
|
64
84
|
config = Remote.configuration
|
65
|
-
say "*********Reading
|
85
|
+
say "********* Reading CLI configuration from #{File.expand_path('~/.nexus_cli')} *********", :blue
|
66
86
|
say "Nexus URL: #{config['url']}", :blue
|
67
87
|
say "Nexus Repository: #{config['repository']}", :blue
|
68
88
|
rescue NexusCliError => e
|
@@ -70,6 +90,43 @@ module NexusCli
|
|
70
90
|
exit e.status_code
|
71
91
|
end
|
72
92
|
end
|
93
|
+
|
94
|
+
desc "get_nexus_status", "Prints out information about the Nexus instance."
|
95
|
+
def get_nexus_status
|
96
|
+
begin
|
97
|
+
data = Remote.status
|
98
|
+
say "********* Getting Nexus status from #{data['base_url']} *********", :blue
|
99
|
+
say "Application Name: #{data['app_name']}", :blue
|
100
|
+
say "Version: #{data['version']}", :blue
|
101
|
+
say "Edition: #{data['edition_long']}", :blue
|
102
|
+
say "State: #{data['state']}", :blue
|
103
|
+
say "Started At: #{data['started_at']}", :blue
|
104
|
+
say "Base URL: #{data['base_url']}", :blue
|
105
|
+
rescue NexusCliError => e
|
106
|
+
say e.message, :red
|
107
|
+
exit e.status_code
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
def set_remote_configuration(overrides)
|
113
|
+
begin
|
114
|
+
config = YAML::load_file(File.expand_path("~/.nexus_cli"))
|
115
|
+
rescue
|
116
|
+
end
|
117
|
+
if config.nil? && (overrides.nil? || overrides.empty?)
|
118
|
+
raise MissingSettingsFileException
|
119
|
+
end
|
120
|
+
overrides.each{|key, value| config[key] = value} unless overrides.nil? || overrides.empty?
|
121
|
+
validate_config(config)
|
122
|
+
Remote.configuration = config
|
123
|
+
end
|
124
|
+
|
125
|
+
def validate_config(configuration)
|
126
|
+
["url", "repository", "username","password"].each do |key|
|
127
|
+
raise InvalidSettingsException.new(key) unless configuration.has_key?(key)
|
128
|
+
end
|
129
|
+
end
|
73
130
|
end
|
74
131
|
end
|
75
132
|
end
|
data/spec/remote_spec.rb
CHANGED
@@ -35,4 +35,9 @@ describe NexusCli do
|
|
35
35
|
RestClient::Resource.any_instance.stub(:get).and_raise(RestClient::ResourceNotFound)
|
36
36
|
expect {NexusCli::Remote.get_artifact_info "com.something:something:1.0.0:tgz"}.to raise_error(NexusCli::ArtifactNotFoundException)
|
37
37
|
end
|
38
|
+
|
39
|
+
it "gives you errors when you attempt to get an artifact's custom info and it cannot be found" do
|
40
|
+
RestClient::Resource.any_instance.stub(:get).and_raise(RestClient::ResourceNotFound)
|
41
|
+
expect {NexusCli::Remote.get_artifact_custom_info "com.something:something:1.0.0:tgz"}.to raise_error(NexusCli::ArtifactNotFoundException)
|
42
|
+
end
|
38
43
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nexus_cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: thor
|
@@ -149,7 +149,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
149
149
|
version: '0'
|
150
150
|
segments:
|
151
151
|
- 0
|
152
|
-
hash:
|
152
|
+
hash: 3449401773214889774
|
153
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
154
154
|
none: false
|
155
155
|
requirements:
|
@@ -158,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
158
158
|
version: '0'
|
159
159
|
segments:
|
160
160
|
- 0
|
161
|
-
hash:
|
161
|
+
hash: 3449401773214889774
|
162
162
|
requirements: []
|
163
163
|
rubyforge_project:
|
164
164
|
rubygems_version: 1.8.21
|