repo-mgr 0.1.1 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: be8fb6163c79ae7f9956b0237f390c4d7764c23ef6f4ffa24c1531a3726187e0
4
- data.tar.gz: 60346b9d260718f3a03745b6c90b1fdb80c34ac62458cd999d67a2cadc7b840d
3
+ metadata.gz: 134dd25e2f420da28416738476d2461cfc4e41e358b9eeefd95740b12fb32b29
4
+ data.tar.gz: 583f3afd307e6b101df5fb316619c8636882388d93937fe8cd66200d302c03e7
5
5
  SHA512:
6
- metadata.gz: 8af9d6f12205d03e88d28ed848331708a9c6313ea377fd9c9144a2a2f88070de904784cc63659a42b9f3d110775caeeea636d90953927ed645039f135873eaf9
7
- data.tar.gz: 4688c21a24223d81a0b7fb1c9694a59e26cc7b125c4466aecf9a3bbc470c74619d6a2aa61f7469c9acc993c9f48ac4267fece461bc9738018bea819f5019214a
6
+ metadata.gz: 88e36dd2757d71c32276fa7a7c02c218a0f3dcc2c497b87264388e0ef9a9cd65308b35588ae3b967073ddb823c6bdb3310be6eb47b87f18a63de75526d6b039e
7
+ data.tar.gz: 0bf223130b5aee561025db95edf42322e09071767c43d2ceddaeee77317a1a808fde24f994cf9995c1e4299424e26ecda35aa0222a047bf6ef6b7ecc0d6d883d
data/README.md CHANGED
@@ -9,8 +9,12 @@ Features:
9
9
  * Create/update deb/rpm repositories.
10
10
  * Add/remove packages to these repositories and automatically sign packages using GPG.
11
11
  * Repository metadata/manifest signing using GPG.
12
+ * Publish to remote via git.
12
13
 
13
- To simplify things, aptly (which, kind of obviously, manages deb repositories) uses "stable" as distribution and "main" as component.
14
+ To simplify things:
15
+
16
+ * aptly (which, kind of obviously, manages deb repositories) uses "stable" as distribution and "main" as component.
17
+ * The git publisher uses the `main` branch for `sync` only.
14
18
 
15
19
  ## Install
16
20
 
@@ -35,6 +39,7 @@ repo-mgr check-depends
35
39
  | dpkg-sig | ✔ |
36
40
  | createrepo | ✔ |
37
41
  | rpm | ✔ |
42
+ | git | ✔ |
38
43
  +------------+--------+
39
44
  ```
40
45
 
@@ -48,6 +53,12 @@ For managing rpm repositories:
48
53
 
49
54
  ```bash
50
55
  sudo apt install createrepo rpm
56
+ ```
57
+
58
+ For using the git publisher:
59
+
60
+ ```bash
61
+ sudo apt install git
51
62
  ```
52
63
 
53
64
  n.b `createrepo` is not normally available for Debian and derrivates (including Ubuntu). This tool
@@ -65,11 +76,27 @@ repo-mgr help
65
76
  # create repo
66
77
  ## --path => a local directory where the repository is published - no remote support at the moment
67
78
  ## GPGKEYID is expected as log keyid i.e 16 hex chars
68
- repo-mgr upsert-repo --name foo --type deb --path path/to/foo --keyid GPGKEYID
79
+ ## --publisher - is optional i.e you can still manually publish a local repository
80
+ repo-mgr upsert-repo --name foo --type deb --path path/to/foo --keyid GPGKEYID --publisher git
69
81
 
70
82
  # sign package, add to repository, and update local repo (includes sign repo release manifest)
71
83
  # the local repo is exported to the path indicated in upsert-repo
84
+ # the git publisher also commits the changes as the path for upsert-repo is expected to be
85
+ # a git repository
72
86
  repo-mgr add-pkg --repo foo --path path/to/bar_0.0.1_amd64.deb
87
+
88
+ # publish the repository to a remote - for git publisher this means doing git push
89
+ repo-mgr sync --repo foo
90
+ ```
91
+
92
+ ## Migrating from v0.1
93
+
94
+ The package list is stored into a structure that's prone to lose the list upon re-running `upsert-repo` for `v0.1.x` of this gem. For this reason, the package list data structure has been redesigned within repo-mgr's config file.
95
+
96
+ So, to migrate from this earlier version, you must run, for every repo:
97
+
98
+ ```bash
99
+ repo-mgr rebuild-pkg-list --repo foo
73
100
  ```
