akabei 0.1.0 → 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.
@@ -0,0 +1,99 @@
1
+ #
2
+ # /etc/pacman.conf
3
+ #
4
+ # See the pacman.conf(5) manpage for option and repository directives
5
+
6
+ #
7
+ # GENERAL OPTIONS
8
+ #
9
+ [options]
10
+ # The following paths are commented out with their default values listed.
11
+ # If you wish to use different paths, uncomment and update the paths.
12
+ #RootDir = /
13
+ #DBPath = /var/lib/pacman/
14
+ #CacheDir = /var/cache/pacman/pkg/
15
+ #LogFile = /var/log/pacman.log
16
+ #GPGDir = /etc/pacman.d/gnupg/
17
+ HoldPkg = pacman glibc
18
+ #XferCommand = /usr/bin/curl -C - -f %u > %o
19
+ #XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u
20
+ #CleanMethod = KeepInstalled
21
+ #UseDelta = 0.7
22
+ Architecture = auto
23
+
24
+ # Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup
25
+ #IgnorePkg =
26
+ #IgnoreGroup =
27
+
28
+ #NoUpgrade =
29
+ #NoExtract =
30
+
31
+ # Misc options
32
+ #UseSyslog
33
+ #Color
34
+ #TotalDownload
35
+ CheckSpace
36
+ #VerbosePkgLists
37
+
38
+ # By default, pacman accepts packages signed by keys that its local keyring
39
+ # trusts (see pacman-key and its man page), as well as unsigned packages.
40
+ SigLevel = Required DatabaseOptional
41
+ LocalFileSigLevel = Optional
42
+ #RemoteFileSigLevel = Required
43
+
44
+ # NOTE: You must run `pacman-key --init` before first using pacman; the local
45
+ # keyring can then be populated with the keys of all official Arch Linux
46
+ # packagers with `pacman-key --populate archlinux`.
47
+
48
+ #
49
+ # REPOSITORIES
50
+ # - can be defined here or included from another file
51
+ # - pacman will search repositories in the order defined here
52
+ # - local/custom mirrors can be added here or in separate files
53
+ # - repositories listed first will take precedence when packages
54
+ # have identical names, regardless of version number
55
+ # - URLs will have $repo replaced by the name of the current repo
56
+ # - URLs will have $arch replaced by the name of the architecture
57
+ #
58
+ # Repository entries are of the format:
59
+ # [repo-name]
60
+ # Server = ServerName
61
+ # Include = IncludePath
62
+ #
63
+ # The header [repo-name] is crucial - it must be present and
64
+ # uncommented to enable the repo.
65
+ #
66
+
67
+ # The testing repositories are disabled by default. To enable, uncomment the
68
+ # repo name header and Include lines. You can add preferred servers immediately
69
+ # after the header, and they will be used before the default mirrors.
70
+
71
+ #[testing]
72
+ #Include = /etc/pacman.d/mirrorlist
73
+
74
+ [core]
75
+ Include = /etc/pacman.d/mirrorlist
76
+
77
+ [extra]
78
+ Include = /etc/pacman.d/mirrorlist
79
+
80
+ #[community-testing]
81
+ #Include = /etc/pacman.d/mirrorlist
82
+
83
+ [community]
84
+ Include = /etc/pacman.d/mirrorlist
85
+
86
+ # If you want to run 32 bit applications on your x86_64 system,
87
+ # enable the multilib repositories as required here.
88
+
89
+ #[multilib-testing]
90
+ #Include = /etc/pacman.d/mirrorlist
91
+
92
+ #[multilib]
93
+ #Include = /etc/pacman.d/mirrorlist
94
+
95
+ # An example of a custom package repository. See the pacman manpage for
96
+ # tips on creating your own repositories.
97
+ #[custom]
98
+ #SigLevel = Optional TrustAll
99
+ #Server = file:///home/custompkgs
@@ -9,9 +9,10 @@ module Akabei
9
9
  class Repository
