Wrap Alpine's newapkbuild (#894)

Closes #836.
This commit is contained in:
Oliver Smith 2018-01-15 22:00:11 +00:00 committed by GitHub
parent 4715c0f1bf
commit 9a3ce3ee70
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 178 additions and 2 deletions

View file

@ -42,6 +42,11 @@ def properties(pkgname):
for prefix in options["prefixes"]: for prefix in options["prefixes"]:
if pkgname.startswith(prefix): if pkgname.startswith(prefix):
return (prefix, folder, options) return (prefix, folder, options)
logging.info("NOTE: aportgen is for generating postmarketOS specific"
" aports, such as the cross-compiler related packages"
" or the linux kernel fork packages.")
logging.info("NOTE: If you wanted to package new software in general, try"
" 'pmbootstrap newapkbuild' to generate a template.")
raise ValueError("No generator available for " + pkgname + "!") raise ValueError("No generator available for " + pkgname + "!")

View file

@ -20,6 +20,7 @@ along with pmbootstrap. If not, see <http://www.gnu.org/licenses/>.
from pmb.build.init import init from pmb.build.init import init
from pmb.build.checksum import checksum from pmb.build.checksum import checksum
from pmb.build.menuconfig import menuconfig from pmb.build.menuconfig import menuconfig
from pmb.build.newapkbuild import newapkbuild
from pmb.build.other import copy_to_buildpath, is_necessary, \ from pmb.build.other import copy_to_buildpath, is_necessary, \
find_aport, index_repo find_aport, index_repo
from pmb.build._package import package from pmb.build._package import package

67
pmb/build/newapkbuild.py Normal file
View file

@ -0,0 +1,67 @@
"""
Copyright 2017 Oliver Smith
This file is part of pmbootstrap.
pmbootstrap is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
pmbootstrap is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with pmbootstrap. If not, see <http://www.gnu.org/licenses/>.
"""
import glob
import os
import logging
import pmb.chroot.user
import pmb.helpers.cli
import pmb.parse.apkbuild
def newapkbuild(args, folder, args_passed):
# Initialize build environment and build folder
pmb.build.init(args)
build = "/home/pmos/build"
build_outside = args.work + "/chroot_native" + build
if os.path.exists(build_outside):
pmb.chroot.root(args, ["rm", "-r", build])
pmb.chroot.user(args, ["mkdir", "-p", build])
# Run newapkbuild
pmb.chroot.user(args, ["newapkbuild"] + args_passed, log=False,
working_dir=build)
glob_result = glob.glob(build_outside + "/*/APKBUILD")
if not len(glob_result):
return
# Paths for copying
source_apkbuild = glob_result[0]
pkgname = pmb.parse.apkbuild(args, source_apkbuild)["pkgname"]
target = args.aports + "/" + folder + "/" + pkgname
# Move /home/pmos/build/$pkgname/* to /home/pmos/build/*
for path in glob.glob(build_outside + "/*/*"):
path_inside = build + "/" + pkgname + "/" + os.path.basename(path)
pmb.chroot.user(args, ["mv", path_inside, build])
pmb.chroot.user(args, ["rmdir", build + "/" + pkgname])
# Overwrite confirmation
if os.path.exists(target):
logging.warning("WARNING: Folder already exists: " + target)
if not pmb.helpers.cli.confirm(args, "Continue and delete its"
" contents?"):
raise RuntimeError("Aborted.")
pmb.helpers.run.user(args, ["rm", "-r", target])
# Copy the aport (without the extracted src folder)
logging.info("Create " + target)
pmb.helpers.run.user(args, ["mkdir", "-p", target])
for path in glob.glob(build_outside + "/*"):
if not os.path.isdir(path):
pmb.helpers.run.user(args, ["cp", path, target])

View file

@ -218,6 +218,13 @@ def update(args):
pmb.helpers.repo.update(args, True) pmb.helpers.repo.update(args, True)
def newapkbuild(args):
if not len(args.args_passed):
logging.info("See 'pmbootstrap newapkbuild -h' for usage information.")
raise RuntimeError("No arguments to pass to newapkbuild specified!")
pmb.build.newapkbuild(args, args.folder, args.args_passed)
def kconfig_check(args): def kconfig_check(args):
# Default to all kernel packages # Default to all kernel packages
packages = args.packages packages = args.packages

View file