74
101
 
75
- You then need to sync the repo to whatever desired target. For the time being, this isn't implemented as the main use case for this tool is publishing into a git repository which is served as GitHub page.
102
+ This rebuilds the data structure in the new config location.
@@ -45,7 +45,7 @@ module RepoMgr
45
45
  repo_publish repo
46
46
  end
47
47
 
48
- def check_sig(pkg, allow_fail = false)
48
+ def check_sig(pkg, allow_fail: false)
49
49
  out, status = Open3.capture2e "dpkg-sig --verify #{pkg}"
50
50
 
51
51
  return out if status.exitstatus.zero? || allow_fail
@@ -55,7 +55,7 @@ module RepoMgr
55
55
  end
56
56
 
57
57
  def sign_pkg(repo, pkg)
58
- signature = check_sig pkg, true
58
+ signature = check_sig pkg, allow_fail: true
59
59
 
60
60
  unless signature[-6, 5] == 'NOSIG'
61
61
  return puts "-- dpkg-sig returned:\n#{signature.first}"
@@ -73,6 +73,21 @@ module RepoMgr
73
73
  Tools.error "unable to sign #{pkg} - dpkg-sig returned:\n#{out}"
74
74
  end
75
75
 
76
+ 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}"
82
+ 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
+ end
90
+
76
91
  private
77
92
 
78
93
  def init_aptly_config
@@ -69,6 +69,12 @@ module RepoMgr
69
69
  Tools.error "unable to sign #{pkg} - rpm --addsign returned:\n#{out}"
70
70
  end
71
71
 
72
+ def rebuild_pkg_list(repo)
73
+ Dir["#{@config.cfg_dir}/rpms/#{repo}/**/*.rpm"].map do |e|
74
+ File.basename e
75
+ end
76
+ end
77
+
72
78
  private
73
79
 
74
80
  def extract_arch(pkg)
data/lib/repo_mgr/cli.rb CHANGED
@@ -8,6 +8,7 @@ require 'terminal-table'
8
8
  require_relative 'tools'
9
9
  require_relative 'config'
10
10
  require_relative 'backends'
11
+ require_relative 'publishers'
11
12
 
12
13
  module RepoMgr
13
14
  # implements CLI interface
@@ -20,12 +21,16 @@ module RepoMgr
20
21
  %w[deb rpm]
21
22
  end
22
23
 
24
+ def self.publishers
25
+ %w[git]
26
+ end
27
+
23
28
  desc 'check-depends', 'Check dependencies'
24
29
 
25
30
  def check_depends
26
31
  rows = []
27
32
 
28
- %w[aptly dpkg-sig createrepo rpm].each do |bin_dep|
33
+ %w[aptly dpkg-sig createrepo rpm git].each do |bin_dep|
29
34
  rows << if Tools.which bin_dep
30
35
  [bin_dep, '✔'.green]
31
36
  else
@@ -45,13 +50,14 @@ module RepoMgr
45
50
  desc: 'Directory path where to build the repository'
46
51
  option :keyid, type: :string, required: true, aliases: %w[-k],
47
52
  desc: 'GPG key id used to sign the repository metadata'
53
+ option :publisher, type: :string, aliases: %w[-r], enum: publishers,
54
+ desc: 'Publisher used to sync repo data to remote target'
48
55
 
49
56
  def upsert_repo
50
57
  FileUtils.mkdir_p options[:path]
51
58
 
52
59
  config = Config.new
53
- config.upsert_repo options[:name], options[:type], options[:path],
54
- options[:keyid]
60
+ config.upsert_repo options
55
61
 
56
62
  backend = Backends.load options[:type], config
57
63
  backend.add_repo options[:name]
@@ -66,12 +72,14 @@ module RepoMgr
66
72
  config = Config.new
