Commit e9357332 authored by Adam Mercer's avatar Adam Mercer
Browse files

Merge branch 'build_src_rpm' into 'master'

Added code to create src rpm

See merge request adam-mercer/koji-packager!1
parents 3738e471 57806a72
......@@ -22,9 +22,15 @@
#
import argparse
import atexit
import os.path
import pathlib
import sys
import re
import shutil
import subprocess
import sys
import tempfile
from distutils.spawn import find_executable
#
# metadata
......@@ -38,6 +44,9 @@ __target__ = "sandbox"
# helper methods
#
RPMBUILD_TS_RESP = re.compile(r'\AWrote: (?P<srcrpm>\S+)\Z')
def parse_options():
# define option parser
parser = argparse.ArgumentParser(description='Build RPMs using Koji')
......@@ -52,9 +61,40 @@ def parse_options():
# source options
source_options = parser.add_argument_group('Source Options')
source_options.add_argument('--git', action='store_true',
help='Source is from git')
source_options.add_argument('source', help='Source to build with Koji')
source_options.add_argument(
'source',
type=pathlib.Path,
help='Source to build with Koji',
)
source_types = source_options.add_mutually_exclusive_group()
source_types.add_argument(
'--tarball',
action='store_const',
const='tarball',
dest='source_type',
help='source is a tarball',
)
source_types.add_argument(
'--git',
action='store_const',
const='git',
dest='source_type',
help='source is a git repo',
)
source_types.add_argument(
'--src-rpm',
action='store_const',
const='srcrpm',
dest='source_type',
help='source is a src.rpm',
)
source_types.add_argument(
'--spec',
action='store_const',
const='spec',
dest='source_type',
help='source is an RPM spec file',
)
# parse options
args = parser.parse_args()
......@@ -62,6 +102,120 @@ def parse_options():
return args
def source_type(source):
"""Determine the source type based on its file name
Parameters
----------
source : `pathlib.Path`
the source `Path`
Returns
-------
type_ : `str`
the source type, one of
- ``'git'``
- ``'spec'``
- ``'srcrpm'``
- ``'tarball'``
Raises
------
ValueError
if the source type is not recognised
"""
name = source.name
if name.endswith(".src.rpm"):
return "srcrpm"
if name.endswith(".spec"):
return "spec"
if name.endswith(".tar") or source.stem.endswith(".tar"):
return "tarball"
if name.endswith(".git"):
return "git"
raise ValueError(
"failed to determine source type for '{0}'".format(source),
)
def _rpmbuild_args(*args, tmpdir=None):
"""Construct a command-line call to ``rpmbuild``
"""
rpmbargs = [find_executable('rpmbuild')]
if tmpdir:
rpmbargs.extend(('--define', '_topdir {0}'.format(tmpdir)))
return rpmbargs + list(args)
def download_spec_sources(spec, outdir):
"""Run spectool to download sources defined in a spec file
Parameters
----------
spec : `str`, `pathlib.Path`
path to spec file
outdir : `str`, `pathlib.Path`
output directory for downloaded files
"""
spectool = find_executable('spectool')
cmd = [
spectool,
"--get-files",
"--directory",
str(outdir),
str(spec),
]
return subprocess.check_call(
cmd,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
def build_src_rpm(source, *extra_rpmbuild_args, outdir=os.path.curdir):
"""Create a src RPM from a tarball or a spec file
Parameters
----------
source : `str`, `pathlib.Path`
path to source file, either a tarball or a spec file
*extra_rpmbuild_args
positional arguments are passed as command-line arguments to
``rpmbuild``
outdir : `str`, `pathlib.Path`, optional
output directory for ``src.rpm`` file
Returns
-------
srcrpm : `str`
the path of the new `src.rpm` file
"""
type_ = source_type(source)
with tempfile.TemporaryDirectory() as tmpdir:
tmppath = pathlib.Path(tmpdir)
sourcepath = tmppath / "SOURCES"
sourcepath.mkdir()
# run spectool to download sources
if type_ == "spec":
download_spec_sources(source, sourcepath)
# run rpmbuild
rpmcmd = "-bs" if type_ == "spec" else "-ts"
cmd = _rpmbuild_args(*extra_rpmbuild_args + (rpmcmd, source),
tmpdir=tmpdir)
resp = subprocess.check_output(cmd).strip().decode('utf-8')
# copy src.rpm into outdir and return path
srcrpm = RPMBUILD_TS_RESP.match(resp).groupdict()['srcrpm']
return shutil.move(srcrpm, outdir)
# method to check for connection to koji
def check_connection_to_koji():
try:
......@@ -95,15 +249,25 @@ def main():
print('source = %s' % args.source)
print('target tag = %s' % args.target)
# determine source type
if not args.source_type:
args.source_type = source_type(args.source)
print("source type = {!r}".format(args.source_type))
# check that source exists
if not args.git:
source = pathlib.Path(args.source)
if not source.is_file():
print('File %s does not exist.' % args.source)
sys.exit(1)
if args.source_type != "git" and not args.source.is_file():
raise FileNotFoundError(
"No such file or directory: '{0}'".format(args.source),
)
if args.source_type not in ("srcrpm", "git"):
tmpdir = tempfile.mkdtemp()
atexit.register(shutil.rmtree, tmpdir)
args.source = build_src_rpm(args.source, args.source_type, outdir=tmpdir)
print("temporary src.rpm generated as '{0}'".format(args.source))
# get pkg name from source rpm
if not args.git:
if args.source_type != "git":
pkg_name = get_package_name_from_source_rpm(args.source)
if args.verbose:
print('package name = %s' % pkg_name)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment