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 CHANGED
@@ -1,5 +1,8 @@
1
1
  .DS_Store
2
2
  .rake_tasks~
3
+ .project
4
+ .buildpath
3
5
  Gemfile.lock
4
6
  tmp/
5
7
  pkg/
8
+ *.gem
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.2.0
@@ -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 is missing the value: #{@missing_setting}"
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 in .nexus_cli is reachable."
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 alread exists inside the repository and that repository does not allow multiple deployments.}
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
@@ -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: split_artifact[0], a: split_artifact[1], v: split_artifact[2], e: split_artifact[3]}})
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 || "."), "#{split_artifact[1]}-#{split_artifact[2]}.#{split_artifact[3]}")
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[0].gsub(".", "/")
56
- group_id = split_artifact[1].gsub(".", "/")
57
- version = split_artifact[2]
58
- file_name = "#{split_artifact[1]}-#{version}.#{split_artifact[3]}"
59
- put_string = "content/repositories/#{configuration['repository']}/#{artifact_id}/#{group_id}/#{version}/#{file_name}"
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
- end
68
- case exit_code
69
- when 60
70
- raise NonSecureConnectionException
71
- when 7
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
- artifact_id = split_artifact[0].gsub(".", "/")
83
- group_id = split_artifact[1].gsub(".", "/")
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/#{artifact_id}/#{group_id}/#{version}"
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
- def validate_config(configuration)
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 parse_overrides(overrides)
112
- overrides.each do |key, value|
113
- configuration[key] = value unless configuration[key].nil?
114
- end
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
@@ -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
- method_option :overrides,
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 Configuration from #{File.expand_path('~/.nexus_cli')}*********", :blue
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
@@ -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.1.2
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-03 00:00:00.000000000 Z
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: 2915524833265829013
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: 2915524833265829013
161
+ hash: 3449401773214889774
162
162
  requirements: []
163
163
  rubyforge_project:
164
164
  rubygems_version: 1.8.21