67
73
 
68
74
  config.cfg[:repos].each do |name, repo|
69
- rows << [name, repo[:type], repo[:path], repo[:keyid]]
75
+ rows << [name, repo[:type], repo[:path], repo[:keyid], repo[:publisher]]
70
76
  end
71
77
 
72
78
  return puts '-- No repos have been created' if rows.count.zero?
73
79
 
74
- puts Terminal::Table.new headings: %w[Name Type Path KeyID], rows: rows
80
+ puts Terminal::Table.new(
81
+ headings: %w[Name Type Path KeyID Publisher], rows: rows
82
+ )
75
83
  end
76
84
 
77
85
  desc 'add-pkg', 'Add package to repository'
@@ -85,6 +93,12 @@ module RepoMgr
85
93
  backend.add_pkg options[:repo], options[:path]
86
94
  config.add_pkg options[:repo], options[:path]
87
95
 
96
+ pub_type = config.cfg[:repos][options[:repo]][:publisher]
97
+ if pub_type
98
+ publisher = Publishers.load pub_type, config
99
+ publisher.save options[:repo], options[:path]
100
+ end
101
+
88
102
  puts "-- Added #{File.basename(options[:path])} to "\
89
103
  "#{options[:repo]} repository"
90
104
  end
@@ -94,7 +108,7 @@ module RepoMgr
94
108
  desc: 'The repository to list the packages from'
95
109
 
96
110
  def list_pkgs
97
- packages = Config.new.cfg[:repos][options[:repo]][:packages]
111
+ packages = Config.new.cfg[:packages][options[:repo]]
98
112
 
99
113
  if packages.nil?
100
114
  Tools.error "#{options[:repo]} repo does not have any packages"
@@ -130,6 +144,38 @@ module RepoMgr
130
144
  puts backend.check_sig options[:path]
131
145
  end
132
146
 
147
+ desc 'rebuild-pkg-list', 'Rebuild package list from local pkg cache'
148
+ option :repo, type: :string, required: true, aliases: %w[-r],
149
+ desc: 'The repository to rebuild pkg list for'
150
+ def rebuild_pkg_list
151
+ config = Config.new
152
+ backend = Backends.load config.cfg[:repos][options[:repo]][:type], config
153
+ pkgs = backend.rebuild_pkg_list options[:repo]
154
+
155
+ pkgs.each do |pkg|
156
+ config.add_pkg options[:repo], pkg
157
+ end
158
+
159
+ puts "-- Rebuilt #{options[:repo]} repo pkg list"
160
+ end
161
+
162
+ desc 'sync', 'Sync local repo to remote target using repo publisher'
163
+ option :repo, type: :string, required: true, aliases: %w[-r],
164
+ desc: 'The repository to sync to remote target via publisher'
165
+ def sync
166
+ config = Config.new
167
+ pub_type = config.cfg[:repos][options[:repo]][:publisher]
168
+
169
+ unless pub_type
170
+ Tools.error "#{options[:repo]} repo does not have a publisher"
171
+ end
172
+
173
+ publisher = Publishers.load pub_type, config
174
+ publisher.sync options[:repo]
175
+
176
+ puts "-- Synchronised #{options[:repo]} using #{pub_type} publisher"
177
+ end
178
+
133
179
  private
134
180
 
135
181
  def load_backend(path)
@@ -15,7 +15,9 @@ module RepoMgr
15
15
  FileUtils.mkdir_p @cfg_dir
16
16
 
17
17
  @cfg_file = "#{@cfg_dir}/repo-mgr.yml"
18
- File.write @cfg_file, { repos: {} }.to_yaml unless File.exist? @cfg_file
18
+ unless File.exist? @cfg_file
19
+ File.write @cfg_file, { repos: {}, packages: {} }.to_yaml
20
+ end
19
21
 
20
22
  @cfg = YAML.load_file @cfg_file
21
23
  end
@@ -24,17 +26,24 @@ module RepoMgr
24
26
  File.write @cfg_file, @cfg.to_yaml
25
27
  end
26
28
 
