Compare commits

...

199 Commits

Author SHA1 Message Date
Piraty a45d12d4c3
abuild-rootbld: copy SRCDEST value from host to chroot
Otherwise the default hardcoded in abuild-fetch (var/cache/distfiles) is
used.

(in the same vein as 6864df03aa)

Fixes: 1582617 ("abuild-rootbld: clear environment for bwrap container")
2024-04-26 00:24:09 +02:00
Natanael Copa 68d6aa65f4 abuild: skip /var/run in fhs check
We have many package containing directories under /var/run. Allow those
for now.

Partially reverts commit 08d2d81587 (abuild: extend fhs check)
2024-04-21 10:37:44 +02:00
Natanael Copa c48f8498e7 abuild: allow packages to install under run
I have some vauge memory that it is conveinent for Docker users that the
state dir under /run exists.

Allow this for alpine 3.20 and revisit later.
2024-04-20 08:20:18 +02:00
Natanael Copa eeca95d195 abuild: pass APORTS_BOOTSTRAP to bubblewrap 2024-04-19 23:41:45 +02:00
Natanael Copa 5023838d60 ==== release 3.13.0 ==== 2024-04-17 08:45:34 +02:00
Natanael Copa 7e7b0a5ba3 tests: increase timeout for abuild-fetch to call curl
The CI may be under load.
2024-04-17 08:40:47 +02:00
Natanael Copa 645c3c07a7 abuild: exclude provides for commans with @
the '@' characted serves as a repository separator (eg. pkg@repo) so we
should not add a cmd: provides for binaries having this character.

This avoids conflicts with for example `who` from coreutils and `who@`
from ucspi-tpc6.

