s3repo 1.0.0 → 2.0.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
  SHA1:
3
- metadata.gz: 037f096771d38b162f01efabbd4f21a3d38d2e54
4
- data.tar.gz: 2639022f0ac61664ed66c9bdd49b28e8b3dc4d13
3
+ metadata.gz: 77fb43c11e189c5bfc7c347fa6b0d2efe566f9ff
4
+ data.tar.gz: 2ce120f3afd0e0b63a6d2f63c84822c3b974bc95
5
5
  SHA512:
6
- metadata.gz: 40e4eba132b5c8374a4c5da86dc5043aca1700daf69c616ee91f018bd214e010cf64bda56b0c1187388252ffc21d95e328be2b68daf1f10d0fdf0d940c2f6978
7
- data.tar.gz: d09e26179074b0c678e798bc814b1a2e4277bea5738d914c7af0c64c306896f4da46423dc03ec2b8af3f0917d432f707f8e8d38614598d50c7fe2dddc6cd7067
6
+ metadata.gz: c0c201ab4c0e8eefc8e7d2ba2490d92fdc9eb6e989c2b1a5cec9436580ca8c0ef5bf874052fac4056725343a9ccfbe5f96747cf1931297d81df5cee6ee251cf5
7
+ data.tar.gz: b2acfdd8d6386b69bddbd772d836b40d825a58b8adcbdf6a0ee64c484e397c94cbaf5d2e8cb99f303030bb031f24ed2e31e2bceab89fa801b587cea1fbfa0da7
@@ -0,0 +1,3 @@
1
+ 2.4.2
2
+ 2.3.5
3
+ 2.2.8
@@ -1,11 +1,25 @@
1
+ Prospectus.extra_dep('file', 'prospectus_circleci')
2
+
3
+ my_slug = 'amylum/s3repo'
4
+
1
5
  item do
2
- expected do
3
- static
4
- set 'green'
5
- end
6
+ noop
6
7
 
7
- actual do
8
- gemnasium
9
- slug 'amylum/server'
8
+ deps do
9
+ item do
10
+ name 'gems'
11
+
12
+ expected do
13
+ static
14
+ set 'green'
15
+ end
16
+
17
+ actual do
18
+ gemnasium
19
+ slug my_slug
20
+ end
21
+ end
10
22
  end
23
+
24
+ extend ProspectusCircleci::Build.new(my_slug)
11
25
  end
@@ -1,2 +1,5 @@
1
- Encoding:
2
- Enabled: false
1
+ inherit_gem:
2
+ goodcop: .rubocop.yml
3
+ AllCops:
4
+ Include:
5
+ - 'bin/*'
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
-
data/README.md CHANGED
@@ -3,7 +3,7 @@ s3repo
3
3
 
