class PkgForge::Forge

Starter Forge object

Add build methods to Forge

Add cflag options to Forge

Add cleanup methods to Forge

Add configure flag options to Forge

Add dep methods to Forge

Add dir methods to Forge

Add metadata methods to Forge

Add upload methods to Forge

Add patch methods to Forge

Add run methods to Forge

Add source methods to Forge

Add state methods to Forge

Add test methods to Forge

Add upload methods to Forge

Attributes

build_block[W]
cflags[W]
configure_flags[W]
deps[W]
endpoint[RW]
libs[W]
licenses[W]
name[W]
org[W]
package[W]
patches[W]
remove_linker_archives[W]
remove_pkgconfig_files[W]
source[W]
test_block[W]

Public Class Methods

new(params = {}) click to toggle source
# File lib/pkgforge/base.rb, line 11
def initialize(params = {})
  @options = params
  nil
end

Public Instance Methods

add_license!() click to toggle source
# File lib/pkgforge/components/metadata.rb, line 25
def add_license!
  return if licenses.empty?
  dest_dir = File.join(tmpdir(:release), 'usr', 'share', 'licenses', name)
  FileUtils.mkdir_p dest_dir
  licenses.each do |license|
    src_file = File.join(tmpdir(:build), license)
    dest_file = File.join(dest_dir, license)
    FileUtils.cp src_file, dest_file
  end
  nil
end
build!() click to toggle source
# File lib/pkgforge/components/build.rb, line 15
def build!
  prepare_source!
  patch_source!
  prepare_deps!
  builder = PkgForge::DSL::Build.new(self)
  Dir.chdir(tmpdir(:build)) { builder.instance_eval(&build_block) }
  nil
end
build_block() click to toggle source
# File lib/pkgforge/components/build.rb, line 10
def build_block
  @build_block ||= proc { raise 'No build block provided' }
end
cflags() click to toggle source
# File lib/pkgforge/components/cflags.rb, line 8
def cflags
  @cflags ||= []
end
cleanup!() click to toggle source
# File lib/pkgforge/components/cleanup.rb, line 8
def cleanup!
  state[:tmpdirs] ||= {}
  state[:tmpfiles] ||= {}
  paths = state.values_at(:tmpdirs, :tmpfiles).map(&:values).flatten
  puts "Cleaning up tmp paths: #{paths}"
  FileUtils.rm_rf paths
  nil
end
configure_flags() click to toggle source
# File lib/pkgforge/components/configure.rb, line 8
def configure_flags
  @configure_flags ||= {}
end
dep(package) click to toggle source
# File lib/pkgforge/components/dirs.rb, line 9
def dep(package)
  tmpdir(package.to_sym)
end
deps() click to toggle source
# File lib/pkgforge/components/deps.rb, line 11
def deps
  @deps ||= {}
end
libs() click to toggle source
# File lib/pkgforge/components/cflags.rb, line 13
def libs
  @libs ||= []
end
licenses() click to toggle source
# File lib/pkgforge/components/metadata.rb, line 20
def licenses
  @licenses ||= ['LICENSE']
end
load_state!(statefile) click to toggle source
# File lib/pkgforge/components/state.rb, line 14
def load_state!(statefile)
  @state = Cymbal.symbolize(JSON.parse(File.read(statefile)))
  nil
end
name() click to toggle source
# File lib/pkgforge/components/metadata.rb, line 10
def name
  @name || raise('No name provided')
end
org() click to toggle source
# File lib/pkgforge/components/metadata.rb, line 15
def org
  @org || raise('No org provided')
end
package() click to toggle source
# File lib/pkgforge/components/package.rb, line 10
def package
  @package ||= { type: 'tarball' }
end
package!() click to toggle source
# File lib/pkgforge/components/package.rb, line 15
def package!
  add_license!
  type_method = "#{package[:type]}_prepare_package"
  method_found = respond_to?(type_method, true)
  raise("Unknown package type: #{package[:type]}") unless method_found
  send(type_method)
  expose_artifacts!
end
patches() click to toggle source
# File lib/pkgforge/components/patch.rb, line 8
def patches
  @patches ||= []
end
push!() click to toggle source
# File lib/pkgforge/components/upload.rb, line 8
def push!
  upload_artifacts!
end
releasedir() click to toggle source
# File lib/pkgforge/components/dirs.rb, line 14
def releasedir
  tmpdir(:release)
end
remove_linker_archives?() click to toggle source
# File lib/pkgforge/components/deps.rb, line 16
def remove_linker_archives?
  @remove_linker_archives ||= false
end
remove_pkgconfig_files?() click to toggle source
# File lib/pkgforge/components/deps.rb, line 21
def remove_pkgconfig_files?
  @remove_pkgconfig_files ||= false
end
run(cmd, env = {}) click to toggle source
# File lib/pkgforge/components/run.rb, line 6
def run(cmd, env = {})
  puts "Running command in #{Dir.pwd}: #{cmd}"
  puts "Using env: #{env}" unless env.empty?
  res = system env, *cmd
  raise('Command failed!') unless res
  nil
