open-build-service-api 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9bf527982bd90cbc256ebf065939281cf3f6448c3c77ae6de5bccf60e576a01b
4
- data.tar.gz: 9de0695570ac504b8b7172cc251dcec5a1712495002c643743d286e1a35e0900
3
+ metadata.gz: 02f4ce3a2f1f328cead66065db1d5b5ff6b12c54a964d29134905bdabbcc5223
4
+ data.tar.gz: 857c13405e1b116ac1607a2bf3ce3316db46d47d83fc7910b0f6402a85958409
5
5
  SHA512:
6
- metadata.gz: 23f3d09d60d92aa116caa2ad2296ed5ef9b6d525aff16e81e64a9c9905cb9f77eb1e91e359b6ac342ac7b1f45192b6abf84b4a7d0da66957f42ec5b30de46a5c
7
- data.tar.gz: b9fe7c2dbec2cb50272097637f08236b505662dfc713b6158e0ddd794490716c9b40fa2cbf56bd9777bc077f6b9715c3be013b2ced4c5c9220d7032234508e18
6
+ metadata.gz: 9013c7b9d55d8bf2ddf3752570d6bc0c2a944728f9a675ac062bfd79ad6cb9142e3dd3d88b74c50592c0c06e306757b120a60889ac7b83794e61c279b2f27d57
7
+ data.tar.gz: 24f6529b60d5a2bffefd2f705384d4c685d07b5a8b75cde9f0ea83832856e431f84b1cec4960b2083e44c14303d0febbc21170f8f65e65e155e53c9b160109d7
@@ -1,3 +1,11 @@
1
+ ## Version: 0.1.0 (alpha)
2
+
3
+ - Exception `RemoteAPIError` does now store the `error_code` and `error_summary` if it is available
4
+ - Added a method to allow creation of Open Build Service projects
5
+ - Added `exists?` method to `Projects module in order to check whether a project exists or not
6
+ - Added a `branch_package` method to Project model to allow branching of source packages
7
+ - Added a `delete!` method to Project model to allow deletion of source projects
8
+
1
9
  ## Version: 0.0.2 (alpha)
2
10
 
3
11
  - Adds `Connection` module to establish a connection with a Build Service instance
@@ -5,9 +5,29 @@ module OpenBuildServiceAPI
5
5
  @connection = connection
6
6
  end
7
7
 
8
+ def create(name, meta = nil)
9
+ raise ProjectAlreadyExistsError.new("Project name '#{name}' has already been taken.") if exists?(name)
10
+
11
+ meta = meta ? meta : meta_for_new_project(name)
12
+
13
+ begin
14
+ response = @connection.send_request(:put, "/source/#{CGI.escape(name)}/_meta", request_body: meta)
15
+ rescue RequestError => err
16
+ raise ProjectCreationPermissionError.new(err.error_summary) if err.error_code == 'create_project_no_permission'
17
+ raise
18
+ end
19
+
20
+ return Project.new(projects: self, connection: @connection, name: name) if response.is_a?(Net::HTTPOK)
21
+ raise ProjectCreationFailedError.new("could not create project. API responded with '#{response.code}': #{response.body}")
22
+ end
23
+
8
24
  def list
9
25
  projects = Nokogiri::XML(@connection.send_request(:get, '/source').body)
10
- projects.xpath('//entry').map {|project| Project.new(projects: self, name: project.attr('name')) }
26
+ projects.xpath('//entry').map {|project| Project.new(projects: self, connection: @connection, name: project.attr('name')) }
27
+ end
28
+
29
+ def exists?(name)
30
+ !!find(name)
11
31
  end
12
32
 
13
33
  def find(name)
@@ -15,8 +35,10 @@ module OpenBuildServiceAPI
15
35
  project_data = Nokogiri::XML(@connection.send_request(:get, "/source/#{CGI.escape(name)}").body)
16
36
  packages = project_data.xpath('//entry').map { |package| package.attr('name') }
17
37
 
18
- Project.new(projects: self, name: name, packages: packages)
19
- rescue NotFoundError
38
+ Project.new(projects: self, name: name, packages: packages, connection: @connection)
39
+ rescue RequestError => err
40
+ return if err.error_code == 'unknown_project'
41
+ raise
20
42
  end
21
43
  end
22
44
 
@@ -26,6 +48,19 @@ module OpenBuildServiceAPI
26
48
  raise ProjectNotFoundError.new("Project '#{name}' does not exist.") unless project
27
49
  project
28
50
  end
51
+
52
+ private
53
+
54
+ def meta_for_new_project(name)
55
+ project_meta = Nokogiri::XML::Builder.new do |xml|
56
+ xml.project('name': name) do
57
+ xml.title name
58
+ xml.description
59
+ end
60
+ end
61
+
62
+ project_meta.to_xml
63
+ end
29
64
  end
30
65
  end
31
66
  end
@@ -13,6 +13,12 @@ module OpenBuildServiceAPI
13
13
  send_request(:get, '/')
14
14
  end
15
15
 
16
+ def inspect
17
+ inspected_object = super
18
+ inspected_object.gsub!(/\@username="([^\"]+)"/, '@username="..."')
19
+ inspected_object.gsub(/\@password="([^\"]+)"/, '@password="..."')
20
+ end
21
+
16
22
  def send_request(method, path, params = {})
17
23
  request_body = params[:request_body] if params[:request_body]
18
24
  params.delete(:request_body)
@@ -31,6 +37,8 @@ module OpenBuildServiceAPI
31
37
  request_method = Net::HTTP::Put.new(uri)
32
38
  elsif method.to_s.downcase == 'get'
33
39
  request_method = Net::HTTP::Get.new(uri)
40
+ elsif method.to_s.downcase == 'delete'
41
+ request_method = Net::HTTP::Delete.new(uri)
34
42
  end
35
43
 
36
44
  request_method['Accept'] = 'application/xml'
@@ -42,9 +50,11 @@ module OpenBuildServiceAPI
42
50
  response = request.request(request_method)
43
51
 
44
52
  raise InternalServerError.new(response) if response.is_a?(Net::HTTPInternalServerError)
45
- raise NotFoundError.new(response) if response.is_a?(Net::HTTPNotFound)
46
53
  raise AuthenticationError.new(response, "Authentication failed. Please check your credentials.") if response.is_a?(Net::HTTPUnauthorized)
47
54
 
55
+ code = response.code.to_i
56
+ raise RequestError.new(response) if code >= 400
57
+
48
58
  return response
49
59
  rescue Errno::ECONNREFUSED, SocketError, Net::OpenTimeout => err
50
60
  raise ConnectionError.new(err.to_s)
@@ -1,11 +1,23 @@
1
1
  module OpenBuildServiceAPI
2
2
  # remote API network errors
3
3
  class RemoteAPIError < Exception
4
- attr_accessor :response, :message
4
+ attr_accessor :response, :message, :error_code, :error_summary
5
5
 
6
6
  def initialize(response, message=nil)
7
+ response_body = response.body
8
+
7
9
  @response = response
8
- @message = message ? message : response.body
10
+ @message = message ? message : response_body
11
+
12
+ response_xml = Nokogiri::XML(response_body)
13
+ status = response_xml.xpath('./status')[0]
14
+
15
+ if status
16
+ @error_code = status.attr('code')
17
+
18
+ summary = status.xpath('./summary')
19
+ @error_summary = summary.text if summary[0]
20
+ end
9
21
  end
10
22
 
11
23
  def to_s
@@ -15,11 +27,17 @@ module OpenBuildServiceAPI
15
27
 
16
28
  class InternalServerError < RemoteAPIError; end
17
29
  class AuthenticationError < RemoteAPIError; end
18
- class NotFoundError < RemoteAPIError; end
30
+ class RequestError < RemoteAPIError; end
19
31
 
20
32
  # remote API errors
21
33
  class APIError < Exception; end
22
34
  class ProjectNotFoundError < APIError; end
35
+ class ProjectCreationPermissionError < APIError; end
36
+ class ProjectCreationFailedError < APIError; end
37
+ class ProjectDeletionPermissionError < APIError; end
38
+ class ProjectAlreadyExistsError < APIError; end
39
+ class PackageAlreadyExistsError < APIError; end
40
+ class TargetProjectPermissionError < APIError; end
23
41
 
24
42
  # library specific exceptions
25
43
  class GeneralError < Exception; end
@@ -0,0 +1,16 @@
1
+ module OpenBuildServiceAPI
2
+ class Package
3
+ attr_reader :name
4
+ attr_accessor :project
5
+
6
+ def initialize(params = {})
7
+ @name = params[:name]
8
+ @project = params[:project]
9
+ @connection = params[:connection]
10
+ end
11
+
12
+ def to_s
13
+ @name
14
+ end
15
+ end
16
+ end
@@ -1,15 +1,62 @@
1
1
  module OpenBuildServiceAPI
2
2
  class Project
3
- attr_accessor :name, :projects, :packages
3
+ attr_accessor :name, :projects
4
4
 
5
5
  def initialize(params = {})
6
6
  @name = params[:name]
7
7
  @projects = params[:projects]
8
- @packages = params[:packages]
8
+ @connection = params[:connection]
9
9
  end
10
10
 
11
11
  def to_s
12
12
  @name
13
13
  end
14
+
15
+ def delete!(message=nil)
16
+ begin
17
+ @connection.send_request(:delete, "/source/#{CGI.escape(@name)}", comment: message)
18
+ rescue RequestError => err
19
+ raise ProjectDeletionPermissionError.new("No permission to delete project '#{@name}'.") if err.error_code == 'delete_project_no_permission'
20
+ raise
21
+ end
22
+
23
+ true
24
+ end
25
+
26
+ def packages
27
+ return @cached_packages if @cached_packages && !@package_reload
28
+ @package_reload = false
29
+ @cached_packages = []
30
+
31
+ packages = Nokogiri::XML(@connection.send_request(:get, "/source/#{CGI.escape(@name)}").body)
32
+ packages.xpath('//entry').each do |package|
33
+ @cached_packages << Package.new(name: package.attr('name'), connection: @connection, project: self)
34
+ end
35
+
36
+ @cached_packages
37
+ end
38
+
39
+ def branch_package(source_project, source_package, package_name_after_branch=nil)
40
+ params = { cmd: 'branch', target_project: name }
41
+ params[:target_package] = package_name_after_branch ? package_name_after_branch : source_package
42
+
43
+ begin
44
+ response = @connection.send_request(:post, "/source/#{CGI.escape(source_project.to_s)}/#{CGI.escape(source_package.to_s)}", params)
45
+ response_xml = Nokogiri::XML(response.body)
46
+
47
+ @package_reload = true
48
+ Package.new(name: response_xml.xpath('//data[@name="targetpackage"]')[0].text, connection: @connection, project: self)
49
+ rescue RequestError => err
50
+ raise PackageAlreadyExistsError.new("Package '#{params[:target_package]}' does already exist " \
51
+ "in project '#{@name}'.") if err.error_code == 'double_branch_package'
52
+ raise TargetProjectPermissionError.new("Branching to project '#{@name}' is not possible: No " \
53
+ "access in target project.") if err.error_code == 'cmd_execution_no_permission'
54
+ raise
55
+ end
56
+ end
57
+
58
+ def reload!
59
+ @package_reload = true
60
+ end
14
61
  end
15
62
  end
@@ -11,4 +11,5 @@ require_relative 'api/about'
11
11
  require_relative 'api/projects'
12
12
 
13
13
  # Models
14
+ require_relative 'models/package'
14
15
  require_relative 'models/project'
@@ -1,3 +1,4 @@
1
1
  module OpenBuildServiceAPI
2
- VERSION = '0.0.2'
2
+ VERSION = '0.1.0'
3
+ RELEASE_DATE = '2019-06-15'
3
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: open-build-service-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manuel Schnitzer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-07 00:00:00.000000000 Z
11
+ date: 2019-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: date
@@ -50,6 +50,26 @@ dependencies:
50
50
  - - ">="
51
51
  - !ruby/object:Gem::Version
52
52
  version: 1.10.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: byebug
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '11.0'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 11.0.1
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '11.0'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 11.0.1
53
73
  description: The Open Build Service API wrapped into a Ruby gem.
54
74
  email: webmaster@mschnitzer.de
55
75
  executables: []
@@ -62,6 +82,7 @@ files:
62
82
  - lib/api/projects.rb
63
83
  - lib/connection.rb
64
84
  - lib/exception.rb
85
+ - lib/models/package.rb
65
86
  - lib/models/project.rb
66
87
  - lib/open-build-service-api.rb
67
88
  - lib/version.rb