aptly-api 0.8.1 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -6
- data/CHANGELOG.md +45 -0
- data/README.md +0 -1
- data/aptly-api.gemspec +2 -2
- data/lib/aptly.rb +13 -4
- data/lib/aptly/connection.rb +4 -1
- data/lib/aptly/files.rb +54 -0
- data/lib/aptly/publish.rb +11 -0
- data/lib/aptly/publishable.rb +3 -1
- data/lib/aptly/repository.rb +10 -8
- data/lib/aptly/snapshot.rb +4 -2
- data/lib/aptly/tmpname.rb +9 -3
- data/lib/aptly/version.rb +2 -1
- metadata +7 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1620dd9faac56d2cdc59e3c4fa5071269dfa3fb500ca6837d0c5c2095dfbc793
|
4
|
+
data.tar.gz: 9010ab42e434fa472f990a4d8d69a519bbf7989597a9e6c826aae988997d533c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 120c7e010476239efb0f3148aaa7871875ec959372d5de59bf29693c2440856f62b5170c6aa9f3d910ae61648a5afc10d8ea88b1283204220e2abd97419d17a5
|
7
|
+
data.tar.gz: 719edccb1abff82d097c269631f15b3d56b1cdb809d121bda40c08b6dbe8032a461aa90010241ec7c7e2c0e385a65dbb9668eb226d5fe1120883a88ec6ae43eb
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,50 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## [0.10.1]
|
4
|
+
### Fixed
|
5
|
+
- Publishing endpoint escaping no longer creates invalid URIs when the Prefix
|
6
|
+
already contains underscores. Prefix=foo_bar is now correctly escaped to
|
7
|
+
foo__bar.
|
8
|
+
- excon 0.71 is now required as earlier versions had open security issues.
|
9
|
+
|
10
|
+
## [0.10.0]
|
11
|
+
### Added
|
12
|
+
- `PublishedRepository#from_repositories` publishes repository sources
|
13
|
+
into the same prefix.
|
14
|
+
- `Aptly.repo` is a new shorthand for `Aptly::Repository.get` to get
|
15
|
+
a repository by name when writing code interactively in IRB, or to
|
16
|
+
write slightly less verbose code.
|
17
|
+
|
18
|
+
### Fixed
|
19
|
+
- Documentation fixes.
|
20
|
+
- `Connection.HTTP_ACTIONS` is now properly marked private.
|
21
|
+
|
22
|
+
## [0.9.1]
|
23
|
+
### Fixed
|
24
|
+
- Hint at needing `noRemove: 1` as param when loop adding files (default
|
25
|
+
behavior is to remove added files) in the `Files.tmp_upload` documentation.
|
26
|
+
- `Connection` properly passes query parameters for post-ish requests now.
|
27
|
+
- `Repository.add_file` no longer mangles it's query parameters as they are
|
28
|
+
inconsistently cased on the API level.
|
29
|
+
|
30
|
+
## [0.9.0]
|
31
|
+
### Added
|
32
|
+
- `Files.tmp_upload` is a new convenience wrapper around `#upload` and
|
33
|
+
`#delete`. It picks a temporary directory name and uploads the list of files
|
34
|
+
to that directory, it then yields the directory name so you can use it as file
|
35
|
+
identifier for the files. When the method returns it automatically cleans the
|
36
|
+
remote up via `#delete`.
|
37
|
+
|
38
|
+
### Changed
|
39
|
+
- `Repository.upload` is now based on `Files.tmp_upload`. Functionally
|
40
|
+
all remains the same; the temporary directory name on the remote changes.
|
41
|
+
- Temporary directory names now include a thread id to reduce the risk of
|
42
|
+
conflicts across different threads.
|
43
|
+
|
44
|
+
## [0.8.2]
|
45
|
+
### Fixed
|
46
|
+
- Temporary files no longer contain characters that trip up the daemon.
|
47
|
+
|
3
48
|
## [0.8.1]
|
4
49
|
### Changed
|
5
50
|
- Ruby 2.5.0 compatible. Temporary name construction of uploaded files now
|
data/README.md
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
[![Inline docs](http://inch-ci.org/github/KDEJewellers/aptly-api.svg?branch=master)](http://inch-ci.org/github/KDEJewellers/aptly-api)
|
4
4
|
[![Build Status](https://travis-ci.org/KDEJewellers/aptly-api.svg?branch=master)](https://travis-ci.org/KDEJewellers/aptly-api)
|
5
5
|
[![Coverage Status](https://coveralls.io/repos/KDEJewellers/aptly-api/badge.svg?branch=master&service=github)](https://coveralls.io/github/KDEJewellers/aptly-api?branch=master)
|
6
|
-
[![Dependency Status](https://gemnasium.com/KDEJewellers/aptly-api.svg)](https://gemnasium.com/KDEJewellers/aptly-api)
|
7
6
|
[![Code Climate](https://codeclimate.com/github/KDEJewellers/aptly-api/badges/gpa.svg)](https://codeclimate.com/github/KDEJewellers/aptly-api)
|
8
7
|
|
9
8
|
## Installation
|
data/aptly-api.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ['lib']
|
21
21
|
|
22
|
-
spec.add_development_dependency 'bundler', '~>
|
22
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
23
23
|
spec.add_development_dependency 'coveralls', '~> 0.8'
|
24
24
|
spec.add_development_dependency 'minitest', '~> 5.8'
|
25
25
|
spec.add_development_dependency 'rake', '~> 12.0'
|
@@ -29,5 +29,5 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.add_development_dependency 'yard', '~> 0.8'
|
30
30
|
|
31
31
|
spec.add_dependency 'faraday', '~> 0.9'
|
32
|
-
spec.add_dependency 'excon', '~> 0.
|
32
|
+
spec.add_dependency 'excon', '~> 0.71'
|
33
33
|
end
|
data/lib/aptly.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2015 Harald Sitter <sitter@kde.org>
|
1
|
+
# Copyright (C) 2015-2020 Harald Sitter <sitter@kde.org>
|
2
2
|
#
|
3
3
|
# This library is free software; you can redistribute it and/or
|
4
4
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -26,18 +26,27 @@ require 'aptly/tmpname'
|
|
26
26
|
# Aptly API
|
27
27
|
module Aptly
|
28
28
|
class << self
|
29
|
+
# Configures aptly in a block.
|
29
30
|
def configure
|
30
31
|
yield configuration
|
31
32
|
end
|
32
33
|
|
34
|
+
# The global configuration instance.
|
33
35
|
def configuration
|
34
36
|
@configuration ||= Configuration.new
|
35
37
|
end
|
36
38
|
|
39
|
+
# Convenience shorthand for {Repository#get}.
|
40
|
+
# @since 0.10.0
|
41
|
+
def repo(name, connection = Connection.new, **kwords)
|
42
|
+
Repository.get(name, connection, **kwords)
|
43
|
+
end
|
44
|
+
|
37
45
|
# Publish 1 or more sources into a public repository prefix.
|
38
46
|
# @param sources [Array<Repository>] array of repositories to source
|
39
|
-
# @param prefix [String]
|
40
|
-
#
|
47
|
+
# @param prefix [String] prefix to publish under (i.e. published repo name).
|
48
|
+
# This must be escaped (see {Aptly.escape_prefix})
|
49
|
+
# @see Aptly.escape_prefix
|
41
50
|
# @param source_kind [String] the source kind (local or snapshot)
|
42
51
|
# @return [PublishedRepository] newly published repository
|
43
52
|
def publish(sources, prefix = '', source_kind = 'local',
|
@@ -60,7 +69,7 @@ module Aptly
|
|
60
69
|
# @return [String] API-safe prefix notation
|
61
70
|
# @since 0.7.0
|
62
71
|
def escape_prefix(prefix_path)
|
63
|
-
prefix_path.
|
72
|
+
prefix_path.gsub('_', '__').tr('/', '_')
|
64
73
|
end
|
65
74
|
end
|
66
75
|
end
|
data/lib/aptly/connection.rb
CHANGED
@@ -31,9 +31,10 @@ module Aptly
|
|
31
31
|
private_constant :GETISH_ACTIONS
|
32
32
|
POSTISH_ACTIONS = %i[post put].freeze
|
33
33
|
private_constant :POSTISH_ACTIONS
|
34
|
-
HTTP_ACTIONS = GETISH_ACTIONS + POSTISH_ACTIONS
|
35
34
|
WRITE_ACTIONS = (POSTISH_ACTIONS + %i[delete]).freeze
|
36
35
|
private_constant :WRITE_ACTIONS
|
36
|
+
HTTP_ACTIONS = GETISH_ACTIONS + POSTISH_ACTIONS
|
37
|
+
private_constant :HTTP_ACTIONS
|
37
38
|
|
38
39
|
CODE_ERRORS = {
|
39
40
|
400 => Errors::ClientError,
|
@@ -126,12 +127,14 @@ module Aptly
|
|
126
127
|
|
127
128
|
def run_postish(action, path, kwords)
|
128
129
|
body = kwords.delete(:body)
|
130
|
+
params = kwords.delete(:query)
|
129
131
|
headers = kwords.delete(:headers)
|
130
132
|
|
131
133
|
body, headers = mangle_post(body, headers, kwords)
|
132
134
|
|
133
135
|
@connection.send(action, path, body, headers) do |request|
|
134
136
|
setup_request(action, request)
|
137
|
+
request.params.update(params) if params
|
135
138
|
end
|
136
139
|
end
|
137
140
|
|
data/lib/aptly/files.rb
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
# Copyright (C) 2015-2018 Harald Sitter <sitter@kde.org>
|
2
|
+
#
|
3
|
+
# This library is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of the GNU Lesser General Public
|
5
|
+
# License as published by the Free Software Foundation; either
|
6
|
+
# version 3 of the License, or (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This library is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
11
|
+
# Lesser General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Lesser General Public
|
14
|
+
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
1
16
|
module Aptly
|
2
17
|
# Aptly files management.
|
3
18
|
# @see http://www.aptly.info/doc/api/files/
|
@@ -14,6 +29,38 @@ module Aptly
|
|
14
29
|
JSON.parse(response.body)
|
15
30
|
end
|
16
31
|
|
32
|
+
# Upload files into a temporary directory on remote.
|
33
|
+
# This method expects a block which will be yielded to with the directory
|
34
|
+
# name on the remote. The directory will be deleted when this method
|
35
|
+
# returns.
|
36
|
+
# You'll generally want to use this instead of #upload so you don't have
|
37
|
+
# to worry about name collission and clean up.
|
38
|
+
#
|
39
|
+
# @param files [Array<String>] paths to files to upload
|
40
|
+
# @param connection [Connection] connection to use
|
41
|
+
# @yield [String] the remote directory name the files were uploaded to
|
42
|
+
# @return return value of block
|
43
|
+
#
|
44
|
+
# @example Can be used to push into multiple repositories with one upload
|
45
|
+
# Files.tmp_upload(files) do |d|
|
46
|
+
# repos.each { |r| r.add_files(d, noRemove: 1) }
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# @since 0.9.0
|
50
|
+
def tmp_upload(files, connection = Connection.new, **kwords)
|
51
|
+
# TODO: 1.0 find out if #upload even has a use case and maybe replace it
|
52
|
+
dir = tmp_dir_name
|
53
|
+
upload(files, dir, connection, **kwords)
|
54
|
+
uploaded = true
|
55
|
+
yield dir
|
56
|
+
ensure
|
57
|
+
# We have an uploaded var here as exceptions raised by upload would
|
58
|
+
# still run this, but they may not have the remote file, so our
|
59
|
+
# delete request would again cause an error making it harder to spot
|
60
|
+
# the orignal problem.
|
61
|
+
delete(dir) if uploaded
|
62
|
+
end
|
63
|
+
|
17
64
|
# Delete files from remote's upload directory.
|
18
65
|
# @param path [String] path to delete (this may be a directory or a file)
|
19
66
|
# @return [nil]
|
@@ -21,6 +68,13 @@ module Aptly
|
|
21
68
|
connection.send(:delete, "/files/#{path}", kwords)
|
22
69
|
nil
|
23
70
|
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def tmp_dir_name
|
75
|
+
prefix = "#{to_s.tr(':', '_')}-#{Socket.gethostname}"
|
76
|
+
TmpName.dir(prefix)
|
77
|
+
end
|
24
78
|
end
|
25
79
|
end
|
26
80
|
end
|
data/lib/aptly/publish.rb
CHANGED
@@ -42,6 +42,17 @@ module Aptly
|
|
42
42
|
query: kwords)
|
43
43
|
JSON.parse(response.body).collect { |h| new(connection, h) }
|
44
44
|
end
|
45
|
+
|
46
|
+
# Publish an array of {Repository} to a prefix.
|
47
|
+
# @param repos [Array<Repository>] array of repositories to source
|
48
|
+
# @param prefix [String] the prefix to publish under (must be escaped see
|
49
|
+
# {.escape_prefix})
|
50
|
+
# @return [PublishedRepository] newly published repository
|
51
|
+
# @since 0.10.0
|
52
|
+
def from_repositories(repos, prefix, **kwords)
|
53
|
+
sources = repos.collect { |x| { Name: x.Name } }
|
54
|
+
Aptly.publish(sources, prefix, **kwords)
|
55
|
+
end
|
45
56
|
end
|
46
57
|
|
47
58
|
private
|
data/lib/aptly/publishable.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
module Aptly
|
2
|
+
# Abstract "type" of all publishable entities. Publishable entities
|
3
|
+
# are everything that can act as Source for a PublishedRepository.
|
2
4
|
module Publishable
|
3
5
|
# Lists all PublishedRepositories self is published in. Namely self must
|
4
6
|
# be a source of the published repository in order for it to appear here.
|
5
7
|
# This method always returns an array of affected published repositories.
|
6
8
|
# If you use this method with a block it will additionally yield each
|
7
9
|
# published repository that would appear in the array, making it a shorthand
|
8
|
-
# for
|
10
|
+
# for Array#each.
|
9
11
|
# @yieldparam pub [PublishedRepository]
|
10
12
|
# @return [Array<PublishedRepository>]
|
11
13
|
def published_in
|
data/lib/aptly/repository.rb
CHANGED
@@ -41,8 +41,11 @@ module Aptly
|
|
41
41
|
# @return [Hash] report data as specified in the API.
|
42
42
|
# FIXME: this should be called file
|
43
43
|
def add_file(path, **kwords)
|
44
|
+
# Don't mangle query, the file API is inconsistently using camelCase
|
45
|
+
# rather than CamelCase.
|
44
46
|
response = connection.send(:post, "/repos/#{self.Name}/file/#{path}",
|
45
|
-
query: kwords
|
47
|
+
query: kwords,
|
48
|
+
query_mangle: false)
|
46
49
|
hash = JSON.parse(response.body)
|
47
50
|
error = Errors::RepositoryFileError.from_hash(hash)
|
48
51
|
raise error if error
|
@@ -52,12 +55,9 @@ module Aptly
|
|
52
55
|
# FIXME: needs to support single files
|
53
56
|
# Convenience wrapper around {Files.upload}, {#add_file} and {Files.delete}
|
54
57
|
def upload(files)
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
add_file(directory)
|
59
|
-
ensure
|
60
|
-
Files.delete(directory, connection)
|
58
|
+
Files.tmp_upload(files, connection) do |dir|
|
59
|
+
add_file(dir)
|
60
|
+
end
|
61
61
|
end
|
62
62
|
|
63
63
|
# List all packages in the repository
|
@@ -95,7 +95,9 @@ module Aptly
|
|
95
95
|
|
96
96
|
# Convenience wrapper around {Aptly.publish}, publishing this repository
|
97
97
|
# locally and as only source of prefix.
|
98
|
-
# @param prefix [String] prefix to publish under (i.e. published repo name)
|
98
|
+
# @param prefix [String] prefix to publish under (i.e. published repo name).
|
99
|
+
# This must be escaped (see {Aptly.escape_prefix})
|
100
|
+
# @see Aptly.escape_prefix
|
99
101
|
# @return [PublishedRepository] newly published repository
|
100
102
|
def publish(prefix, **kwords)
|
101
103
|
Aptly.publish([{ Name: self.Name }], prefix, 'local', kwords)
|
data/lib/aptly/snapshot.rb
CHANGED
@@ -28,7 +28,7 @@ module Aptly
|
|
28
28
|
end
|
29
29
|
|
30
30
|
# Find differences between this and another snapshot
|
31
|
-
# @param [Snapshot] to diff against
|
31
|
+
# @param other_snapshot [Snapshot] to diff against
|
32
32
|
# @return [Array<Hash>] diff between the two snashots
|
33
33
|
def diff(other_snapshot)
|
34
34
|
endpoint = "/snapshots/#{self.Name}/diff/#{other_snapshot.Name}"
|
@@ -47,7 +47,9 @@ module Aptly
|
|
47
47
|
|
48
48
|
# Convenience wrapper around {Aptly.publish}, publishing this snapshot
|
49
49
|
# locally and as only source of prefix.
|
50
|
-
# @param prefix [String] prefix to publish under (i.e. published
|
50
|
+
# @param prefix [String] prefix to publish under (i.e. published repo name).
|
51
|
+
# This must be escaped (see {Aptly.escape_prefix})
|
52
|
+
# @see Aptly.escape_prefix
|
51
53
|
# @return [PublishedRepository] newly published repository
|
52
54
|
def publish(prefix, **kwords)
|
53
55
|
Aptly.publish([{ Name: self.Name }], prefix, 'snapshot', kwords)
|
data/lib/aptly/tmpname.rb
CHANGED
@@ -13,16 +13,22 @@
|
|
13
13
|
# You should have received a copy of the GNU Lesser General Public
|
14
14
|
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
15
15
|
|
16
|
+
require 'English'
|
17
|
+
|
16
18
|
module Aptly
|
17
19
|
# Helper to generate temporary names
|
18
20
|
module TmpName
|
19
|
-
|
20
|
-
|
21
|
+
# Generate a random temporary directory name.
|
22
|
+
# @param prefix [String] arbitrary prefix string to start the name with
|
23
|
+
# @return [String] temporary directory name (only safe characters)
|
24
|
+
def self.dir(prefix)
|
25
|
+
format('%<prefix>s-%<time>s-%<pid>s-%<tid>s-%<rand>s',
|
21
26
|
prefix: prefix,
|
22
27
|
# rubocop:disable Style/FormatStringToken
|
23
28
|
time: Time.now.strftime('%Y%m%d'),
|
24
29
|
# rubocop:enable Style/FormatStringToken
|
25
|
-
|
30
|
+
pid: $PROCESS_ID,
|
31
|
+
tid: Thread.current.object_id,
|
26
32
|
rand: rand(0x100000000).to_s(36))
|
27
33
|
end
|
28
34
|
end
|
data/lib/aptly/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aptly-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Harald Sitter
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-10-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '
|
20
|
+
version: '2.0'
|
21
21
|
type: :development
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: '
|
27
|
+
version: '2.0'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: coveralls
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -143,14 +143,14 @@ dependencies:
|
|
143
143
|
requirements:
|
144
144
|
- - "~>"
|
145
145
|
- !ruby/object:Gem::Version
|
146
|
-
version: '0.
|
146
|
+
version: '0.71'
|
147
147
|
type: :runtime
|
148
148
|
prerelease: false
|
149
149
|
version_requirements: !ruby/object:Gem::Requirement
|
150
150
|
requirements:
|
151
151
|
- - "~>"
|
152
152
|
- !ruby/object:Gem::Version
|
153
|
-
version: '0.
|
153
|
+
version: '0.71'
|
154
154
|
description: REST client for the Aptly API
|
155
155
|
email:
|
156
156
|
- sitter@kde.org
|
@@ -201,8 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
201
201
|
- !ruby/object:Gem::Version
|
202
202
|
version: '0'
|
203
203
|
requirements: []
|
204
|
-
|
205
|
-
rubygems_version: 2.7.3
|
204
|
+
rubygems_version: 3.1.2
|
206
205
|
signing_key:
|
207
206
|
specification_version: 4
|
208
207
|
summary: REST client for the Aptly API
|