@ -140,6 +140,16 @@ def arguments_pkgrel_bump(subparser):
return ret return ret
def arguments_newapkbuild(subparser):
ret = subparser.add_parser("newapkbuild", help="get a template to package"
" new software")
ret.add_argument("folder", help="aports subfolder, where the new aport will"
" be located (main, cross, device, ...)")
ret.add_argument("args_passed", nargs=argparse.REMAINDER,
help="arguments directly passed to Alpine's newapkbuild,"
" more information: 'pmbootstrap newapkbuild main -h'")
def arguments(): def arguments():
parser = argparse.ArgumentParser(prog="pmbootstrap") parser = argparse.ArgumentParser(prog="pmbootstrap")
arch_native = pmb.parse.arch.alpine_native() arch_native = pmb.parse.arch.alpine_native()
@ -201,6 +211,7 @@ def arguments():
arguments_initfs(sub) arguments_initfs(sub)
arguments_qemu(sub) arguments_qemu(sub)
arguments_pkgrel_bump(sub) arguments_pkgrel_bump(sub)
arguments_newapkbuild(sub)
# Action: log # Action: log
log = sub.add_parser("log", help="follow the pmbootstrap logfile") log = sub.add_parser("log", help="follow the pmbootstrap logfile")
@ -288,8 +299,8 @@ def arguments():
# Action: build / checksum / aportgen # Action: build / checksum / aportgen
checksum = sub.add_parser("checksum", help="update aport checksums") checksum = sub.add_parser("checksum", help="update aport checksums")
aportgen = sub.add_parser("aportgen", help="generate a package build recipe" aportgen = sub.add_parser("aportgen", help="generate a postmarketOS"
" (aport/APKBUILD) based on an upstream aport from Alpine") " specific package build recipe (aport/APKBUILD)")
build = sub.add_parser("build", help="create a package for a" build = sub.add_parser("build", help="create a package for a"
" specific architecture") " specific architecture")
build.add_argument("--arch", choices=arch_choices, default=None, build.add_argument("--arch", choices=arch_choices, default=None,

85
test/test_newapkbuild.py Normal file
View file

@ -0,0 +1,85 @@
"""
Copyright 2017 Oliver Smith
This file is part of pmbootstrap.
pmbootstrap is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
pmbootstrap is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with pmbootstrap. If not, see <http://www.gnu.org/licenses/>.
"""
import glob
import os
import pytest
import sys
# Import from parent directory
sys.path.append(os.path.realpath(
os.path.join(os.path.dirname(__file__) + "/..")))
import pmb.build.newapkbuild
import pmb.config
import pmb.config.init
import pmb.helpers.logging
@pytest.fixture
def args(tmpdir, request):
import pmb.parse
sys.argv = ["pmbootstrap.py", "init"]
args = pmb.parse.arguments()
args.log = args.work + "/log_testsuite.txt"
pmb.helpers.logging.init(args)
request.addfinalizer(args.logfd.close)
return args
def test_newapkbuild(args, monkeypatch, tmpdir):
# Fake functions
def confirm_true(*nargs):
return True
def confirm_false(*nargs):
return False
# Preparation
monkeypatch.setattr(pmb.helpers.cli, "confirm", confirm_false)
pmb.build.init(args)
args.aports = tmpdir = str(tmpdir)
func = pmb.build.newapkbuild
# Show the help
func(args, "main", ["-h"])
assert glob.glob(tmpdir + "/*") == []
# Test package
pkgname = "testpackage"
func(args, "main", [pkgname])
apkbuild_path = tmpdir + "/main/" + pkgname + "/APKBUILD"
apkbuild = pmb.parse.apkbuild(args, apkbuild_path)
assert apkbuild["pkgname"] == pkgname
assert apkbuild["pkgdesc"] == ""
# Don't overwrite
with pytest.raises(RuntimeError) as e:
func(args, "main", [pkgname])
assert "Aborted" in str(e.value)
# Overwrite
monkeypatch.setattr(pmb.helpers.cli, "confirm", confirm_true)
pkgdesc = "testdescription"
func(args, "main", ["-d", pkgdesc, pkgname])
args.cache["apkbuild"] = {}
apkbuild = pmb.parse.apkbuild(args, apkbuild_path)
assert apkbuild["pkgname"] == pkgname
assert apkbuild["pkgdesc"] == pkgdesc
# There should be no src folder
assert not os.path.exists(tmpdir + "/main/" + pkgname + "/src")