repo-mgr 0.2.1 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 977383f34636b8ba22a0e7a936869ccf69060691787f9ebb2ed4bad5826af13b
4
- data.tar.gz: fb53030359f59ecad95adcf2a304e304fdd5c6ebed32c0c3c4e74f2e214d877d
3
+ metadata.gz: a977e25ed86d9763543cd445087e3d4e94e6ecf830e707ffb8c9dfb9c5d19541
4
+ data.tar.gz: a7d2ea6036a1d3a4fc3fc2c6f575e7dda9eaa7bc2db1d7bc0b2fe7dcdb459891
5
5
  SHA512:
6
- metadata.gz: e78a4a1dafca417fa59fe93d458ee6cf8b4fa22ad48ef0bd60ae95258e02adc9c9a3c6d91c4516224576fe0ba6c9f8eebed1bed8f82777b85836cde089b6133e
7
- data.tar.gz: 2a3c93c1f6768d6296682c17e5eacc4cf416f46d58e2c232962ca1b86bc7fff4fddff2e5c6441bb9392f823d1e9fcbe1bcb0e4d8f64b108307adbfbce71ff07e
6
+ metadata.gz: 8044c481083ac23582a3d3133dbd225ab874188217766e71d0e82e3a76bf325776ef6241064347ee5fb39df5e63d89acfe7c086f592314062fe1c3a391645ae8
7
+ data.tar.gz: d58d378485e4a41741360d308652e56b4dc9a3abd4be396840d1131c6daf187fdce3bde7de00eb2242ac0207dfacd912c591783e6fe38eaf91e266f4e77892d0
data/README.md CHANGED
@@ -16,6 +16,8 @@ To simplify things:
16
16
  * aptly (which, kind of obviously, manages deb repositories) uses "stable" as distribution and "main" as component.
17
17
  * The git publisher uses the `main` branch for `sync` only.
18
18
 