10
10
  attr_accessor :signer, :include_files
11
11
 
12
- def initialize
12
+ def initialize(opts = {})
13
13
  @db = {}
14
- @include_files = false
14
+ @include_files = opts[:include_files] || false
15
+ @signer = opts[:signer]
15
16
  end
16
17
 
17
18
  extend Forwardable
@@ -55,8 +56,8 @@ module Akabei
55
56
  nil
56
57
  end
57
58
 
58
- def self.load(path)
59
- new.tap do |repo|
59
+ def self.load(path, opts = {})
60
+ new(opts).tap do |repo|
60
61
  repo.load(path)
61
62
  end
62
63
  end
@@ -36,9 +36,13 @@ module Akabei
36
36
  end
37
37
  end
38
38
 
39
- def initialize(gpg_key, crypto = GPGME::Crypto.new)
39
+ def self.get(gpg_key, crypto = nil)
40
+ gpg_key && new(gpg_key, crypto)
41
+ end
42
+
43
+ def initialize(gpg_key, crypto = nil)
40
44
  @gpg_key = find_secret_key(gpg_key)
41
- @crypto = crypto
45
+ @crypto = crypto || GPGME::Crypto.new
42
46
  end
43
47
 
44
48
  def detach_sign(path)
@@ -1,3 +1,3 @@
1
1
  module Akabei
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -3,7 +3,7 @@ require 'akabei/builder'
3
3
  require 'akabei/signer'
4
4
 
5
5
  describe Akabei::Builder do
6
- let(:builder) { described_class.new }
6
+ let(:builder) { described_class.new(pkgdest: pkgdest) }
7
7
  let(:pkgdest) { test_dest('packages').tap(&:mkpath) }
8
8
  let(:package_dir) { test_dest('nkf').tap(&:mkpath) }
9
9
  let(:pkgname) { 'nkf-2.1.3-1' }
@@ -14,10 +14,6 @@ describe Akabei::Builder do
14
14
  let(:log_package_fname) { "#{pkgname}-#{arch}-package.log" }
15
15
  let(:srcpkg_fname) { "#{pkgname}.src.tar.gz" }
16
16
 
17
- before do
18
- builder.pkgdest = pkgdest
19
- end
20
-
21
17
  describe '#build_package' do
22
18
  let(:chroot) { double('ChrootTree') }
23
19
 
@@ -2,4 +2,139 @@ require 'spec_helper'
2
2
  require 'akabei/cli'
3
3
 
4
4
  describe Akabei::CLI do