fixes https://gitlab.alpinelinux.org/alpine/abuild/-/issues/10074
2024-04-17 08:35:27 +02:00
Natanael Copa e4896c01b8 test: inline bin-in-path APKBUILD
Improves readability. No functional changes
2024-04-17 08:21:40 +02:00
Sertonix 54fd3e4117 abump: preserve in-line comments after pkgver/pkgrel
Fixes [#10133]

[#10133]: https://gitlab.alpinelinux.org/alpine/abuild/-/issues/10133
2024-04-12 11:59:56 +00:00
Sertonix 855992822d abuild: update cachedir logic for rootbld
Closes [#10111]

[#10111]: https://gitlab.alpinelinux.org/alpine/abuild/-/issues/10111
2024-04-12 11:59:04 +00:00
Sertonix 7276042237 abuild: always use $APK instead of apk 2024-04-12 11:59:04 +00:00
Sertonix 6aa8fcc012 abuild: remove libc specific logic
Last use of the '!libc_*' option has been removed in [61cb57cda98].
libpthread special casing only triggers on uclibc.

[61cb57cda98]: https://git.alpinelinux.org/aports/commit/?id=61cb57cda98923032f7ff15f7a0f057bb35aae6d
2024-04-12 11:56:05 +00:00
Sertonix 20b1f47c63 abuild: fix ~ splitting pkgname and pkgver 2024-04-12 11:51:48 +00:00
Sertonix 0e325a2354 abuild: fix python3 depending on python3 2024-04-03 14:09:03 +02:00
Natanael Copa 22e17446f7 Revert "checkapk: Check how many packages depend on a previous soname"
The implementation is difficult to get right. Keep checkapk simple.
Fixes https://gitlab.alpinelinux.org/alpine/abuild/-/merge_requests/229

This reverts commit acfa7d6732.
2024-03-29 12:19:20 +01:00
Sertonix 141da52d19 abuild: warn on go packages without net option 2024-03-29 11:15:43 +00:00
Sertonix 21b5a2298d abuild: fix help message 2024-03-29 11:14:35 +00:00
Sertonix 20c0a15856 functions.sh: fix ABUILD_USERDIR overwrite in ABUILD_CONF 2024-03-29 11:14:35 +00:00
Sertonix 1804361f61 abuild: error on digit+letter+digit version format 2024-03-29 11:12:51 +00:00
Sertonix f0051d2658 doc: document replaces_priority 2024-03-28 22:43:42 +00:00
Hugo Osvaldo Barrera d65a054bc5 Add a man page for abump 2024-03-28 22:42:43 +00:00
Sertonix 17648366cc abuild: invalidate pkgver ending with -r# 2024-03-28 22:41:30 +00:00
Sertonix 2e27c5b202 abuild: sanitycheck pkgver regardless of -d flag 2024-03-28 22:41:30 +00:00
Sertonix a9053617db abuild: stricter pkgname check 2024-03-28 22:40:14 +00:00
Sertonix 73cc75b3e0 abuild: amove: allow spaces in pattern 2024-03-28 18:40:25 +00:00
Sertonix 08d2d81587 abuild: extend fhs check 2024-03-27 14:53:58 +01:00
Timo Teräs ec11f495cd abuild: add an option to keep all directories
This is mainly needed for alpine-baselayout which creates all
directories, and most of them are empty. The code in question
would remove directories we explicitly want alpine-baselayout
to create and own.
2024-03-22 21:56:14 +02:00
Sertonix 8588378efa checkapk: new arch can cause old apk missing 2024-03-13 11:14:34 +00:00
Hugo Osvaldo Barrera 2e987e10ff Remove deprecated option from abuild man page
Using this flag yields:

  >>> ERROR: : Use newapkbuild to create new aports
2024-03-13 11:12:15 +00:00
Natanael Copa 8da2501613 abuild: warn for more version suffixes
give a warning when version suffix a<digit>/b<digit> probably should be
_alpha<digit>/_beta<digit>.

ref: https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10972#note_380899
2024-03-13 11:57:50 +01:00
Sertonix 648529aa35 abuild: remove duplicate SOURCE_DATE_EPOCH from .PKGINFO 2024-03-06 13:05:10 +00:00
Sertonix f63c117df6 abuild: avoid variables in sed pattern 2024-03-05 11:59:10 +00:00
Jingyun Hua e3ba1238d3 abuild.in: update autoconf test for loongarch64 2024-03-05 11:56:33 +00:00
Hugo Osvaldo Barrera 1861b23f0c Remove --recursive from abump --help
This flag does not exist.
2024-03-05 11:27:52 +00:00
Hugo Osvaldo Barrera 06ee1d3cfb .editorconfig: add yml rules
While editing .gitlab-ci.yml, my editor kept indenting to tabs due to
the override for [*]. This retains the existing style.
2024-03-05 11:03:27 +00:00
Celeste 19bebd8497 apkbuild-cpan.in: use distribution name cached in %distfiles
instead of sending a duplicate query to metacpan

follow up from what was done in
e448c9a452
2024-03-05 11:01:27 +00:00
Timothy Legge 5710eefb63 apkbuild-cpan.in: remove perl-dev package wherever it occurs
if the package does not have any xs files and the old APKBUILD data is used

The regex to get perl-dev wherever it might occur was breaking my head
2024-03-05 11:01:27 +00:00
Timothy Legge b0fb5c7038 apkbuild-cpan.in: don't add perl-dev if its not needed on recreate 2024-03-05 11:01:27 +00:00
Sertonix 4ae1b39910 abuild: fix quote handling in check_license 2024-02-12 12:39:17 +01:00
Celeste 39c2b44c63 apkbuild-pypi.in: add option to use project homepage as url=
instead of pypi.org page
2024-02-02 02:51:27 +00:00
Celeste 9e336571e1 apkbuild-pypi.in: fixes #10129 move _pkgreal and comment
this makes it easier to see the maintainer line in
an unexpanded diff that shows a three-line context
2024-02-02 02:51:27 +00:00
Celeste 49983f5af5 apkbuild-pypi.in: fix a number of uninitialized value warnings 2024-02-02 02:51:27 +00:00
Celeste fb262fad5e apkbuild-pypi.in: redefine builddir if not based on $_pkgreal 2024-02-02 02:51:27 +00:00
Celeste db578302aa apkbuild-pypi.in: clean up read_assignments_from_file
also, keep the comment associated with provides & replaces, and
return early to avoid running APKBUILD-specific regex matches
2024-02-02 02:51:27 +00:00
Celeste bc4efd7f0c apkbuild-pypi.in: keep options and patches (copied from apkbuild-cpan)
thanks @timlegge for working out how to make this work in apkbuild-cpan
2024-02-02 02:51:27 +00:00
Celeste 9b513da2f4 apkbuild-pypi.in: keep old dependencies during recreate
unless py3-gpep517 or py3-pytest is missing, then
add that in as the template generated uses it.

To force dependencies to be recalculated, use
`recreate deps`.
2024-02-02 02:51:27 +00:00
Celeste a9e956dc16 apkbuild-pypi.in: move requires_dist parsing code to its own function
also, use regex from https://peps.python.org/pep-0508/#names
to parse valid pypi package names in requires_dist
2024-02-02 02:51:26 +00:00
Celeste 9e416f782a apkbuild-pypi.in: keep old license, url, pkgname/desc during recreate 2024-02-02 02:51:26 +00:00
Celeste d05bc1a4af apkbuild-pypi.in: change position of replaces/provides in template
Most Python aports put replaces/provides
between `builddir` and `build()`.

Follow this convention, so they don't change
position when running `apkbuild-pypi recreate`.
2024-02-02 02:51:26 +00:00
Celeste fc863565f1 apkbuild-pypi.in: update url generated in template 2024-02-02 02:51:26 +00:00
Celeste 32c0815828 apkbuild-pypi.in: switch to pypi.org
pypi.python.org now redirects to it
2024-02-02 02:51:26 +00:00
Celeste 81fb95d31a apkbuild-pypi.in: format depends and checkdepends
with `format_depends` function
taken from `apkbuild-cpan.in`
2024-02-02 02:51:26 +00:00
Celeste 250412d18c apkbuild-pypi.in: use pypi json in get_deps
the old method of calling
`python3 ./setup.py --requires`
doesn't seem to be working anymore
2024-02-02 02:51:26 +00:00
Celeste 54550dc597 apkbuild-pypi.in: use $pkgver in source
regex taken from `apkbuild-cpan.in`
2024-02-02 02:51:26 +00:00
Celeste 11c96f25d6 apkbuild-pypi.in: add -pyc subpackage to template 2024-02-02 02:51:26 +00:00
Celeste ad9324fd52 apkbuild-pypi.in: use gpep517 in template
copied from `newapkbuild.in`, should work
even without a `pyproject.toml` due to the
`setuptools.build_meta:__legacy__` backend
2024-02-02 02:51:26 +00:00
Celeste 4a55e30881 apkbuild-pypi.in: remove depends="python3" from template
it is automatically traced since 6806a0d39b
2024-02-02 02:51:26 +00:00
Celeste 157e390ffa apkbuild-pypi.in: create pretty urls in get_source 2024-02-02 02:51:26 +00:00
Timothy Legge 60c00a4d39 apkbuild-cpan.in: Remmove unnecessary/unused code
Should have been removed in:
27c430cc64
2024-02-01 22:08:23 -04:00
Timothy Legge 99cda3db69 apkbuild-cpan.in: fix uninitialized value when running with no parameters
by applying Celeste's suggested fix
2024-02-01 22:08:23 -04:00
Timothy Legge 1dd67c1beb apkbuild-cpan.in: remove unnecessary pragmas 2024-02-01 22:08:17 -04:00
Timothy Legge 9cde1ad278 apkbuild-cpan.in: Standardize the source and patches output 2024-02-01 07:35:23 -04:00
Celeste 0ad7489969 apkbuild-cpan.in: move code that queries metacpan into its own function
this piece of code was repeated in multiple places, so factor it out
2024-01-31 19:29:56 -04:00
Timothy Legge 726e37920c apkbuild-cpan.in: fix read_assignments_from_file
remove unnecessary regex in functions

Return early if not processing an APKBUILD file

and fix undefined variable of there are no patches
2024-01-30 23:05:45 -04:00
Celeste 1c017bb5d5 apkbuild-cpan.in: add newline after inserting *depends=
Upon `apkbuild-cpan upgrade`, an aport without any
checkdepends would get a line like this inserted:
`checkdepends=""subpackages="$pkgname-doc"`

which would then be deleted by the substitution
that removes empty variables, so the net result
is an APKBUILD with the subpackages field removed.

Inserting a newline results in `checkdepends=""`
being a line all by itself, which then gets
correctly removed by the empty variables regex.
2024-01-28 02:50:25 +00:00
Timothy Legge b0f60ee85a apkbuild-cpan.in: fixes #10129 move _pkgreal and comment 2024-01-27 12:10:06 -04:00
Celeste 28edb26d5b apkbuild-cpan.in: fix empty lines in recreated depends variables
this is a preliminary attempt at fixing #10126, however, i think
the whole logic around recreating depends should be reviewed and
improved, as we may want to carry over all the depends from the
old APKBUILD, and not just the non-perl libs, as the old depends
may be compensating for something not declared in the META file.
2024-01-26 22:33:02 -04:00
Celeste b48c12ea86 apkbuild-cpan.in: do not increase number of spaces in options_comment
the regex used to match options_comment in read_assignments_from_file
starts matching immediately after the closing double quote (it does
not remove the prefixing space), so without this change, a new space
is inserted by the template upon each `recreate`.
2024-01-26 21:37:18 -04:00
Celeste 6a8a61f9d8 apkbuild-cpan.in: find Build.PL using glob() in update_functions sub
this is more consistent with the method we use to
find Build.PL / Makefile.PL in the do_depends sub
2024-01-26 21:37:18 -04:00
Celeste 1c771b0d6a apkbuild-cpan.in: keep arch of old APKBUILD
also, prevent removal of `arch=""` line,
which is sometimes used for disabled aports
2024-01-26 21:37:18 -04:00
Celeste ef6aef38b1 apkbuild-cpan.in: sort & de-duplicate dependencies 2024-01-26 21:37:18 -04:00
Celeste 41a36bca95 apkbuild-cpan.in: move .pod files to the -doc subpackage
this `doc()` function is copied from main/perl/APKBUILD
2024-01-26 21:37:18 -04:00
Celeste 3336955a4a apkbuild-cpan.in: update $package_mappings 2024-01-26 21:37:18 -04:00
Celeste fe072f9866 apkbuild-cpan.in: fix empty directories
by not installing .packlist and perllocal.pod.

The call to find -delete has been removed as
the modifications to build() have covered
almost all cases, so deleting .packlist and
perllocal.pod manually is no longer necessary.

Also, increment template version from 3
to 4 to allow easy identification of
aports that have this change applied.
2024-01-26 21:37:18 -04:00
Celeste 7101d6164a apkbuild-cpan.in: also attempt to generate MYMETA from running Build.PL 2024-01-26 21:37:18 -04:00
Celeste 1753907af0 apkbuild-cpan.in: fix use of uninitialized value $1 2024-01-26 21:37:18 -04:00
Timothy Legge c704644b3c Initial attempt to keep the options and patches 2024-01-26 21:37:18 -04:00
Celeste 37e99da359 apkbuild-cpan.in: tidy up abstract before using it as pkgdesc 2024-01-26 21:37:18 -04:00
Celeste 0bb1482c3a New way of calculating builddir & metaprefix
apkbuild-cpan.in: attempt to get a metaprefix if no metafiles exist

apkbuild-cpan.in: try harder to find a metaprefix

apkbuild-cpan.in: redefine builddir if not based on $_pkgreal
2024-01-26 21:37:18 -04:00
Timothy Legge 505a64bfa7 Improve handling of missing meta files and detection of perl-dev requirment 2024-01-26 21:37:18 -04:00
Sertonix cd32e245e2 abuild: fix subpackage setting arch to all explicitly 2024-01-12 18:28:09 +01:00
Natanael Copa 84e29d94f9 ==== release 3.12.0 ==== 2023-10-18 12:32:17 +02:00
Sören Tempel acfa7d6732 checkapk: Check how many packages depend on a previous soname
Since the changeset committed by psykose a while ago in commit
26118d4997 we now extract the
previous soname. We can pass this previous soname to `apk search -R`
to figure out how many packages are linked against this old soname.

I believe this to be useful for reviewing MRs since the checkapk
output will directly tell us if a contributor has missed rebuilds.
It will also inform us when no rebuilds are necessary, e.g. if the
SONAME was changed but no packages is linked against the library.

Example output for `main/libsodium`:

```
>>> Size difference for libsodium: 336 KiB -> 340 KiB
--- filelist-libsodium-old      2023-09-22 11:24:54.799204225 +0200
+++ filelist-libsodium-new      2023-09-22 11:24:54.799204225 +0200
@@ -1,5 +1,5 @@
 .PKGINFO
 usr/
 usr/lib/
-usr/lib/libsodium.so.23
-usr/lib/libsodium.so.23.3.0
+usr/lib/libsodium.so.26
+usr/lib/libsodium.so.26.1.0
SODIFF:
-usr/lib/libsodium.so.23.3.0:    SONAME               libsodium.so.23
+usr/lib/libsodium.so.26.1.0:    SONAME               libsodium.so.26
REBUILDS:
*** 36 packages linked against 'libsodium.so.23' need to be rebuild!
```
2023-10-18 09:39:12 +00:00
Natanael Copa fab41364f7 checkapk: dont require abuild.conf if we have default conf
also add tests
2023-10-18 11:22:47 +02:00
Natanael Copa 643637dd5d checkapk: add test, fix usage
print --help output to stdout and errors to stderr.
2023-10-18 11:07:24 +02:00
Natanael Copa 3a7fdeaaf0 tests: speed up abuild cleanoldpkg test
skip various steps when buliding the package.
2023-10-18 08:46:09 +02:00
Natanael Copa 08126de5f2 tests: add another test for abuild deps
Test that passing only `CHOST=... abuild deps` works as expected
2023-10-17 22:30:00 +02:00
Natanael Copa c73b8f4ca7 tests: test checkdepends
verify that checkdepends is pulled in when it should and not installed
when it shouldn't.
2023-10-17 22:04:56 +02:00
Natanael Copa 852bb238f3 tests: add test for abuild dep
verify that makedepends_build and makedepends_host works as expected.
2023-10-17 19:51:35 +00:00
Natanael Copa 9ed6a92107 make: run tests in parallel 2023-10-17 19:51:35 +00:00
Natanael Copa c63cae3b15 abuild-tar: fix warnings from scan-build
ref: https://gitlab.alpinelinux.org/alpine/abuild/-/issues/10102
2023-10-17 16:33:15 +00:00
Natanael Copa fcdfd871af abuild-sudo: handle errors from setuid/setgid
ref https://gitlab.alpinelinux.org/alpine/abuild/-/issues/10102
2023-10-17 16:33:15 +00:00
Natanael Copa 1332d5b171 abuild-rmtemp: fix build with clang 2023-10-17 16:33:15 +00:00
Natanael Copa 4128fa6392 ci: build with clang and scan-build
ref: https://gitlab.alpinelinux.org/alpine/abuild/-/issues/10102
2023-10-17 16:33:15 +00:00
Natanael Copa a6a95ad633 abuild: set filetype sh for abuild.in 2023-10-17 16:33:15 +00:00
ptrcnull f688130443 abuild: simplify finding repo_template
related to #10069, this keeps the original behaviour when
running in aports and allows for using rootbld in other package repositories
2023-10-12 15:39:09 +00:00
jvoisin dd67240f01 Actually set values for libcpp hardening macros
Otherwise, it wouldn't do much…
2023-09-04 01:56:15 +02:00
sudotac 9fe0d14d7e apkbuild-pypi.in: replace given/when with if/elsif
smartmatch is deprecated in Perl 5.37.10
2023-08-30 05:50:04 +00:00
sudotac 00aa9aab12 apkbuild-pypi.in: use $() instead of backticks 2023-08-30 05:50:04 +00:00
jvoisin 65b5d578b2 Enable more hardening for libcpp
- _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS: This macro is used to enable -Wthread-safety annotations on libc++’s std::mutex and std::lock_guard.
- _LIBCPP_ENABLE_HARDENED_MODE to enable the hardened mode.
2023-08-21 13:37:35 +02:00
psykose 28b97249fa ==== release 3.11.21 ==== 2023-07-17 06:28:54 +02:00
psykose 6c20db871b checkapk: fix a mistaken grep warning
grep: warning: stray \ before -
it matches without \ anyway
2023-07-17 06:12:56 +02:00
psykose cc17a1cc79 checkapk: exit on trap signal
otherwise it cleans up but the loop keeps going and just fails until end,
just spamming the output
2023-07-11 15:38:09 +02:00
Iztok Fister Jr 617df473b0 apkbuild-cpan: fix typo 2023-07-07 22:48:12 +02:00
psykose d4b2415fb1 apkbuild-cpan: run perltidy over the source
it was a mismatch of mixed indents
2023-07-03 23:52:43 +02:00
psykose 0e555d58a7 apkbuild-cpan: port given/when to if/else
the former is deprecated syntax
2023-07-03 23:49:52 +02:00
psykose fc575e8361 abuild: fix a mistake in 0e333003df
the prefix was dropped from the check so it always says it's unregistered
no actual breakage happened as this just prints a warning
2023-07-03 04:45:13 +02:00
psykose cbca6d4f48 ==== release 3.11.20 ==== 2023-06-29 06:02:28 +02:00
psykose 21faeb7f47 checkapk: use grep instead of awk for size checking
the previous implementation had a bug that + chars needed escaping
(which was fixed), and now has another discovered but that pkgnames
could start with a number, so the /^pkg/ match matches the pkgname again
and a size comparison gives you:

>>> Size difference for 7zip: 7zip-22.01-r5 installed size: -> 7zip-23.01-r0 installed size:

using grep -F avoids any magic character expansion and works correctly
in all cases.
2023-06-29 06:00:22 +02:00
psykose 446b68359f tests: make sure move_caches tests don't fail with envs set 2023-06-26 10:33:40 +02:00
psykose 873a4b6654 ==== release 3.11.19 ==== 2023-06-26 10:31:15 +02:00
psykose df31829660 checkapk: don't objdump invalid elfs
cleans up the output a bit for things that have .so in the name
2023-06-26 10:30:49 +02:00
psykose 535afd9544 checkapk: do simple parallel
this is quite trivial and should be safe
2023-06-26 07:52:28 +02:00
psykose 5c25099d4f ==== release 3.11.18 ==== 2023-06-26 07:41:07 +02:00
psykose 9855e304c7 checkapk: ignore missing apk error
prior to the recent reworks, this error handling path was never
triggered, because the script is ran without pipefail, and it was at
the end of a | pipe | line | sort, so all it did was be ignored for 'new
apks', when the old one would fail to fetch and be missing.

since we now do hit this path on fetch failure however, it aborts the
script when a new subpackage/package is added (since the 'old apk' won't
exist), and doesn't output a diff. since before we always ignored this,
ignore the 'old apk' perhaps not existing, which gives the currently
intended behaviour.
2023-06-26 07:41:07 +02:00
psykose d451522e53 ==== release 3.11.17 ==== 2023-06-26 04:25:43 +02:00
psykose 256a249feb checkapk: but actually skip symlinks
boolean logic gets confusing..
2023-06-26 04:25:08 +02:00
psykose d51cf9c2bb ==== release 3.11.16 ==== 2023-06-26 04:23:08 +02:00
psykose fd5ec6b4fa checkapk: skip symlinks
this affected the old version too- duplicate sodiffs on symlinks are useless
2023-06-26 04:22:26 +02:00
psykose 64f2b3af4e ==== release 3.11.15 ==== 2023-06-26 04:15:06 +02:00
psykose 9af4012177 checkapk: also make sure only sofiles objdumped 2023-06-26 04:14:15 +02:00
psykose 3e5501c9fa ==== release 3.11.14 ==== 2023-06-26 03:27:35 +02:00
psykose 26118d4997 checkapk: refactor to show previous soname and decompress once and use unified context
closes #10070

previously:
>>> Size difference for gegl: 7480 KiB -> 7956 KiB
--- filelist-gegl-old	2023-06-26 02:28:40.176085274 +0200
+++ filelist-gegl	2023-06-26 02:28:40.202085952 +0200
@@ -47,12 +47,13 @@
 usr/lib/gegl-0.4/tiff-load.so
 usr/lib/gegl-0.4/tiff-save.so
 usr/lib/gegl-0.4/transformops.so
+usr/lib/gegl-0.4/vector-fill.so
 usr/lib/gegl-0.4/vector-stroke.so
 usr/lib/gegl-0.4/webp-load.so
 usr/lib/gegl-0.4/webp-save.so
 usr/lib/girepository-1.0/
 usr/lib/girepository-1.0/Gegl-0.4.typelib
 usr/lib/libgegl-0.4.so.0
-usr/lib/libgegl-0.4.so.0.443.1
+usr/lib/libgegl-0.4.so.0.445.1
 usr/lib/libgegl-npd-0.4.so
 usr/lib/libgegl-sc-0.4.so
usr/lib/gegl-0.4/vector-fill.so:    SONAME               vector-fill.so
usr/lib/libgegl-0.4.so.0.445.1:    SONAME               libgegl-0.4.so.0

now:
>>> Size difference for gegl: 7480 KiB -> 7956 KiB
--- filelist-gegl-old
+++ filelist-gegl-new
@@ -47,12 +47,13 @@
 usr/lib/gegl-0.4/tiff-load.so
 usr/lib/gegl-0.4/tiff-save.so
 usr/lib/gegl-0.4/transformops.so
+usr/lib/gegl-0.4/vector-fill.so
 usr/lib/gegl-0.4/vector-stroke.so
 usr/lib/gegl-0.4/webp-load.so
 usr/lib/gegl-0.4/webp-save.so
 usr/lib/girepository-1.0/
 usr/lib/girepository-1.0/Gegl-0.4.typelib
 usr/lib/libgegl-0.4.so.0
-usr/lib/libgegl-0.4.so.0.443.1
+usr/lib/libgegl-0.4.so.0.445.1
 usr/lib/libgegl-npd-0.4.so
 usr/lib/libgegl-sc-0.4.so
SODIFF:
+usr/lib/gegl-0.4/vector-fill.so:    SONAME               vector-fill.so
-usr/lib/libgegl-0.4.so.0.443.1:    SONAME               libgegl-0.4.so.0
+usr/lib/libgegl-0.4.so.0.445.1:    SONAME               libgegl-0.4.so.0

it also no longer relies on diffutils default output, utilising diff -U0 for comparison

there is also a slight optimisation wrt apk handling, previously it
would get decompressed twice for soname diff. now the intermediate is
stored
2023-06-26 03:17:31 +02:00
psykose 7c85598b7f ==== release 3.11.13 ==== 2023-06-22 22:41:17 +02:00
psykose 8e25f6d14a checkapk: undo broken parallel thing
this doesn't work for setting lvalues and *size= is never populated

todo: write tests.., or just port this to lua
2023-06-22 22:40:38 +02:00
psykose e3777a7259 checkapk: silence old-pkg gzip/tar errors
when apk fetch fails (a new package is added) these just say 'gzip invalid magic' or similar, as there is no old apk to compare to.

the || die is also never triggered, as it only triggers when the sort fails, since it won't trigger on earlier pipeline steps

this needs more cleaning up, but i'll leave that for the future when i write some tests.
2023-06-22 22:29:34 +02:00
psykose 1eb4ca5369 ==== release 3.11.12 ==== 2023-06-22 20:04:04 +02:00
psykose 3e5cbbee13 abuild: unset default_lang depends unless set
for consistency with every default split
2023-06-22 20:03:32 +02:00
psykose 9987e57a20 ==== release 3.11.11 ==== 2023-06-22 17:56:52 +02:00
Sören Tempel c9b4146aaa Revert "rootbld: run mkusers inside the chroot and don't affect host users"
We can't run mkusers inside the chroot because of bwrap peculiarities.
Presently, rootbld does therefore not work at all for APKBUILDs which
use $pkggroups/$pkguser. While not polluting the host is a noble goal
it isn't really useful if it causes rootbld to be incapable of building
certain packages (i.e. those using $pkggroups/$pkguser with groups
not existent on the host).

This commit therefore restores the original behavior for now. While at
it, I also added a comment to the mkusers invocation.

See: https://gitlab.alpinelinux.org/alpine/abuild/-/issues/10094

This reverts commit 84d7b7693d.
2023-06-22 21:53:46 +02:00
Cowington Post 7e82b6a34b
newapkbuild: do not expand $CTARGET 2023-06-22 07:13:25 -07:00
psykose fdbd71d816 checkapk: use pigz when available and run newsize/oldsize in parallel 2023-06-22 13:40:37 +02:00
psykose e995b9ec5b ==== release 3.11.10 ==== 2023-06-22 06:23:09 +02:00
Rodrigo Lourenço 1679651370 newapkbuild: fix generating wrong URL with new github urls
When giving GitHub URLs like

https://github.com/USER/REPO/archive/refs/tags/TAG.tar.gz

Strip away the /refs/tags part so a valid URL is generated.
Fixes #10034.
2023-06-22 06:10:54 +02:00
Jakub Panek c26043748e abuild: fix completions to vendor dir, warn on incorrect dir
Signed-off-by: Jakub Panek <me@panekj.dev>
2023-06-22 04:08:05 +00:00
psykose 38e84f9016 abuild: simplify et_dyn/et_exec check 2023-06-22 03:37:06 +00:00
Dimitry Andric 76ff15a7b1 abuild: unset option variables to prevent environment leaking in
In abuild's getopts loop, option variables such as "keep", "verbose",
etc are only set if the corresponding option is found. If such an option
is *not* found, any environment variable with the same name will leak
in, instead. Prevent this by explicitly unsetting almost all of them.
2023-06-22 03:35:46 +00:00
ptrcnull d27b635768 abuild: set cache directories to a temporary directory if MOVE_CACHES is set
this allows for isolating cache directories per package
2023-06-22 05:33:59 +02:00
Jakub Jirutka 8efe527ff3 sample.*: improve sample init script 2023-06-21 15:34:27 +02:00
psykose 6ef31d9e99 ==== release 3.11.9 ==== 2023-06-15 14:54:45 +02:00
psykose 8d11e9f410 abuild: refactor duplicate python detection to not use find(1)
the previous implementation used -regex, which is subtly different between busybox and findutils

[0-9]\+ matches on busybox, but doesn't match with gnu findutils
[0-9]+ matches with findutils, but doesn't match on busybox

this means python deps were subtly broken when findutils was installed
(sometimes pulled via makedeps) vs not
2023-06-15 12:54:00 +00:00
psykose 8f41a924e3 abuild: fix cmd: provides to not provide directory names
/usr/bin/somedirectory/ was providing cmd:somedirectory, because dirs
have +x.
2023-06-15 14:37:24 +02:00
psykose 5d4e763459 ==== release 3.11.8 ==== 2023-06-15 12:59:59 +02:00
Sören Tempel 4a2a0337d0 abuild: Scan for binaries with extra setcap(8) capabilities
Similar to suid binaries, abuild will now error out if the package
includes binaries with setcap(8) capabilities but doesn't have `setcap`
in `$options`. This eases identifying package which ship binaries
with extra capabilities.

Furthermore, if these binaries are executable by others a warning is
emitted. This warning could be changed to an error in the future.
The recommendation is to make such binaries only executable by owner
and group, thereby requiring the system administrator to explicitly
add users to a specific group in order to give them accesses to these
capabilities.

See: https://gitlab.alpinelinux.org/alpine/tsc/-/issues/45

Discussion: This change requires abuild to depend on the `libcap`
package for the `getcap` binary. It does not seem to be possible
at the moment to use scanelf(1) to identify these binaries.
2022-07-03 14:30:15 +02:00
Timo Teräs 8d6fb8b45f abuild-sudo: fix determining number of groups
Musl _SC_NGROUPS_MAX is fixed at 32. The kernel can support more.
Query the kernel for number of groups needed.
2023-06-07 12:42:00 +03:00
psykose 69d15d3225 ==== release 3.11.7 ==== 2023-06-07 07:30:58 +02:00
psykose 49ebbd94e9 newapkbuild: update gpep517 template for new style 2023-06-07 07:30:38 +02:00
Haelwenn (lanodan) Monnier 446a2a66e3 abuild. Use date -u instead of date --utc 2023-06-04 20:10:22 +02:00
psykose 64b3901777 ==== release 3.11.6 ==== 2023-06-03 19:51:50 +02:00
psykose 4f7a2aff7b default.conf: define -fstack-clash-protection by default
see https://gitlab.alpinelinux.org/alpine/tsc/-/issues/64 discussion
2023-06-03 19:48:09 +02:00
psykose 4e4e005530 ==== release 3.11.5 ==== 2023-06-03 12:56:21 +02:00
Sören Tempel e2ab6219d3 abuild: Warn if -doc subpackage exceeds a certain threshold
In the warning, suggest splitting the -doc subpackage into additional
smaller packages (which are not pulled in by the `docs` meta package).

Fixes https://gitlab.alpinelinux.org/alpine/tsc/-/issues/16
2023-06-03 10:55:12 +00:00
psykose a787a9c9c1 ==== release 3.11.4 ==== 2023-06-01 09:32:00 +02:00
psykose 0e333003df abuild: downgrade binfmt-registration error to a warning
strictly speaking, it is possible for an x86_64 cpu to run 32-bit
userspace binaries without qemu emulation. it is also possible for an
aarch64 cpu to run armhf/armv7 binaries (as long as the cpu implements
it, most do). rather than check for every possible combination of when
this is allowed (host cpu + emulated target, does cpu support it, ...),
just downgrade this case to a warning, to permit non-emulated use.

ref https://gitlab.alpinelinux.org/alpine/abuild/-/merge_requests/117#note_255174
2023-06-01 09:29:59 +02:00
psykose fdf1a3a6fb ==== release 3.11.3 ==== 2023-06-01 06:15:46 +02:00
psykose 44c933da5d default.conf: enable _GLIBCXX_ASSERTIONS
these have a slight runtime hit (like fortify-source), but help find
bugs early, by making programs crash on invariants that would corrupt
memory and lead to hard to debug crashes/bugs later.
2023-06-01 04:14:58 +00:00
psykose 861e21fab2 default.conf: kill cppflags
these are mostly useless and redundant given the other flags. all they
do is spam more flags onto every invocation line- things don't "only"
pass cppflags for anything in the general case.
2023-06-01 04:14:58 +00:00
psykose 59caf9e11e checkapk: handle + in pkgname
the pkgname is passed to awk, and + matches in regex, so it fails to
match the actual package name.

closes #10077
2023-06-01 04:13:23 +00:00
psykose 72fa67ca7f abuild: do not use cache in rootbld when cross-building
ref https://gitlab.alpinelinux.org/alpine/abuild/-/issues/10111
2023-06-01 06:11:43 +02:00
psykose eab5926d17 ==== release 3.11.2 ==== 2023-05-26 23:20:46 +02:00
psykose b99565a722 abuild: also set CARCH for rootbld root
otherwise it's set to the default host one, and things that use CARCH in rootbld see the wrong one
2023-05-26 23:19:28 +02:00
psykose fc2f1d628a newapkbuild: make cmake crossopts less aggressive 2023-05-26 00:14:23 +02:00
psykose 96cfde0e88 ==== release 3.11.1 ==== 2023-05-24 02:11:54 +02:00
Natanael Copa c39a988c1b functions: set sharedir properly
fixes loading of default.conf

(applied from aports)

closes #10108
2023-05-24 02:11:12 +02:00
psykose f1d8172827 newapkbuild: don't add python to depends by default
this is already traced by abuild python changes
2023-05-24 02:09:48 +02:00
Lauren N. Liberda bfb88aef29 newapkbuild: add documentation for -e (gpep517 flag) 2023-05-24 00:08:39 +00:00
Lauren N. Liberda a9e06de217 newapkbuild: add gpep517 buildtype 2023-05-24 00:08:39 +00:00
psykose 19d620e8b4 newapkbuild: use cargo-auditable for rust builds 2023-05-20 01:04:12 +02:00
Hugo Osvaldo Barrera 5f500be4c6 abuild.1: add new manpage
This is mostly based on the output of --help.
2023-05-15 18:02:11 +02:00
Hugo Osvaldo Barrera b2b87f8394 newapkbuild.1: fix indentation
There's some extra indentation on the first sections that doesn't match
other man pages and just looks misaligned with the rest of the page.

Example from man:

```
NAME
     man – display manual pages

SYNOPSIS
     man [-acfhklw] [-C file] [-M path] [-m path] [-S subsection]
         [[-s] section] name ...

DESCRIPTION
```

Example from newapkbuild before this patch:

```
NAME
           newapkbuild - generate a new APKBUILD

SYNOPSIS
           newapkbuild options... [pkgname[-pkgver] | source_url]

DESCRIPTION
```

Example for newapkbuild after this patch:

```
NAME
       newapkbuild - generate a new APKBUILD

SYNOPSIS
       newapkbuild options... [pkgname[-pkgver] | source_url]

DESCRIPTION
```
2023-05-15 18:00:52 +02:00
psykose 7bc993400f newapkbuild: fetch --target for rust
this fetches only things for the target triple, so it usually skips e.g.
all the windows crates.
we do this in aports already, in places where it doesn't work we just
unset it.
2023-05-10 15:01:07 +02:00
psykose f810a11cfb newapkbuild: improve default cmake
- -G Ninja because that is always preferred
- remove inferred trailing dot
- use =ON as that is what we usually use most of the time for true/false
- add samurai to makedeps for -G Ninja
- use flatter ctest invocation
2023-05-10 14:57:48 +02:00
Natanael Copa 6576698918 ==== release 3.11.0 ==== 2023-05-09 13:12:34 +00:00
Natanael Copa f2978eb33f abuild-keygen: add support for creating kernel signing key
We need to have a key that can be used to sign kernel modules and
specifically 3rd party kernel modules. Add support for creating this key
in abuild-keygen.

ref: https://gitlab.alpinelinux.org/alpine/aports/-/issues/14873
2023-05-05 13:39:47 +02:00
psykose b5c25f1b62 abuild: use $git in rootbld symbolic-ref
missed git call, compared to the others
2023-04-28 08:42:29 +00:00
psykose 9a61082d8d ==== release 3.11_rc13 ==== 2023-04-21 01:59:45 +02:00
psykose fa3e12f664 default.conf: drop int-conversion error for now
this is a good thing to have and we should reinstate it after 3.18,
however it requires fixing a million things, which is a bit too much for
a sudden release build.

i forgot the implications of this aside from fixing strerror_r and how
much work it was, so put this back after 3.18 branch.
2023-04-21 01:58:26 +02:00
psykose 2c8b0cd1ed newapkbuild: cleanup meson
the jobs are useless because SAMUFLAGS already reads the jobs.
we made a cross file in abuild-meson in aports too.
2023-04-20 18:44:59 +02:00
psykose 9624f202a8 ==== release 3.11_rc12 ==== 2023-04-19 15:28:08 +02:00
psykose 69b3e82296 abuild: .. but silence only errors, not output
fixes previous commit
2023-04-19 15:27:51 +02:00
psykose ff37770904 ==== release 3.11_rc11 ==== 2023-04-19 15:26:17 +02:00
psykose 633353b265 abuild: silence pycache postcheck
otherwise every package prints

 >>> gotosocial-openrc*: Running postcheck for gotosocial-openrc
 find: /builds/raspbeguy/aports/testing/gotosocial/pkg/gotosocial-openrc/usr/lib/python*: No such file or directory

the other postchecks already conditionalise on if [ -d, but we use a wildcard here

no actual package change
2023-04-19 15:26:05 +02:00
psykose 264be38ecd ==== release 3.11_rc10 ==== 2023-04-18 18:37:24 +02:00
psykose 91e6e0b542 abuild: set *-pyc as noarch
the files are noarch themselves
2023-04-18 18:36:23 +02:00
Natanael Copa 0daf4ae637 tests: unset CFLAGS
CFLAGS may be set in the running environment (eg in abuild check)
2023-04-18 15:53:11 +02:00
Natanael Copa 0a129755fd ==== release 3.11_rc9 ==== 2023-04-18 15:42:01 +02:00
Natanael Copa b24bc33446 abuild: warn if pycache is found
and add tests for -pyc package split
2023-04-18 13:27:51 +00:00
Dominique Martinet dd07911cbf abuild: add default_pyc helper
Python by default pre-compiles cache files in __pycache__ directories,
which we currently happily install along in python packages.

Theses .pyc files are rather big and the time/space tradeoff could be
left to users if we just split these out to a -pyc subpackage.

With this default_pyc helper, one can add $pkgname-pyc to their
package's subpackages and it will automatically split off the pyc files
in a package that will be automatically installed if the virtual 'pyc'
package is installed.
Note that this does not work so easily if there already were python
subpackages, the function could be adjusted to strip off the last dash
if required but that seems rather rare.

Random data, sizes:
 - python3: currently 47MiB, split into 23M (main package) / 24M (pyc)
 - py3-markdown: currently 700KiB, 368K (main) / 288K (pyc)

Random benchmark, with python3-pyc:
hyperfine --warmup 5 -m 100 \
    "python3 -c 'import time; print(time.strftime(\"%T\"))'"
  Time (mean ± σ):      24.5 ms ±   2.5 ms    [User: 18.4 ms, System: 6.0 ms]
  Range (min … max):    19.4 ms …  28.9 ms    148 runs

without python3-pyc (same as user without root permissions, root would
generate files on first root, for reference this command generates 184KB
of pyc files):
hyperfine --warmup 5 -m 100 \
    -p 'rm -rf /usr/lib/python3.10/__pycache__ /usr/lib/python3.10/encodings/__pycache__' \
    "python3 -c 'import time; print(time.strftime(\"%T\"))'"
  Time (mean ± σ):      53.7 ms ±   4.3 ms    [User: 39.3 ms, System: 14.3 ms]
  Range (min … max):    47.0 ms …  65.6 ms    100 runs

Link: https://gitlab.alpinelinux.org/alpine/aports/-/issues/11906
Suggested-by: Alex Xu (Hello71) <alex_y_xu@yahoo.ca>
2023-04-18 13:22:14 +00:00
Natanael Copa bb8b1f8dd0 git ignore abulid.conf and fix make clean 2023-04-18 15:14:28 +02:00
Natanael Copa 6008158fb9 default.conf: drop -fomit-frame-pointer
it is implied with -Os where it should.
2023-04-18 13:50:22 +02:00
Natanael Copa 565690da31 make: use install instead of cp 2023-04-18 13:49:04 +02:00
Natanael Copa bbb4fcdd3b Install default config as /usr/share/abuild/default.conf
Split the config a bit so its easier to ship default flags and
maintainer builders.
2023-04-18 13:47:17 +02:00
Natanael Copa a1b672cad2 functions: read default configs from /usr/share/abuild/default.conf
This makes it easier to push default config updates with apk
2023-04-18 13:26:49 +02:00
Natanael Copa fe26e9483b functions: add test for environment preference 2023-04-18 13:15:38 +02:00
Marian Buschsieweke 6806a0d39b abuild: scan for python3 version requirements
Packages installing python3 site packages for python3 in version 3.x.y
depend on python3~3.x. This automatically adds the required
dependencies.

Unit test cases have been added by reusing the `py3-foo-and-bar` test
package. However, the path of that has been renamed to contain spaces
to be extra sure the logic is safe in regrade to spaces in path
names.
2023-04-18 09:26:12 +00:00
Natanael Copa 40ecb4b07c abuild-fetch: try harder to yield
Try a bit harder to let other process aquire lock.

This will hopefully reduce flakiness of testsuite when builder is under
load.
2023-04-18 11:22:54 +02:00
Natanael Copa 6ef57910ab abuild-tar: improve invalid opt handling
make sure we always print usage help text if we have an invalid option.

fixes https://gitlab.alpinelinux.org/alpine/abuild/-/issues/10101
2023-04-17 13:01:05 +02:00
psykose 2d446f094c ==== release 3.11.0_rc8 ==== 2023-04-16 12:32:59 +02:00
Sören Tempel 6864df03aa abuild-rootbld: copy REPODEST value from host to chroot
Otherwise, if a different REPODEST is being used (e.g. due to
`buildrepo -d <repo-dest>`) then the abuild invocation in the
created chroot will not write packages to the correct REPODEST.
Therefore, `buildrepo -R -d` does presently not work correctly.
This commit fixes this by also copying the REPODEST value from
the environment.

This fixes a regression introduced in 1582617eb8.
2023-04-16 14:25:42 +02:00
37 changed files with 2403 additions and 765 deletions

View File

@ -20,3 +20,7 @@ indent_style = space
[Makefile]
indent_size = 8
indent_style = tab
[*.yml]
indent_size = 2
indent_style = space

1
.gitignore vendored
View File

@ -11,6 +11,7 @@ abuild-rmtemp
abuild-sign
abuild-sudo
abuild-tar
abuild.conf
abump
ap
apkbuild-cpan

View File

@ -5,7 +5,27 @@ tests:
image:
name: alpinelinux/abuild-ci
stage: verify
script: [pwd]
script:
- make
- make check
tags:
- docker-alpine
- x86_64
build-clang:
image:
name: alpinelinux/abuild-ci
stage: verify
script: [CC=clang make]
tags:
- docker-alpine
- x86_64
build-scan:
image:
name: alpinelinux/abuild-ci
stage: verify
script: [scan-build --status-bugs make]
tags:
- docker-alpine
- x86_64

View File

@ -168,6 +168,12 @@ file.
Specifies packages that the package replaces. This is typically
used for packages renamed by upstream.
*replaces_priority*
Specifies the numeric value that is used by apk(8) when multiple
packages with *replaces* include the same file. It is also used
to decide which package should define the permissions of a directory
even without *replaces* set.
*subpackages*
Specifies subpackages or split packages built with this
package. Typically, this will include _$pkgname-dev_ for development
@ -215,6 +221,11 @@ file.
packages containing firmware, and should typically never
be needed.
*bigdocs*
Specifies that this packages intentionally has a large -doc subpackage.
Thereby suppressing a warning to be emitted if the -doc subpackage
exceeds a certain package size threshold (currently 2 MiB).
*charset.alias*
Specifies that the package ships a _/usr/lib/charset.alias_
file and that it should be installed on the user's
@ -273,6 +284,12 @@ file.
to use capabilities or process separation instead of set-uid
where available.
*setcap*
Specifies that binaries in the package may be installed
with extra setcap(8) capabilities. If this option is enabled,
it is highly recommended to only make these binaries executable
by root and users of a specific group, not by others.
*textrels*
Specifies that the package's binaries are known to contain
relocations against text segments. By default, abuild(1)

View File

@ -1,5 +1,5 @@
PACKAGE := abuild
VERSION := 3.11.0_rc7
VERSION := 3.13.0
prefix ?= /usr
bindir ?= $(prefix)/bin
@ -11,7 +11,7 @@ SCRIPTS := abuild abuild-keygen abuild-sign newapkbuild \
abump apkgrel buildlab apkbuild-cpan apkbuild-pypi checkapk \
apkbuild-gem-resolver
USR_BIN_FILES := $(SCRIPTS) abuild-tar abuild-gzsplit abuild-sudo abuild-fetch abuild-rmtemp
MAN_1_PAGES := newapkbuild.1
MAN_1_PAGES := newapkbuild.1 abuild.1 abump.1
MAN_5_PAGES := APKBUILD.5
SAMPLES := sample.APKBUILD sample.initd sample.confd \
sample.pre-install sample.post-install
@ -60,7 +60,10 @@ OBJS-abuild-fetch = abuild-fetch.o
TEST_TIMEOUT = 15
.SUFFIXES: .sh.in .in
.SUFFIXES: .conf.in .sh.in .in
%.conf: %.conf.in
${SED} ${SED_REPLACE} ${SED_EXTRA} $< > $@
%.sh: %.sh.in
${SED} ${SED_REPLACE} ${SED_EXTRA} $< > $@
${CHMOD} +x $@
@ -77,10 +80,10 @@ TEST_TIMEOUT = 15
P=$(PACKAGE)-$(VERSION)
all: $(USR_BIN_FILES) $(MAN_PAGES) functions.sh
all: $(USR_BIN_FILES) $(MAN_PAGES) functions.sh abuild.conf
clean:
@rm -f $(USR_BIN_FILES) $(MAN_PAGES) *.o functions.sh Kyuafile \
@rm -f $(USR_BIN_FILES) $(MAN_PAGES) *.o functions.sh abuild.conf Kyuafile \
tests/Kyuafile tests/testdata/abuild.key*
%.o: %.c
@ -124,9 +127,9 @@ Kyuafile: tests/Kyuafile
echo "include('tests/Kyuafile')" >> $@
check: $(SCRIPTS) $(USR_BIN_FILES) functions.sh tests/Kyuafile Kyuafile tests/testdata/abuild.key.pub
kyua test || (kyua report --verbose && exit 1)
kyua --variable parallelism=$(shell nproc) test || (kyua report --verbose && exit 1)
install: $(USR_BIN_FILES) $(SAMPLES) $(MAN_PAGES) abuild.conf functions.sh
install: $(USR_BIN_FILES) $(SAMPLES) $(MAN_PAGES) default.conf abuild.conf functions.sh
install -d $(DESTDIR)/$(bindir) $(DESTDIR)/$(sysconfdir) \
$(DESTDIR)/$(sharedir) $(DESTDIR)/$(mandir)/man1 \
$(DESTDIR)/$(mandir)/man5
@ -144,11 +147,12 @@ install: $(USR_BIN_FILES) $(SAMPLES) $(MAN_PAGES) abuild.conf functions.sh
install -m 644 $$i $(DESTDIR)/$(mandir)/man5/$$i;\
done
if [ -n "$(DESTDIR)" ] || [ ! -f "/$(sysconfdir)"/abuild.conf ]; then\
cp abuild.conf $(DESTDIR)/$(sysconfdir)/; \
install -t $(DESTDIR)/$(sysconfdir)/ abuild.conf; \
fi
cp $(SAMPLES) $(DESTDIR)/$(prefix)/share/abuild/
cp $(AUTOTOOLS_TOOLCHAIN_FILES) $(DESTDIR)/$(prefix)/share/abuild/
cp functions.sh $(DESTDIR)/$(sharedir)/
install -t $(DESTDIR)/$(prefix)/share/abuild/ $(SAMPLES)
install -t $(DESTDIR)/$(prefix)/share/abuild/ $(AUTOTOOLS_TOOLCHAIN_FILES)
install -t $(DESTDIR)/$(sharedir)/ functions.sh default.conf
depends depend:
sudo apk --no-cache -U --virtual .abuild-depends add openssl-dev zlib-dev

View File

@ -34,6 +34,7 @@ THE SOFTWARE.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
static char *program;
@ -181,7 +182,9 @@ fetch_done:
release_lock(lockfd);
// give other processes the chance to acquire the lock if they have the file open
sleep(0);
// sleep for a millisecond
const struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000};
nanosleep(&ts, NULL);
if (status == 0 || try_lock(lockfd))
unlink(lockfile);

View File

@ -90,6 +90,41 @@ do_keygen() {
msg ""
}
do_kernel_key() {
mkdir -p "$ABUILD_USERDIR"
pem="$ABUILD_USERDIR"/kernel_signing_key.pem
(
umask 0007
# https://www.kernel.org/doc/html/v6.1/admin-guide/module-signing.html#generating-signing-keys
openssl req -verbose -new -nodes -utf8 -sha256 -days 36500 -batch -x509 \
-outform PEM -out "$pem" \
-keyout "$pem" -config - <<-EOF
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = myexts
[ req_distinguished_name ]
O = alpinelinux.org
CN = Alpine Linux kernel key
#emailAddress = unspecified.user@unspecified.company
[ myexts ]
basicConstraints=critical,CA:FALSE
keyUsage=digitalSignature
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid
EOF
)
msg "Kernel signing key was created: $pem"
if ! grep -q "^KERNEL_SIGNING_KEY=" "$ABUILD_USERCONF" 2>/dev/null; then
echo "KERNEL_SIGNING_KEY='$pem'" >> "$ABUILD_USERCONF"
fi
msg "KERNEL_SIGNING_KEY='$pem' was added to $ABUILD_USERCONF"
}
usage() {
cat <<-__EOF__
$program $program_version - generate signing keys
@ -100,6 +135,7 @@ usage() {
-i, --install Install public key into /etc/apk/keys using doas
-n Non-interactive. Use defaults
--kernel Generate a key for kernel modules
-b, --numbits [BITS] The size of the private key to generate in bits.
-q, --quiet
-h, --help Show this help
@ -116,8 +152,9 @@ install_pubkey=
interactive=1
numbits=4096
quiet=
kernel_key=
args=$(getopt -o ab:inqh --long append,numbits:,install,quiet,help -n "$program" -- "$@")
args=$(getopt -o ab:inqh --long append,numbits:,install,quiet,help,kernel -n "$program" -- "$@")
if [ $? -ne 0 ]; then
usage
exit 2
@ -127,6 +164,7 @@ while true; do
case $1 in
-a|--append) append_config=1;;
-i|--install) install_pubkey=1;;
--kernel) kernel_key=1;;
-n) unset interactive ;;
-b|--numbits) numbits="$2"; shift 1;;
-q|--quiet) quiet=1;; # suppresses msg
@ -141,4 +179,8 @@ if [ $# -ne 0 ]; then
exit 2
fi
if [ -n "$kernel_key" ]; then
do_kernel_key
exit
fi
do_keygen

View File

@ -18,7 +18,7 @@
#define PREFIX "/var/tmp/abuild."
static void fail() {
static void fail(void) {
errx(1, "%s", strerror(errno));
}

View File

@ -62,7 +62,7 @@ void check_option(const char *opt)
int is_in_group(gid_t group)
{
int ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1;
int ngroups_max = getgroups(0, 0);
gid_t *buf = malloc(ngroups_max * sizeof(gid_t));
int ngroups;
int i;
@ -125,9 +125,11 @@ int main(int argc, const char *argv[])
argv[0] = path;
/* set our uid to root so bbsuid --install works */
setuid(0);
if (setuid(0) < 0)
err(1, "setuid(0) failed");
/* set our gid to root so apk commit hooks run with the same gid as for "sudo apk add ..." */
setgid(0);
if (setgid(0) < 0)
err(1, "setgid(0) failed");
execv(path, (char * const*)argv);
perror(path);
return 1;

View File

@ -221,7 +221,8 @@ static int buf_padto(struct buf *b, size_t alignment)
newsize = (oldsize + alignment - 1) & -alignment;
if (buf_resize(b, newsize)) return -ENOMEM;
b->size = newsize;
memset(b->ptr + oldsize, 0, newsize - oldsize);
if (b->ptr)
memset(b->ptr + oldsize, 0, newsize - oldsize);
return 0;
}
@ -260,6 +261,8 @@ static int buf_add_ext_header_hexdump(struct buf *b, const char *hdr, const unsi
for (i = len; i > 9; i /= 10) len++;
if (buf_resize(b, b->size + len)) return -ENOMEM;
if (b->ptr == NULL)
return 0;
b->size += snprintf(&b->ptr[b->size], len, "%u %s=", len, hdr);
for (i = 0; i < valuelen; i++)
b->size += snprintf(&b->ptr[b->size], 3, "%02x", (int)value[i]);
@ -385,7 +388,10 @@ int main(int argc, char **argv)
ENGINE_register_all_complete();
#endif
while (getopt_long(argc, argv, "", options, &ndx) != -1) {
int c;
while ((c = getopt_long(argc, argv, "", options, &ndx)) != -1) {
if (c == '?')
return usage(stderr);
if (ndx == 0)
digest = optarg ? optarg : "sha1";
}

166
abuild.1.scd Normal file
View File

@ -0,0 +1,166 @@
abuild(1)
# NAME
*abuild* - build an apk from an APKBUILD
# SYNOPSIS
*abuild* [options] [-P _REPODEST_] [-s _SRCDEST_] [-D _DESCRIPTION_] [cmd] ...
# DESCRIPTION
*abuild* builds an apk binary package based on an input APKBUILD(5), as well as
other related operations.
# OPTIONS
*-A*
Print CARCH and exit
*-c*
Enable colored output
*-d*
Disable dependency checking
*-D*
Set APKINDEX description (default: *$repo $(git describe)*)
*-f*
Force specified cmd (skip checks: apk up to date, arch)
*-F*
Force run as root
*-h*
Show this help
*-k*
Keep built packages, even if APKBUILD or sources are newer
*-K*
Keep buildtime temp dirs and files (srcdir/pkgdir/deps)
*-m*
Disable colors (monochrome)
*-P*
Set REPODEST as the repository location for created packages
*-q*
Quiet
*-r*
Install missing dependencies from system repository (using sudo)
*-s*
Set source package destination directory
*-v*
Verbose: show every command as it is run (very noisy)
# COMMANDS
*build*
Compile and install package into *$pkgdir*.
*check*
Run any defined tests concerning the package
*checksum*
Generate checksum to be included in APKBUILD
*clean*
Remove temp build and install dirs
*cleancache*
Remove downloaded files from $SRCDEST
*cleanoldpkg*
Remove binary packages except current version
*cleanpkg*
Remove already built binary and source package
*deps*
Install packages listed in makedepends and depends
*fetch*
Fetch sources to $SRCDEST (consider: 'abuild fetch verify')
*index*
Regenerate indexes in $REPODEST
*listpkg*
List target packages
*package*
Install project into
*prepare*
Apply patches
*rootbld*
Build package in clean chroot. Requires *abuild-rootbld*.
*rootpkg*
Run 'package', the split functions and create apks as fakeroot
*sanitycheck*
Basic sanity check of APKBUILD
*snapshot*
Create a *$giturl* snapshot and upload to *$disturl*
*sourcecheck*
Check if remote source package exists upstream
*srcpkg*
Make a source package
*undeps*
Uninstall packages listed in makedepends and depends
*unpack*
Unpack sources to $srcdir
*up2date*
Compare target and sources dates
*verify*
Verify checksums
# FILES
/etc/abuild.conf
Configuration is read from this file by default.
$HOME/.abuild/abuild.conf
User-specific configuration is read from this file, if it exists.
# EXAMPLES
Update checksums for an APKBUILD:
```
abuild checksum
```
Build an APKBUILD and print coloured output:
```
abuild -rc
```
# SEE ALSO
SPDX license reference (on the Web at <https://spdx.org/licenses/>),
newapkbuild(1), apk(8), APKBUILD(5).
# AUTHORS
*abuild*: Natanael Copa <_ncopa@alpinelinux.org_>
Documentation:++
Hugo Osvaldo Barrera <_hugo@whynothugo.nl_>

26
abuild.conf.in Normal file
View File

@ -0,0 +1,26 @@
# defaults are in @sharedir@/default.conf
#
# uncomment line below to enable colors
#USE_COLORS=1
# uncomment line below to enable ccache support.
#USE_CCACHE=1
# where downloaded files are stored
#SRCDEST=/var/cache/distfiles
# uncomment line below to store built packages in other location
# The package will be stored as $REPODEST/$repo/$pkgname-$pkgver-r$pkgrel.apk
# where $repo is the name of the parent directory of $startdir.
#REPODEST=$HOME/packages/
# PACKAGER and MAINTAINER are used by newapkbuild when creating new aports for
# the APKBUILD's "Contributor:" and "Maintainer:" comments, respectively.
#PACKAGER="Your Name <your@email.address>"
#MAINTAINER="$PACKAGER"
# what to clean up after a successful build
#CLEANUP="srcdir bldroot pkgdir deps"
# what to cleanup after a failed build
#ERROR_CLEANUP="bldroot deps"

302
abuild.in Executable file → Normal file
View File

@ -1,4 +1,5 @@
#!/bin/ash -e
# vim: set filetype=sh:
# abuild - build apk packages (light version of makepkg)
# Copyright (c) 2008-2015 Natanael Copa <ncopa@alpinelinux.org>
@ -32,6 +33,7 @@ fi
: ${SETFATTR:="setfattr"}
apk_opt_wait="--wait 30"
doc_threshold=$((2 * 1024 * 1024)) # 2 MiB
umask 022
@ -76,17 +78,17 @@ amove() {
d="$(pwd -L)"
cd "$pkgdir"
local pattern f
local pattern f IFS=""
for pattern; do
for f in ${pattern#/}; do # let shell expand the pattern
# strip trailing /
f=${f%/}
if [ "${f%/*}" != "$f" ]; then
mkdir -p "$subpkgdir/${f%/*}"
mv -v "$pkgdir"/$f "$subpkgdir/${f%/*}"
mv -v "$pkgdir/$f" "$subpkgdir/${f%/*}"
else
mkdir -p "$subpkgdir"
mv -v "$pkgdir"/$f "$subpkgdir/"
mv -v "$pkgdir/$f" "$subpkgdir/"
fi
# cleanup
rmdir -p "$f" 2>/dev/null || rmdir -p "${f%/*}" 2>/dev/null || true
@ -155,6 +157,7 @@ cleanup() {
fi;;
pkgdir) msg "Cleaning up pkgdir"; rm -rf "$pkgbasedir";;
srcdir) msg "Cleaning up srcdir"; cleanup_srcdir;;
tmpdir) msg "Cleaning up tmpdir"; rm -rf "$tmpdir";;
deps)
if [ -n "$uninstall_after" ]; then
msg "Uninstalling dependencies..."
@ -177,30 +180,30 @@ spell_error() {
}
verify_pkgname() {
local name=${1%%=*}
case "$name" in
""|*" "*|-*) return 1;;
case $1 in
''|*[!a-zA-Z0-9._+-]*|[!a-zA-Z0-9]*) return 1;;
esac
return 0
}
# check if apkbuild is basically sane
default_sanitycheck() {
local i= j= suggestion=
local i= j=
msg "Checking sanity of $APKBUILD..."
[ -z "$pkgver" ] && die "Missing pkgver in APKBUILD"
if [ -z "$nodeps" ]; then
$APK version --check --quiet "$pkgver" ||\
die "$pkgver is not a valid version"
fi
$APK version --check --quiet -- "$pkgver"-r0 || \
die "$pkgver is not a valid version"
[ -z "$pkgrel" ] && die "Missing pkgrel in APKBUILD"
# give 0 as it is always valid and give the pkgrel
$APK version --check --quiet 0-r"$pkgrel" || \
die "$pkgrel is not a valid pkgrel"
# warn when p1 should be _p1
case "$pkgver" in
*[0-9]p[0-9]) warning "pkgver should probably be $(echo "$pkgver" | sed -E -e 's/(.*[0-9])p([0-9])/\1_p\2/')";;
# digit+letter+digit passes the apk2 version check
case $pkgver in
*[0-9][a-z][0-9]*)
die "the digit+letter+digit version format is invalid. Use suffixes instead"
;;
esac
[ -z "$pkgdesc" ] && die "Missing pkgdesc in APKBUILD"
[ -z "$url" ] && die "Missing url in APKBUILD"
[ -z "$license" ] && die "Missing license in APKBUILD"
@ -316,6 +319,9 @@ default_sanitycheck() {
check_secfixes_comment || return 1
makedepends_has 'g++' && ! options_has toolchain && warning "g++ should not be in makedepends"
if makedepends_has 'go' && ! options_has 'net'; then
warning "Go packages require network connection to build. Maybe add 'net' to options"
fi
if ! options_has "!check" && [ -n "$REQUIRE_CHECK" ]; then
(unset check; . "$APKBUILD"; type check >/dev/null 2>&1) || \
@ -552,10 +558,11 @@ unpack() {
default_unpack
}
# cleanup source and package dir
# cleanup source, package and temporary dir
clean() {
cleanup srcdir
cleanup pkgdir
cleanup tmpdir
}
# cleanup fetched sources
@ -597,19 +604,25 @@ subpkg_set() {
subpkgarch=${_splitarch#*:}
if [ "$subpkgarch" = "$_splitarch" -o -z "$subpkgarch" ]; then
case "$subpkgname" in
*-doc | *-openrc | *-lang | *-lang-* | *sh-completion) subpkgarch="noarch" ;;
*-doc | *-openrc | *-lang | *-lang-* | *sh-completion | *-pyc) subpkgarch="noarch" ;;
*) subpkgarch="$pkgarch" ;;
esac
fi
}
arch2dir() {
local arch="$1"
[ "$arch" = "noarch" -o "$arch" = "all" ] && arch="$CARCH"
printf '%s\n' "$arch"
}
cleanpkg() {
local i
msg "Cleaning built packages..."
rm -f "$REPODEST/$repo/src/$pkgname-$pkgver-r$pkgrel.src.tar.gz"
for i in $allpackages; do
subpkg_set "$i"
rm -f "$REPODEST/$repo/${subpkgarch/noarch/$CARCH}/$subpkgname-$pkgver-r$pkgrel.apk"
rm -f "$REPODEST/$repo/$(arch2dir "$subpkgarch")/$subpkgname-$pkgver-r$pkgrel.apk"
done
subpkg_unset
@ -657,7 +670,7 @@ mkusers() {
# helper to update config.sub to a recent version
update_config_sub() {
find . -name config.sub | (local changed=false; while read f; do
if ! ./$f riscv64-alpine-linux-musl 2>/dev/null; then
if ! ./$f loongarch64-alpine-linux-musl 2>/dev/null; then
msg "Updating $f"
cp "$sharedir"/${f##*/} "$f" || return 1
changed=true
@ -670,7 +683,7 @@ update_config_sub() {
# helper to update config.guess to a recent version
update_config_guess() {
find . -name config.guess | (local changed=false; while read f; do
if grep -q aarch64 "$f" && grep -q ppc64le "$f" && grep -q riscv64 "$f"; then
if grep -q aarch64 "$f" && grep -q ppc64le "$f" && grep -q riscv64 "$f" && grep -q loongarch64 "$f"; then
msg "No update needed for $f"
else
msg "Updating $f"
@ -689,7 +702,17 @@ runpart() {
prepare|build|package|check)
# exclude aports from git repo discovery
export GIT_CEILING_DIRECTORIES="$startdir"
cd "$builddir";;
# prevent using global cache directories
if [ -n "$MOVE_CACHES" ]; then
export GOCACHE="${GOCACHE:-"$tmpdir/go"}"
export GOMODCACHE="${GOCACHE:-"$tmpdir/gomod"}"
export GOTMPDIR="${GOTMPDIR:-"$tmpdir"}"
export CARGO_HOME="${CARGO_HOME:-"$tmpdir/cargo"}"
fi
cd "$builddir"
;;
esac
fi
$part
@ -755,15 +778,18 @@ targz() {
}
postcheck() {
local dir="$1" name="$2" i= e=0
local dir="$1" name="$2" i= j= e=0
msg "Running postcheck for $name"
# checking for FHS compat
if ! options_has "!fhs"; then
for i in "$dir"/srv/* "$dir"/usr/local/* "$dir"/opt/*; do
if [ -e "$i" ]; then
error "Packages must not put anything under /srv, /usr/local or /opt"
e=1
fi
for i in srv usr/local opt tmp var/tmp var/lock var/empty home sys proc mnt dev; do
for j in "$dir"/"$i"/* "$dir"/"$i"/.[!.]* "$dir"/"$i"/..?*; do
if [ -L "$j" ] || [ -e "$j" ]; then
error "Packages must not put anything under /$i"
e=1
break
fi
done
done
if [ -d "$dir"/usr/var ]; then
error "Found /usr/var, localstatedir is most likely wrong"
@ -817,13 +843,21 @@ postcheck() {
warning "Found /usr/share/man but package name doesn't end with -doc"
fi
# check for uncompressed man pages
i=$(find "$dir"/usr/share/man -name '*.[0-8]' -type f | sed "s|^$dir|\t|")
i=$(find "$dir"/usr/share/man -name '*.[0-8]' -type f | sed -e 's/^/\t/')
if [ -n "$i" ]; then
error "Found uncompressed man pages:"
echo "$i"
e=1
fi
fi
# look for pycache
# wildcard should always get the system python dir, and this is faster than
# trying to calculate the python version.
local pycache="$(find "$dir"/usr/lib/python* \( -type d -a -name "__pycache__" \) 2>/dev/null )"
if [ -n "$pycache" ] && [ "${name%-pyc}" = "$name" ]; then
warning "Found __pycache__ but package name doesn't end with -pyc"
fi
# check that we don't have any files names with newline
i=$(find "$dir" -name $'*\n*')
if [ -n "$i" ]; then
@ -832,7 +866,7 @@ postcheck() {
e=1
fi
# check directory permissions
i=$(find "$dir" -type d -perm -777 | sed "s|^$dir|\t|")
i=$(find "$dir" -type d -perm -777 | sed -e 's/^/\t/')
if [ -n "$i" ]; then
warning "World writeable directories found:"
echo "$i"
@ -840,7 +874,7 @@ postcheck() {
# check so we dont have any suid root binaries that are not PIE
i=$(find "$dir" -type f -perm /6000 \
| xargs scanelf --nobanner --etype ET_EXEC \
| sed "s|ET_EXEC $dir|\t|")
| sed -e 's/ET_EXEC /\t/')
if [ -n "$i" ]; then
warning "Found non-PIE files that have SUID:"
echo "$i"
@ -856,6 +890,20 @@ postcheck() {
e=1
fi
fi
# test capabilities on executables
# see: https://gitlab.alpinelinux.org/alpine/tsc/-/issues/45
getcap -r "$dir" | (local r=true; while read -r line; do
local filename="${line% *}"
if ! options_has "setcap"; then
error "Found binary with extra capabilities: $filename"
r=false
fi
local execothers="$(find "$filename" -perm -o+x)"
if [ -n "$execothers" ]; then
warning "Found setcap binary executable by others: $filename"
fi
done; $r) || e=1
# test for textrels
if ! options_has "textrels"; then
@ -904,6 +952,10 @@ prepare_subpackages() {
warning2 "Add \$pkgname-zsh-completion to subpackages"
fi
if [ -d "$pkgdir"/usr/share/fish/completions ]; then
warning "Found /usr/share/fish/completions"
warning2 "fish completions for programs should be located in /usr/share/fish/vendor_completions.d"
fi
if [ -d "$pkgdir"/usr/share/fish/vendor_completions.d ]; then
warning "Found /usr/share/fish/completions"
warning2 "Add \$pkgname-fish-completion to subpackages"
fi
@ -912,6 +964,7 @@ prepare_subpackages() {
default_lang() {
pkgdesc="Languages for package $pkgname"
install_if="$pkgname=$pkgver-r$pkgrel lang"
depends="$depends_lang"
local dir
for dir in ${langdir:-/usr/share/locale}; do
@ -994,12 +1047,12 @@ check_maintainer() {
check_license() {
local ret=0
local license_list=/usr/share/spdx/license.lst
local exclude="AND OR WITH ( )"
if options_has "!spdx" || ! [ -f "$license_list" ]; then
return 0
fi
local IFS="$IFS()"
local i; for i in $license; do
list_has "$i" $exclude && continue
list_has "$i" AND OR WITH && continue
if ! grep -q -x -F "$i" "$license_list"; then
ret=1
warning "\"$i\" is not a known license"
@ -1044,7 +1097,7 @@ check_depends_dev() {
check_provides() {
local i
for i in $provides; do
if [ "${i%%[<>=]*}" = "$pkgname" ]; then
if [ "${i%%[<>=~]*}" = "$pkgname" ]; then
return 1
fi
done
@ -1105,7 +1158,6 @@ prepare_metafiles() {
if [ -n "$FAKEROOTKEY" ]; then
echo "# using $($FAKEROOT -v)" >> "$pkginfo"
fi
echo "# $(date -u -d @$SOURCE_DATE_EPOCH)" >> "$pkginfo"
cat >> "$pkginfo" <<-EOF
pkgname = $name
pkgver = $pkgver-r$pkgrel
@ -1244,9 +1296,16 @@ prepare_command_provides() {
options_has "!tracedeps" && return 0
cd "$dir" || return 1
for i in bin/* sbin/* usr/bin/* usr/sbin/*; do
if ! [ -x "$i" ]; then
if ! [ -x "$i" ] || ! [ -f "$i" ]; then
continue
fi
# exclude any provides: lines for commands that has '@' because '@'
# is used as seperator between command name and repository. This
# avoids potential conflicts
# ref: https://gitlab.alpinelinux.org/alpine/abuild/-/issues/10074
case "$i" in
*@*) continue;;
esac
local f=${i##*/}
echo $f >> "$controldir"/.provides-command
done
@ -1439,14 +1498,6 @@ trace_apk_deps() {
autodeps="$autodeps pkgconfig"
fi
# special case for libpthread: we need depend on libgcc
if [ "$CLIBC" = "uclibc" ] && [ -f "$dir"/.needs-so ] \
&& grep -q -w '^libpthread.so.*' "$dir"/.needs-so \
&& ! grep -q -w "^depend = libgcc" "$dir"/.PKGINFO; then
autodeps="$autodeps libgcc"
msg " added libgcc (due to libpthread)"
fi
[ -f "$dir"/.needs-so ] && for i in $(cat "$dir"/.needs-so); do
# first check if its provided by same apkbuild
grep -q -w "^$sonameprefix$i" "$dir"/.provides-so 2>/dev/null && continue
@ -1481,6 +1532,11 @@ trace_apk_deps() {
autodeps="$autodeps $i"
done
# python3 dependencies
for i in $(sort -u "$dir"/.python3-needs 2>/dev/null); do
autodeps="$autodeps $i"
done
# pkg-config depends
for i in $(sort -u "$dir"/.needs-pc 2>/dev/null); do
# first check if its provided by same apkbuild
@ -1622,8 +1678,8 @@ scan_shared_objects() {
fi
# now find the so dependencies
scanelf --nobanner --recursive --needed "$datadir" | tr ' ' ':' \
| awk -F ":" '$2 != "" && ($1 == "ET_DYN" || $1 == "ET_EXEC") {print $2}' \
scanelf --nobanner --recursive --needed --etype ET_DYN,ET_EXEC "$datadir" | tr ' ' ':' \
| awk -F ":" '$2 != "" {print $2}' \
| sed 's:,:\n:g' | sort -u \
| while read soname; do
# only add files that are not self provided
@ -1674,6 +1730,30 @@ scan_symlink_targets() {
done
}
# check if python3 site packages are installed and depend on a compatible version
scan_python3_dependency() {
local controldir="$2" datadir="$3"
local dir_count=0
local site_pkg_dir
for site_pkg_dir in "$datadir"/usr/lib/python3*/site-packages; do
if ! [ -d "$site_pkg_dir" ]; then
# empty iteration
continue
fi
dir_count=$((dir_count + 1))
if [ "$dir_count" -gt 1 ]; then
error "package contains python3 modules for conflicting python3 versions"
return 1
fi
local pyver="${site_pkg_dir##*usr/lib/python}"
pyver="${pyver%%/*}"
if [ -n "$pyver" ] && [ "${subpkgname:-$pkgname}" != python3 ]; then
echo "python3~$pyver" \
>> "$controldir"/.python3-needs
fi
done
}
#find pkg-config dependencies
scan_pkgconfig_depends() {
local provides_pc="$1" controldir= name= datadir=
@ -1707,12 +1787,14 @@ human_size() {
create_apks() {
local file= dir= name= ver= apk= datadir= size=
local gzip=$(command -v pigz || echo gzip)
rmdir "$pkgdir"/usr/lib \
"$pkgdir"/usr/bin \
"$pkgdir"/usr/share \
"$pkgdir"/usr \
"$pkgdir"/etc/ \
2>/dev/null || :
if ! options_has "keepdirs"; then
rmdir "$pkgdir"/usr/lib \
"$pkgdir"/usr/bin \
"$pkgdir"/usr/share \
"$pkgdir"/usr \
"$pkgdir"/etc/ \
2>/dev/null || :
fi
if ! options_has "!tracedeps"; then
for file in "$pkgbasedir"/.control.*/.PKGINFO; do
dir="${file%/.PKGINFO}"
@ -1721,6 +1803,7 @@ create_apks() {
subpkgname=$name
scan_shared_objects "$name" "$dir" "$datadir"
scan_symlink_targets "$name" "$dir" "$datadir"
scan_python3_dependency "$name" "$dir" "$datadir"
done
for file in "$pkgbasedir"/.control.*/.provides-pc; do
scan_pkgconfig_depends "$file"
@ -1731,14 +1814,19 @@ create_apks() {
local dir="${file%/.PKGINFO}"
local name=$(pkginfo_val pkgname "$file")
local ver=$(pkginfo_val pkgver "$file")
local size=$(pkginfo_val size "$file" | human_size)
local size=$(pkginfo_val size "$file")
local apk=$name-$ver.apk
local datadir="$pkgbasedir"/$name
local subpkgname=$name
local subpkgarch=$(pkginfo_val arch "$file")
# See https://gitlab.alpinelinux.org/alpine/tsc/-/issues/16
if ! options_has "bigdocs" && is_doc_pkg "$name" && [ "$size" -gt "$doc_threshold" ]; then
warning "The -doc subpackage is unusually large, consider splitting it"
fi
trace_apk_deps "$name" "$dir" "$subpkgarch" || return 1
msg "Package size: ${size}"
msg "Package size: $(echo "$size" | human_size)"
msg "Compressing data..."
(
cd "$datadir"
@ -1778,8 +1866,8 @@ create_apks() {
abuild-sign -q control.tar.gz || exit 1
msg "Create $apk"
mkdir -p "$REPODEST"/$repo/${subpkgarch/noarch/$CARCH}
cat control.tar.gz data.tar.gz > "$REPODEST"/$repo/${subpkgarch/noarch/$CARCH}/$apk
mkdir -p "$REPODEST/$repo/$(arch2dir "$subpkgarch")"
cat control.tar.gz data.tar.gz > "$REPODEST/$repo/$(arch2dir "$subpkgarch")/$apk"
)
done
}
@ -1796,7 +1884,7 @@ build_abuildrepo() {
# check early if we have abuild key
abuild-sign --installed
logcmd "building $repo/$pkgname-$pkgver-r$pkgrel"
local _starttime=$(date --utc +%s)
local _starttime=$(date -u +%s)
msg "Building $repo/$pkgname $pkgver-r$pkgrel (using $program $program_version) started $(date -R)"
# make sure SOURCE_DATE_EPOCH is set
@ -1806,7 +1894,7 @@ build_abuildrepo() {
$_check rootpkg; do
runpart $part
done
local _endtime=$(date --utc +%s)
local _endtime=$(date -u +%s)
local _difftime=$((_endtime - _starttime))
msg "Build complete at $(date -R) elapsed time $((_difftime/3600))h $((_difftime/60%60))m $((_difftime%60))s"
cleanup $CLEANUP
@ -1821,9 +1909,9 @@ update_abuildrepo_index() {
##NOARCH: These packages are really in $CARCH and do not need their
# own repository. --rewrite-arch is used below to make sure the index
# thinks they are for $CARCH and apk-tools will fetch them from
# correct URL path. Remainder of the script uses ${subpkgarch/noarch/$CARCH}
# correct URL path. Remainder of the script uses $(arch2dir "$subpkgarch")
# when expanding to the target repository path.
[ "$subpkgarch" = "noarch" ] && subpkgarch="$CARCH"
[ "$subpkgarch" = "noarch" -o "$subpkgarch" = "all" ] && subpkgarch="$CARCH"
list_has "$subpkgarch" "$allarch" || allarch="$allarch $subpkgarch"
done
subpkg_unset
@ -2109,13 +2197,34 @@ default_fishcomp() {
install_if="$pkgname=$pkgver-r$pkgrel fish"
cd "$pkgdir" || return 0
amove usr/share/fish/completions
if [ -d usr/share/fish/vendor_completions.d ]; then
amove usr/share/fish/vendor_completions.d
fi
if [ -d usr/share/fish/completions ]; then
warning "fish completions for programs should be in /usr/share/fish/vendor_completions.d"
amove usr/share/fish/completions
fi
}
fishcomp() {
default_fishcomp
}
default_pyc() {
pkgdesc="Precompiled Python bytecode for ${subpkgname%-pyc}"
install_if="${subpkgname%-pyc}=$pkgver-r$pkgrel pyc"
cd "$pkgdir" || return 0
local IFS=$'\n'
amove $(find usr/lib/python* -type d -name __pycache__)
}
pyc() {
default_pyc
}
is_function() {
type "$1" 2>&1 | head -n 1 | grep -E -q "is a (shell )?function"
}
@ -2194,17 +2303,12 @@ check_arch() {
return $ret
}
# return true if libc is not masked in options
check_libc() {
! options_has "!libc_$CLIBC"
}
# check if package is up to date
apk_up2date() {
local i s
for i in $allpackages; do
subpkg_set "$i"
if [ ! -f "$REPODEST/$repo/${subpkgarch/noarch/$CARCH}/$subpkgname-$pkgver-r$pkgrel.apk" ]; then
if [ ! -f "$REPODEST/$repo/$(arch2dir "$subpkgarch")/$subpkgname-$pkgver-r$pkgrel.apk" ]; then
subpkg_unset
return 1
fi
@ -2219,7 +2323,7 @@ apk_up2date() {
else
s="$startdir/${i##*/}"
fi
if [ "$s" -nt "$REPODEST/$repo/${pkgarch/noarch/$CARCH}/$pkgname-$pkgver-r$pkgrel.apk" ]; then
if [ "$s" -nt "$REPODEST/$repo/$(arch2dir "$pkgarch")/$pkgname-$pkgver-r$pkgrel.apk" ]; then
return 1
fi
done
@ -2231,7 +2335,7 @@ abuildindex_up2date() {
for i in $allpackages; do
subpkg_set "$i"
local dir="$REPODEST"/$repo/${subpkgarch/noarch/$CARCH}
local dir="$REPODEST/$repo/$(arch2dir "$subpkgarch")"
local idx="$dir"/APKINDEX.tar.gz
local file="$dir"/$subpkgname-$pkgver-r$pkgrel.apk
@ -2249,7 +2353,6 @@ abuildindex_up2date() {
up2date() {
check_arch || return 0
check_libc || return 0
apk_up2date && abuildindex_up2date
}
@ -2263,17 +2366,17 @@ calcdeps() {
builddeps="$builddeps $i"
done
for i in $EXTRADEPENDS_HOST $EXTRADEPENDS_TARGET $makedepends_host; do
[ "$pkgname" = "${i%%[<>=]*}" ] && continue
[ "$pkgname" = "${i%%[<>=~]*}" ] && continue
list_has $i $hostdeps && continue
subpackages_has ${i%%[<>=]*} || hostdeps="$hostdeps $i"
subpackages_has ${i%%[<>=~]*} || hostdeps="$hostdeps $i"
done
else
[ -z "$makedepends" ] && makedepends="$makedepends_build $makedepends_host"
want_check && makedepends="$makedepends $checkdepends"
for i in $EXTRADEPENDS_BUILD $EXTRADEPENDS_HOST $1 $depends $makedepends; do
[ "$pkgname" = "${i%%[<>=]*}" ] && continue
[ "$pkgname" = "${i%%[<>=~]*}" ] && continue
list_has $i $builddeps && continue
subpackages_has ${i%%[<>=]*} || builddeps="$builddeps $i"
subpackages_has ${i%%[<>=~]*} || builddeps="$builddeps $i"
done
hostdeps="$EXTRADEPENDS_TARGET"
fi
@ -2388,7 +2491,7 @@ rootbld_actions() {
if ! want_check; then
_check=true
fi
for part in symlinksrc unpack prepare mkusers build $_check rootpkg; do
for part in symlinksrc unpack prepare build $_check rootpkg; do
runpart $part
done
}
@ -2411,11 +2514,20 @@ rootbld() {
return
fi
apk info -eq abuild-rootbld || die "rootbld: abuild-rootbld package not installed"
$APK info -eq abuild-rootbld || die "rootbld: abuild-rootbld package not installed"
[ $CBUILD = $CHOST ] || die "rootbld: set CBUILD=$CHOST to build for $CHOST"
[ $CBUILD_ARCH = "$(apk --print-arch)" -o -f "/proc/sys/fs/binfmt_misc/qemu-$(rootbld_qemu_arch)" ] || \
die "rootbld: binfmt registration missing for $(rootbld_qemu_arch) binaries"
local cachedir=/etc/apk/cache
if ! [ $CBUILD_ARCH = "$($APK --print-arch)" ]; then
# cross-building, so check for binfmt registration
local qarch="$(rootbld_qemu_arch)"
if ! [ -f "/proc/sys/fs/binfmt_misc/qemu-$qarch" ]; then
warning "rootbld: binfmt registration missing for $qarch binaries"
fi
# Old versions of apk have cache conflicts
$APK info -eq 'cmd:apk>=2.14.1' || cachedir=""
fi
logcmd "chroot building building $repo/$pkgname-$pkgver-r$pkgrel"
@ -2433,6 +2545,13 @@ rootbld() {
msg "Preparing build chroot..."
# Unfortunately, we can't create the users inside the chroot.
# Hence, we need to do it on the host which is not optimal as it
# pollutes the host's /etc/group and /etc/passwd file.
#
# See https://gitlab.alpinelinux.org/alpine/abuild/-/issues/10094
mkusers
BUILD_ROOT=$(mktemp -d /var/tmp/abuild.XXXXXXXXXX)
mkdir -p "$BUILD_ROOT/proc" "$BUILD_ROOT/etc/apk/keys" \
@ -2455,7 +2574,7 @@ rootbld() {
fi
local version="edge" buildhost="edge" gitref
if gitref="$(expr "$(git symbolic-ref --short HEAD)" : '\([0-9]\+\(\.[0-9]\+\)*\)-')"; then
if gitref="$(expr "$($git symbolic-ref --short HEAD)" : '\([0-9]\+\(\.[0-9]\+\)*\)-')"; then
version=v${gitref}
buildhost=${gitref/./-}
fi
@ -2481,7 +2600,7 @@ rootbld() {
$SUDO_APK add --initdb --update \
--arch $CBUILD_ARCH \
--root "$BUILD_ROOT" \
--cache-dir /etc/apk/cache \
${cachedir:+--cache-dir $cachedir} \
abuild alpine-base build-base git $hostdeps $builddeps \
${USE_CCACHE:+ccache}
@ -2503,8 +2622,13 @@ rootbld() {
--hostname "build-$buildhost-$CARCH" \
--chdir "$startdir" \
--clearenv \
--setenv CARCH "$CARCH" \
--setenv HOME "$HOME" \
--setenv REPODEST "$REPODEST" \
--setenv SRCDEST "$SRCDEST" \
--setenv ABUILD_USERDIR "$ABUILD_USERDIR" \
${ABUILD_BOOTSTRAP:+--setenv ABUILD_BOOTSTRAP "$ABUILD_BOOTSTRAP"} \
${APORTS_BOOTSTRAP:+--setenv APORTS_BOOTSTRAP "$APORTS_BOOTSTRAP"} \
--setenv SOURCE_DATE_EPOCH "$SOURCE_DATE_EPOCH" \
--setenv ABUILD_LAST_COMMIT "$ABUILD_LAST_COMMIT" \
--setenv PATH ${USE_CCACHE:+/usr/lib/ccache/bin:}/bin:/usr/bin:/sbin:/usr/sbin \
@ -2598,7 +2722,7 @@ deplist_has() {
local i
shift
for i in $@; do
i=${i%%[<>=]*}
i=${i%%[<>=~]*}
[ "$needle" = "$i" ] && return 0
[ "$needle" = "!$i" ] && return 1
done
@ -2654,12 +2778,9 @@ uninstalldeps() { undeps; }
index() { update_abuildrepo_index; }
all() {
if ! [ -n "$force" ]; then
if ! check_arch; then
echo "Package not available for the target architecture ($CARCH). Aborting."
return 0
fi
check_libc || return 0
if ! [ -n "$force" ] && ! check_arch; then
echo "Package not available for the target architecture ($CARCH). Aborting."
return 0
fi
if up2date && [ -z "$force" ]; then
msg "Package is up to date"
@ -2722,7 +2843,7 @@ usage() {
-c Enable colored output
-d Disable dependency checking
-D Set APKINDEX description (default: \$repo \$(git describe))
-f Force specified cmd (skip checks: apk up to date, arch, libc)
-f Force specified cmd (skip checks: apk up to date, arch)
-F Force run as root
-h Show this help
-k Keep built packages, even if APKBUILD or sources are newer
@ -2730,7 +2851,7 @@ usage() {
-m Disable colors (monochrome)
-P Set REPODEST as the repository location for created packages
-q Quiet
-r Install missing dependencies from system repository (using sudo)
-r Install missing dependencies from system repository (using \$SUDO_APK)
-s Set source package destination directory
-v Verbose: show every command as it is run (very noisy)
@ -2746,7 +2867,7 @@ usage() {
fetch Fetch sources to \$SRCDEST (consider: 'abuild fetch verify')
index Regenerate indexes in \$REPODEST
listpkg List target packages
package Install project into $pkgdir
package Install project into \$pkgdir
prepare Apply patches
rootbld Build package in clean chroot
rootpkg Run 'package', the split functions and create apks as fakeroot
@ -2767,7 +2888,7 @@ usage() {
}
APKBUILD="${APKBUILD:-./APKBUILD}"
unset force
unset color_opt force forceroot install_deps keep keep_build nodeps quiet verbose
while getopts ":AcdD:fFhkKmnP:qrRs:uvV" opt; do
case $opt in
'A') echo "$CARCH"; exit 0;;
@ -2814,12 +2935,13 @@ APKBUILD=$(readlink -f "$APKBUILD")
startdir="${APKBUILD%/*}"
srcdir=${srcdir:-"$startdir/src"}
pkgbasedir=${pkgbasedir:-"$startdir/pkg"}
tmpdir=${tmpdir:-"$startdir/tmp"}
repo=${startdir%/*}
repo=${repo##*/}
aportsgit=${APORTSDIR:-${startdir}}
repo_template=$aportsgit/$repo/.rootbld-repositories
repo_template=$startdir/../.rootbld-repositories
SRCDEST=${SRCDEST:-$startdir}

53
abump.1.scd Normal file
View File

@ -0,0 +1,53 @@
abump(1)
# NAME
*abump* - bump pkgver in an APKBUILD file
# SYNOPSIS
*abump* [-s _CVE-1_,...] [-f _ISSUE_] [-k|--keep] _PKGNAME-1.2.3_
# DESCRIPTION
*abump* updates the *pkgver* in an APKBUILD file, updates its checksums,
rebuilds it, and finally creates a new commit commit with the changes resulting.
*abump* operates looks for the specified package in nested directories inside
the current working, assuming a layout like that of the aports repository.
# OPTIONS
*-s, --security CVE1,...*
Include CVE in the *secfixes* comment section.
*-f, --fixes ISSUE*
Include *Fixes #ISSUE* in the commit message. This will close the upstream
issue when the commit is merged into the aports master branch.
*-k, --keep*
Keep existing packages.
*-h, --help*
Print help information and exit.
# ENVIRONMENT
APORTSDIR
Force operating on an alternate directory.
# EXAMPLES
```
abump mml-1.0.0
abump glibmm2.68-2.78.0
abump telegram-desktop-4.11.8
```
# SEE ALSO
abuild(1), apkgrel(1), newapkbuild(1), APKBUILD(5), apk(8).
# AUTHORS
Natanael Copa <_ncopa@alpinelinux.org_> and open source contributors.

View File

@ -73,8 +73,8 @@ fixes #${fixes#\#}
fi
msg "$message"
sed -i -e "s/^pkgver=.*/pkgver=$ver/" \
-e "s/^pkgrel=.*/pkgrel=0/" \
sed -i -e "s/^pkgver=[^ ]*/pkgver=$ver/" \
-e "s/^pkgrel=[^ ]*/pkgrel=0/" \
APKBUILD
$ABUILD $abuild_opts checksum all
@ -96,7 +96,7 @@ fixes #${fixes#\#}
usage() {
cat <<-__EOF__
$program $program_version - bump pkgver in APKBUILDs
Usage: $program [-s CVE-1,CVE-2,...] [-f ISSUE] [-R|--recursive] [-k|--keep] PKGNAME-1.2.3 ...
Usage: $program [-s CVE-1,CVE-2,...] [-f ISSUE] [-k|--keep] PKGNAME-1.2.3 ...
Options:
-s, --security CVE1,CVE-2,... Security update
-f, --fixes ISSUE Fixes ISSUE

File diff suppressed because it is too large Load Diff

View File

@ -4,50 +4,52 @@ use strict;
use warnings;
use autodie qw(:all);
use feature qw(:5.14);
use experimental 'switch';
use LWP::UserAgent;
use LWP::ConnCache;
use JSON;
use URI;
use Text::Wrap qw(wrap $columns);
use File::Basename qw(dirname);
our $packager = '';
my %pkgmap = ();
my %licenses = ();
my $template = <<'EOF';
# Automatically generated by apkbuild-pypi, template 3
# Automatically generated by apkbuild-pypi, template 4
[% authors %]
pkgname=[% pkgname %]
#_pkgreal is used by apkbuild-pypi to find modules at PyPI
_pkgreal=[% pkgreal %]
pkgver=[% pkgver %]
pkgrel=[% pkgrel %]
#_pkgreal is used by apkbuild-pypi to find modules at PyPI
_pkgreal=[% pkgreal %]
pkgdesc="[% pkgdesc %]"
provides="[% provides %]"
replaces="[% replaces %]"
url="http://packages.python.org/pypi/[% pkgreal %]"
url="[% url %]"
arch="noarch"
license="[% license %]"
depends="python3"
checkdepends="python3-dev"
makedepends="py3-setuptools"
subpackages=""
depends=""
makedepends="py3-gpep517 py3-setuptools py3-wheel"
checkdepends="py3-pytest"
subpackages="$pkgname-pyc"
source="[% source %]"
builddir="$srcdir/$_pkgreal-$pkgver"
builddir="[% builddir %]"
options="[% options %]"[% options_comment %]
[% compatibility %]
build() {
python3 setup.py build
gpep517 build-wheel \
--wheel-dir .dist \
--output-fd 3 3>&1 >&2
}
check() {
python3 setup.py test
python3 -m venv --clear --without-pip --system-site-packages .testenv
.testenv/bin/python3 -m installer .dist/*.whl
.testenv/bin/python3 -m pytest
}
package() {
PYTHONPATH=$pkgdir`python3 -c "import site; print(site.getsitepackages()[0])"` \
python3 setup.py install \
--prefix=/usr \
--root="$pkgdir" \
--single-version-externally-managed
python3 -m installer -d "$pkgdir" \
.dist/*.whl
}
EOF
@ -73,14 +75,31 @@ sub read_assignments_from_file {
my %mline = $text =~ /^(\w+)\s*=\s*\"([^\"]*)\".*$/mg;
my %hash = ( %sline, %mline );
my $authors = join("\n", $text =~ /^# Contributor: .*$/mg, $text =~ /^# Maintainer: .*$/mg);
return \%hash if $filename ne 'APKBUILD';
my $authors = join( "\n",
$text =~ /^# Contributor: .*$/mg,
$text =~ /^# Maintainer: .*$/mg );
$hash{'authors'} = $authors if length($authors) > 1;
my $provides = $text =~ m/provides=\"(.*)\"".*/mg;
$hash{'provides'} = $1 if length($provides) >= 1;
if ($text =~ m/^provides=\"(.*)\"(.*)$/m) {
$hash{'provides'} = $1;
$hash{'provides_comment'} = $2;
}
my $requires = $text =~ m/^requires=\"(.*)\"".*$/mg;
$hash{'requires'} = $1 if length($requires) >= 1;
if ($text =~ m/^replaces=\"(.*)\"(.*)$/m) {
$hash{'replaces'} = $1;
$hash{'replaces_comment'} = $2;
}
# workaround for `builddir="$srcdir"/$_pkgname-$pkgver`
if ($text =~ m/^builddir=\"(.*)\"([^\s]*)/m) {
$hash{'builddir'} = $1 . $2;
}
if ($text =~ m/^options=\"(.*)\"(.*)$/m) {
$hash{'options'} = $1;
$hash{'options_comment'} = $2;
}
return \%hash;
}
@ -94,6 +113,7 @@ sub map_pypi_to_apk {
sub map_license {
my ($license) = @_;
$license //= '';
$license =~ s/ or / /g;
return $license;
@ -101,48 +121,131 @@ sub map_license {
sub get_source {
my ($distdata) = @_;
my $pkgname = $distdata->{info}{name};
my $source;
for my $url (@{$distdata->{urls}}) {
return $url->{url} if $url->{python_version} eq 'source'
if ($url->{python_version} eq 'source') {
$source = URI->new($url->{url});
last;
}
}
die "Unable to locate sources for $pkgname.\n" unless $source;
my $filename = ($source->path_segments)[-1];
my $pretty_path = substr($pkgname, 0, 1) . "/$pkgname";
my $pretty_url = $source->clone;
$pretty_url->path("/packages/source/$pretty_path/$filename");
my $response = $ua->head($pretty_url);
if ($response->is_success) {
return $pretty_url->as_string;
} else {
return $source->as_string;
}
die "Unable to locate sources for $distdata->{name}.\n";
}
sub read_apkbuild {
return read_assignments_from_file('APKBUILD');
}
sub format_line {
my $line = shift;
return "\t" . $line . "\n";
}
sub format_source {
my $srcurl = shift;
my $orig_src = shift;
$orig_src =~ s/^\s+//mg;
$orig_src =~ s/\s+/ /g;
my @sources = split (/\s/, $orig_src);
return $srcurl if @sources <= 1;
shift @sources if $sources[0] =~ m/pkgver/;
my $patches;
for my $patch (@sources) {
next if $patch eq "";
$patches .= format_line($patch);
}
return $srcurl . "\n" . ($patches // '') . "\t";
}
sub write_apkbuild {
my ($distdata, $apkbuild) = @_;
my $replaces = undef;
my $provides = undef;
my $authors = undef;
my $license = undef;
my $url = undef;
my $pkgname = undef;
my $pkgdesc = undef;
my $pkgrel = 0;
my $builddir = undef;
my $options = undef;
my $options_comment = undef;
my $orig_source = "";
if (our $use_homepage) {
$url =
$distdata->{info}{project_urls}{Homepage}
|| $distdata->{info}{home_page};
}
if (defined $apkbuild) {
$authors = $apkbuild->{authors};
$provides = $apkbuild->{provides};
$replaces = $apkbuild->{replaces};
$license = $apkbuild->{license};
$url = $apkbuild->{url};
$pkgname = $apkbuild->{pkgname};
$pkgdesc = $apkbuild->{pkgdesc};
$pkgrel = $apkbuild->{pkgrel};
$builddir = $apkbuild->{builddir};
$options = $apkbuild->{options} if defined $apkbuild->{options};
$options_comment = $apkbuild->{options_comment} if defined $apkbuild->{options_comment};
$orig_source = $apkbuild->{source};
if ($apkbuild->{pkgver} eq $distdata->{info}{version}) {
$pkgrel++;
}
}
my $pkgreal = $distdata->{info}{name};
my $srcurl = get_source($distdata);
my %repl = (
authors => ($authors or "# Contributor: $packager\n# Maintainer: $packager"),
pkgname => map_pypi_to_apk($distdata->{info}{name}),
pkgreal => $distdata->{info}{name},
pkgname => ($pkgname or map_pypi_to_apk($pkgreal)),
pkgreal => $pkgreal,
pkgver => $distdata->{info}{version},
pkgrel => $pkgrel,
source => get_source($distdata),
license => map_license($distdata->{info}{license}),
pkgdesc => $distdata->{info}{summary},
provides => ($provides or ''),
replaces => ($replaces or ''),
source => format_source($srcurl, $orig_source),
license => ($license or map_license($distdata->{info}{license})),
url => ($url or "https://pypi.org/project/${pkgreal}/"),
pkgdesc => ($pkgdesc or $distdata->{info}{summary} or "Python module for $pkgreal"),
builddir => ($builddir or ''),
options => ($options or ''),
options_comment => ($options_comment or ''),
);
$repl{compatibility} = "";
if ($replaces) {
my $comment = $apkbuild->{'replaces_comment'} // '';
$repl{compatibility} .= "\nreplaces=\"$replaces\"" . $comment;
}
if ($provides) {
my $comment = $apkbuild->{'provides_comment'} // '';
$repl{compatibility} .= "\nprovides=\"$provides\"" . $comment;
}
$repl{compatibility} .= "\n" if $replaces or $provides;
$repl{source} =~ s/-$repl{pkgver}/-\$pkgver/g;
$template =~ s/\[% (.*?) %\]/$repl{$1}/g;
open my $fh, '>:utf8', 'APKBUILD';
@ -154,8 +257,15 @@ sub write_apkbuild {
return \%repl;
}
sub unpack_source {
system('abuild checksum unpack');
}
sub prepare_tree {
system('abuild checksum unpack prepare');
my %options = @_;
unpack_source if $options{unpack};
system('abuild prepare');
}
sub find_package_name {
@ -188,42 +298,172 @@ sub find_package_name {
sub get_data {
my ($package) = @_;
my $response = $ua->get("https://pypi.python.org/pypi/$package/json");
my $response = $ua->get("https://pypi.org/pypi/$package/json");
$response->is_success or die $response->status_line;
my $distdata = $json->decode($response->decoded_content);
return $distdata;
}
sub get_deps {
my ($data) = @_;
sub parse_requires_dist {
my $reqs = shift;
chdir "src/$data->{pkgreal}-$data->{pkgver}";
my $reqs = `python3 ./setup.py --requires`;
# Valid PyPI regex: https://peps.python.org/pep-0508/#names
my $pypi_regex = qr/(?i)([A-Z0-9][A-Z0-9][A-Z0-9._-]*[A-Z0-9])/;
my @reqs = split /\n/, $reqs;
my @depends =
map { m/$pypi_regex/; $1 || () }
grep { $_ !~ m/; extra ==/ }
@$reqs;
foreach my $i (0 .. $#reqs) {
$reqs[$i] =~ s/(\(|\s+).*$//;
$reqs[$i] = map_pypi_to_apk($reqs[$i]);
my @checkdeps =
map { m/$pypi_regex/; $1 || () }
grep { m/; extra == ["'](tests|pytest)["']/ }
@$reqs;
my %reqs = (
depends => \@depends,
checkdeps => \@checkdeps,
);
return \%reqs;
}
sub format_depends {
my $deps = shift;
$columns = 102;
$deps =~ s/ {2,}/ /g;
$deps =~ s/^\s//g;
$deps =~ s/\s$//g;
if ( length($deps) >= $columns ) {
$deps = wrap( "\t", "\t", $deps );
}
$deps =~ s/\s$//g;
chdir '../..';
if ( length($deps) >= $columns ) {
$deps = "\n" . $deps . "\n\t";
}
return $deps;
}
sub get_deps {
my ($distdata, $data) = @_;
my $reqs = parse_requires_dist($distdata->{info}{requires_dist});
my %depends = ('py3-pytest' => 'py3-pytest');
my @depends =
map {
my $apkname = map_pypi_to_apk($_);
if (exists $depends{$apkname}) { () }
else { $depends{$apkname} = $apkname }
}
@{$reqs->{depends}};
my @checkdeps =
map {
my $apkname = map_pypi_to_apk($_);
exists($depends{$apkname}) ? () : $apkname
}
@{$reqs->{checkdeps}};
my $apk = read_file('APKBUILD');
$reqs = join ' ', @reqs;
my $depends = format_depends(join ' ', @depends);
$apk =~ s/pymakedepends=""/pymakedepends="$reqs"/;
$apk =~ s/^depends=""/depends="$depends"/m;
unshift @checkdeps, 'py3-pytest';
my $checkdeps = format_depends(join ' ', @checkdeps);
$apk =~ s/^checkdepends="py3-pytest"/checkdepends="$checkdeps"/m;
# remove empty variables
$apk =~ s/.*=""\n//g;
$apk =~ s/.*="".{0,}\n//g;
open my $fh, '>:utf8', 'APKBUILD';
print $fh $apk;
say "Requires: $reqs";
say "Requires: @depends\n\nCheckDepends: @checkdeps";
}
sub write_old_deps {
my ($data, $apkbuild) = @_;
my $apk = read_file('APKBUILD');
if (my $depends = $apkbuild->{depends}) {
$apk =~ s/^depends=".*"/depends="$depends"/m;
}
if (my $makedeps = $apkbuild->{makedepends}) {
if ($makedeps =~ m/py3-gpep517/) {
$apk =~ s/^makedepends=".*"/makedepends="$makedeps"/m;
} else {
$apk =~ s/^makedepends="(.*)"/makedepends="$1 $makedeps"/m;
}
}
if (my $checkdeps = $apkbuild->{checkdepends}) {
if ($checkdeps =~ m/py3-pytest/) {
$apk =~ s/^checkdepends=".*"/checkdepends="$checkdeps"/m;
} else {
$apk =~ s/^checkdepends="(.*)"/checkdepends="$1 $checkdeps"/m;
}
}
# remove empty variables
$apk =~ s/.*="".{0,}\n//g;
open my $fh, '>:utf8', 'APKBUILD';
print $fh $apk;
}
sub update_builddir {
my $apkbuild = read_apkbuild;
my $pkgreal = $apkbuild->{'_pkgreal'};
my $pkgname = $apkbuild->{pkgname};
my $pkgver = $apkbuild->{pkgver};
my $oldbuilddir = $apkbuild->{builddir};
my $build_path = glob("
src/*${pkgver}/pyproject.toml
src/*${pkgver}/setup.py
");
if ($build_path) {
my $newbuilddir = dirname($build_path);
$newbuilddir =~ s/src/\$srcdir/;
$newbuilddir =~ s/$pkgreal/\$_pkgreal/;
$newbuilddir =~ s/$pkgver/\$pkgver/;
my $apk = read_file('APKBUILD');
if ($pkgname eq $pkgreal and
$newbuilddir eq '$srcdir/$_pkgreal-$pkgver') {
# this will be deleted by the remove empty
# variables regex in get_deps/write_old_deps
$apk =~ s/^builddir=".*"/builddir=""/m;
$newbuilddir = '<same as default, deleted>';
} elsif ($newbuilddir eq $oldbuilddir) {
return;
} else {
$apk =~ s/^builddir=".*"/builddir="$newbuilddir"/m;
}
print "\n\$builddir redefined:\n\t",
"OLD: $oldbuilddir, NEW: $newbuilddir\n\n";
open my $fh, '>:utf8', 'APKBUILD';
print $fh $apk;
}
}
my $abuild_conf = read_assignments_from_file('/etc/abuild.conf');
@ -234,95 +474,104 @@ $packager = $user_abuild_conf->{PACKAGER} if $user_abuild_conf->{PACKAGER};
sub usage {
say <<'EOF';
Usage: apkbuild-pypi [create <package> | check | recreate | upgrade | update]
Usage: apkbuild-pypi [create <package> [homepage] | check | recreate [deps] | upgrade | update]
In the repository root:
create <package>: Creates an APKBUILD for <package>
create <package> homepage: Creates an APKBUILD for <package> with url= field set to project homepage, if available
In the package root:
check : Reports current & latest version of the package
recreate : Recreates the APKBUILD
recreate [deps] : Recreates the APKBUILD [also recalculate dependencies]
upgrade : Upgrades to the latest version of the package
update : Updates APKBUILD metadata
EOF
}
given ($ARGV[0]) {
when ('create') {
my $package = $ARGV[1];
$package or die usage;
if (! defined $ARGV[0]) {
die usage;
} elsif ($ARGV[0] eq 'create') {
my $package = $ARGV[1];
$package or die usage;
my $distdata = get_data($package);
my $apkname = map_pypi_to_apk($package);
my $distdata = get_data($package);
my $apkname = map_pypi_to_apk($package);
mkdir $apkname;
chdir $apkname;
mkdir $apkname;
chdir $apkname;
my $data = write_apkbuild($distdata, undef);
prepare_tree;
if ($ARGV[2] and $ARGV[2] eq 'homepage') { our $use_homepage = 1; }
get_deps($data);
} when ('recreate') {
my $apkbuild = read_apkbuild;
if (! defined $apkbuild->{_pkgreal}) {
$apkbuild->{_pkgreal} = find_package_name($apkbuild);
}
my $distdata = get_data($apkbuild->{_pkgreal});
my $pkgver = $distdata->{info}{version} =~ s/^[^0-9]+//r;
if ($pkgver ne $apkbuild->{pkgver}) {
#Reset pkgrel on upgrade on recreate
say "Upgrading PyPI module from $apkbuild->{pkgver} to $pkgver";
$apkbuild->{pkgrel}=0;
}
my $data = write_apkbuild($distdata, $apkbuild);
my $data = write_apkbuild($distdata, undef);
unpack_source;
update_builddir;
prepare_tree;
get_deps($data);
} when ('upgrade') {
my $apkbuild = read_apkbuild;
if (! defined $apkbuild->{_pkgreal}) {
$apkbuild->{_pkgreal} = find_package_name($apkbuild);
}
my $distdata = get_data($apkbuild->{_pkgreal});
my $pkgver = $distdata->{info}{version};
if ($pkgver ne $apkbuild->{pkgver}) {
say "Upgrading PyPI package from $apkbuild->{pkgver} to $pkgver";
my $text = read_file('APKBUILD');
$text =~ s/^(pkgver)=.*$/$1=$pkgver/mg or
die "Can't find pkgver line in APKBUILD";
$text =~ s/^(pkgrel)=.*$/$1=0/mg or
die "Can't find pkgrel line in APKBUILD";
open my $fh, '>:utf8', 'APKBUILD';
print $fh $text;
close $fh;
} else {
say "Already up to date with PyPI";
}
} when ('check') {
my $apkbuild = read_apkbuild;
if (! defined $apkbuild->{_pkgreal}) {
$apkbuild->{_pkgreal} = find_package_name($apkbuild);
}
my $distdata = get_data($apkbuild->{_pkgreal});
my $pkgver = $distdata->{info}{version};
say "$apkbuild->{pkgname}: Latest version: $pkgver Packaged version: $apkbuild->{pkgver}";
if ($pkgver ne $apkbuild->{pkgver}) {
exit(1);
}
} when ('update') {
prepare_tree;
} default {
die usage;
get_deps($distdata, $data);
prepare_tree( unpack => 0 );
} elsif ($ARGV[0] eq 'recreate') {
my $apkbuild = read_apkbuild;
if (! defined $apkbuild->{_pkgreal}) {
$apkbuild->{_pkgreal} = find_package_name($apkbuild);
}
my $distdata = get_data($apkbuild->{_pkgreal});
my $pkgver = $distdata->{info}{version} =~ s/^[^0-9]+//r;
if ($pkgver ne $apkbuild->{pkgver}) {
#Reset pkgrel on upgrade on recreate
say "Upgrading PyPI module from $apkbuild->{pkgver} to $pkgver";
$apkbuild->{pkgrel}=0;
}
my $data = write_apkbuild($distdata, $apkbuild);
unpack_source;
update_builddir;
if ($ARGV[1] and $ARGV[1] eq 'deps') { get_deps($distdata, $data); }
else { write_old_deps($data, $apkbuild); }
prepare_tree( unpack => 0 );
} elsif ($ARGV[0] eq 'upgrade') {
my $apkbuild = read_apkbuild;
if (! defined $apkbuild->{_pkgreal}) {
$apkbuild->{_pkgreal} = find_package_name($apkbuild);
}
my $distdata = get_data($apkbuild->{_pkgreal});
my $pkgver = $distdata->{info}{version};
if ($pkgver ne $apkbuild->{pkgver}) {
say "Upgrading PyPI package from $apkbuild->{pkgver} to $pkgver";
my $text = read_file('APKBUILD');
$text =~ s/^(pkgver)=.*$/$1=$pkgver/mg or
die "Can't find pkgver line in APKBUILD";
$text =~ s/^(pkgrel)=.*$/$1=0/mg or
die "Can't find pkgrel line in APKBUILD";
open my $fh, '>:utf8', 'APKBUILD';
print $fh $text;
close $fh;
} else {
say "Already up to date with PyPI";
}
} elsif ($ARGV[0] eq 'check') {
my $apkbuild = read_apkbuild;
if (! defined $apkbuild->{_pkgreal}) {
$apkbuild->{_pkgreal} = find_package_name($apkbuild);
}
my $distdata = get_data($apkbuild->{_pkgreal});
my $pkgver = $distdata->{info}{version};
say "$apkbuild->{pkgname}: Latest version: $pkgver Packaged version: $apkbuild->{pkgver}";
if ($pkgver ne $apkbuild->{pkgver}) {
exit(1);
}
} elsif ($ARGV[0] eq 'update') {
prepare_tree( unpack => 1 );
} else {
die usage;
}

View File

@ -17,21 +17,41 @@ fi
usage() {
cat >&2 <<-__EOF__
cat <<-__EOF__
$program $program_version - find ABI breakages in package upgrades
Usage: $program
Usage: $program [-h|--help]
Run in the directory of a built package.
Options:
-h, --help Print this help
__EOF__
}
args=$(getopt -o h --long help \
-n "$program" -- "$@")
if [ $? -ne 0 ]; then
usage >&2
exit 2
fi
eval set -- "$args"
while true; do
case $1 in
-h|--help) usage; exit 0;;
--) shift; break;;
*) exit 1;; # getopt error
esac
shift
done
if [ $# -gt 0 ]; then
usage
usage >&2
exit 2
fi
if ! [ -f "$ABUILD_CONF" ] && ! [ -f "$ABUILD_USERCONF" ]; then
if ! [ -f "$ABUILD_CONF" ] && ! [ -f "$ABUILD_USERCONF" ] && ! [ -f "$ABUILD_DEFCONF" ]; then
die "no abuild.conf found"
fi
@ -47,9 +67,15 @@ fi
startdir="$PWD"
tmpdir=$(mktemp -d -t checkpkg-script.XXXXXX)
trap "rm -rf '$tmpdir'" INT EXIT
trap "rm -rf '$tmpdir'; exit" INT EXIT
cd "$tmpdir" || die "failed to create temp dir"
# storage for downloaded/copied apks
mkdir -p apks
# default to pigz for unpacking
gunzip="$(command -v pigz || echo gzip) -d"
for i in $pkgname $subpackages; do
_pkgname=${i%%:*}
pkg=${_pkgname}-$pkgver-r$pkgrel
@ -65,18 +91,24 @@ for i in $pkgname $subpackages; do
[ -f "$filepath" ] || die "can't find $pkgfile"
# generate a temp repositories file with only the http(s) repos
grep -E "^https?:" /etc/apk/repositories > $tmpdir/repositories
grep -E "^https?:" /etc/apk/repositories > "$tmpdir"/repositories
oldpkg=$(apk fetch --repositories-file $tmpdir/repositories --simulate $_pkgname 2>&1 | sed 's/^Downloading //')
oldpkg=$(apk fetch --repositories-file "$tmpdir"/repositories --simulate $_pkgname 2>&1 | sed 's/^Downloading //')
if [ "${oldpkg}" = "${pkg}" ]; then
die "the built package ($_pkgname) is already in the repo"
fi
# For our local repo (newsize) apk info might return multiple packages, e.g. if different
# version of the package where build previously. Filter out this specific pkgver using awk.
newsize=$(apk info --repositories-file /dev/null --repository "$REPODEST"/$repo --size $_pkgname | \
awk "/^$pkg/ { found = 1 } /^[0-9]+/ { if (found) { print \$0; exit } }")
oldsize=$(apk info --repositories-file $tmpdir/repositories --size $_pkgname | awk '/^[0-9]+/ { print $0 }' | head -1)
# version of the package where built previously. However, for a repo only one of pkgname=pkgver-rpkgrel can exist.
# Filter out this specific pkgver with grep, as it can have only one match, then take the second line:
# 7zip-23.01-r0 installed size:
# 1668 KiB
newsize="$(apk info --repositories-file /dev/null --repository "$REPODEST"/$repo --size $_pkgname | \
grep -F "$pkg" -A1 | \
tail -n1)"
oldsize="$(apk info --repositories-file "$tmpdir"/repositories --size "$_pkgname" | \
grep -F "$_pkgname" -A1 | \
tail -n1)"
if [ "$oldsize" = "$newsize" ]; then
msg "No size differences for $_pkgname."
@ -84,22 +116,42 @@ for i in $pkgname $subpackages; do
msg "Size difference for $_pkgname: $oldsize -> $newsize"
fi
apk fetch --quiet --repositories-file $tmpdir/repositories --stdout $_pkgname \
| tar -zt | grep -v '^\.SIGN\.' | sort > filelist-$_pkgname-old \
|| die "failed to download old pkg, maybe run 'apk update'?"
apk fetch --quiet --repositories-file "$tmpdir"/repositories --stdout "$_pkgname" > apks/old.apk \
|| msg2 "Old apk for $_pkgname missing. (new package/arch? broken internet?)"
tar -ztf "$filepath" | grep -v '^\.SIGN\.' | sort > "filelist-$_pkgname"
# pre-uncompress to not decompress twice
# we do a decompression + tar -t for the file list, but then later we might do a full extraction for sodiff.
# to not decompress here and then later again, store the intermediate tar
$gunzip -c 2>/dev/null < apks/old.apk > apks/old.tar &
$gunzip -c "$filepath" < "$filepath" > apks/new.tar &
wait
tar -t -f apks/old.tar 2>/dev/null | grep -v '^\.SIGN\.' | sort > "filelist-$_pkgname-old" &
tar -t -f apks/new.tar | grep -v '^\.SIGN\.' | sort > "filelist-$_pkgname-new" &
wait
diff -u "filelist-$_pkgname-old" "filelist-$_pkgname"
diff -U3 "filelist-$_pkgname-old" "filelist-$_pkgname-new"
if diff "filelist-$_pkgname-old" "filelist-$_pkgname" | grep '\.so' > /dev/null 2>&1; then
mkdir -p pkg
cd pkg
tar -zxf "$filepath" > /dev/null
diff "../filelist-$_pkgname-old" "../filelist-$_pkgname" | awk '/>.*\.so/{$1 = ""; print $0}' | while read i; do
echo "${i}: " "$(objdump -p "$i" | grep SONAME)"
if diff -U0 "filelist-$_pkgname-old" "filelist-$_pkgname-new" | grep -q '\.so'; then
echo "SODIFF:"
mkdir -p "$_pkgname-pkg-old" "$_pkgname-pkg-new"
tar -C "$_pkgname-pkg-old" 2>/dev/null -x -f apks/old.tar > /dev/null &
tar -C "$_pkgname-pkg-new" -x -f apks/new.tar > /dev/null &
wait
# filter to things that start with -+ but strip the header (---/+++)
diff -U0 "filelist-$_pkgname-old" "filelist-$_pkgname-new" | grep -E '^(\+|-)[A-Za-z0-9]+' | grep '\.so' | while read -r diff_sofile; do
case "$diff_sofile" in
-*) path="$_pkgname-pkg-old"; sofile="${diff_sofile#\-}" ;;
+*) path="$_pkgname-pkg-new"; sofile="${diff_sofile#\+}" ;;
esac
# skip symlinks (only adds duplicate output or is dangling), and things that aren't valid elfs
# matching .so above matches anything with .so in the name, e.g. xyz.sourceforge
if ! [ -L "$path"/"$sofile" ] && readelf -h "$path"/"$sofile" >/dev/null 2>&1; then
echo "$diff_sofile: " "$(objdump -p "$path"/"$sofile" | grep SONAME)"
fi
done
cd ..
else
msg "No soname differences for $_pkgname."
fi

View File

@ -1,6 +1,6 @@
export CFLAGS="-Os -fomit-frame-pointer -Wformat -Werror=format-security -Werror=int-conversion"
export CXXFLAGS="-Os -fomit-frame-pointer -Wformat -Werror=format-security"
export CPPFLAGS="-Os -fomit-frame-pointer -Wformat -Werror=format-security"
export CFLAGS="-Os -fstack-clash-protection -Wformat -Werror=format-security"
export CXXFLAGS="-Os -fstack-clash-protection -Wformat -Werror=format-security"
export CXXFLAGS="$CXXFLAGS -D_GLIBCXX_ASSERTIONS=1 -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS=1 -D_LIBCPP_ENABLE_HARDENED_MODE=1"
export LDFLAGS="-Wl,--as-needed,-O1,--sort-common"
export GOFLAGS="-buildmode=pie -modcacherw -trimpath -buildvcs=false"
# Do note that these should work with at least GDC and LDC
@ -18,15 +18,8 @@ export CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1
export CARGO_PROFILE_RELEASE_LTO="true"
export CARGO_REGISTRIES_CRATES_IO_PROTOCOL="sparse"
# remove line below to disable colors
USE_COLORS=1
# uncomment line below to enable ccache support.
#USE_CCACHE=1
SRCDEST=/var/cache/distfiles
# uncomment line below to store built packages in other location
# The package will be stored as $REPODEST/$repo/$pkgname-$pkgver-r$pkgrel.apk
# where $repo is the name of the parent directory of $startdir.
REPODEST=$HOME/packages/
@ -41,3 +34,6 @@ CLEANUP="srcdir bldroot pkgdir deps"
# what to cleanup after a failed build
ERROR_CLEANUP="bldroot deps"
# uncomment to prevent using global cache directories for Go and Cargo
#MOVE_CACHES=1

View File

@ -1,6 +1,7 @@
# /usr/share/abuild/functions.sh
sysconfdir=@sysconfdir@
sharedir=@sharedir@
program=${0##*/}
arch_to_hostspec() {
@ -77,7 +78,7 @@ readconfig() {
[ -n "${SRCDEST+x}" ] && _SRCDEST=$SRCDEST
[ -n "${CC+x}" ] && _CC=$CC
[ -n "${CXX+x}" ] && _CXX=$CXX
[ -n "${LD+x}" ] && _LD=$LD
[ -n "${LD+x}" ] && _LD=$LD
[ -n "${CARCH+x}" ] && _CARCH=$CARCH
[ -n "${CHOST+x}" ] && _CHOST=$CHOST
[ -n "${CTARGET+x}" ] && _CTARGET=$CTARGET
@ -96,10 +97,12 @@ readconfig() {
[ -n "${PACKAGER+x}" ] && _PACKAGER=$PACKAGER
[ -n "${USE_COLORS+x}" ] && _USE_COLORS="$USE_COLORS"
[ -n "${USE_CCACHE+x}" ] && _USE_CCACHE="$USE_CCACHE"
: ${ABUILD_DEFCONF:=${ABUILD_SHAREDIR:-$sharedir}/default.conf}
[ -f "$ABUILD_DEFCONF" ] && . "$ABUILD_DEFCONF"
: ${ABUILD_CONF:=$sysconfdir/abuild.conf}
[ -f "$ABUILD_CONF" ] && . "$ABUILD_CONF"
: ${ABUILD_USERDIR:=$HOME/.abuild}
: ${ABUILD_USERCONF:=$ABUILD_USERDIR/abuild.conf}
[ -f "$ABUILD_CONF" ] && . "$ABUILD_CONF"
[ -f "$ABUILD_USERCONF" ] && . "$ABUILD_USERCONF"
APORTSDIR=${_APORTSDIR-$APORTSDIR}

View File

@ -2,12 +2,12 @@ newapkbuild(1)
# NAME
*newapkbuild* - generate a new APKBUILD
*newapkbuild* - generate a new APKBUILD
# SYNOPSIS
*newapkbuild* _options_... [_pkgname_[-_pkgver_] | _source_url_]
*newapkbuild* _options_... [_pkgname_[-_pkgver_] | _source_url_]
# DESCRIPTION
@ -43,6 +43,11 @@ the generated APKBUILD file will not contain any build instructions.
*-d* _DESC_
Specifies the description (pkgdesc=) for the new package.
*-e*
Specifies that the package uses a Python PEP517 build
system. Python's gpep517, setuptools and wheel will be added
to the makedepends.
*-f*
Forces *newapkbuild* to overwrite an existing APKBUILD, if one
already exists in the package directory.

View File

@ -32,7 +32,7 @@ is_github_url() {
prepare_rust() {
cat >>APKBUILD<<__EOF__
cargo fetch --locked
cargo fetch --target="\$CTARGET" --locked
__EOF__
}
@ -65,14 +65,14 @@ build_cmake() {
cat >>APKBUILD<<__EOF__
if [ "\$CBUILD" != "\$CHOST" ]; then
CMAKE_CROSSOPTS="-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_HOST_SYSTEM_NAME=Linux"
local crossopts="-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_HOST_SYSTEM_NAME=Linux"
fi
cmake -B build \\
cmake -B build -G Ninja \\
-DCMAKE_INSTALL_PREFIX=/usr \\
-DCMAKE_INSTALL_LIBDIR=lib \\
-DBUILD_SHARED_LIBS=True \\
-DBUILD_SHARED_LIBS=ON \\
-DCMAKE_BUILD_TYPE=None \\
\$CMAKE_CROSSOPTS .
\$crossopts
cmake --build build
__EOF__
}
@ -81,12 +81,11 @@ build_meson() {
# References:
# http://mesonbuild.com/Reference-manual.html
# http://mesonbuild.com/Cross-compilation.html
# TODO For cross compilation a cross_file needs to be created.
cat >>APKBUILD<<__EOF__
abuild-meson \\
. output
meson compile \${JOBS:+-j \${JOBS}} -C output
meson compile -C output
__EOF__
}
@ -103,9 +102,17 @@ build_python() {
__EOF__
}
build_python_gpep517() {
cat >>APKBUILD<<__EOF__
gpep517 build-wheel \\
--wheel-dir .dist \\
--output-fd 3 3>&1 >&2
__EOF__
}
build_rust() {
cat >>APKBUILD<<__EOF__
cargo build --frozen --release
cargo auditable build --frozen --release
__EOF__
}
@ -125,8 +132,7 @@ __EOF__
check_cmake() {
cat >>APKBUILD<<__EOF__
cd build
CTEST_OUTPUT_ON_FAILURE=TRUE ctest
ctest --test-dir build --output-on-failure
__EOF__
}
@ -136,6 +142,14 @@ check_python() {
__EOF__
}
check_python_gpep517() {
cat >>APKBUILD<<__EOF__
python3 -m venv --clear --without-pip --system-site-packages .testenv
.testenv/bin/python3 -m installer .dist/*.whl
.testenv/bin/python3 -m pytest
__EOF__
}
check_empty() {
cat >>APKBUILD<<__EOF__
# Replace with proper check command(s)
@ -191,6 +205,13 @@ package_python() {
__EOF__
}
package_python_gpep517() {
cat >>APKBUILD<<__EOF__
python3 -m installer -d "\$pkgdir" \\
.dist/*.whl
__EOF__
}
package_empty() {
cat >>APKBUILD<<__EOF__
# Replace with proper package command(s)
@ -209,7 +230,7 @@ __EOF__
newaport() {
local newname="${1##*/}"
local pn=${newname%[-_][0-9]*}
local pv
local prearchive postarchive pv
local source=
is_url "$1" && source="$1"
@ -220,6 +241,10 @@ newaport() {
fi
pv=${newname%.t*} #strip .tar.gz .tgz .tar.bz2 etc
pv=${pv#*[a-z]}
prearchive=${source%/archive/*}
postarchive=${source#*/archive/}
postarchive=${postarchive#refs/tags/}
source="${prearchive}/archive/${postarchive}"
source="${source%.t*}/$pkgname-$pv.tar.gz"
elif [ "$pn" != "$newname" ]; then
pv=${newname#$pn[-_]}
@ -239,23 +264,20 @@ newaport() {
source="https://downloads.sourceforge.net/$pn/$pn-$pv.tar.gz"
fi
if [ -z "$depends" ] && [ "$buildtype" = "python" ]; then
depends="python3"
fi
if [ -z "$depends" ] && [ "$buildtype" = "perl" ]; then
depends="perl"
fi
if [ -z "$checkdepends" ] && [ "$buildtype" = "python" ]; then
if [ -z "$checkdepends" ] && [ "$buildtype" = "python"* ]; then
checkdepends="py3-pytest"
fi
case "$buildtype" in
python) makedepends="py3-setuptools";;
cmake) makedepends="cmake";;
python_gpep517) makedepends="py3-gpep517 py3-setuptools py3-wheel";;
cmake) makedepends="cmake samurai";;
meson) makedepends="meson";;
rust) makedepends="cargo";;
rust) makedepends="cargo cargo-auditable";;
*) makedepends="\$depends_dev";;
esac
@ -329,6 +351,8 @@ __EOF__
buildtype="make"
elif [ -r "$sdir"/setup.py ] || [ "${pn#py[0-9]-}" != "$pn" ]; then
buildtype="python"
elif [ -r "$sdir"/pyproject.toml ] || [ "${pn#py[0-9]-}" != "$pn" ]; then
buildtype="python_gpep517"
elif [ -r "$sdir"/Cargo.toml ]; then
buildtype="rust"
fi
@ -367,6 +391,8 @@ __EOF__
build_perl;;
python)
build_python;;
python_gpep517)
build_python_gpep517;;
rust)
build_rust;;
*)
@ -392,6 +418,8 @@ __EOF__
check_meson;;
python)
check_python;;
python_gpep517)
check_python_gpep517;;
rust)
check_rust;;
*)
@ -421,6 +449,8 @@ __EOF__
package_perl;;
python)
package_python;;
python_gpep517)
package_python_gpep517;;
rust)
package_rust;;
*)
@ -461,7 +491,8 @@ usage() {
-C Create CMake package (Assume cmake/ is there)
-m Create meson package (Assume meson.build is there)
-p Create perl package (Assume Makefile.PL is there)
-y Create python package (Assume setup.py is there)
-y Create python setuptools package (Assume setup.py is there)
-e Create python gpep517 package (Assume pyproject.toml is there)
-r Create rust package (Assume Cargo.toml is there)
-s Use sourceforge source URL
-c Copy a sample init.d, conf.d, and install script
@ -498,7 +529,7 @@ check_arguments() {
fi
}
while getopts "acCmd:fhl:n:pyu:sr" opt; do
while getopts "acCmd:fhl:n:pyeu:sr" opt; do
case $opt in
'a') set_buildtype "autotools";;
'c') cpinitd=1;;
@ -511,6 +542,7 @@ while getopts "acCmd:fhl:n:pyu:sr" opt; do
'n') pkgname="$OPTARG";;
'p') set_buildtype "perl";;
'y') set_buildtype "python";;
'e') set_buildtype "python_gpep517";;
'r') set_buildtype "rust";;
'u') url="$OPTARG";;
's') sourceforge=1;;

View File

@ -1,7 +1,10 @@
# Sample conf.d file for alpine linux
# Configuration for /etc/init.d/<SERVICE>
#
# Specify daemon options here.
#
# User (and group) to run <SERVICE> as.
#command_user="<USER>"
sample_opts=""
# Additional arguments for <SERVICE> daemon.
#command_args=
# Comment out to disable process supervisor.
supervisor=supervise-daemon

View File

@ -1,14 +1,14 @@
#!/sbin/openrc-run
# Sample init.d file for alpine linux.
name="SampleService"
description="Sample init.d file for Alpine Linux"
name=
command="/usr/sbin/$name"
command_args="$sample_opts"
: ${command_user:="<USER>"}
command="/usr/sbin/<SERVICE>"
command_args="$command_args"
command_background="yes"
start_stop_daemon_args="--user $sample_user:$sample_group"
pidfile="/run/$name.pid"
pidfile="/run/$RC_SVCNAME.pid"
depend() {
need net

View File

@ -141,7 +141,7 @@ abuild_fetch_locking_body() {
pid1=\$!
# give enough time for abuild-fetch to call curl
sleep 0.2
sleep 0.5
# the first stamp should not exist, second instance should block the retry
if [ -e stamp3 ]; then

View File

@ -11,7 +11,8 @@ init_tests \
abuild_keygen_install_without_sudo \
abuild_keygen_install_interactive \
abuild_keygen_install_non_interactive \
abuild_keygen_install_doas
abuild_keygen_install_doas \
abuild_keygen_kernel \
export ABUILD_SHAREDIR="$SRCDIR"/..
export GIT=false
@ -103,3 +104,14 @@ abuild_keygen_install_doas_body() {
abuild-keygen --install -n
}
abuild_keygen_kernel_body() {
atf_check -s exit:0 \
-e match:"(Generating|writing) RSA" \
-e match:"signing key was created:.*kernel_signing_key.pem" \
-e match:"KERNEL_SIGNING_KEY=.*was added to.*abuild.conf" \
abuild-keygen --kernel
grep '^KERNEL_SIGNING_KEY=.*' "$HOME"/.abuild/abuild.conf \
|| atf_fail 'KERNEL_SIGNING_KEY not set in abuild.conf'
test -f "$HOME"/.abuild/kernel_signing_key.pem \
|| atf_fail '$HOME/.abuild/kernel_signing_key.pem was not created'
}

View File

@ -16,16 +16,24 @@ init_tests \
abuild_checksum_duplicates \
abuild_subpkg_dep_leak \
abuild_py_providers_creation \
abuild_py_dependency_scan \
abuild_py_dependency_scan_conflict \
abuild_reject_init_with_improper_shebang \
abuild_valid_pkgnames \
abuild_invalid_pkgnames \
abuild_invalid_subpkgnames \
abuild_invalid_subpkg_version \
abuild_warn_pkgver_patch_version \
abuild_provide_pkgname \
abuild_subpackage_arch \
abuild_large_doc_subpackage \
abuild_bigdocs \
abuild_pkgver_digit_letter_digit \
abuild_multiline_license \
abuild_license_spdx \
abuild_git_ceiling \
abuild_package_size_zero \
abuild_package_size_nonzero \
abuild_keepdirs \
abuild_amove \
abuild_doc \
abuild_dev \
@ -33,7 +41,16 @@ init_tests \
abuild_devhelp \
abuild_check_maintainer \
abuild_cleanoldpkg \
abuild_path_with_spaces
abuild_path_with_spaces \
abuild_pyc_warn \
abuild_pyc \
abuild_setcap_binary \
abuild_setcap_binary_with_option \
abuild_command_provides \
abuild_gocache_dir \
abuild_cargo_home_dir \
abuild_fish_comp_split \
abuild_deps
export ABUILD_SHAREDIR=$(atf_get_srcdir)/..
export ABUILD_CONF=/dev/null
@ -331,13 +348,32 @@ abuild_subpkg_dep_leak_body() {
abuild_py_providers_creation_body() {
init_keys
cp -ra "$testrepo" .
cd testrepo/py3-foo-and-bar
cd testrepo/py3\ foo\ and\ bar
abuild rootpkg || atf_fail "abuild failed"
atf_check -s exit:0 \
-o match:"provides = py3.9:foo=1.0.0-r0" \
cat pkg/.control.py3-foo-and-bar/.PKGINFO
}
abuild_py_dependency_scan_body() {
init_keys
cp -ra "$testrepo" .
cd testrepo/py3\ foo\ and\ bar
abuild rootpkg || atf_fail "abuild failed"
atf_check -s exit:0 \
-o match:"depend = python3~3.9" \
cat pkg/.control.py3-foo-and-bar/.PKGINFO
}
abuild_py_dependency_scan_conflict_body() {
init_keys
cp -ra "$testrepo" .
cd testrepo/py3-conflicting-python-versions
atf_check -s exit:1 \
-e match:"ERROR.*package contains python3 modules for conflicting python3 versions" \
abuild rootpkg
}
abuild_reject_init_with_improper_shebang_body() {
mkdir invalid-initd
cd invalid-initd
@ -380,6 +416,9 @@ abuild_valid_pkgnames_body() {
TESTSUBNAME=foo atf_check -s exit:0 \
-e match:"Checking sanity" \
abuild sanitycheck
TESTNAME="more_+-2.0-complicated" atf_check -s exit:0 \
-e match:"Checking sanity" \
abuild sanitycheck
}
abuild_invalid_pkgnames_body() {
@ -395,6 +434,12 @@ abuild_invalid_pkgnames_body() {
TESTNAME="foo with spaces" atf_check -s exit:1 \
-e match:"Checking sanity" \
abuild sanitycheck
TESTNAME="width@at" atf_check -s exit:1 \
-e match:"Checking sanity" \
abuild sanitycheck
TESTNAME="width=equal" atf_check -s exit:1 \
-e match:"Checking sanity" \
abuild sanitycheck
}
abuild_invalid_subpkgnames_body() {
@ -418,14 +463,65 @@ abuild_invalid_subpkg_version_body() {
abuild all
}
abuild_warn_pkgver_patch_version_body() {
abuild_provide_pkgname_body() {
init_keys
cp -ra "$testrepo"/test-pkgname .
cd test-pkgname
TESTPKGVER=1.0_p1 atf_check -s exit:0 \
-e not-match:'WARNING' \
TESTNAME=provided atf_check -s exit:1 \
-e match:"provides must not contain" \
abuild sanitycheck
TESTPKGVER=1.0p1 atf_check -s exit:0 \
-e match:'WARNING.*1.0_p1' \
TESTNAME=test TESTPROVIDES='test~1' atf_check -s exit:1 \
-e match:"provides must not contain" \
abuild sanitycheck
TESTNAME=test TESTPROVIDES='test=1' atf_check -s exit:1 \
-e match:"provides must not contain" \
abuild sanitycheck
TESTNAME=test TESTPROVIDES='test>1' atf_check -s exit:1 \
-e match:"provides must not contain" \
abuild sanitycheck
TESTNAME=test TESTPROVIDES='test<=1' atf_check -s exit:1 \
-e match:"provides must not contain" \
abuild sanitycheck
}
abuild_subpackage_arch_body() {
init_keys
cp -ra "$testrepo" .
cd testrepo/subpackage-arch
arch="$(abuild -A)"
for i in noarch all "$arch"; do
TESTSUBARCH="$i" abuild all
[ -f "$REPODEST/testrepo/$arch/test-pkgname-$i-1.0-r0.apk" ] || \
atf_fail "Failed to place $i arch subpackage correctly"
rm -rf "$REPODEST/testrepo"
done
}
abuild_large_doc_subpackage_body() {
init_keys
cp -ra "$testrepo"/large-doc-subpkg .
cd large-doc-subpkg
atf_check -s exit:0 \
-e match:"-doc subpackage is unusually large" \
abuild all
}
abuild_bigdocs_body() {
init_keys
cp -ra "$testrepo"/large-doc-subpkg .
cd large-doc-subpkg
options=bigdocs atf_check -s exit:0 \
-e not-match:"-doc subpackage is unusually large" \
abuild all
}
abuild_pkgver_digit_letter_digit_body() {
cp -ra "$testrepo"/test-pkgname .
cd test-pkgname
TESTPKGVER=1.0p1 atf_check -s exit:1 \
-e match:'ERROR.*version' \
abuild sanitycheck
}
@ -433,10 +529,18 @@ abuild_multiline_license_body() {
cp -ra "$testrepo"/test-licenses .
cd test-licenses
abuild rootpkg
atf_check -o match:'^license = MIT AND GPL-3.0-only OR GPL-3.0-or-later AND BSD-Clause-4$' \
atf_check -o match:'^license = MIT AND \(GPL-3.0-only OR GPL-3.0-or-later AND BSD-Clause-4\)$' \
cat pkg/.control.test-licenses/.PKGINFO
}
abuild_license_spdx_body() {
cp -ra "$testrepo"/test-licenses .
cd test-licenses
TESTPKGVER=1.0_p1 atf_check -s exit:0 \
-e not-match:'WARNING' \
abuild sanitycheck
}
abuild_git_ceiling_body() {
init_keys
git init
@ -467,7 +571,6 @@ abuild_git_ceiling_body() {
abuild
}
create_fake_du() {
mkdir -p bin
cat > bin/du <<-EOF
@ -539,6 +642,32 @@ abuild_package_size_nonzero_body() {
cat pkg/.control.test-size/.PKGINFO
}
abuild_keepdirs_body() {
init_keys
mkdir -p test-amove
cd test-amove
cat > APKBUILD <<-EOF
# Maintainer: Test User 123 <123@example.com>
# test package
pkgname="test-keepdirs"
pkgver="1.0"
pkgrel=0
pkgdesc='Dummy test package - keepdirs'
url='https://gitlab.alpinelinux.org/alpine/aports'
arch='noarch'
license='MIT'
options='keepdirs'
package() {
mkdir -p "\$pkgdir"/usr/bin
}
EOF
abuild rootpkg || atf_fail "abuild rootpkg failed"
test -d pkg/test-keepdirs/usr/bin || atf_fail "$i failed"
}
abuild_amove_body() {
init_keys
mkdir -p test-amove
@ -560,7 +689,8 @@ abuild_amove_body() {
\$pkgname-bin:_bin
\$pkgname-sbin:_sbin
\$pkgname-var:_var
\$pkgname-usr:_usr"
\$pkgname-usr:_usr
\$pkgname-space:_space"
package() {
mkdir -p "\$pkgdir"/etc \
@ -572,6 +702,7 @@ abuild_amove_body() {
"\$pkgdir"/etc/\$pkgname.conf \
"\$pkgdir"/bin/hello \
"\$pkgdir"/sbin/shello \
"\$pkgdir"/sbin/space' ' \
"\$pkgdir"/var/lib/\$pkgname/testfile \
"\$pkgdir"/usr/share/a \
"\$pkgdir"/usr/share/b
@ -599,6 +730,10 @@ abuild_amove_body() {
# glob *
amove usr/share/*
}
_space() {
# with space
amove sbin/space' '
}
EOF
abuild rootpkg || atf_fail "abuild rootpkg failed"
@ -610,8 +745,9 @@ abuild_amove_body() {
test-amove-var/var/lib/test-amove/testfile \
test-amove-usr/usr/share/a \
test-amove-usr/usr/share/b \
test-amove-space/sbin/space' ' \
; do \
test -f pkg/$i || atf_fail "$i failed"
test -f pkg/"$i" || atf_fail "$i failed"
done
}
@ -782,7 +918,7 @@ abuild_cleanoldpkg_body() {
mkdir -p "\$pkgdir"
}
EOF
CARCH=$arch atf_check -e not-empty abuild
CARCH=$arch atf_check -e not-empty abuild clean unpack rootpkg
done
done
@ -824,3 +960,286 @@ abuild_path_with_spaces_body() {
-e match:"Build complete" \
abuild
}
abuild_pyc_warn_body() {
init_keys
mkdir -p pycachetest
cd pycachetest
cat >APKBUILD <<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="pycachetest"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
source=""
package() {
mkdir -p "\$pkgdir"/usr/lib/python3.11/site-packages/test/__pycache__/
touch "\$pkgdir"/usr/lib/python3.11/site-packages/test/__pycache__/main.cpython-311.pyc
}
EOF
atf_check -e match:"WARNING.*pyc*" abuild rootpkg
}
abuild_pyc_body() {
init_keys
mkdir -p foo
cd foo
cat >APKBUILD <<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="foo"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
source=""
subpackages="\$pkgname-pyc"
package() {
mkdir -p "\$pkgdir"/usr/lib/python3.11/site-packages/test/__pycache__/
touch "\$pkgdir"/usr/lib/python3.11/site-packages/test/__pycache__/main.cpython-311.pyc
}
EOF
atf_check -o match:"->" -e not-match:"WARNING.*pyc*" abuild rootpkg
atf_check -o match:"__pycache__" find pkg/foo-pyc -name '__pycache__'
# verify install_if is correct
atf_check -o match:"foo=1.0-r0" -o match:"pyc" \
grep install_if pkg/.control.foo-pyc/.PKGINFO
}
abuild_setcap_binary_body() {
init_keys
cp -ra "$testrepo"/setcap .
cd setcap
atf_check -s exit:1 \
-e match:"Found binary with extra capabilities" \
-e match:"Found setcap binary executable by others" \
abuild all
}
abuild_setcap_binary_with_option_body() {
init_keys
cp -ra "$testrepo"/setcap .
cd setcap
options=setcap atf_check -s exit:0 \
-e not-match:"Found binary with extra capabilities" \
-e match:"Found setcap binary executable by others" \
abuild all
}
abuild_command_provides_body() {
init_keys
mkdir testprovides
cd testprovides
cat >APKBUILD<<-EOF
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=testprovides
pkgver=1.0
pkgrel=0
pkgdesc="Dummy test package that installs a file and directory in path"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
prepare() { mkdir -p "\$builddir"; }
build() { true; }
check() { true; }
package() {
mkdir -p "\$pkgdir/usr/bin"
printf "%s\n" '#!/bin/sh' >"\$pkgdir/usr/bin/foo"
chmod +x "\$pkgdir/usr/bin/foo"
cp -a "\$pkgdir/usr/bin/foo" "\$pkgdir/usr/bin/foo@"
mkdir -p "\$pkgdir/usr/bin/dir/"
}
EOF
abuild rootpkg
atf_check \
-o match:"provides = cmd:foo=1.0-r0" \
-o not-match:"provides = cmd:foo@=1.0-r0" \
-o not-match:"provides = cmd:dir=1.0-r0" \
grep '^provides = ' pkg/.control.testprovides/.PKGINFO
}
abuild_gocache_dir_body() {
init_keys
mkdir gocache-dir
cd gocache-dir
cat >APKBUILD<<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="gocache-dir"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
prepare() {
mkdir -p "\$builddir"
}
build() {
echo "dir:\$GOCACHE"
}
package() {
:
}
EOF
unset GOCACHE
MOVE_CACHES=1 \
atf_check -s exit:0 \
-o match:"dir:.*/tmp/go" \
abuild prepare build
}
abuild_cargo_home_dir_body() {
init_keys
mkdir cargo-home-dir
cd cargo-home-dir
cat >APKBUILD<<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="cargo-home-dir"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
prepare() {
mkdir -p "\$builddir"
}
build() {
echo "dir:\$CARGO_HOME"
}
package() {
:
}
EOF
unset CARGO_HOME
MOVE_CACHES=1 \
atf_check -s exit:0 \
-o match:"dir:.*/tmp/cargo" \
abuild prepare build
}
abuild_fish_comp_split_body() {
init_keys
mkdir fish-split-dir
cd fish-split-dir
cat >APKBUILD<<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="fish-split-dir"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
prepare() {
mkdir -p "\$builddir"
}
package() {
mkdir -p "\$pkgdir"/usr/share/fish/completions/
mkdir -p "\$pkgdir"/usr/share/fish/vendor_completions.d/
echo "comp" > "\$pkgdir"/usr/share/fish/completions/comp.fish
echo "comp" > "\$pkgdir"/usr/share/fish/vendor_completions.d/comp.fish
}
EOF
# test that there is a warning for the legacy dir existing
atf_check -s exit:0 \
-e match:"fish completions for programs should be located in /usr/share/fish/vendor_completions.d" \
abuild prepare build rootpkg
# now add the correct subpackage
echo 'subpackages="$pkgname-fish-completion"' >> APKBUILD
abuild clean prepare build rootpkg
if ! [ -d pkg/fish-split-dir-fish-completion/usr/share/fish/completions ]; then
echo "missing old dir"
exit 1
fi
if ! [ -d pkg/fish-split-dir-fish-completion/usr/share/fish/vendor_completions.d ]; then
echo "missing new dir"
exit 1
fi
}
create_mock_apk() {
mkdir -p bin
cat > bin/apk <<-EOF
#!/bin/sh
if [ "\$1" = "--print-arch" ]; then
echo 'aarch64'
exit 0
fi
echo apk "\$@" >&2
EOF
chmod +x bin/apk
ln -s apk bin/abuild-apk
PATH="$PWD/bin:$PATH"
}
abuild_deps_body() {
create_mock_apk
mkdir testdeps
cd testdeps
cat >APKBUILD <<-EOF
# Maintainer: Joe User <juser@example.com>
pkgname="testdeps"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
depends="foo"
makedepends="bar"
checkdepends="checkdep"
makedepends_host="hostdep"
makedepends_build="builddep"
EOF
# native build. pull in both depends and makedepends
# do not install in any --root
atf_check \
-e match:'Installing for build: foo bar checkdep$' \
-e match:'apk add .*--virtual .makedepends-testdeps foo bar checkdep' \
-e not-match:'apk add .*--root' \
abuild deps
# dont install checkdep with ABUILD_BOOTSTRAP
ABUILD_BOOTSTRAP=1 atf_check \
-e not-match:"apk add.*checkdep" \
abuild deps
# crosscompile:
# install makedepends_build without --root
# install makedepends_host with --root
CTARGET='s390x' CHOST='ppc64le' CBUILDROOT="$PWD/root" atf_check \
-e match:'Installing for build: builddep' \
-e match:'Installing for host: hostdep' \
-e match:'apk add .*--virtual .makedepends-testdeps builddep' \
-e not-match:'apk add.*--root.*builddep' \
-e match:'apk add .*--root.*hostdep' \
-e match:'apk add .*--arch s390x.*hostdep' \
-e not-match:'apk add.*checkdep' \
abuild deps
# crosscompile, set only CHOST
CHOST='armhf' atf_check \
-e match:'apk add.*builddep' \
-e not-match:'apk add.*--root.*builddep' \
-e match:'apk add.*--root.*--arch armhf.*hostdep' \
-e not-match:'apk add.*--arch armhf.*builddep' \
abuild deps
}

View File

@ -3,9 +3,13 @@
# fake openssl
while [ $# -gt 0 ]; do
case "$1" in
genrsa|rsa)
genrsa|rsa|req)
cmd="$1"
;;
-config)
shift
config="$1"
;;
-out)
shift
outfile="$1"
@ -25,5 +29,16 @@ case "$cmd" in
echo "writing RSA key" >&2
cat "$FAKEKEYPUB" > "$outfile"
;;
req)
echo "Using configuration from $config" >&2
echo "Generating RSA key with 4096 bits" >&2
echo "Writing private key to '$outfile'" >&2
cat "$FAKEKEY" "$FAKEKEYPUB" > "$outfile"
;;
*)
echo "unimplemented fake openssl command: $cmd" >&2
exit 1
;;
esac

40
tests/checkapk_test Executable file
View File

@ -0,0 +1,40 @@
#!/usr/bin/env atf-sh
. $(atf_get_srcdir)/test_env.sh
init_tests \
checkapk_help \
checkapk_invalid_opt \
checkapk_missing_abuild_conf \
checkapk_missing_apkbuild
DATADIR=$(atf_get_srcdir)/testdata
export ABUILD_SHAREDIR=$(atf_get_srcdir)/..
export ABUILD_CONF=/dev/null
export ABUILD_USERCONF=/dev/null
checkapk_help_body() {
atf_check -s exit:0 \
-o match:"Usage:" \
checkapk --help
}
checkapk_invalid_opt_body() {
atf_check -s not-exit:0 \
-e match:"Usage:" \
checkapk --invalid
}
checkapk_missing_abuild_conf_body() {
ABUILD_DEFCONF=/dev/null atf_check \
-s not-exit:0 \
-e match:"no abuild.conf found" \
checkapk
}
checkapk_missing_apkbuild_body() {
atf_check \
-s not-exit:0 \
-e match:"must be run in the directory of a built package" \
checkapk
}

View File

@ -6,7 +6,8 @@ init_tests \
funcs_check_missing_gcc \
funcs_check_missing_apk \
funcs_check_missing_git \
funcs_check_env_set_but_empty
funcs_check_env_set_but_empty \
funcs_check_defconfig
FUNCS=$(atf_get_srcdir)/../functions.sh
@ -53,3 +54,34 @@ funcs_check_env_set_but_empty_body() {
done
done
}
funcs_check_defconfig_body() {
echo "CFLAGS=defcflags" > def.conf
echo "CFLAGS=syscflags" > etc.conf
echo "CFLAGS=usercflags" > user.conf
unset CFLAGS
# test /usr/share/abuild/default.conf
ABUILD_DEFCONF="$PWD"/def.conf ABUILD_CONF=/dev/null ABUILD_USERCONF=/dev/null \
atf_check -o match:"defcflags" \
sh -e -c " . $FUNCS; echo \"\$CFLAGS\""
# test /etc/abuild.conf
ABUILD_DEFCONF=/dev/null ABUILD_CONF="$PWD"/etc.conf ABUILD_USERCONF=/dev/null \
atf_check \
-o match:"syscflags" \
sh -e -c " . $FUNCS; echo \"\$CFLAGS\""
# user config ($HOME/.abuild/abuild.conf) wins over /etc/abuild.conf
ABUILD_DEFCONF="$PWD"/def.conf ABUILD_CONF="$PWD/etc.conf" ABUILD_USERCONF="$PWD/user.conf" \
atf_check \
-o match:"usercflags" \
sh -e -c " . $FUNCS; echo \"\$CFLAGS\""
# environment wins
ABUILD_DEFCONF="$PWD"/def.conf ABUILD_CONF="$PWD/etc.conf" ABUILD_USERCONF="$PWD/user.conf" \
CFLAGS="envcflags" atf_check \
-o match:"envcflags" \
sh -e -c " . $FUNCS; echo \"\$CFLAGS\""
}

View File

@ -0,0 +1,35 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
# test package
pkgname="large-doc-subpkg"
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package to check if large doc subpackages cause a warning to be emitted"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
subpackages="$pkgname-doc"
source=""
prepare() {
mkdir -p "$builddir"
}
build() {
true
}
check() {
true
}
package() {
mkdir -p "$pkgdir/usr/bin"
cat >"$pkgdir/usr/bin/foo" <<EOF
#!/bin/sh
EOF
mkdir -p "$pkgdir/usr/share/doc/$pkgname"
dd bs=1024 count=$((3 * 1024)) if=/dev/random \
of="$pkgdir/usr/share/doc/$pkgname/large-file"
}

View File

@ -0,0 +1,17 @@
# Maintainer: Test user <user@example.com>
pkgname=py3-conflicting-python-versions
pkgver=1.0.0
pkgrel=0
pkgdesc="dummy package for test"
url="https://alpinelinux.org"
license="MIT"
builddir="$srcdir"
package() {
for pyver in 3.9 3.42; do
local sitedir="usr/lib/python$pyver/site-packages"
mkdir -p "$pkgdir"/$sitedir/foo
touch "$pkgdir"/$sitedir/foo/__init__.py
touch "$pkgdir"/$sitedir/bar.py
done
}

View File

@ -0,0 +1,33 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
# test package
pkgname=setcap
pkgver="1.0"
pkgrel=0
pkgdesc="Dummy test package that has an setcap binary but no setcap option"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
source=""
prepare() {
mkdir -p "$builddir"
}
build() {
true
}
check() {
true
}
package() {
mkdir -p "$pkgdir/usr/bin"
cat >"$pkgdir/usr/bin/foo" <<EOF
#!/bin/sh
EOF
chmod +x "$pkgdir/usr/bin/foo"
setcap cap_net_bind_service=+ep "$pkgdir/usr/bin/foo"
}

View File

@ -0,0 +1,24 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
# test package
pkgname=${TESTNAME-test-pkgname}
pkgver="${TESTPKGVER-1.0}"
pkgrel=0
pkgdesc="Dummy subpackage arch"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
subpackages="$pkgname-$TESTSUBARCH:_sub:$TESTSUBARCH"
options="!archcheck"
check() {
true
}
package() {
mkdir -p "$pkgdir"
}
_sub() {
mkdir -p "$subpkgdir"
}

View File

@ -8,10 +8,10 @@ pkgdesc='Dummy test package that has multi-line licenses'
url='https://gitlab.alpinelinux.org/alpine/aports'
arch='noarch'
license='MIT AND
GPL-3.0-only OR
(GPL-3.0-only OR
GPL-3.0-or-later AND
BSD-Clause-4
BSD-Clause-4)
'
prepare() {

View File

@ -8,6 +8,7 @@ pkgdesc="Dummy test package that fails to build"
url="https://gitlab.alpinelinux.org/alpine/aports"
arch="noarch"
license="MIT"
provides="${TESTPROVIDES-provided}"
subpackages="${TESTSUBNAME-$pkgname-sub}:_sub"
prepare() {