akabei 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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