5
+ let(:cli) { described_class.new }
6
+ let(:package_dir) { test_dest('nkf') }
7
+ let(:srcpkg_path) { test_input('nkf.tar.gz') }
8
+ let(:package_path) { test_input('nkf-2.1.3-1-x86_64.pkg.tar.xz') }
9
+
10
+ describe '#build' do
11
+ let(:repo_dir) { test_dest('repo').tap(&:mkpath) }
12
+ let(:base_opts) { { arch: 'x86_64', repo_dir: repo_dir.to_s, repo_name: 'test' } }
13
+ let(:package) { double('built package') }
14
+ let(:entry) { Akabei::PackageEntry.new }
15
+ let(:chroot_expectations) { lambda { |chroot| } }
16
+
17
+ before do
18
+ tar('xf', test_input('nkf.tar.gz').to_s, '-C', package_dir.parent.to_s)
19
+ # Disable warning
20
+ entry.add('files', 'usr/bin/nkf')
21
+
22
+ allow(package).to receive(:db_name).and_return('nkf-2.1.3-1')
23
+ allow(package).to receive(:to_entry).and_return(entry)
24
+
25
+ allow_any_instance_of(Akabei::ChrootTree).to receive(:with_chroot) { |chroot, &block|
26
+ chroot_expectations.call(chroot)
27
+ block.call
28
+ }
29
+ allow_any_instance_of(Akabei::Builder).to receive(:build_package) { |builder, dir, chroot|
30
+ expect(builder).to receive(:with_source_package).with(package_dir.to_s).and_yield(srcpkg_path)
31
+ [package]
32
+ }
33
+ end
34
+
35
+ it 'calls Builder#build_package in chroot and create repository database' do
36
+ cli.invoke(:build, [package_dir.to_s], base_opts)
37
+ expect(repo_dir.join('test.db')).to be_file
38
+ expect(repo_dir.join('test.files')).to be_file
39
+ expect(repo_dir.join('test.abs.tar.gz')).to be_file
40
+ end
41
+
42
+ context 'with --makepkg-config' do
43
+ let(:makepkg_path) { test_input('makepkg.x86_64.conf') }
44
+ let(:chroot_expectations) {
45
+ lambda do |chroot|
46
+ expect(chroot.makepkg_config).to eq(makepkg_path)
47
+ end
48
+ }
49
+
50
+ it 'calls ChrootTree#with_chroot with makepkg_config' do
51
+ cli.invoke(:build, [package_dir.to_s], base_opts.merge(makepkg_config: makepkg_path.to_s))
52
+ end
53
+ end
54
+
55
+ context 'with --pacman-config' do
56
+ let(:pacman_path) { test_input('pacman.x86_64.conf') }
57
+ let(:chroot_expectations) {
58
+ lambda do |chroot|
59
+ expect(chroot.pacman_config).to eq(pacman_path)
60
+ end
61
+ }
62
+
63
+ it 'calls ChrootTree#with_chroot with pacman_config' do
64
+ cli.invoke(:build, [package_dir.to_s], base_opts.merge(pacman_config: pacman_path.to_s))
65
+ end
66
+ end
67
+ end
68
+
69
+ describe '#abs_add' do
70
+ let(:repo_name) { 'test' }
71
+ let(:abs_path) { test_dest('abs.tar.gz') }
72
+
73
+ it 'creates abs tarball' do
74
+ allow_any_instance_of(Akabei::Builder).to receive(:with_source_package).with(package_dir.to_s).and_yield(srcpkg_path)
75
+ cli.invoke(:abs_add, [package_dir.to_s, abs_path.to_s], repo_name: repo_name)
76
+ expect(abs_path).to be_file
77
+ end
78
+ end
79
+
80
+ describe '#abs_remove' do
81
+ let(:repo_name) { 'test' }
82
+ let(:abs_path) { test_dest('abs.tar.gz') }
83
+
84
+ before do
85
+ FileUtils.cp(test_input('abs.tar.gz'), abs_path)
86
+ end
87
+
88
+ it 'removes package from abs tarball' do
89
+ cli.invoke(:abs_remove, ['htop-vi', abs_path.to_s], repo_name: repo_name)
90
+ expect(abs_path).to be_file
91
+ expect(tar('tf', abs_path.to_s)).to_not include('test/htop-vi/PKGBUILD')
92
+ end
93
+ end
94
+
95
+ describe '#repo_add' do
96
+ let(:db_path) { test_dest('test.db') }
97
+
98
+ it 'creates repository database' do
99
+ cli.invoke(:repo_add, [package_path.to_s, db_path.to_s])
100
+ expect(db_path).to be_file
101
+ expect(tar('tf', db_path.to_s)).to include('nkf-2.1.3-1/desc')
102
+ end
103
+ end
104
+
105
+ describe '#repo_remove' do
106
+ let(:db_path) { test_dest('test.db') }
107
+
108
+ before do
109
+ FileUtils.cp(test_input('test.db'), db_path)
110
+ end
111
+
112
+ it 'removes package from repository database' do
113
+ cli.invoke(:repo_remove, ['htop-vi', db_path.to_s])
114
+ expect(tar('tf', db_path.to_s)).to_not include('htop-vi-1.0.2-4/desc')
115
+ end
116
+ end
117
+
118
+ describe '#files_add' do
119
+ let(:files_path) { test_dest('test.files') }
120
+
121
+ it 'creates files database' do
122
+ cli.invoke(:files_add, [package_path.to_s, files_path.to_s])
123
+ expect(files_path).to be_file
124
+ expect(tar('tf', files_path.to_s)).to include('nkf-2.1.3-1/files')
125
+ end
126
+ end
127
+
128
+ describe '#files_remove' do
129
+ let(:files_path) { test_dest('test.files') }
130
+
131
+ before do
132
+ FileUtils.cp(test_input('test.files'), files_path)
133
+ end
134
+
135
+ it 'removes package from files database' do
136
+ cli.invoke(:files_remove, ['htop-vi', files_path.to_s])
137
+ expect(tar('tf', files_path.to_s)).to_not include('htop-vi-1.0.2-4/files')
138
+ end
139
+ end
5
140
  end
