#!/bin/sh export LC_ALL=C # Finds from which repo a package comes from # it can return multiple values if it finds multiple matches find_repo() { [ -z "$1" ] || [ -z "$2" ] && return 0 local pkgname="$1" # Repo the package we are linting currently is. We want it # for avoiding checks on repos we don't want local targetrepo="$2" # Unmaintained is the top of the ladder, it can depend on any # of the steps below if [ "$targetrepo" = "unmaintained" ]; then return 0 fi # Perform some transformations that can be done easily and cheaply # and are common. # # This is a hack until apk has something like xpkg -m or aports adopt # the xbps-src symlinks pkgname="${pkgname%-dev}" pkgname="${pkgname%-doc}" pkgname="${pkgname%-openrc}" pkgname="${pkgname%-bash-completion}" pkgname="${pkgname%-zsh-completion}" pkgname="${pkgname%-fish-completion}" # Disabled because it can cause conflicts with -dev packages, there is glade and libglade # which are separate packages but end up causing false-postiives # pkgname="${pkgname#lib}" pkgname="${pkgname%-static}" pkgname="${pkgname%-lang}" check_in_repo() { test -d "$1"/"$2" && echo "$1" ; } case "$targetrepo" in testing) check_in_repo unmaintained "$pkgname" ;; community) check_in_repo unmaintained "$pkgname" check_in_repo testing "$pkgname" ;; main) check_in_repo unmaintained "$pkgname" check_in_repo testing "$pkgname" check_in_repo community "$pkgname" ;; esac } find_dupe() { local pkgname="$1" repo="$2" r= check_in_repo() { test -d "$1"/"$2" && echo "$1" ; } for r in unmaintained testing community main; do [ "$r" = "$repo" ] && continue check_in_repo "$r" "$pkgname" done } upper_repo_depends() { [ "$SKIP_UPPER_REPO_DEPENDS" ] && return 0 printf "%s\n" "$depends" | tr " " "\n" | sort -u | while read -r pkg; do for p in $(find_repo "$pkg" "$_repo"); do printf "$apkbuild:: depends '$pkg' is in upper repo '$p'\n" done done } duplicate_depends() { [ "$SKIP_DUPLICATE_DEPENDS" ] && return 0 printf "%s\n" "$depends" | tr " " "\n" | sort | uniq -d | while read -r dup; do [ -z "$dup" ] && continue printf "$apkbuild:: duplicate '$dup' in depends\n" done } upper_repo_makedepends() { [ "$SKIP_UPPER_REPO_MAKEDEPENDS" ] && return 0 printf "%s\n" "$makedepends" | tr " " "\n" | sort -u | while read -r pkg; do for p in $(find_repo "$pkg" "$_repo"); do printf "$apkbuild:: makedepends '$pkg' is in upper repo '$p'\n" done done } duplicate_makedepends() { [ "$SKIP_DUPLICATE_MAKEDEPENDS" ] && return 0 printf "%s\n" "$makedepends" | tr " " "\n" | sort | uniq -d | while read -r dup; do [ -z "$dup" ] && continue printf "$apkbuild:: duplicate '$dup' in makedepends\n" done } upper_repo_checkdepends() { [ "$SKIP_UPPER_REPO_CHECKDEPENDS" ] && return 0 printf "%s\n" "$checkdepends" | tr " " "\n" | sort -u | while read -r pkg; do for p in $(find_repo "$pkg" "$_repo"); do printf "$apkbuild:: checkdepends '$pkg' is in upper repo '$p'\n" done done } duplicate_checkdepends() { [ "$SKIP_DUPLICATE_CHECKDEPENDS" ] && return 0 printf "%s\n" "$checkdepends" | tr " " "\n" | sort | uniq -d | while read -r dup; do [ -z "$dup" ] && continue printf "$apkbuild:: duplicate '$dup' in checkdepends\n" done } duplicate_package() { [ "$SKIP_DUPLICATE_PACKAGE" ] && return 0 for _r in $(find_dupe "$pkgname" "$_repo"); do printf "$apkbuild:: package is already present in $_r\n" done } pkgname_dirname_mismatch() { [ "$SKIP_PKGNAME_DIRNAME_MISMATCH" ] && return 0 local _dirname= case "${apkbuild%%/*}" in main|community|testing|unmaintained|non-free) _dirname="${apkbuild%/*}" _dirname="${_dirname##*/}" ;; *) return 0 ;; esac if [ "$pkgname" != "$_dirname" ]; then printf "$apkbuild:: pkgname is '$pkgname' but is in directory '$_dirname'\n" fi } depends_makedepends_checkdepends_overlap() { [ "$SKIP_DEPENDS_MAKEDEPENDS_CHECKDEPENDS_OVERLAP" ] && return 0 local _mkdeps _ckdeps d _mkdeps="$(echo $makedepends | tr " " "\\n" | sort -u)" _ckdeps="$(echo $checkdepends | tr " " "\\n" | sort -u)" [ -z "$_mkdeps" ] && [ -z "$_ckdeps" ] && return 0 for d in $depends; do if printf "%s\\n" "$_mkdeps" | grep -q "^$d$"; then printf "%s:: dependency '%s' is in depends and makedepends\n" "$apkbuild" "$d" fi # Don't check against checkdepends if it is empty [ -z "$checkdepends" ] && continue if printf "%s\\n" "$_ckdeps" | grep -q "^$d$"; then printf "%s:: dependency '%s' is in depends and checkdepends\n" "$apkbuild" "$d" fi done # Don't check against checkdepends if it is empty [ -z "$checkdepends" ] && return 0 for d in $makedepends; do if printf "%s\\n" "$_ckdeps" | grep -q "^$d$"; then printf "%s:: dependency '%s' is in makedepends and checkdepends\n" "$apkbuild" "$d" fi done } for apkbuild; do if [ -f "$apkbuild" ]; then # Try to guess the repo, first see if our working directory is where # the repo is located _repo="${PWD%/*}" _repo="${_repo%/*}" _repo="${_repo##*/}" case "$_repo" in main|community|testing|unmaintained) ;; # Then have the path given to use be used *) _repo="${apkbuild%/*}" _repo="${_repo%/*}" _repo="${_repo##*/}" ;; esac # Source apkbuild, we need some nice values srcdir="" . ./"$apkbuild" 2>/dev/null if [ ! -z "$depends" ]; then upper_repo_depends & duplicate_depends & fi if [ ! -z "$makedepends" ]; then upper_repo_makedepends & duplicate_makedepends & depends_makedepends_checkdepends_overlap & fi if [ ! -z "$checkdepends" ]; then if [ ! -z "${options##*!check*}" ]; then upper_repo_checkdepends & fi duplicate_checkdepends & fi if [ -z "$SKIP_DUPLICATE_PACKAGE" ]; then duplicate_package & fi pkgname_dirname_mismatch & wait else echo no such apkbuild "$apkbuild" 1>&2 fi | sort -t: -n -k2 | grep . && ret=1 done exit $ret