end
run_patch(file) click to toggle source
# File lib/pkgforge/components/patch.rb, line 13
def run_patch(file)
  run "patch -d #{tmpdir(:build)} -p1 < patches/#{file}"
end
source() click to toggle source
# File lib/pkgforge/components/source.rb, line 11
def source
  @source ||= { type: 'git', path: 'upstream' }
end
state() click to toggle source
# File lib/pkgforge/components/state.rb, line 9
def state
  @state ||= {}
end
test!() click to toggle source
# File lib/pkgforge/components/test.rb, line 15
def test!
  tester = PkgForge::DSL::Test.new(self)
  Dir.chdir(tmpdir(:release)) { tester.instance_eval(&test_block) }
  nil
end
test_block() click to toggle source
# File lib/pkgforge/components/test.rb, line 10
def test_block
  @test_block ||= proc { raise 'No test block provided' }
end
test_run(cmd, env = {}) click to toggle source
# File lib/pkgforge/components/test.rb, line 22
def test_run(cmd, env = {})
  cmd.unshift('/usr/bin/env') if cmd.is_a? Array
  cmd.prepend('/usr/bin/env ') if cmd.is_a? String
  env['PATH'] ||= './usr/bin'
  lib_override do
    run(cmd, env)
  end
end
tmpdir(id) click to toggle source
# File lib/pkgforge/components/dirs.rb, line 19
def tmpdir(id)
  state[:tmpdirs] ||= {}
  state[:tmpdirs][id] ||= Dir.mktmpdir(id.to_s)
end
tmpfile(id) click to toggle source
# File lib/pkgforge/components/dirs.rb, line 25
def tmpfile(id)
  state[:tmpfiles] ||= {}
  state[:tmpfiles][id] ||= Tempfile.create(id.to_s).path
end
write_state!(statefile) click to toggle source
# File lib/pkgforge/components/state.rb, line 20
def write_state!(statefile)
  File.open(statefile, 'w') do |fh|
    fh << state.to_json
  end
  nil
end

Private Instance Methods

add_artifact(params) click to toggle source
# File lib/pkgforge/components/upload.rb, line 15
def add_artifact(params)
  state[:artifacts] ||= []
  state[:artifacts] << params
  nil
end
download_deps!() click to toggle source
# File lib/pkgforge/components/deps.rb, line 35
def download_deps!
  deps.each do |dep_name, dep_hash|
    file = tmpfile(dep_name)
    dir = tmpdir(dep_name)
    download_file(dep_name, dep_hash, file)
    verify_file(file, dep_hash[:checksum])
    extract_file(file, dir)
  end
  nil
end
download_file(dep_name, dep_hash, file) click to toggle source
# File lib/pkgforge/components/deps.rb, line 47
def download_file(dep_name, dep_hash, file)
  dep_hash[:org] ||= org
  dep_hash[:site] ||= 'https://github.com'
  url = "#{dep_hash[:site]}/#{dep_hash[:org]}/#{dep_name}/releases/download/#{dep_hash[:version]}/#{dep_name}.tar.gz" # rubocop:disable Metrics/LineLength
  File.open(file, 'wb') do |fh|
    fh << open(url, 'rb').read # rubocop:disable Security/Open
  end
  nil
end
empty_prepare_source() click to toggle source
# File lib/pkgforge/components/source.rb, line 45
def empty_prepare_source
  # This source type is a no-op
end
expose_artifacts!() click to toggle source
# File lib/pkgforge/components/upload.rb, line 22
def expose_artifacts!
  FileUtils.mkdir_p 'pkg'
  return unless state[:artifacts]
  state[:artifacts].each do |artifact|
    dest = File.join('pkg', artifact[:long_name] || artifact[:name])
    FileUtils.cp artifact[:source], dest
    FileUtils.chmod 0o0644, dest
  end
  nil
end
extract_file(file, dir) click to toggle source
# File lib/pkgforge/components/deps.rb, line 72
def extract_file(file, dir)
  run "tar -x -C #{dir} -f #{file}"
end
file_prepare_package() click to toggle source
# File lib/pkgforge/components/package.rb, line 32
def file_prepare_package
  artifacts = package[:artifacts] || [package[:artifact]].compact
  raise('File package type requires artifacts list') if artifacts.empty?
  artifacts.each do |x|
    x[:source] = File.join(tmpdir(:release), x[:source])
    add_artifact(x)
  end
  nil
end
git_hash() click to toggle source
# File lib/pkgforge/components/package.rb, line 61
def git_hash
  `git rev-parse --short HEAD`.rstrip
end
git_prepare_source() click to toggle source
# File lib/pkgforge/components/source.rb, line 25
def git_prepare_source
  run 'git submodule update --init --recursive'
  run "git clone --recursive '#{source[:path]}' #{tmpdir(:build)}"