19
+ The requred aptly version is 1.4.0+ which may be installed from [aptly's deb repository](https://www.aptly.info/download/). The version available in Ubuntu 20.04 (1.3.0) doesn't support gpg2.
20
+
19
21
  ## Install
20
22
 
21
23
  ```bash
@@ -26,21 +28,21 @@ gem install repo-mgr
26
28
  rake install
27
29
  ```
28
30
 
29
- As repo-mgr is a frontend for other tools, there's dependencies which must be installed separately.
31
+ As repo-mgr is a frontend for other tools, there are dependencies which must be installed separately. It is not compulsory to install all dependencies, only those needed for a particular use case. The purpose for each tool is explained by `check-depends`.
30
32
 
31
- To check which dependencies are required and their status:
33
+ To check which dependencies are required based on use case and their status:
32
34
 
33
35
  ```bash
34
36
  repo-mgr check-depends
35
- +------------+--------+
36
- | Binary | Status |
37
- +------------+--------+
38
- | aptly | ✔ |
39
- | dpkg-sig | ✔ |
40
- | createrepo | ✔ |
41
- | rpm | ✔ |
42
- | git | ✔ |
43
- +------------+--------+
37
+ +------------+--------+-----------------------+
38
+ | Binary | Status | Purpose |
39
+ +------------+--------+-----------------------+
40
+ | aptly | ✔ | Manage apt repository |
41
+ | dpkg-sig | ✔ | Sign deb packages |
42
+ | createrepo | ✔ | Manage rpm repository |
43
+ | rpm | ✔ | Sign rpm packages |
44
+ | git | ✔ | Use git publisher |
45
+ +------------+--------+-----------------------+
44
46
  ```
45
47
 
46
48
  For managing deb repositories:
@@ -67,6 +69,12 @@ sudo apt install git
67
69
 
68
70
  You can get our build of createrepo from our [deb repository](https://deb.staker.ltd/).
69
71
 
72
+ Pro tip: if the pkg signing fails because gpg can't open the output device, add this to your shell config:
73
+
74
+ ```bash
75
+ export GPG_TTY=$(tty)
76
+ ```
77
+
70
78
  ## How to use
71
79
 
72
80
  ```bash
@@ -87,6 +95,20 @@ repo-mgr add-pkg --repo foo --path path/to/bar_0.0.1_amd64.deb
87
95
 
88
96
  # publish the repository to a remote - for git publisher this means doing git push
89
97
  repo-mgr sync --repo foo
98
+
99
+ # download repo from remote e.g when changing development machines
100
+ # repo-mgr upsert-repo (...) # needed only once if the machine is brand new
101
+ ## --url must point to the root of the remote repository
102
+ ## i.e where the pool and dists directories can be found for deb repos
103
+ ## --keyring is required for deb repositories; it is a file from
104
+ ## /usr/share/keyrings - the base path is automatically prepended
105
+ ## WARNING: the packages are not signed when imported via this method!
106
+ repo-mgr dl-repo --repo foo --type deb --url https://apt.example.com --keyring foo-keyring.gpg
107
+
108
+ ## --arch must be specified as each rpm repo arch is self-contained
109
+ ## the remote repository gpg key must be imported into the user's keyring and trusted
110
+ ## prior to starting the import process from remote rpm repo
111
+ repo-mgr dl-repo --repo foo --type rpm --url https://rpm.example.com --arch x86_64
90
112
  ```
91
113
 
92
114
  ## Migrating from v0.1
@@ -14,14 +14,7 @@ module RepoMgr
14
14
  end
15
15
 
16
16
  def add_repo(name)
17
- return if aptly_repos.include? name
18
-
19
- cmd = "aptly -config=#{@aptly_config_file} repo create #{name}"
20
- out, status = Open3.capture2e cmd
21
-
22
- unless status.exitstatus.zero?
23
- Tools.error "aptly repo create failed with:\n#{out}"
24
- end
17
+ aptly "repo create #{name}" unless aptly_repos.include? name
25
18
 
26
19
  repo_config = @config.cfg[:repos][name]
27
20
 
@@ -34,6 +27,24 @@ module RepoMgr
34
27
  save_aptly_config
35
28
  end
36
29
 
30
+ def dl_repo(options)
31
+ name = options[:repo]
32
+ url = options[:url]
33
+ keyring = options[:keyring]
34
+
35
+ if keyring.nil?
36
+ Tools.error 'you must specify a keyring file for deb repo'
37
+ end
38
+
39
+ keyring = "/usr/share/keyrings/#{keyring}"
40
+
41
+ aptly "-keyring=#{keyring} mirror create #{name} #{url} stable main"
42
+ aptly "-keyring=#{keyring} mirror update #{name}", :output
43
+ aptly "repo import #{name} #{name} Name"
44
+ aptly "mirror drop #{name}"
45
+ aptly("repo search #{name}", :return).split.map { |e| "#{e}.deb" }
46
+ end
47
+
37
48
  def add_pkg(repo, pkg)
38
49
  sign_pkg repo, pkg
39
50
  repo_add repo, pkg
@@ -51,14 +62,14 @@ module RepoMgr
51
62
  return out if status.exitstatus.zero? || allow_fail
52
63
 
53
64
  Tools.error "unable to check package signature for #{pkg} - "\
54
- "dpkg-sig returned:\n#{out}"
65
+ "dpkg-sig returned:\n#{out}"
55
66
  end
56
67
 
57
68
  def sign_pkg(repo, pkg)
58
69
  signature = check_sig pkg, allow_fail: true
59
70
 
60
71
  unless signature[-6, 5] == 'NOSIG'
61
- return puts "-- dpkg-sig returned:\n#{signature.first}"
72
+ return puts "-- dpkg-sig returned:\n#{signature.split.first}"
62
73
  end
63
74
 
64
75
  if @config.cfg[:repos][repo].nil?
@@ -74,18 +85,9 @@ module RepoMgr
74
85
  end
75
86
 
76
87
  def rebuild_pkg_list(repo)
77
- out, status = Open3.capture2e "aptly -config=#{@aptly_config_file} "\
78
- "-with-packages repo show #{repo}"
79
-
80
- unless status.exitstatus.zero?
81
- Tools.error "aptly repo show failed with with:\n#{out}"
88
+ aptly("-with-packages repo search #{repo}", :return).split.map do |e|
89
+ "#{e}.deb"
82
90
  end
83
-
84
- pkgs = out.split
85
- mark = pkgs.find_index 'Packages:'
86
- pkgs = pkgs.drop(mark + 1)
87
-
88
- pkgs.map { |e| "#{e}.deb" }
89
91
  end
90
92
 
91
93
  def export(repo)
@@ -121,8 +123,6 @@ module RepoMgr
121
123
  dependencyVerboseResolve: false,
122
124
  gpgDisableSign: false,
123
125
  gpgDisableVerify: false,
124
- # despite the binary being gpg, this must spell gpg2, otherwise aptly
125
- # defaults to gpg1 with less than impressive results
126
126
  gpgProvider: 'gpg2',
127
127
  downloadSourcePackages: false,
128
128
  skipLegacyPool: true,
@@ -136,36 +136,30 @@ module RepoMgr
136
136
  end
137
137
  # rubocop:enable Metrics/MethodLength
138
138
 
139
- def aptly_repos
140
- cmd = "aptly -raw -config=#{@aptly_config_file} repo list"
139
+ def aptly(cmd, output = nil)
140
+ cmd = "aptly -config=#{@aptly_config_file} #{cmd}"
141
141
  out, status = Open3.capture2e cmd
142
142
 
143
- unless status.exitstatus.zero?
144
- Tools.error "aptly repo list failed with:\n#{out}"
143
+ Tools.error "#{cmd} failed with:\n#{out}" unless status.exitstatus.zero?
144
+
145
+ case output
146
+ when :output
147
+ puts out
148
+ when :return
149
+ out
145
150
  end
151
+ end
146
152
 
147
- out.split("\n")
153
+ def aptly_repos
154
+ aptly('-raw repo list', :return).split
148
155
  end
149
156
 
150
157
  def aptly_published_repos
151
- cmd = "aptly -raw -config=#{@aptly_config_file} publish list"
152
- out, status = Open3.capture2e cmd
153
-
154
- unless status.exitstatus.zero?
155
- Tools.error "aptly publish list failed with:\n#{out}"
156
- end
157
-
158
- out.split("\n")
158
+ aptly('-raw publish list', :return).split("\n")
159
159
  end
160
160
 
161
161
  def aptly_publish_drop(repo)
162
- cmd = "aptly -config=#{@aptly_config_file} publish drop stable "\
163
- "filesystem:#{repo}:"
164
- out, status = Open3.capture2e cmd
165
-
166
- return if status.exitstatus.zero?
167
-
168
- Tools.error "aptly publish drop failed with:\n#{out}"
162
+ aptly "publish drop stable filesystem:#{repo}:"
169
163
  end
170
164
 
171
165
  def save_aptly_config
@@ -173,23 +167,12 @@ module RepoMgr
173
167
  end
174
168
 
175
169
  def repo_add(repo, pkg)
176
- cmd = "aptly -config=#{@aptly_config_file} repo add #{repo} #{pkg}"
177
- out, status = Open3.capture2e cmd
178
-
179
- return if status.exitstatus.zero?
180
-
181
- Tools.error "aptly repo add failed with:\n#{out}"
170
+ aptly "repo add #{repo} #{pkg}"
182
171
  end
183
172
 
184
173
  def repo_rm(repo, pkg)
185
174
  package = File.basename pkg, File.extname(pkg)
186
- cmd = "aptly -config=#{@aptly_config_file} repo remove "\
187
- "#{repo} #{package}"
188
- out, status = Open3.capture2e cmd
189
-
190
- return if status.exitstatus.zero?
191
-
192
- Tools.error "aptly repo remove failed with:\n#{out}"
175
+ aptly "repo remove #{repo} #{package}"
193
176
  end
194
177
 
195
178
  def repo_publish(repo)
@@ -198,14 +181,8 @@ module RepoMgr
198
181
  end
199
182
 
200
183
  keyid = @config.cfg[:repos][repo][:keyid]
201
- cmd = "aptly -config=#{@aptly_config_file} -distribution=stable "\
202
- "-gpg-key=#{keyid} publish repo #{repo} filesystem:#{repo}:"
203
-
204
- out, status = Open3.capture2e cmd
205
-
206
- return if status.exitstatus.zero?
207
-
208
- Tools.error "aptly publish repo failed with:\n#{out}"
184
+ aptly "-distribution=stable -gpg-key=#{keyid} publish repo #{repo} "\
185
+ "filesystem:#{repo}:"
209
186
  end
210
187
  end
211
188
  end
@@ -1,7 +1,12 @@
1
1
  # frozen_string_literal: false
2
2
 
3
+ require 'zlib'
3
4
  require 'open3'
4
5
  require 'gpgme'
6
+ require 'digest'
7
+ require 'faraday'
8
+ require 'nokogiri'
9
+ require 'stringio'
5
10
  require 'fileutils'
6
11
 
7
12
  module RepoMgr
@@ -27,6 +32,30 @@ module RepoMgr
27
32
  sync_repo repo
28
33
  end
29
34
 
35
+ def dl_repo(options)
36
+ name = options[:repo]
37
+ url = options[:url]
38
+ arch = options[:arch]
39
+
40
+ Tools.error 'you must specify an arch name for rpm repo' if arch.nil?
41
+
42
+ tmpdir = "/tmp/#{name}/#{arch}"
43
+ dest_dir = "#{@config.cfg_dir}/rpms/#{name}/#{arch}"
44
+ make_dirs tmpdir, dest_dir
45
+
46
+ repomd = dl_repomd url, arch, tmpdir
47
+ pkgs = dl_primary url, arch, tmpdir, repomd
48
+
49
+ pkgs.each do |hash, file|
50
+ dl_pkg hash, url, arch, file, tmpdir
51
+ copy_pkg "#{tmpdir}/#{file}", dest_dir
52
+ end
53
+
54
+ sync_repo name
55
+
56
+ pkgs.values
57
+ end
58
+
30
59
  def remove_pkg(repo, pkg)
31
60
  name = File.basename pkg
32
61
  arch = extract_arch pkg
@@ -43,7 +72,7 @@ module RepoMgr
43
72
  return out if status.exitstatus.zero?
44
73
 
45
74
  Tools.error "unable to check package signature for #{pkg} - "\
46
- "rpm -K returned:\n#{out}"
75
+ "rpm -K returned:\n#{out}"
47
76
  end
48
77
 
49
78
  def sign_pkg(repo, pkg)
@@ -114,7 +143,7 @@ module RepoMgr
114
143
  return if status.exitstatus.zero?
115
144
 
116
145
  Tools.error "unable to create repo for #{arch} - createrepo "\
117
- "returned:\n#{out}"
146
+ "returned:\n#{out}"
118
147
  end
119
148
 
120
149
  def sign_repo(repo)
@@ -131,6 +160,83 @@ module RepoMgr
131
160
 
132
161
  File.write 'repomd.xml.asc', signature
133
162
  end
163
+
164
+ def faraday_dl(url, tmpdir, file = File.basename(url))
165
+ puts "-- Download #{file}"
166
+ File.write "#{tmpdir}/#{file}", Faraday.get(url).body
167
+ end
168
+
169
+ def dl_repomd(url, arch, tmpdir)
170
+ faraday_dl "#{url}/#{arch}/repodata/repomd.xml", tmpdir
171
+ faraday_dl "#{url}/#{arch}/repodata/repomd.xml.asc", tmpdir
172
+
173
+ valid = false
174
+ crypto = GPGME::Crypto.new armor: true
175
+ sig = GPGME::Data.new File.read "#{tmpdir}/repomd.xml.asc"
176
+ data = File.read "#{tmpdir}/repomd.xml"
177
+ crypto.verify(sig, signed_text: data) do |sign|
178
+ valid = sign.valid?
179
+ end
180
+
181
+ unless valid == true
182
+ Tools.error "unable to check signature for #{tmpdir}/repomd.xml"
183
+ end
184
+
185
+ Nokogiri::XML data
186
+ end
187
+
188
+ def extract_pkgs(primary)
189
+ pkgs = {}
190
+
191
+ primary.css('package').each do |pkg|
192
+ pkg_hash = pkg.at('checksum[type=sha256]').text
193
+ pkgs[pkg_hash] = pkg.at('location')['href']
194
+ end
195
+
196
+ pkgs
197
+ end
198
+
199
+ def dl_primary(url, arch, tmpdir, repomd)
200
+ hash = repomd.at('data[type=primary]').at('checksum').text
201
+ primary = "#{url}/#{arch}/repodata/#{hash}-primary.xml.gz"
202
+
203
+ faraday_dl primary, tmpdir, 'primary.xml.gz'
204
+
205
+ primary_xml_gz = "#{tmpdir}/primary.xml.gz"
206
+ fl_hash = Digest::SHA256.hexdigest(File.read(primary_xml_gz))
207
+
208
+ unless fl_hash == hash
209
+ Tools.error "failed hash check for #{tmpdir}/primary.xml.gz"
210
+ end
211
+
212
+ primary_xml_gz = File.read("#{tmpdir}/primary.xml.gz")
213
+ primary = Zlib::GzipReader.new(StringIO.new(primary_xml_gz)).read
214
+ File.write("#{tmpdir}/primary.xml", primary)
215
+
216
+ extract_pkgs Nokogiri::XML(primary)
217
+ end
218
+
219
+ def dl_pkg(hash, url, arch, file, tmpdir)
220
+ unless File.exist? "#{tmpdir}/#{file}"
221
+ faraday_dl "#{url}/#{arch}/#{file}", tmpdir
222
+ end
223
+
224
+ fl_hash = Digest::SHA256.hexdigest(File.read("#{tmpdir}/#{file}"))
225
+
226
+ return if fl_hash == hash
227
+
228
+ Tools.error "failed hash check for #{tmpdir}/#{file}"
229
+ end
230
+
231
+ def copy_pkg(file, destdir)
232
+ puts "-- Copy to repo-mgr #{File.basename(file)}"
233
+ FileUtils.cp file, destdir
234
+ end
235
+
236
+ def make_dirs(tmpdir, dest_dir)
237
+ FileUtils.mkdir_p tmpdir
238
+ FileUtils.mkdir_p dest_dir
239
+ end
134
240
  end
135
241
  end
136
242
  end
data/lib/repo_mgr/cli.rb CHANGED
@@ -29,16 +29,19 @@ module RepoMgr
29
29
 
30
30
  def check_depends
31
31
  rows = []
32
-
33
- %w[aptly dpkg-sig createrepo rpm git].each do |bin_dep|
34
- rows << if Tools.which bin_dep
35
- [bin_dep, ''.green]
36
- else
37
- [bin_dep, ''.red]
38
- end
32
+ deps = {
33
+ 'aptly' => 'Manage apt repository',
34
+ 'dpkg-sig' => 'Sign deb packages',
35
+ 'createrepo' => 'Manage rpm repository',
36
+ 'rpm' => 'Sign rpm packages',
37
+ 'git' => 'Use git publisher'
38
+ }
39
+
40
+ deps.each do |bin_dep, purpose|
41
+ rows << which_depends(bin_dep, purpose)
39
42
  end
40
43
 
41
- puts Terminal::Table.new headings: %w[Binary Status], rows: rows
44
+ puts Terminal::Table.new headings: %w[Binary Status Purpose], rows: rows
42
45
  end
43
46
 
44
47
  desc 'upsert-repo', 'Create/Update new repository'
@@ -82,6 +85,28 @@ module RepoMgr
82
85
  )
83
86
  end
84
87
 
88
+ desc 'dl-repo', 'Download repository from remote endpoint'
89
+ option :repo, type: :string, required: true, aliases: %w[-r],
90
+ desc: 'The repository to download packages into'
91
+ option :type, type: :string, required: true, aliases: %w[-t],
92
+ enum: types, desc: 'Repository type'
93
+ option :url, type: :string, required: true, aliases: %w[-u],
94
+ desc: 'The URL for the remote repository'
95
+ option :keyring, type: :string, aliases: %w[-k],
96
+ desc: 'Name of keyring file if required to auth repository'
97
+ option :arch, type: :string, aliases: %w[-a],
98
+ desc: 'Pkg arch if multiple arch are supported by repo'
99
+
100
+ def dl_repo
101
+ backend, config = load_backend options[:type]
102
+
103
+ pkgs = backend.dl_repo options
104
+
105
+ pkgs.each do |pkg|
106
+ config.add_pkg options[:repo], pkg
107
+ end
108
+ end
109
+
85
110
  desc 'add-pkg', 'Add package to repository'
86
111
  option :repo, type: :string, required: true, aliases: %w[-r],
87
112
  desc: 'The repository to add the package to'
@@ -100,7 +125,7 @@ module RepoMgr
100
125
  end
101
126
 
102
127
  puts "-- Added #{File.basename(options[:path])} to "\
103
- "#{options[:repo]} repository"
128
+ "#{options[:repo]} repository"
104
129
  end
105
130
 
106
131
  desc 'list-pkgs', 'List repository packages'
@@ -132,7 +157,7 @@ module RepoMgr
132
157
  config.remove_pkg options[:repo], options[:path]
133
158
 
134
159
  puts "-- Removed #{File.basename(options[:path])} from "\
135
- "#{options[:repo]} repository"
160
+ "#{options[:repo]} repository"
136
161
  end
137
162
 
138
163
  desc 'check-sig', 'Check package signature'
@@ -190,8 +215,15 @@ module RepoMgr
190
215
 
191
216
  private
192
217
 
218
+ def which_depends(bin_dep, purpose)
219
+ return [bin_dep, '✔'.green, purpose] if Tools.which bin_dep
220
+
221
+ [bin_dep, '✘'.red, purpose]
222
+ end
223
+
193
224
  def load_backend(path)
194
225
  type = File.extname(path).strip.downcase[1..-1]
226
+ type = path if type.nil?
195
227
 
196
228
  unless CLI.types.include? type
197
229
  Tools.error "unsupported package type #{type}"
@@ -68,7 +68,7 @@ module RepoMgr
68
68
  def remove_pkg(repo, path)
69
69
  if @cfg[:repos][repo].nil?
70
70
  Tools.error "unable to remove packages from #{repo} "\
71
- '- repo does not exist'
71
+ '- repo does not exist'
72
72
  end
73
73
 
74
74
  @cfg[:packages] ||= {}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: repo-mgr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ștefan Rusu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-17 00:00:00.000000000 Z
11
+ date: 2022-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colored
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.9.3
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.9.3
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: git
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +66,20 @@ dependencies:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
68
  version: '2.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: nokogiri
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.13.3
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.13.3
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: terminal-table
57
85
  requirement: !ruby/object:Gem::Requirement
@@ -81,7 +109,7 @@ dependencies:
81
109
  - !ruby/object:Gem::Version
82
110
  version: '1.1'
83
111
  - !ruby/object:Gem::Dependency
84
- name: jeweler
112
+ name: juwelier
85
113
  requirement: !ruby/object:Gem::Requirement
86
114
  requirements:
87
115
  - - ">="
@@ -176,7 +204,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
176
204
  - !ruby/object:Gem::Version
177
205
  version: '0'
178
206
  requirements: []
179
- rubygems_version: 3.1.4
207
+ rubygems_version: 3.2.32
180
208
  signing_key:
181
209
  specification_version: 4
182
210
  summary: deb and rpm repository manager