4
4
  [![Gem Version](https://img.shields.io/gem/v/s3repo.svg)](https://rubygems.org/gems/s3repo)
5
5
  [![Dependency Status](https://img.shields.io/gemnasium/amylum/s3repo.svg)](https://gemnasium.com/amylum/s3repo)
6
- [![Build Status](https://img.shields.io/circleci/project/amylum/s3repo.svg)](https://circleci.com/gh/amylum/s3repo)
6
+ [![Build Status](https://img.shields.io/circleci/project/amylum/s3repo/master.svg)](https://circleci.com/gh/amylum/s3repo)
7
7
  [![Coverage Status](https://img.shields.io/codecov/c/github/amylum/s3repo.svg)](https://codecov.io/github/amylum/s3repo)
8
8
  [![Code Quality](https://img.shields.io/codacy/eef971ff937642219c1d4094001c33e7.svg)](https://www.codacy.com/app/akerl/s3repo)
9
9
  [![MIT Licensed](https://img.shields.io/badge/license-MIT-green.svg)](https://tldrlegal.com/license/mit-license)
data/Rakefile CHANGED
@@ -7,8 +7,7 @@ RSpec::Core::RakeTask.new(:spec)
7
7
 
8
8
  desc 'Run Rubocop on the gem'
9
9
  RuboCop::RakeTask.new(:rubocop) do |task|
10
- task.patterns = ['lib/**/*.rb', 'spec/**/*.rb', 'bin/*']
11
10
  task.fail_on_error = true
12
11
  end
13
12
 
14
- task default: [:spec, :rubocop, :build, :install]
13
+ task default: %i[spec rubocop build install]
data/bin/s3repo CHANGED
@@ -2,49 +2,72 @@
2
2
 
3
3
  require 's3repo'
4
4
  require 'mercenary'
5
+ require 'yaml'
6
+ require 'cymbal'
5
7
 
6
8
  def find(pattern, limits)
7
9
  Dir.glob(pattern).select { |x| !limits || limits.include?(File.dirname(x)) }
8
10
  end
9
11
 
12
+ def common_opts(cmd)
13
+ cmd.option :config_file, '-c', '--config FILE', 'Path of config file'
14
+ end
15
+
16
+ def load_config(file)
17
+ file ||= 'config.yml'
18
+ file = File.expand_path(file)
19
+ raise("Config file not found: #{file}") unless File.exist? file
20
+ Cymbal.symbolize YAML.safe_load(File.read(file))
21
+ end
22
+
23
+ def repo(options)
24
+ config = load_config(options[:config_file])
25
+ S3Repo.new(config)
26
+ end
27
+
28
+ # rubocop:disable Metrics/BlockLength
10
29
  Mercenary.program(:s3repo) do |p|
11
30
  p.version S3Repo::VERSION
12
31
  p.description 'Package management tool for Archlinux repos'
13
32
  p.syntax 's3repo <subcommand> [args]'
14
33
 
15
34
  p.command(:build) do |c|
35
+ common_opts(c)
16
36
  c.syntax 'build [package...]'
17
37
  c.description 'Build package files from PKGBUILDs'
18
38
 
19
- c.action do |args, _|
20
- S3Repo.new.build_packages find('*/PKGBUILD', args), ENV['MAKEPKG_FLAGS']
39
+ c.action do |args, opts|
40
+ repo(opts).build_packages find('*/PKGBUILD', args)
21
41
  end
22
42
  end
23
43
 
24
44
  p.command(:upload) do |c|
45
+ common_opts(c)
25
46
  c.syntax 'upload [package...]'
26
47
  c.description 'Upload packages to repo'
27
48
 
28
- c.action do |args, _|
29
- S3Repo.new.add_packages find('*/*.pkg.tar.xz', args)
49
+ c.action do |args, opts|
50
+ repo(opts).add_packages find('*/*.pkg.tar.xz', args)
30
51
  end
31
52
  end
32
53
 
33
54
  p.command(:remove) do |c|
55
+ common_opts(c)
34
56
  c.syntax 'remove [package...]'
35
57
  c.description 'Remove packages from repo DB'
36
58
 
37
- c.action do |args, _|
38
- S3Repo.new.remove_packages args
59
+ c.action do |args, opts|
60
+ repo(opts).remove_packages args
39
61
  end
40
62
  end
41
63
 
42
64
  p.command(:prune) do |c|
65
+ common_opts(c)
43
66
  c.syntax 'prune'
44
67
  c.description 'Prune orphaned files from the repo'
45
68
 
46
- c.action do
47
- S3Repo.new.prune_files
69
+ c.action do |_, opts|
70
+ repo(opts).prune_files
48
71
  end
49
72
  end
50
73
 
data/circle.yml CHANGED
@@ -1,8 +1,11 @@
1
+ machine:
2
+ environment:
3
+ AWS_ACCESS_KEY_ID: '1'
4
+ AWS_SECRET_ACCESS_KEY: '1'
1
5
  dependencies:
2
6
  override:
3
- - 'rvm-exec 2.1.6 bundle install'
4
- - 'rvm-exec 2.2.2 bundle install'
7
+ - 'for i in $(cat .circle-ruby) ; do rvm-exec $i gem update --system --no-doc || exit 1 ; done'
8
+ - 'for i in $(cat .circle-ruby) ; do rvm-exec $i bundle install || exit 1 ; done'
5
9
  test:
6
10
  override:
7
- - 'rvm-exec 2.1.6 bundle exec rake'
8
- - 'rvm-exec 2.2.2 bundle exec rake'
11
+ - 'for i in $(cat .circle-ruby) ; do rvm-exec $i bundle exec rake || exit 1 ; done'
@@ -13,7 +13,9 @@ end
13
13
 
14
14
  require 's3repo/version'
15
15
  require 's3repo/base'
16
+ require 's3repo/signer'
16
17
  require 's3repo/metadata'
17
18
  require 's3repo/cache'
18
19
  require 's3repo/client'
20
+ require 's3repo/templates'
19
21
  require 's3repo/repo'
@@ -13,23 +13,19 @@ module S3Repo
13
13
  def run(cmd)
14
14
  results = `#{cmd} 2>&1`
15
15
  return results if $CHILD_STATUS.success?
16
- fail "Failed running #{cmd}:\n#{results}"
16
+ raise "Failed running #{cmd}:\n#{results}"
17
17
  end
18
18
 
19
19
  def bucket
20
- @bucket ||= @options[:bucket] || ENV['S3_BUCKET']
21
- return @bucket if @bucket
22
- fail('No bucket given')
20
+ @options[:bucket] || raise('No bucket given')
23
21
  end
24
22
 
25
23
  def client
26
- @client ||= @options[:client] || Client.new(bucket: bucket)
24
+ @options[:client] ||= Client.new(@options)
27
25
  end
28
26
 
29
27
  def file_cache
30
- @file_cache ||= @options[:file_cache] || Cache.new(
31
- client: client, tmpdir: @options[:tmpdir]
32
- )
28
+ @file_cache ||= @options[:file_cache] || Cache.new(@options)
33
29
  end
34
30
  end
35
31
  end
@@ -7,7 +7,6 @@ module S3Repo
7
7
  # Cache object, stores S3 objects on disk
8
8
  class Cache < Base
9
9
  TMPDIRS = [
10
- ENV['S3REPO_TMPDIR'],
11
10
  ENV['TMPDIR'],
12
11
  Dir.tmpdir,
13
12
  '/tmp/s3repo'
@@ -18,20 +17,18 @@ module S3Repo
18
17
  [partialdir, cachedir].each { |x| FileUtils.mkdir_p x }
19
18
  end
20
19
 
21
- def serve(key, refresh = true)
22
- File.open(download(key, refresh), &:read)
23
- rescue Aws::S3::Errors::NoSuchKey
24
- nil
25
- end
26
-
27
- private
28
-
29
20
  def download(key, refresh = true)
30
21
  path = expand_path key
31
22
  get_object(key, path) if refresh || !cached?(path)
32
23
  path
33
24
  end
34
25
 
26
+ private
27
+
28
+ def file_cache
29
+ raise('Tried to call file_cache recursively')
30
+ end
31
+
35
32
  def expand_path(key)
36
33
  File.absolute_path(key, cachedir)
37
34
  end
@@ -71,7 +68,13 @@ module S3Repo
71
68
  end
72
69
 
73
70
  def tmpdir
74
- @tmpdir ||= File.absolute_path(@options[:tmpdir] || TMPDIRS.compact.first)
71
+ @tmpdir ||= Dir.mktmpdir 's3repo', tmpdir_root
72
+ end
73
+
74
+ def tmpdir_root
75
+ @tmpdir_root ||= File.absolute_path(
76
+ @options[:tmpdir] || TMPDIRS.compact.first
77
+ )
75
78
  end
76
79
  end
77
80
  end
@@ -5,21 +5,33 @@ module S3Repo
5
5
  # AWS API client
6
6
  class Client
7
7
  def initialize(params = {})
8
- @api = Aws::S3::Client.new
9
- @defaults = params
8
+ @options = params
9
+ @api = Aws::S3::Client.new(region: region)
10
10
  end
11
11
 
12
- def respond_to?(method, include_all = false)
12
+ def respond_to_missing?(method, include_all = false)
13
13
  @api.respond_to?(method, include_all) || super
14
14
  end
15
15
 
16
- def upload!(key, path)
16
+ def upload(key, body)
17
17
  puts "Uploading #{key}"
18
- put_object key: key, body: File.open(path), &:read
18
+ put_object key: key, body: body
19
+ end
20
+
21
+ def upload_file(key, path)
22
+ upload(key, File.open(path).read)
19
23
  end
20
24
 
21
25
  private
22
26
 
27
+ def region
28
+ @options[:region] || raise('AWS region not set')
29
+ end
30
+
31
+ def bucket
32
+ @options[:bucket] || raise('Bucket not set')
33
+ end
34
+
23
35
  def method_missing(method, *args, &block)
24
36
  return super unless @api.respond_to?(method)
25
37
  define_singleton_method(method) do |*singleton_args|
@@ -30,10 +42,11 @@ module S3Repo
30
42
  end
31
43
 
32
44
  def build_params(args)
33
- fail 'Too many arguments given' if args.size > 1
45
+ raise 'Too many arguments given' if args.size > 1
34
46
  params = args.first || {}
35
- fail 'Argument must be a hash' unless params.is_a? Hash
36
- @defaults.dup.merge!(params)
47
+ raise 'Argument must be a hash' unless params.is_a? Hash
48
+ params[:bucket] ||= bucket
49
+ params
37
50
  end
38
51
  end
39
52
  end
@@ -5,11 +5,6 @@ module S3Repo
5
5
  ##
6
6
  # Metadata object, represents repo's DB file
7
7
  class Metadata < Base
8
- def initialize(params = {})
9
- super
10
- FileUtils.mkdir_p db_dir
11
- end
12
-
13
8
  def add_packages(paths)
14
9
  @db_path = nil
15
10
  paths.each do |path|
@@ -29,38 +24,31 @@ module S3Repo
29
24
  end
30
25
 
31
26
  def update!
32
- sign_db if ENV['S3REPO_SIGN_DB']
33
- client.upload!('repo.db', db_path)
27
+ sign_db if @options[:sign_db]
28
+ client.upload_file('repo.db', db_path)
29
+ client.upload_file('repo.db.tar.xz', db_path)
34
30
  end
35
31
 
36
32
  def packages
37
33
  return @packages if @packages
38
- cmd = "tar tf #{db_path}"
34
+ cmd = "bsdtar tf #{db_path}"
39
35
  @packages = run(cmd).split.map { |x| x.split('/').first }.uniq
40
36
  end
41
37
 
42
38
  private
43
39
 
44
- def sign_db
45
- run "gpg --detach-sign --use-agent #{db_path}"
46
- client.upload!('repo.db.sig', "#{db_path}.sig")
47
- end
48
-
49
- def db_path
50
- @db_path ||= download_db
40
+ def signer
41
+ @options[:signer] ||= Signer.new(@options)
51
42
  end
52
43
 
53
- def download_db
54
- tmpfile = Tempfile.create(['repo', '.db.tar.xz'], db_dir)
55
- tmpfile << file_cache.serve('repo.db')
56
- tmpfile.close
57
- tmpfile.path
44
+ def sign_db
45
+ sig_path = signer.sign(db_path)
46
+ client.upload_file('repo.db.sig', sig_path)
47
+ client.upload_file('repo.db.tar.xz.sig', sig_path)
58
48
  end
59
49
 
60
- def db_dir
61
- @db_dir ||= File.absolute_path(
62
- @options[:tmpdir] || Cache::TMPDIRS.compact.first
63
- )
50
+ def db_path
51
+ @db_path ||= file_cache.download('repo.db.tar.xz')
64
52
  end
65
53
  end
66
54
  end
@@ -5,25 +5,23 @@ module S3Repo
5
5
  ##
6
6
  # Repo object, represents an Arch repo inside an S3 bucket
7
7
  class Repo < Base
8
- def initialize(params = {})
9
- super
10
- end
11
-
12
- def build_packages(paths, makepkg_flags = '')
8
+ def build_packages(paths)
13
9
  paths.each do |path|
14
10
  dir = File.dirname(path)
15
11
  puts "Building #{File.basename(dir)}"
16
- Dir.chdir(dir) { run "makepkg #{makepkg_flags}" }
12
+ Dir.chdir(dir) { run "makepkg #{@options[:makepkg_flags]}" }
17
13
  end
18
14
  end
19
15
 
20
16
  def add_packages(paths)
21
17
  paths.select! { |path| upload_package(path) }
22
18
  metadata.add_packages(paths) unless paths.empty?
19
+ templates.update! unless paths.empty?
23
20
  end
24
21
 
25
22
  def remove_packages(packages)
26
23
  metadata.remove_packages(packages)
24
+ templates.update!
27
25
  end
28
26
 
29
27
  def prune_files
@@ -47,19 +45,15 @@ module S3Repo
47
45
  !packages.find { |x| x.key == key }.nil?
48
46
  end
49
47
 
50
- def serve(key)
51
- refresh = !key.match(/\.pkg\.tar\.xz$/)
52
- file_cache.serve(key, refresh)
53
- end
54
-
55
48
  private
56
49
 
57
50
  def upload_package(path)
58
51
  key = File.basename(path)
59
- sig_key, sig_path = [key, path].map { |x| x + '.sig' }
60
52
  return false if include? key
61
- client.upload!(sig_key, sig_path) if ENV['S3REPO_SIGN_PACKAGES']
62
- client.upload!(key, path)
53
+ sig_path = signer.sign(path)
54
+ sig_key = key + '.sig'
55
+ client.upload_file(sig_key, sig_path) if @options[:sign_packages]
56
+ client.upload_file(key, path)
63
57
  true
64
58
  end
65
59
 
@@ -70,7 +64,15 @@ module S3Repo
70
64
  end
71
65
 
72
66
  def metadata
73
- @metadata ||= Metadata.new(client: client, file_cache: file_cache)
67
+ @options[:metadata] ||= Metadata.new(@options)
68
+ end
69
+
70
+ def signer
71
+ @options[:signer] ||= Signer.new(@options)
72
+ end
73
+
74
+ def templates
75
+ @templates ||= Templates.new(@options)
74
76
  end
75
77
 
76
78
  def package_cache