end
ld_library_path() click to toggle source
# File lib/pkgforge/components/test.rb, line 59
def ld_library_path
  paths = ["#{releasedir}/usr/lib"]
  paths += deps.keys.map { |x| "#{dep(x)}/usr/lib" }
  paths.join(':')
end
lib_override() { || ... } click to toggle source
# File lib/pkgforge/components/test.rb, line 39
def lib_override
  old_lib_paths = File.read(lib_path_file) if File.exist?(lib_path_file)
  puts "Setting library path: #{ld_library_path}"
  File.open(lib_path_file, 'w') { |fh| fh << ld_library_path }
  yield
ensure
  reset_lib_path_file(old_lib_paths)
end
lib_path_file() click to toggle source
# File lib/pkgforge/components/test.rb, line 34
def lib_path_file
  '/etc/ld-musl-x86_64.path'
end
make_tarball!() click to toggle source
# File lib/pkgforge/components/package.rb, line 53
def make_tarball!
  Dir.chdir(tmpdir(:release)) do
    run "tar -czvf #{tmpfile(:tarball)} *"
  end
  nil
end
noop_prepare_package() click to toggle source
# File lib/pkgforge/components/package.rb, line 27
def noop_prepare_package
  nil
end
patch_source!() click to toggle source
# File lib/pkgforge/components/patch.rb, line 20
def patch_source!
  patches.each { |patch| run_patch(patch) }
  nil
end
prepare_deps!() click to toggle source
# File lib/pkgforge/components/deps.rb, line 28
def prepare_deps!
  download_deps!
  remove_linker_archives! if remove_linker_archives?
  remove_pkgconfig_files! if remove_pkgconfig_files?
end
prepare_source!() click to toggle source
# File lib/pkgforge/components/source.rb, line 18
def prepare_source!
  type_method = "#{source[:type]}_prepare_source"
  return send(type_method) if respond_to?(type_method, true)
  raise("Unknown source type: #{source[:type]}")
end
remove_linker_archives!() click to toggle source
# File lib/pkgforge/components/deps.rb, line 77
def remove_linker_archives!
  deps.keys.each do |dep_name|
    File.unlink(*Dir.glob("#{tmpdir(dep_name)}/**/*.la"))
  end
  nil
end
remove_pkgconfig_files!() click to toggle source
# File lib/pkgforge/components/deps.rb, line 85
def remove_pkgconfig_files!
  deps.keys.each do |dep_name|
    File.unlink(*Dir.glob("#{tmpdir(dep_name)}/**/*.pc"))
  end
  nil
end
reset_lib_path_file(old_lib_paths) click to toggle source
# File lib/pkgforge/components/test.rb, line 49
def reset_lib_path_file(old_lib_paths)
  if old_lib_paths
    File.open(lib_path_file, 'w') { |fh| fh << old_lib_paths }
  else
    File.unlink(lib_path_file)
  end
  nil
end
tar_prepare_source() click to toggle source
# File lib/pkgforge/components/source.rb, line 31
def tar_prepare_source
  dest_file = tmpfile(:source_tar)
  File.open(dest_file, 'wb') do |fh|
    open(source[:url], 'rb') do |request| # rubocop:disable Security/Open
      fh.write request.read
    end
    verify_file(dest_file, source[:checksum])
  end
  Dir.chdir(tmpdir(:build)) do
    run "tar -xf #{dest_file} --strip-components=1"
  end
end
tarball_prepare_package() click to toggle source
# File lib/pkgforge/components/package.rb, line 43
def tarball_prepare_package
  add_artifact(
    source: tmpfile(:tarball),
    name: "#{name}.tar.gz",
    long_name: "#{name}-#{git_hash}.tar.gz"
  )
  make_tarball!
end
upload_artifacts!() click to toggle source
# File lib/pkgforge/components/upload.rb, line 39
def upload_artifacts!
  return unless state[:artifacts]
  state[:artifacts].each do |artifact|
    args = ['targit', '--authfile', '.creds_github', '--create']
    args += ['--name', artifact[:name]]
    args += ['--endpoint', endpoint] if endpoint
    args += ["#{org}/#{name}", version, artifact[:source]]
    run args
  end
  nil
end
verify_file(file, expected = nil) click to toggle source
# File lib/pkgforge/components/deps.rb, line 58
def verify_file(file, expected = nil)
  case expected
  when nil
    raise "No checksum provided for #{file}"
  when 'skip'
    puts "Skipping checksum for #{file}"
  else
    actual = Digest::SHA256.file(file).hexdigest
    return if actual == expected
    raise "Checksum fail for #{file}: #{actual} (actual) != #{expected} (expected)" # rubocop:disable Metrics/LineLength
  end
end
version() click to toggle source
# File lib/pkgforge/components/upload.rb, line 34
def version
  @version ||= `git describe --abbrev=0 --tags`.rstrip
end