@@ -0,0 +1,154 @@
1
+ require 'spec_helper'
2
+ require 'akabei/cli'
3
+
4
+ class TestShell < Thor::Shell::Basic
5
+ attr_reader :stdout
6
+
7
+ def initialize(stdout)
8
+ @stdout = stdout
9
+ super()
10
+ end
11
+ end
12
+
13
+ describe Akabei::Omakase::CLI do
14
+ let(:stdout) { StringIO.new }
15
+ let(:cli) { described_class.new }
16
+
17
+ before do
18
+ cli.shell = TestShell.new(stdout)
19
+ end
20
+
21
+ around do |example|
22
+ Dir.mktmpdir do |dir|
23
+ cli.inside(dir) do
24
+ Dir.chdir(dir) do
25
+ example.run
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ describe '#init' do
32
+ it 'creates template directories' do
33
+ cli.invoke(:init, ['test'])
34
+ here = Pathname.new('.')
35
+ expect(here.join('.akabei.yml')).to be_file
36
+ expect(here.join('test')).to be_directory
37
+ expect(here.join('sources')).to be_directory
38
+ expect(here.join('logs')).to be_directory
39
+ expect(here.join('PKGBUILDs')).to be_directory
40
+ %w[i686 x86_64].each do |arch|
41
+ %w[makepkg pacman].each do |conf|
42
+ expect(here.join('etc', "#{conf}.#{arch}.conf")).to be_file
43
+ end
44
+ end
45
+ end
46
+
47
+ it 'creates valid config' do
48
+ cli.invoke(:init, ['test'])
49
+ config = Akabei::Omakase::Config.load
50
+ expect { config.validate! }.to_not raise_error
51
+ expect(config.name).to eq('test')
52
+ expect(config.srcdest).to be_directory
53
+ expect(config.logdest).to be_directory
54
+ expect(config.pkgbuild).to be_directory
55
+ config.builds.each do |arch, config_file|
56
+ expect(Pathname.new(config_file['makepkg'])).to be_file
57
+ expect(Pathname.new(config_file['pacman'])).to be_file
58
+ end
59
+ expect(config['s3']).to be_nil
60
+ end
61
+
62
+ context 'with --s3' do
63
+ it 'creates config with s3' do
64
+ cli.invoke(:init, ['test'], s3: true)
65
+ config = Akabei::Omakase::Config.load
66
+ expect { config.validate! }.to_not raise_error
67
+ expect(config['s3']).to_not be_nil
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#build' do
73
+ let(:config) { Akabei::Omakase::Config.load }
74
+ let(:packages) { { 'i686' => double('built package (i686)'), 'x86_64' => double('built package (x86_64)') } }
75
+ let(:entry) { Akabei::PackageEntry.new }
76
+ let(:init_opts) { {} }
77
+
78
+ before do
79
+ cli.invoke(:init, ['test'], init_opts)
80
+ tar('xf', test_input('nkf.tar.gz').to_s, '-C', config.pkgbuild.to_s)
81
+
82
+ packages.each do |arch, package|
83
+ allow(package).to receive(:db_name).and_return('nkf-2.1.3-1')
84
+ allow(package).to receive(:to_entry).and_return(entry)
85
+ allow(package).to receive(:path).and_return(Pathname.new("test/os/#{arch}/nkf-2.1.3-1-#{arch}.pkg.tar.xz"))
86
+ end
87
+ entry.add('files', 'usr/bin/nkf')
88
+
89
+ allow_any_instance_of(Akabei::ChrootTree).to receive(:with_chroot) { |chroot, &block|
90
+ expect(chroot.makepkg_config.to_s).to eq("etc/makepkg.#{chroot.arch}.conf")
91
+ expect(chroot.pacman_config.to_s).to eq("etc/pacman.#{chroot.arch}.conf")
92
+ block.call
93
+ }
94
+ expect(config['builds'].size).to eq(2)
95
+
96
+ allow_any_instance_of(Akabei::Builder).to receive(:build_package) { |builder, dir, chroot|
97
+ expect(builder).to receive(:with_source_package).with(config.package_dir('nkf')).and_yield(test_input('nkf.tar.gz'))
98
+ [packages[chroot.arch]]
99
+ }
100
+ end
101
+
102
+ it 'builds a package and add it to repository' do
103
+ cli.invoke(:build, ['nkf'])
104
+ end
105
+
106
+ context 'with --s3' do
107
+ let(:init_opts) { { s3: true } }
108
+ let(:access_key_id) { 'ACCESS/KEY' }
109
+ let(:secret_access_key) { 'SECRET/ACCESS/KEY' }
110
+ let(:bucket_name) { 'test.bucket.name' }
111
+ let(:region) { 'ap-northeast-1' }
112
+
113
+ let(:buckets) { double('S3::BucketCollection') }
114
+ let(:bucket) { double('S3::Bucket') }
115
+ let(:objects) { double('S3::ObjectCollection') }
116
+ let(:write_options) { { reduced_redundancy: true } }
117
+
118
+ before do
119
+ c = SafeYAML.load_file('.akabei.yml')
120
+ c['s3']['access_key_id'] = access_key_id
121
+ c['s3']['secret_access_key'] = secret_access_key
122
+ c['s3']['bucket'] = bucket_name
123
+ c['s3']['region'] = region
124
+ c['s3']['write_options'] = write_options
125
+ open('.akabei.yml', 'w') { |f| YAML.dump(c, f) }
126
+
127
+ allow_any_instance_of(AWS::S3).to receive(:buckets).and_return(buckets)
128
+ end
129
+
130
+ it 'uploads built packages and update repositories' do
131
+ expect(buckets).to receive(:[]).with(bucket_name).and_return(bucket)
132
+ allow(bucket).to receive(:objects).and_return(objects)
133
+
134
+ %w[i686 x86_64].each do |arch|
135
+ %w[test.db test.files test.abs.tar.gz].each do |fname|
136
+ obj = double("S3::Object #{fname}")
137
+ # download and upload
138
+ expect(objects).to receive(:[]).with("test/os/#{arch}/#{fname}").twice.and_return(obj)
139
+ expect(obj).to receive(:read).and_yield('')
140
+ expect(obj).to receive(:write)
141
+ end
142
+
143
+ # upload only
144
+ pkg = double("S3::Object built package (#{arch})")
145
+ db_name = "nkf-2.1.3-1-#{arch}.pkg.tar.xz"
146
+ expect(objects).to receive(:[]).with("test/os/#{arch}/#{db_name}").and_return(pkg)
147
+ expect(pkg).to receive(:write).with(anything, hash_including(write_options))
148
+ end
149
+
150
+ cli.invoke(:build, ['nkf'])
151
+ end
152
+ end
153
+ end
154
+ end