27
- def upsert_repo(name, type, path, keyid)
29
+ def upsert_repo(options)
30
+ name = options[:name]
31
+ type = options[:type]
32
+
28
33
  if @cfg[:repos][name] && @cfg[:repos][name][:type] != type
29
34
  Tools.error "unable to change type for #{name} repository"
30
35
  end
31
36
 
32
37
  @cfg[:repos][name] = {
33
38
  type: type,
34
- path: path,
35
- keyid: keyid
39
+ path: options[:path],
40
+ keyid: options[:keyid]
36
41
  }
37
42
 
43
+ if options[:publisher]
44
+ @cfg[:repos][name][:publisher] = options[:publisher]
45
+ end
46
+
38
47
  save
39
48
  end
40
49
 
@@ -43,14 +52,15 @@ module RepoMgr
43
52
  Tools.error "unable to add packages to #{repo} - repo does not exist"
44
53
  end
45
54
 
46
- @cfg[:repos][repo][:packages] ||= []
55
+ @cfg[:packages] ||= {}
56
+ @cfg[:packages][repo] ||= []
47
57
  pkg = File.basename path
48
58
 
49
- if @cfg[:repos][repo][:packages].include?(pkg)
59
+ if @cfg[:packages][repo].include?(pkg)
50
60
  Tools.error "you already have #{pkg} in your #{repo} repo"
51
61
  end
52
62
 
53
- @cfg[:repos][repo][:packages] << pkg
63
+ @cfg[:packages][repo] << pkg
54
64
 
55
65
  save
56
66
  end
@@ -61,9 +71,10 @@ module RepoMgr
61
71
  '- repo does not exist'
62
72
  end
63
73
 
64
- @cfg[:repos][repo][:packages] ||= []
74
+ @cfg[:packages] ||= {}
75
+ @cfg[:packages][repo] ||= []
65
76
  pkg = File.basename path
66
- @cfg[:repos][repo][:packages].delete pkg
77
+ @cfg[:packages][repo].delete pkg
67
78
 
68
79
  save
69
80
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: false
2
+
3
+ require_relative 'publishers/git'
4
+
5
+ module RepoMgr
6
+ # factory loader for RepoMgr::Publisher::Foo objects
7
+ class Publishers
8
+ def self.load(publisher, config)
9
+ @obj ||= {}
10
+
11
+ @obj[publisher] ||= Object.const_get(
12
+ "RepoMgr::Publisher::#{publisher.capitalize}"
13
+ ).new(config)
14
+
15
+ @obj[publisher]
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: false
2
+
3
+ require 'git'
4
+
5
+ module RepoMgr
6
+ module Publisher
7
+ # git publisher
8
+ class Git
9
+ def initialize(config)
10
+ @config = config
11
+ end
12
+
13
+ # method invoked when the local deb/rpm repository is built
14
+ # for git, this requires a commit into the target git repository
15
+ # which is the target for deb/rpm repository export
16
+ def save(repo, pkg)
17
+ git = ::Git.open @config.cfg[:repos][repo][:path]
18
+ git.add(all: true)
19
+ git.commit "Add #{File.basename(pkg)}."
20
+ end
21
+
22
+ # method invoked when the local deb/rpm repository is published
23
+ # for git, this is pushing to a remote
24
+ def sync(repo)
25
+ git = ::Git.open @config.cfg[:repos][repo][:path]
26
+ git.push(git.remote('origin'), 'main')
27
+ end
28
+ end
29
+ end
30
+ end
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.1.1
4
+ version: 0.2.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-04-17 00:00:00.000000000 Z
11
+ date: 2021-04-26 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: git
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.8.1
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: gpgme
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -140,6 +154,8 @@ files:
140
154
  - lib/repo_mgr/backends/rpm.rb
141
155
  - lib/repo_mgr/cli.rb
142
156
  - lib/repo_mgr/config.rb
157
+ - lib/repo_mgr/publishers.rb
158
+ - lib/repo_mgr/publishers/git.rb
143
159
  - lib/repo_mgr/tools.rb
144
160
  homepage: https://github.com/mr-staker/repo-mgr
145
161
  licenses: