if MULTI_PACKAGE isn't set $subpkg is "-" and it breaks the check for COMMENT. Trim out the - with ${subpkg%-} as already done in other parts of portcheck. ok tb@, sthen@
1941 lines
47 KiB
Bash
Executable File
1941 lines
47 KiB
Bash
Executable File
#!/bin/ksh
|
|
#
|
|
# $OpenBSD: portcheck,v 1.143 2022/11/23 17:51:47 op Exp $
|
|
# Copyright (c) 2013 Vadim Zhukov
|
|
#
|
|
# Permission to use, copy, modify, and distribute this software for any
|
|
# purpose with or without fee is hereby granted, provided that the above
|
|
# copyright notice and this permission notice appear in all copies.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
set -e
|
|
set +X
|
|
set -u
|
|
|
|
usage() {
|
|
echo "usage: ${0##*/} [-dNP] [-p portsdir] [-x glob]" >&2
|
|
echo " ${0##*/} -A [-dP] [-p portsdir] [-x glob] [subdir ...]" >&2
|
|
exit 1
|
|
}
|
|
|
|
|
|
############################################################
|
|
# Parsing command line options
|
|
#
|
|
|
|
existing_port=true
|
|
ignore_cvs=true
|
|
plist_checks=true
|
|
portsdir=
|
|
rootrun=false
|
|
debugging=false
|
|
|
|
ignore_list=; unset ignore_list[0]
|
|
|
|
while getopts "AdNPp:x:" OPT; do
|
|
case $OPT in
|
|
A)
|
|
$existing_port || usage
|
|
if ! $rootrun; then
|
|
ignore_list[${#ignore_list[@]}]=.cvsignore
|
|
ignore_list[${#ignore_list[@]}]=.fslckout
|
|
ignore_list[${#ignore_list[@]}]=.git
|
|
ignore_list[${#ignore_list[@]}]=.gitignore
|
|
ignore_list[${#ignore_list[@]}]=.hg
|
|
ignore_list[${#ignore_list[@]}]=.hgignore
|
|
ignore_list[${#ignore_list[@]}]=.svn
|
|
ignore_list[${#ignore_list[@]}]=FINISHED
|
|
ignore_list[${#ignore_list[@]}]=INDEX
|
|
ignore_list[${#ignore_list[@]}]=README
|
|
ignore_list[${#ignore_list[@]}]=README.md
|
|
ignore_list[${#ignore_list[@]}]=bulk
|
|
ignore_list[${#ignore_list[@]}]=distfiles
|
|
ignore_list[${#ignore_list[@]}]=infrastructure
|
|
ignore_list[${#ignore_list[@]}]=lost+found
|
|
ignore_list[${#ignore_list[@]}]=mystuff
|
|
ignore_list[${#ignore_list[@]}]=openbsd-wip
|
|
ignore_list[${#ignore_list[@]}]=packages
|
|
ignore_list[${#ignore_list[@]}]=plist
|
|
ignore_list[${#ignore_list[@]}]=pobj
|
|
ignore_list[${#ignore_list[@]}]=tests
|
|
ignore_list[${#ignore_list[@]}]=update
|
|
fi
|
|
rootrun=true
|
|
;;
|
|
|
|
d)
|
|
debugging=true
|
|
;;
|
|
|
|
N)
|
|
$rootrun && usage
|
|
existing_port=false
|
|
ignore_cvs=false
|
|
;;
|
|
|
|
P)
|
|
plist_checks=false
|
|
;;
|
|
|
|
p)
|
|
portsdir=$OPTARG
|
|
;;
|
|
|
|
x)
|
|
set -A ignore_list -- "${ignore_list[@]}" "$OPTARG"
|
|
;;
|
|
|
|
*)
|
|
usage
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if ! $rootrun && [[ -n $portsdir && ${PWD##"$portsdir"} == "$PWD" ]]; then
|
|
cat >&2 <<EOE
|
|
${0##*/}: current directory does not seem to be under the
|
|
specified root directory: $portsdir.
|
|
EOE
|
|
exit 3
|
|
fi
|
|
|
|
shift $(($OPTIND - 1))
|
|
(($# > 0)) && ! $rootrun && usage
|
|
(($# == 0)) && set -- .
|
|
|
|
############################################################
|
|
# Detect path to root of directory tree of current port(s) and put it
|
|
# in $portsdir, unless it was set by user above. As a last resort, we
|
|
# use some heuristics based on the commonly used names.
|
|
#
|
|
# We also have a $pkgpath variable, that represents subdirectory under
|
|
# root ports directory where the port(s) will be imported. In case we
|
|
# use heuristics for determining $portsdir, we'll set up $pkgpath, too,
|
|
# since we would get this info anyway.
|
|
#
|
|
# In make_args we write PORTSDIR_PATH override, that allows us to run
|
|
# even in ports directory that is not on the PORTSDIR_PATH. This is
|
|
# useful, for example, when you check your port on cvs.openbsd.org,
|
|
# where you cannot just override mk.conf.
|
|
#
|
|
|
|
pkgpath=
|
|
|
|
if [[ -z $portsdir ]]; then
|
|
# idea from DPB/Vars.pm
|
|
test_mf=$(cat <<EOF
|
|
DUMMY_PACKAGE = yes
|
|
.include <bsd.port.mk>
|
|
EOF
|
|
)
|
|
IFS=:
|
|
set -A portsdir_path -- \
|
|
$( (echo "$test_mf" | env FLAVOR= make -C / -f - show=PORTSDIR_PATH 2>/dev/null) || true)
|
|
unset IFS
|
|
if ((${#portsdir_path[@]} > 0)); then
|
|
for p in "${portsdir_path[@]}"; do
|
|
if [[ -z $portsdir && ${PWD#"$p"} != "$PWD" ]]; then
|
|
portsdir=$p
|
|
elif [[ -n $portsdir && ${PWD#"$p"} != "$PWD" &&
|
|
$p > $portsdir ]]; then
|
|
portsdir=$p
|
|
fi
|
|
done
|
|
fi
|
|
fi
|
|
|
|
if [[ -z $portsdir ]]; then
|
|
# heuristics mode ON
|
|
pkgpath=${PWD##*/ports/*(mystuff/|openbsd-wip/)}
|
|
portsdir=${PWD%"/$pkgpath"}
|
|
fi
|
|
|
|
if [[ -z $portsdir ]]; then
|
|
cat >&2 <<EOE
|
|
${0##*/}: could not detect root ports directory. Please provide
|
|
one with -p option.
|
|
EOE
|
|
exit 2
|
|
fi
|
|
|
|
# This way we can run all checks even on cvs.openbsd.org and/or
|
|
# when SKIPDIR framework is used
|
|
set -A make_args -- \
|
|
SKIPDIR= STARTAFTER= STARTDIR= \
|
|
MASTER_SITE_OPENBSD= \
|
|
PORTSDIR_PATH="$portsdir:$(cd /usr/ports && make -V PORTSDIR_PATH || true)"
|
|
|
|
if $rootrun; then
|
|
cd -- "$portsdir"
|
|
echo "scanning ports under the $portsdir" >&2
|
|
fi
|
|
|
|
############################################################
|
|
# Support for SKIPDIR, STARTDIR and STARTAFTER, see ports(7)
|
|
#
|
|
|
|
SKIPDIR=${SKIPDIR:-}
|
|
STARTDIR=${STARTDIR:-}
|
|
STARTAFTER=${STARTAFTER:-}
|
|
if [[ -n $STARTAFTER ]]; then
|
|
STARTDIR=$STARTAFTER
|
|
SKIPDIR="$SKIPDIR $STARTAFTER"
|
|
fi
|
|
|
|
path_parts_count() {
|
|
(IFS=/; set -- $1; echo $#)
|
|
}
|
|
|
|
# true if directory given should be skipped based on STARTDIR
|
|
# and/or SKIPDIR variable
|
|
skip_dir() {
|
|
$rootrun || return 1
|
|
local dir=$(readlink -f "$1")
|
|
dir=${dir##$portsdir*(/)}
|
|
local startpartscount=$(path_parts_count "$STARTDIR")
|
|
local dirpartscount=$(path_parts_count "$dir")
|
|
if ((dirpartscount >= startpartscount)); then
|
|
[[ -n $STARTDIR && $dir < $STARTDIR ]] && return 0
|
|
fi
|
|
local d
|
|
for d in $SKIPDIR; do
|
|
[[ $d == "$dir" ]] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
############################################################
|
|
# List of well-known top-level port categories
|
|
# in a form usable in pattern matching: "foo|bar|baz"
|
|
#
|
|
|
|
top_level_categories=$(xargs <<EOF | sed -e 's/ /|/g'
|
|
archivers
|
|
astro
|
|
audio
|
|
base
|
|
benchmarks
|
|
biology
|
|
books
|
|
cad
|
|
chinese
|
|
comms
|
|
converters
|
|
databases
|
|
devel
|
|
editors
|
|
education
|
|
emulators
|
|
fonts
|
|
games
|
|
geo
|
|
graphics
|
|
inputmethods
|
|
japanese
|
|
java
|
|
korean
|
|
lang
|
|
mail
|
|
math
|
|
meta
|
|
misc
|
|
multimedia
|
|
net
|
|
news
|
|
perl5
|
|
plan9
|
|
print
|
|
productivity
|
|
security
|
|
shells
|
|
sysutils
|
|
telephony
|
|
tests
|
|
textproc
|
|
wayland
|
|
www
|
|
x11
|
|
EOF
|
|
)
|
|
|
|
############################################################
|
|
# List of variables that should not go into port Makefiles
|
|
#
|
|
|
|
user_settings=$(xargs <<EOF | sed -e 's/ /|/g'
|
|
BASELOCALSTATEDIR
|
|
BASESYSCONFDIR
|
|
BATCH
|
|
BUILD_ONCE
|
|
BULK
|
|
BULK_COOKIES_DIR
|
|
CHECKSUM_PACKAGES
|
|
CHECK_LIB_DEPENDS
|
|
COPTS
|
|
CXXOPTS
|
|
DISTDIR
|
|
ECHO_MSG
|
|
ECHO_REORDER
|
|
FAKEOBJDIR
|
|
FETCH_CMD
|
|
FETCH_PACKAGES
|
|
FETCH_SYMLINK_DISTFILES
|
|
FORCE_UPDATE
|
|
FTP_PACKAGES
|
|
IGNORE_IS_FATAL
|
|
IGNORE_SILENT
|
|
INTERACTIVE
|
|
LIST_DB
|
|
LOCKDIR
|
|
LOCK_VERBOSE
|
|
MASTER_SITE_BACKUP
|
|
MASTER_SITE_OVERRIDE
|
|
NO_CHECKSUM
|
|
NO_DEPENDS
|
|
NO_IGNORE
|
|
PACKAGE_REPOSITORY
|
|
PKG_ADD
|
|
PKG_CREATE
|
|
PKG_DBDIR
|
|
PKG_DELETE
|
|
PKG_INFO
|
|
REFETCH
|
|
SIGNING_PARAMETERS
|
|
SUDO
|
|
TEMPLATES
|
|
TRY_BROKEN
|
|
UNLOCK_CMD
|
|
UPDATE_COOKIES_DIR
|
|
USE_CCACHE
|
|
VARBASE
|
|
WARNINGS
|
|
EOF
|
|
)
|
|
|
|
############################################################
|
|
# Check and fail routines
|
|
#
|
|
|
|
error=false
|
|
|
|
err() {
|
|
local prefix=
|
|
while (($# > 0)); do
|
|
printf "$prefix%s" "$1" >&2
|
|
prefix=" "
|
|
shift
|
|
done
|
|
echo >&2
|
|
error=true
|
|
}
|
|
|
|
err_duplicated() {
|
|
err "both $2 and some of its parents has $1"
|
|
}
|
|
|
|
err_coredump_found() {
|
|
err "core dump file found: $1"
|
|
}
|
|
|
|
has_subdirs_only() {
|
|
$debugging && echo "CALLED: has_subdirs_only($*)" >&2
|
|
|
|
local dir=$1; shift
|
|
ls -A "$dir" | {
|
|
local has_files=false has_dirs=false
|
|
while read F; do
|
|
$ignore_cvs && [[ $F == CVS ]] && continue
|
|
ignoring "$dir/$F" && continue
|
|
if [[ -d $dir/$F ]]; then
|
|
has_dirs=true
|
|
else
|
|
has_files=true
|
|
fi
|
|
done
|
|
$has_dirs && ! $has_files
|
|
}
|
|
}
|
|
|
|
ignoring() {
|
|
((${#ignore_list[*]} > 0)) || return 1
|
|
local iglob
|
|
for iglob in "${ignore_list[@]}"; do
|
|
[[ ${1#./} == $iglob ]] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
is_vcs_item() {
|
|
[[ -d "$1" && ${1##*/} == @(CVS|.fslckout|.git|.hg|.svn) ]]
|
|
}
|
|
|
|
handle_extra_file() {
|
|
ignoring "$1" && return 0
|
|
|
|
# avoid warning, e.g., about ".*"
|
|
test -e "$1" || return 0
|
|
|
|
if is_vcs_item "$1"; then
|
|
if ! $ignore_cvs || [[ ${1##*/} != CVS ]]; then
|
|
err "VCS item detected: $1"
|
|
fi
|
|
elif [[ -f $1 && $1 == *.core ]]; then
|
|
err_coredump_found "$1"
|
|
elif [[ -d $1 ]]; then
|
|
err "extra directory: $1"
|
|
else
|
|
err "extra file: $1"
|
|
fi
|
|
}
|
|
|
|
# Make a path to .py[co] file looks like as if it's in the same dir
|
|
# as the corresponding .py file, and has same basename. E.g.:
|
|
# lib/python3.3/__pycache__/Foo/cpython-33.Bar.pyc
|
|
# became:
|
|
# lib/python2.7/Foo/Bar.pyc
|
|
# which corresponds to:
|
|
# lib/python2.7/Foo/Bar.py
|
|
normalize_pyco() {
|
|
local pyco=$1
|
|
[[ $pyco == *.cpython-+([0-9]).py[co] ]] &&
|
|
pyco=${pyco%.cpython-+([0-9]).py[co]}.${pyco##*.}
|
|
[[ $pyco == */__pycache__/* ]] &&
|
|
pyco=${pyco%/__pycache__/*}/${pyco##*/__pycache__/}
|
|
printf "%s" "$pyco"
|
|
}
|
|
|
|
# Print out a ref to the particular subport/subpackage, if needed.
|
|
# Port FLAVORs could also be handled, if provided.
|
|
# Usage: portref directory [subpackage [flavor all_flavors]]
|
|
portref() {
|
|
local dir=$1; shift
|
|
local subpkg= flavor all_flavors=
|
|
if (($# > 0)); then
|
|
subpkg=$1
|
|
shift
|
|
fi
|
|
if (($# > 0)); then
|
|
flavor=$1
|
|
all_flavors=$2
|
|
shift 2
|
|
fi
|
|
|
|
local ref=
|
|
if [[ $dir != . ]]; then
|
|
ref="${dir#./}"
|
|
[[ -n $subpkg && $subpkg != "-" ]] && ref="$ref,$subpkg"
|
|
else
|
|
[[ $subpkg != "-" ]] && ref="$subpkg"
|
|
fi
|
|
|
|
if [[ -n $all_flavors ]]; then
|
|
[[ -n $ref ]] && ref="$ref, "
|
|
if [[ -z $flavor ]]; then
|
|
ref="${ref}default FLAVOR"
|
|
else
|
|
ref="${ref}FLAVOR \"$flavor\""
|
|
fi
|
|
fi
|
|
|
|
[[ -n $ref ]] && echo "in $ref: "
|
|
}
|
|
|
|
# Contains last SUBST_CMD. Filled by check_port_dir(), used
|
|
# by check_port_hier() to lazily call the check_pkg_dir().
|
|
last_subst_cmd=
|
|
|
|
# Checks made:
|
|
# * Whitelist filter of what could be in this directory.
|
|
check_port_hier() {
|
|
$debugging && echo "CALLED: check_port_hier($*)" >&2
|
|
|
|
local distinfo_lives_upper pkg_lives_upper plist_lives_upper
|
|
local dir=$1; shift
|
|
for opt; do
|
|
# looks unsafe but we do not pass anything except
|
|
# "foo=true" and "foo=false" here
|
|
eval "$opt"
|
|
done
|
|
|
|
distinfo_lives_upper=${distinfo_lives_upper:-false}
|
|
pkg_lives_upper=${pkg_lives_upper:-false}
|
|
plist_lives_upper=${plist_lives_upper:-false}
|
|
|
|
local distinfo_exists=false
|
|
[[ -f $dir/distinfo ]] && distinfo_exists=true
|
|
$distinfo_exists && $distinfo_lives_upper &&
|
|
err_duplicated distinfo "$dir"
|
|
|
|
local pkg_exists=false tell_pkg_exists=$pkg_lives_upper
|
|
if [[ -d $dir/pkg ]]; then
|
|
pkg_exists=true
|
|
tell_pkg_exists=true
|
|
fi
|
|
|
|
local plist_exists=false
|
|
ls $dir/pkg/PLIST* >/dev/null 2>&1 && plist_exists=true
|
|
$plist_lives_upper && $plist_exists &&
|
|
err_duplicated "packing list(s)" "$dir"
|
|
|
|
$distinfo_lives_upper && distinfo_exists=true
|
|
$plist_lives_upper && plist_exists=true
|
|
|
|
local recursive_args
|
|
set -A recursive_args -- \
|
|
distinfo_lives_upper=$distinfo_exists \
|
|
pkg_lives_upper=$tell_pkg_exists \
|
|
plist_lives_upper=$plist_exists
|
|
|
|
local F
|
|
for F in "$dir"/* "$dir"/.*; do
|
|
F=${F#./}
|
|
ignoring "$F" && continue
|
|
|
|
if is_vcs_item "$F"; then
|
|
if ! $ignore_cvs || [[ ${F##*/} != CVS ]]; then
|
|
err "VCS item detected: $F"
|
|
fi
|
|
elif [[ -d $F ]]; then
|
|
case ${F##*/} in
|
|
files|patches)
|
|
check_${F##*/}_dir "$F"
|
|
;;
|
|
|
|
pkg)
|
|
# Do nothing, pkg_exists is already set,
|
|
# and we need to read SUBST_CMD first.
|
|
;;
|
|
|
|
patches?(-*))
|
|
check_patches_dir "$F"
|
|
;;
|
|
|
|
*)
|
|
if ! ([[ -f $F/Makefile ]] ||
|
|
ls $F/*.port.mk >/dev/null 2>&1) &&
|
|
! has_subdirs_only "$F"; then
|
|
# Avoid extra spam
|
|
err "not a port directory: $F"
|
|
else
|
|
local pkgpath_set=false
|
|
[[ -n $pkgpath ]] && pkgpath_set=true
|
|
check_port_dir "$F" "${recursive_args[@]}"
|
|
$pkgpath_set || pkgpath=${pkgpath%/*}
|
|
fi
|
|
;;
|
|
esac
|
|
else
|
|
case ${F##*/} in
|
|
Makefile?(.inc)|*.port.mk)
|
|
check_makefile "$F"
|
|
;;
|
|
|
|
distinfo)
|
|
;;
|
|
|
|
*)
|
|
handle_extra_file "$F"
|
|
;;
|
|
esac
|
|
fi
|
|
done
|
|
|
|
$pkg_exists && check_pkg_dir "$dir"/pkg "$last_subst_cmd"
|
|
|
|
$existing_port ||
|
|
egrep -q '^ *SUBDIR[[:space:]]*\+?=' "$dir"/Makefile ||
|
|
err missing subdir Makefile
|
|
}
|
|
|
|
# Checks made:
|
|
# * Whitelist filter of what could be in this directory.
|
|
check_port_dir() {
|
|
$debugging && echo "CALLED: check_port_dir($*)" >&2
|
|
|
|
local dir=$1; shift
|
|
skip_dir "$dir" && return
|
|
local distinfo_lives_upper pkg_lives_upper plist_lives_upper
|
|
for opt; do
|
|
# looks unsafe but we do not pass anything except
|
|
# "foo=true" and "foo=false" here
|
|
eval "$opt"
|
|
done
|
|
|
|
distinfo_lives_upper=${distinfo_lives_upper:-false}
|
|
pkg_lives_upper=${pkg_lives_upper:-false}
|
|
plist_lives_upper=${plist_lives_upper:-false}
|
|
|
|
check_perms_in_dir "$dir"
|
|
|
|
if [[ -f $dir/Makefile.inc ]] ||
|
|
egrep -sq '^ *SUBDIR[[:space:]]*\+?=' "$dir"/Makefile ||
|
|
has_subdirs_only "$dir"; then
|
|
check_port_hier "${dir#./}" "${@:-}"
|
|
return
|
|
fi
|
|
|
|
local F
|
|
local distinfo_exists=false
|
|
local mk_exists=false
|
|
local pkg_exists=false
|
|
local plist_exists=false
|
|
local portmk_exists=true
|
|
local non_portmk=0
|
|
|
|
for F in "$dir"/* "$dir"/.*; do
|
|
F=${F#./}
|
|
ignoring "$F" && continue
|
|
case ${F##*/} in
|
|
Makefile)
|
|
test -f "$F" || err "$F is not a file"
|
|
check_makefile "$F"
|
|
mk_exists=true
|
|
((++non_portmk))
|
|
;;
|
|
|
|
distinfo)
|
|
$distinfo_lives_upper && err_duplicated distinfo "$dir"
|
|
distinfo_exists=true
|
|
test -f "$F" || err "$F is not a file"
|
|
((++non_portmk))
|
|
;;
|
|
|
|
*.port.mk)
|
|
test -f "$F" || err "$F is not a file"
|
|
check_makefile "$F"
|
|
portmk_exists=true
|
|
;;
|
|
|
|
crates.inc|modules.inc)
|
|
test -f "$F" || err "$F is not a file"
|
|
fgrep -qx ".include \"$F\"" "$dir"/Makefile ||
|
|
err "$F not included in Makefile"
|
|
((++non_portmk))
|
|
;;
|
|
|
|
files|patches)
|
|
if [[ -d $F ]]; then
|
|
check_${F##*/}_dir "$F"
|
|
else
|
|
err "$F" is not a directory
|
|
fi
|
|
((++non_portmk))
|
|
;;
|
|
|
|
pkg)
|
|
if [[ -d $F ]]; then
|
|
pkg_exists=true
|
|
# Actual check to be done later, we need to gather
|
|
# additional info through "make show=" call.
|
|
ls "$F"/PLIST* >/dev/null 2>&1 &&
|
|
plist_exists=true
|
|
$plist_lives_upper && $plist_exists &&
|
|
err_duplicated "packing list(s)" "$dir"
|
|
else
|
|
err "$F" is not a directory
|
|
fi
|
|
((++non_portmk))
|
|
;;
|
|
|
|
*)
|
|
handle_extra_file "$F"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# examples: lang/clang, www/mozilla
|
|
$portmk_exists && ((non_portmk == 0)) && return
|
|
|
|
$mk_exists || err no Makefile in "$dir"
|
|
$pkg_exists || $pkg_lives_upper || err "no pkg/ in $dir"
|
|
$distinfo_lives_upper && distinfo_exists=true
|
|
$distinfo_exists || $existing_port || err "no distinfo in $dir"
|
|
|
|
# Now gather and check some info via "make show=...".
|
|
# We request all info at once for speed.
|
|
|
|
local categories dist_subdir distfiles flavor flavors
|
|
local gh_commit master_sites
|
|
local multi_packages pkgpath_this pseudo_flavor pseudo_flavors
|
|
local shared_libs subst_cmd
|
|
local permit_package permit_distfiles
|
|
local show_items="CATEGORIES DIST_SUBDIR DISTFILES FLAVOR FLAVORS GH_COMMIT"
|
|
local show_items="$show_items MASTER_SITES MULTI_PACKAGES PKGPATH"
|
|
local show_items="$show_items PSEUDO_FLAVOR PSEUDO_FLAVORS"
|
|
local show_items="$show_items SHARED_LIBS SUBST_CMD"
|
|
local show_items="$show_items PERMIT_PACKAGE PERMIT_DISTFILES"
|
|
local read_ok=false
|
|
|
|
local read_failed=false
|
|
(cd -- "$dir"; make "${make_args[@]}" show="$show_items" || true) </dev/null |&
|
|
read -pr categories &&
|
|
read -pr dist_subdir &&
|
|
read -pr distfiles &&
|
|
read -pr flavor &&
|
|
read -pr flavors &&
|
|
read -pr gh_commit &&
|
|
read -pr master_sites &&
|
|
read -pr multi_packages &&
|
|
read -pr pkgpath_this &&
|
|
read -pr pseudo_flavor &&
|
|
read -pr pseudo_flavors &&
|
|
read -pr shared_libs &&
|
|
read -pr subst_cmd &&
|
|
read -pr permit_package &&
|
|
read -pr permit_distfiles &&
|
|
read_ok=true
|
|
if $read_ok; then
|
|
exec 3<&p
|
|
exec 3<&-
|
|
wait
|
|
else
|
|
error=true
|
|
return
|
|
fi
|
|
|
|
pseudo_flavor=$(echo "$pseudo_flavor" | sed -e 's/,/ /g')
|
|
pseudo_flavor=${pseudo_flavor##" "}
|
|
|
|
local f pf found
|
|
|
|
local check_flavors=
|
|
[[ $flavor != "$pseudo_flavor" ]] && unset check_flavors[0]
|
|
|
|
for f in $flavors; do
|
|
for pf in $pseudo_flavors; do
|
|
[[ $f == "$pf" ]] && continue 2
|
|
done
|
|
[[ $f == debug ]] && continue # XXX
|
|
check_flavors[${#check_flavors[@]}]=$f
|
|
done
|
|
|
|
check_categories "$dir" $categories
|
|
check_distfiles "$dir" "$dist_subdir" $distfiles
|
|
check_master_sites "$dir" $master_sites
|
|
check_permit_dist "$dir" "$permit_package" "$permit_distfiles"
|
|
$pkg_exists && check_pkg_dir "$dir"/pkg "$subst_cmd"
|
|
$existing_port || check_shlibs_versions "$dir" $shared_libs
|
|
|
|
if [[ -n $gh_commit ]]; then
|
|
local ghclen=$(echo -n "$gh_commit" | wc -c)
|
|
if ((ghclen != 40)); then
|
|
err "GH_COMMIT should be in full form (40 characters)"
|
|
fi
|
|
fi
|
|
|
|
for _s in $multi_packages; do
|
|
sub_checks "$dir" "$_s" "${check_flavors[@]}"
|
|
done
|
|
|
|
pkgpath=${pkgpath:-"$pkgpath_this"}
|
|
last_subst_cmd="$subst_cmd"
|
|
}
|
|
|
|
# Checks made: obvious
|
|
check_dos_line_endings() {
|
|
grep -q "$(printf '\r\n')\$" "$1" &&
|
|
err "MS-DOS line endings in $1 -- if patching,"\
|
|
"use FIX_CRLF_FILES to correct the input file."
|
|
}
|
|
|
|
# Checks made: obvious
|
|
check_trailing_whitespace() {
|
|
egrep -q '[[:space:]]+$' "$1" &&
|
|
err "trailing whitespace in $1"
|
|
}
|
|
|
|
# Checks made: obvious
|
|
check_newline_at_eof() {
|
|
(( $(tail -1 -- "$1" | wc -l) == 0)) &&
|
|
err "no newline at EOF in $1"
|
|
}
|
|
|
|
# Checks made:
|
|
# * Every library in SHARED_LIBS has 0.0 version.
|
|
check_shlibs_versions() {
|
|
$debugging && echo "CALLED: check_shlibs_versions($*)" >&2
|
|
|
|
local dir=$1; shift
|
|
local lib
|
|
local libver
|
|
local portref=$(portref "$dir")
|
|
|
|
while (($# > 1)); do
|
|
lib=$1
|
|
libver=$2
|
|
if [[ $libver != 0.0 ]]; then
|
|
err "${portref}the $lib shared library has" \
|
|
"version $libver instead of 0.0"
|
|
fi
|
|
shift 2
|
|
done
|
|
}
|
|
|
|
# Checks made:
|
|
# * All top-level category names are well-known.
|
|
check_categories() {
|
|
$debugging && echo "CALLED: check_categories($*)" >&2
|
|
|
|
local dir=$1; shift
|
|
local portref=$(portref "$dir")
|
|
for c in "$@"; do
|
|
c=${c%%/*}
|
|
if ! echo "$c" | egrep -q "^($top_level_categories)\$"; then
|
|
err "${portref}non-standard top-level category: $c"
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Checks made:
|
|
# * Distfiles with useless names go into DIST_SUBDIR or have {url} suffix.
|
|
check_distfiles() {
|
|
$debugging && echo "CALLED: check_distfiles($*)" >&2
|
|
|
|
local dir=$1; shift
|
|
local dist_subdir=$1; shift
|
|
local portref=$(portref "$dir")
|
|
|
|
# do not care about absent distfiles, this is fine for meta ports
|
|
while (($# > 1)); do
|
|
# try to catch "version-only" names, but not anything more
|
|
if [[ $1 == ?(v)?(.)+([0-9])?(.+([0-9]))*(.+([a-z])) &&
|
|
-z $dist_subdir && $1 != *\{*\} ]]; then
|
|
err "${portref}badly named distfile $1 without" \
|
|
"DIST_SUBDIR or {url} postfix"
|
|
fi
|
|
shift
|
|
done
|
|
}
|
|
|
|
# Checks made:
|
|
# * No unreliable (without fixed distfiles) hosting listed in MASTER_SITES.
|
|
check_master_sites() {
|
|
$debugging && echo "CALLED: check_master_sites($*)" >&2
|
|
|
|
local dir=$1; shift
|
|
local portref=$(portref "$dir")
|
|
local name
|
|
|
|
while (($# > 1)); do
|
|
case $1 in
|
|
http?(s)://bitbucket.com/*) name=BitBucket;;
|
|
http?(s)://gitorious.com/*) name=Gitorious;;
|
|
*) name=;;
|
|
esac
|
|
[[ -n $name ]] && err "$portref$name does not hold real" \
|
|
"releases, please host the distfiles somewhere" \
|
|
"else or ask someone to do this for you"
|
|
shift
|
|
done
|
|
}
|
|
|
|
# Run checks that are FLAVOR/SUBPACKAGE-dependent.
|
|
sub_checks() {
|
|
$debugging && echo "CALLED: sub_checks($*)" >&2
|
|
|
|
local dir=$1; shift
|
|
local subpkg=$1; shift
|
|
local flavor
|
|
for flavor in "$@"; do
|
|
# avoid extra noise
|
|
[[ ${flavor#no_} != ${flavor} &&
|
|
${subpkg#-} == ${flavor#no_} ]] &&
|
|
continue
|
|
|
|
(
|
|
cd -- "$dir"
|
|
portref=$(portref "$dir" "$subpkg" "$flavor" "$*")
|
|
export SUBPACKAGE="$subpkg" FLAVOR="$flavor"
|
|
|
|
local wantlib_var=WANTLIB${subpkg%-}
|
|
local vars="COMMENT${subpkg%-} FULLPKGNAME${subpkg%-}"
|
|
vars="$vars MODULES"
|
|
vars="$vars PKG_ARCH$subpkg $wantlib_var WANTLIB-"
|
|
vars="$vars PERMIT_PACKAGE${subpkg%-}"
|
|
vars="$vars COMPILER"
|
|
make "${make_args[@]}" show="$vars" | {
|
|
local comment fullpkgname modules pkg_arch
|
|
local wantlib permit_package
|
|
local arch_independent=false
|
|
local default_compiler=false
|
|
read -r comment
|
|
read -r fullpkgname
|
|
read -r modules
|
|
read -r pkg_arch
|
|
[[ $pkg_arch == "*" ]] && arch_independent=true
|
|
read -r wantlib
|
|
read -r wantlib_ss
|
|
read -r permit_package
|
|
read -r compiler
|
|
|
|
if [[ $comment == @(a|an|the)" "* ]]; then
|
|
err "${portref}no leading articles in" \
|
|
"COMMENT${subpkg%-}, please"
|
|
fi
|
|
|
|
if $arch_independent && [[ -n $wantlib ]]; then
|
|
if [[ $subpkg != - || -n $wantlib_ss ]]; then
|
|
err "${portref}non-empty $wantlib_var for" \
|
|
"arch-independent package"
|
|
fi
|
|
fi
|
|
|
|
[[ "$compiler" == "base-clang base-gcc gcc3" ]] \
|
|
&& default_compiler=true
|
|
|
|
check_wantlib "$portref" "$modules" \
|
|
"$default_compiler" $wantlib
|
|
|
|
check_permit_subpkg "$portref" "$subpkg" \
|
|
"$permit_package"
|
|
|
|
if $plist_checks; then
|
|
(make "${make_args[@]}" \
|
|
print-plist-with-depends || true) \
|
|
</dev/null |&
|
|
check_plist "$portref" "$fullpkgname" \
|
|
"$flavor" "${subpkg%-}" "$modules" \
|
|
"$arch_independent"
|
|
check_lib_depends "$portref" "$subpkg" \
|
|
"$modules" "$wantlib"
|
|
wait
|
|
fi
|
|
|
|
! $error
|
|
} || error=true
|
|
|
|
! $error
|
|
) || error=true
|
|
done
|
|
wait
|
|
}
|
|
|
|
# Checks made:
|
|
# * If package installs system-wide icons, it should have the
|
|
# x11/gtk+3,-guic dependency and
|
|
# @tag gtk-update-icon-cache %D/share/icons/$theme
|
|
# for each icon theme used in package.
|
|
#
|
|
# * If package adds a MIME type handler, it should have the
|
|
# devel/desktop-file-utils dependency and @tag update-desktop-database .
|
|
# Unfortunately, it's hard to tell if there is a MIME type handler
|
|
# in .desktop file, so we just trigger if any .desktop files are added to
|
|
# ${PREFIX}/share/applications/ .
|
|
#
|
|
# * If package adds a MIME types package, it should have the
|
|
# misc/shared-mime-info dependency and @tag update-mime-database
|
|
#
|
|
# * If package adds a GLib schema, it should have
|
|
# @tag glib-compile-schemas
|
|
# and "devel/dconf" in MODULES (or at least RDEP on devel/dconf).
|
|
#
|
|
# * If package installs files under ${PREFIX}/share/dbus-1/system-services/,
|
|
# it must have a run-time dependency on x11/dbus,-suid.
|
|
#
|
|
# * Each .py should have corresponding .pyc files, to avoid
|
|
# generation of the latter at run-time.
|
|
#
|
|
# * Manual (man and info) pages should go under ${PREFIX}/{man,info},
|
|
# not under ${PREFIX}/share/{man,info}.
|
|
#
|
|
# * Manual pages shouldn't be compressed.
|
|
#
|
|
# * If port installs QML files, it should depend on
|
|
# x11/qt5/qtdeclarative,-main
|
|
#
|
|
# * Qt5-QML files should live under PREFIX/lib/qt5/qml/.
|
|
#
|
|
# * Qt5-QML-enabled port depend on x11/qt5/qtdeclarative.
|
|
#
|
|
# * @rcscript items and pkg-readmes have @mode, @owner and @group reset.
|
|
#
|
|
# * PKG_ARCH is not set to * if a library is present.
|
|
#
|
|
check_plist() {
|
|
$debugging && echo "CALLED: check_plist($*)" >&2
|
|
|
|
local portref=$1; shift
|
|
local fullpkgname=$1; shift
|
|
local flavor_list=$1; shift
|
|
local subpkg=$1; shift
|
|
local modules_list=$1; shift
|
|
local arch_independent=$1; shift
|
|
|
|
local flavor is_static=false
|
|
for flavor in $flavor_list; do
|
|
[[ $flavor == static ]] && is_static=true
|
|
done
|
|
|
|
local guic_dep=false
|
|
local guic_dep_needed=false
|
|
|
|
local mime_dep=false
|
|
local mime_dep_needed=false
|
|
local mime_tag_cnt=0
|
|
|
|
local mimepkg_dep=false
|
|
local mimepkg_dep_needed=false
|
|
|
|
local dconf_module
|
|
if [[ $modules_list == ?(* )devel/dconf?( *) ]]; then
|
|
dconf_module=true
|
|
else
|
|
dconf_module=false
|
|
fi
|
|
local dconf_dep=false
|
|
local dconf_dep_needed=false
|
|
|
|
local dbus_suid_dep=false is_dbus_suid=false
|
|
local dbus_suid_dep_needed=false
|
|
|
|
# Lists of .py, .pyc and .pyo items found, accordingly
|
|
local py_files= pyc_files= pyo_files=
|
|
unset py_files[0] pyc_files[0] pyo_files[0]
|
|
|
|
local wrong_man=false wrong_info=false
|
|
|
|
local regsh=false unregsh=false
|
|
local regsh_exec=false unregsh_exec=false
|
|
|
|
local qml_found=false qt5_qml_found=false non_qt5_qml_found=false
|
|
local qt5_dep=false qt5declarative_dep=false
|
|
local lib_found=false
|
|
|
|
local owner_set=false group_set=false mode_set=false
|
|
local readme_seen=false
|
|
|
|
# Temporary ones
|
|
local app l theme varname py
|
|
|
|
while read -pr l; do
|
|
case $l in
|
|
"@comment "*)
|
|
# ignore
|
|
;;
|
|
share/icons/*/*/*|share/icons/*/@(index.theme|iconrc?(-png)))
|
|
# Themes have at least two levels in depth.
|
|
#
|
|
guic_dep_needed=true
|
|
;;
|
|
share/icons/*(*/))
|
|
# Do not match intermediate directories to avoid false
|
|
# positives.
|
|
;;
|
|
share/icons/*.xpm)
|
|
app=${l#share/icons/}
|
|
app=${app%%/*}
|
|
app=${app%%.*}
|
|
err "${portref}installs icon ${l##*/} in ${l%/*}, it" \
|
|
"should likely go in share/pixmaps/ instead"
|
|
;;
|
|
share/icons/default.*)
|
|
;;
|
|
share/icons/*)
|
|
app=${l#share/icons/}
|
|
app=${app%%/*}
|
|
app=${app%%.*}
|
|
err "${portref}installs icon ${l##*/} in ${l%/*}, it" \
|
|
"should go in share/$app/icons/ or like instead"
|
|
;;
|
|
"@depend x11/gtk+3,-guic"*)
|
|
guic_dep=true
|
|
;;
|
|
@?(un)exec*" %D/bin/gtk-update-icon-cache"*)
|
|
err "${portref}obsolete gtk-update-icon-cache" \
|
|
"invocation: ${l#@* }"
|
|
;;
|
|
|
|
share/applications/*(*/)*.desktop)
|
|
mime_dep_needed=true
|
|
;;
|
|
"@depend devel/desktop-file-utils"*)
|
|
mime_dep=true
|
|
;;
|
|
@?(un)exec*" %D/bin/update-desktop-database"*)
|
|
err "${portref}obsolete update-desktop-database" \
|
|
"invocation: ${l#@* }"
|
|
;;
|
|
share/mime/packages/*.xml)
|
|
mimepkg_dep_needed=true
|
|
;;
|
|
"@depend misc/shared-mime-info"*)
|
|
mimepkg_dep=true
|
|
;;
|
|
@?(un)exec*" %D/bin/update-mime-database"*)
|
|
err "${portref}obsolete update-mime-database" \
|
|
"invocation: ${l#@* }"
|
|
;;
|
|
|
|
share/glib-2.0/schemas/*.xml)
|
|
dconf_dep_needed=true
|
|
;;
|
|
"@depend devel/dconf"*)
|
|
dconf_dep=true
|
|
;;
|
|
@?(un)exec*" %D/bin/glib-compile-schemas"*)
|
|
err "${portref}obsolete glib-compile-schemas" \
|
|
"invocation: ${l#@* }"
|
|
;;
|
|
|
|
"@depend x11/qt5/qtdeclarative,-main"*)
|
|
qt5declarative_dep=true
|
|
qt5_dep=true
|
|
;;
|
|
"@depend x11/qt5/"*)
|
|
qt5_dep=true
|
|
;;
|
|
lib/qt5/qml/*)
|
|
qml_found=true
|
|
lib_found=true
|
|
qt5_qml_found=true
|
|
;;
|
|
*/qmldir)
|
|
qml_found=true
|
|
non_qt5_qml_found=true
|
|
;;
|
|
|
|
*.so|*.a|*.so.*)
|
|
lib_found=true
|
|
;;
|
|
|
|
share/dbus-1/system-services/*)
|
|
dbus_suid_dep_needed=true
|
|
;;
|
|
"@depend x11/dbus,-suid"*)
|
|
dbus_suid_dep=true
|
|
;;
|
|
"@bin libexec/dbus-daemon-launch-helper")
|
|
is_dbus_suid=true
|
|
;;
|
|
|
|
lib/ghc/*/register.sh)
|
|
regsh=true
|
|
;;
|
|
lib/ghc/*/unregister.sh)
|
|
unregsh=true
|
|
;;
|
|
"@exec /usr/bin/env HOME=/nonexistent "%D/lib/ghc/*/register.sh" -v0")
|
|
regsh_exec=true
|
|
;;
|
|
"@unexec /usr/bin/env HOME=/nonexistent "%D/lib/ghc/*/unregister.sh" -v0 --force")
|
|
unregsh_exec=true
|
|
if $unregsh; then
|
|
err "${portref}unregister.sh call placed before" \
|
|
"script itself in PLIST${subpkg}"
|
|
fi
|
|
;;
|
|
|
|
# XXX KSH arrays are limited to 10239 items
|
|
share/@(doc|*(*/)examples)+(/*).py|?(s)bin/*.py)
|
|
# ignore
|
|
;;
|
|
*.py)
|
|
py_files[${#py_files[@]}]=$l
|
|
;;
|
|
*.pyc)
|
|
pyc_files[${#pyc_files[@]}]=$(normalize_pyco "$l")
|
|
;;
|
|
*.pyo)
|
|
pyo_files[${#pyo_files[@]}]=$(normalize_pyco "$l")
|
|
;;
|
|
|
|
share/man/*)
|
|
wrong_man=true
|
|
;;
|
|
share/info/*)
|
|
wrong_info=true
|
|
;;
|
|
"@man "*.gz)
|
|
err "${portref}compressed $l"
|
|
;;
|
|
|
|
@owner)
|
|
owner_set=false
|
|
;;
|
|
@group)
|
|
group_set=false
|
|
;;
|
|
@mode)
|
|
mode_set=false
|
|
;;
|
|
"@owner "*)
|
|
owner_set=true
|
|
;;
|
|
"@group "*)
|
|
group_set=true
|
|
;;
|
|
"@mode "*)
|
|
mode_set=true
|
|
;;
|
|
"@rcscript "*)
|
|
! $owner_set || err "${portref}$l has @owner set"
|
|
! $group_set || err "${portref}$l has @group set"
|
|
! $mode_set || err "${portref}$l has @mode set"
|
|
;;
|
|
share/doc/pkg-readmes/*)
|
|
! $owner_set || err "${portref}$l has @owner set"
|
|
! $group_set || err "${portref}$l has @group set"
|
|
! $mode_set || err "${portref}$l has @mode set"
|
|
readme_seen=true
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# gtk-update-icon-cache
|
|
$guic_dep_needed && ! $guic_dep &&
|
|
[[ $fullpkgname != gtk-update-icon-cache-* ]] &&
|
|
err "${portref}missing RDEP on x11/gtk+3,-guic"
|
|
local cnt
|
|
|
|
# desktop-file-utils (simplier than previous, isn't it?)
|
|
$mime_dep_needed && ! $mime_dep &&
|
|
[[ $fullpkgname != desktop-file-utils-* ]] &&
|
|
err "${portref}missing RDEP on devel/desktop-file-utils"
|
|
|
|
# update-mime-database (same as previous)
|
|
$mimepkg_dep_needed && ! $mimepkg_dep &&
|
|
[[ $fullpkgname != shared-mime-info-* ]] &&
|
|
err "${portref}missing RDEP on misc/shared-mime-info"
|
|
|
|
# glib-compile-schemas (almost same as previous)
|
|
#
|
|
# TODO: detect situation of extra devel/dconf in MODULES
|
|
# (requires investigation of all subpackages).
|
|
if $dconf_dep_needed; then
|
|
if ! $dconf_module; then
|
|
err "${portref}GLib2 XML schemas found without" \
|
|
"devel/dconf in MODULES"
|
|
elif ! $dconf_dep; then
|
|
err "${portref}missing" \
|
|
"RUN_DEPENDS${subpkg}+=\${MODDCONF_RUN_DEPENDS}"
|
|
fi
|
|
fi
|
|
|
|
# QML
|
|
$qt5_qml_found && ! $qt5declarative_dep &&
|
|
[[ $fullpkgname != qtdeclarative-[0-9]* ]] &&
|
|
err "${portref}provides Qt5 QML files without" \
|
|
"x11/qt5/qtdeclarative dependency"
|
|
$qt5_dep && $non_qt5_qml_found &&
|
|
err "${portref}depends on Qt5 but installs QML files" \
|
|
"outside PREFIX/lib/qt5/qml/"
|
|
|
|
$lib_found && $arch_independent &&
|
|
err "${portref}arch-independent package contains library files"
|
|
|
|
# dbus,-suid
|
|
if $dbus_suid_dep_needed && ! $dbus_suid_dep && ! $is_dbus_suid; then
|
|
err "${portref}missing" \
|
|
"RUN_DEPENDS${subpkg}+=x11/dbus,-suid"
|
|
fi
|
|
|
|
# Haskell register/unregister
|
|
if $regsh && ! $regsh_exec; then
|
|
err "${portref}missing @exec of register.sh"
|
|
fi
|
|
if $unregsh && ! $unregsh_exec; then
|
|
err "${portref}missing @unexec of unregister.sh"
|
|
fi
|
|
|
|
# Python modules
|
|
((${#py_files[@]} > 0)) && set -sA py_files -- "${py_files[@]}"
|
|
((${#pyc_files[@]} > 0)) && set -sA pyc_files -- "${pyc_files[@]}"
|
|
((${#pyo_files[@]} > 0)) && set -sA pyo_files -- "${pyo_files[@]}"
|
|
local ic=0 io=0
|
|
if ((${#py_files[@]} > 0)); then for py in "${py_files[@]}"; do
|
|
while [[ $ic -lt ${#pyc_files[@]} ]]; do
|
|
[[ ${pyc_files[$ic]} < "$py"c ]] || break
|
|
# allowed behaviour
|
|
#err "${portref}compiled Python module without" \
|
|
# "source, expected: ${pyc_files[$ic]%c}"
|
|
((++ic))
|
|
done
|
|
if [[ $ic -lt ${#pyc_files[@]} &&
|
|
${pyc_files[$ic]} == "$py"c ]]; then
|
|
((++ic))
|
|
else
|
|
err "${portref}Python module without" \
|
|
"compiled version, consider using" \
|
|
"\${MODPY_BIN} \${MODPY_LIBDIR}/compileall.py: $py"
|
|
fi
|
|
|
|
while [[ $io -lt ${#pyo_files[@]} ]]; do
|
|
[[ ${pyo_files[$io]} < "$py"o ]] || break
|
|
# allowed behaviour
|
|
#err "${portref}optimized Python module without" \
|
|
# "source, expected: ${pyo_files[$io]%o}"
|
|
((++io))
|
|
done
|
|
if [[ $io -lt ${#pyo_files[@]} &&
|
|
${pyo_files[$io]} == "$py"o ]]; then
|
|
((++io))
|
|
# too much noise, maybe enable in the future
|
|
#else
|
|
# err "${portref}Python module without" \
|
|
# "optimized version: $py"
|
|
fi
|
|
done; fi
|
|
|
|
# allowed behaviour
|
|
#while (($ic < ${#pyc_files[@]})); do
|
|
# err "${portref}compiled Python module without source," \
|
|
# "expected: ${pyc_files[$ic]%c}"
|
|
# ((++ic))
|
|
#done
|
|
|
|
# allowed behaviour
|
|
#while (($io < ${#pyo_files[@]})); do
|
|
# err "${portref}optimized Python module without source," \
|
|
# "expected: ${pyo_files[$io]%o}"
|
|
# ((++io))
|
|
#done
|
|
|
|
$wrong_man && err "${portref}manual pages should go under" \
|
|
"\${PREFIX}/man/ rather than under \${PREFIX}/share/man/"
|
|
$wrong_info && err "${portref}info pages should go under" \
|
|
"\${PREFIX}/info/ rather than under \${PREFIX}/share/info/"
|
|
|
|
if ! $readme_seen; then
|
|
local readme=pkg/README${subpkg}
|
|
if [[ -e $readme ]]; then
|
|
err "${portref}missing share/doc/pkg-readmes/\${PKGSTEM} in PLIST${subpkg}"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Checks made:
|
|
# * stdc++ doesn't get into WANTLIB when gcc4.port.mk is used.
|
|
check_wantlib() {
|
|
local portref="$1"; shift
|
|
local modules="$1"; shift
|
|
local default_compiler="$1"; shift
|
|
|
|
local gcc4_module=false
|
|
|
|
local v
|
|
|
|
for v in $modules; do case $v in
|
|
gcc4) gcc4_module=true;;
|
|
esac; done
|
|
|
|
for v; do case $v in
|
|
@(smbclient|wbclient)?(?('>')=+([0-9])))
|
|
err "$portref$v instead of lib/samba/$v" \
|
|
"in WANTLIB"
|
|
;;
|
|
|
|
@(DCOP|soundserver_idl|vcard)?(?('>')=+([0-9])))
|
|
err "$portref$v instead of \${KDE}/$v" \
|
|
"in WANTLIB (check other libs, too!)"
|
|
;;
|
|
|
|
@(c++|stdc++)?(?('>')=+([0-9])))
|
|
if $default_compiler; then
|
|
err "C++ libraries in WANTLIB with default COMPILER" \
|
|
"(most ports need 'COMPILER=base-clang ports-gcc'" \
|
|
"or 'COMPILER=base-clang ports-gcc base-gcc')"
|
|
fi
|
|
;;
|
|
|
|
stdc++?(?('>')=+([0-9])))
|
|
if $gcc4_module; then
|
|
err "$portref$v in WANTLIB when gcc4 is" \
|
|
"in MODULES; run port-lib-depends-check" \
|
|
"and if stdc++ is still there, check" \
|
|
"actual build thoroughly, it's broken"
|
|
fi
|
|
esac; done
|
|
|
|
true
|
|
}
|
|
|
|
# Checks made:
|
|
# * Each library mentioned in WANTLIB is accessible either:
|
|
# a) as a part of base system, in /usr/lib or /usr/X11R6/lib;
|
|
# b) via LIB_DEPENDS directly, or via deeper dependency of LIB_DEPENDS.
|
|
check_lib_depends() {
|
|
$debugging && echo "CALLED: check_lib_depends($*)" >&2
|
|
|
|
local portref="$1"; shift
|
|
local subpkg="$1"; shift
|
|
local modules="$1"; shift
|
|
local wantlib="$1"; shift
|
|
|
|
# The idea as follows: build full list of run-time dependencies, but
|
|
# without RUN_DEPENDS begin involved.
|
|
#
|
|
# Then we look at libs in each pkgpath we got, and strip those
|
|
# from WANTLIB. We also strip system libraries from /usr/lib
|
|
# and /usr/X11R6/lib. And all WANTLIBs coming from MODULES are stripped
|
|
# too, supposing that authors of those MODULES know what they're doing
|
|
# (without stripping 'em, we'll get many false positives).
|
|
#
|
|
# If there are any non-stripped items in WANTLIB, we found a problem.
|
|
#
|
|
# XXX those checks do not take actual versions into account!
|
|
|
|
# get list of all WANTLIBs coming from MODULES
|
|
local m modvars=
|
|
for m in $modules; do
|
|
m=${m##*/}
|
|
case $m in
|
|
python)
|
|
m=py
|
|
;;
|
|
esac
|
|
m=$(echo "MOD${m}_WANTLIB" | tr a-z A-Z)
|
|
modvars="$modvars $m"
|
|
done
|
|
local l modlibs=
|
|
make "${make_args[@]}" show="$modvars" </dev/null |&
|
|
while read -pr l; do
|
|
modlibs="$modlibs $l"
|
|
done
|
|
wait # make sure process exited before possible return below
|
|
|
|
# strip WANTLIBs coming from MODULES
|
|
local libsleft wl
|
|
for l in $modlibs; do
|
|
libsleft=
|
|
for wl in $wantlib; do
|
|
if [[ $l != "$wl" ]]; then
|
|
libsleft="$libsleft $wl"
|
|
elif $debugging; then
|
|
echo "WANTLIB ITEM $wl COMES FROM MODULES"
|
|
fi
|
|
done
|
|
[[ -n $libsleft ]] || return 0 # all libs found
|
|
wantlib=$libsleft
|
|
done
|
|
|
|
# prepare easy-to-use WANTLIB list in $checklibs
|
|
local wlprefix checklibs=
|
|
for wl in $wantlib; do
|
|
wl=${wl%%[><=]*}
|
|
wlprefix=${wl%/*}
|
|
[[ $wlprefix == "$wl" ]] && wlprefix=lib
|
|
wl=${wl##*/}
|
|
checklibs="$checklibs ${wlprefix}/lib$wl"
|
|
done
|
|
|
|
# strip system libraries
|
|
local d
|
|
for d in /usr /usr/X11R6; do
|
|
for l in $d/lib/lib*.@(so*(.+([0-9]))|a); do
|
|
libsleft=
|
|
for wl in $checklibs; do
|
|
if [[ $l != +(/*)/${wl}.@(so*(.+([0-9]))|a) ]]; then
|
|
libsleft="$libsleft $wl"
|
|
elif $debugging; then
|
|
echo "FOUND WANTLIB ITEM $wl: $l"
|
|
fi
|
|
done
|
|
[[ -n $libsleft ]] || return 0 # all libs found
|
|
checklibs=$libsleft
|
|
done
|
|
done
|
|
|
|
# get deep list of LDEPs
|
|
local lmake_args="${make_args[@]}"
|
|
lmake_args[${#lmake_args[@]}]="RUN_DEPENDS="
|
|
lmake_args[${#lmake_args[@]}]="RUN_DEPENDS$subpkg="
|
|
# Rely on the fact we're already in the port directory, see sub_checks().
|
|
# XXX ignoring make errors for now
|
|
local pure_lib_deps=$(make "${lmake_args[@]}" show-run-depends | sort)
|
|
[[ -n $pure_lib_deps ]] || return 0
|
|
# SUBDIR doesn't accept newline-separated values
|
|
set -A pure_lib_deps -- $pure_lib_deps
|
|
|
|
(
|
|
# strip libraries from ports
|
|
# TODO cache print-plist-libs output?
|
|
cd -- /usr/ports # XXX "$portsdir" fails for openbsd-wip and like
|
|
unset FLAVOR SUBPACKAGE
|
|
SUBDIR="${pure_lib_deps[*]}" make "${make_args[@]}" \
|
|
print-plist-libs </dev/null 2>/dev/null |&
|
|
while read -pr l; do
|
|
case $l in
|
|
"===> "*)
|
|
;;
|
|
|
|
*)
|
|
libsleft=
|
|
for wl in $checklibs; do
|
|
if [[ $l != +(/*)/${wl}.@(so*(.+([0-9]))|a) ]]; then
|
|
libsleft="$libsleft $wl"
|
|
elif $debugging; then
|
|
echo "FOUND WANTLIB ITEM $wl: $l"
|
|
fi
|
|
done
|
|
[[ -n $libsleft ]] || exit 0 # all libs found
|
|
checklibs=$libsleft
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# prettify list of WANTLIBs left and print it
|
|
libsleft=
|
|
for wl in $checklibs; do
|
|
libsleft="$libsleft ${wl##*/lib}"
|
|
done
|
|
err "${portref}the following libraries in WANTLIB${subpkg%-}" \
|
|
"look like masked by RUN_DEPENDS${subpkg%-}:$libsleft"
|
|
wait
|
|
! $error
|
|
) || error=true
|
|
}
|
|
|
|
# Checks made:
|
|
# * No extra PERMIT_DISTFILES variables in Makefile.
|
|
# * PERMIT_DISTFILES should not contain just "No" but a reason.
|
|
#
|
|
# Runs in the port directory.
|
|
# XXX does not handle Makefile.inc and other .include cases correctly.
|
|
check_permit_dist() {
|
|
$debugging && echo "CALLED: check_permit_dist($*)" >&2
|
|
|
|
local portref=$(portref $1); shift
|
|
local permit_package=$(echo "$1" | tr '[:upper:]' '[:lower:]')
|
|
local permit_distfiles=$(echo "$2" | tr '[:upper:]' '[:lower:]')
|
|
|
|
if [[ $permit_package == yes && $permit_distfiles == yes ]]; then
|
|
egrep -sq "^ *PERMIT_DISTFILES[[:space:]]*=" Makefile &&
|
|
err "${portref}extra PERMIT_DISTFILES line(-s)"
|
|
fi
|
|
|
|
if [[ $permit_distfiles == no ]]; then
|
|
err "${portref}PERMIT_DISTFILES should be either" \
|
|
"\"Yes\" or a reason for being non-redistributable"
|
|
fi
|
|
|
|
true
|
|
}
|
|
|
|
# Checks made:
|
|
# * PERMIT_PACKAGE should not contain just "No" but a reason.
|
|
#
|
|
# Runs in the port directory.
|
|
# XXX does not handle Makefile.inc and other .include cases correctly.
|
|
check_permit_subpkg() {
|
|
$debugging && echo "CALLED: check_permit_subpkg($*)" >&2
|
|
|
|
local portref=$1; shift
|
|
local subpkg=${1%-}; shift
|
|
local permit_package=$(echo "$1" | tr '[:upper:]' '[:lower:]')
|
|
|
|
if [[ $permit_package == no ]]; then
|
|
err "${portref} PERMIT_PACKAGE should be either" \
|
|
"\"Yes\" or a reason for being non-redistributable"
|
|
fi
|
|
|
|
true
|
|
}
|
|
|
|
# Checks made:
|
|
# * Directory is not empty
|
|
# * No '*.core' files present
|
|
# * Files should not contain OpenBSD RCS tags
|
|
check_files_dir() {
|
|
$debugging && echo "CALLED: check_files_dir($*)" >&2
|
|
|
|
find -f "$1" -- -type f | {
|
|
local empty=true
|
|
local mode
|
|
while read F; do
|
|
ignoring "$F" && continue
|
|
mode=$(stat -f %p "$F" || true)
|
|
(( (0$mode & 0111) != 0 )) &&
|
|
err "executable file: $F"
|
|
empty=false
|
|
if [[ $F == *.core ]]; then
|
|
err_coredump_found "$F"
|
|
else
|
|
grep -q '\$OpenBSD.*\$' "$F" &&
|
|
err "$F should not contain \$OpenBSD\$ tag"
|
|
fi
|
|
done
|
|
$empty && err "there are no files, please remove the $1 directory"
|
|
! $error
|
|
} || error=true
|
|
}
|
|
|
|
# Checks made:
|
|
# * The patch is not empty.
|
|
# * The patch should not contain an OpenBSD RCS tag.
|
|
check_patch() {
|
|
local F=$1
|
|
|
|
test -f "$F" || {
|
|
err "$F is not a file"
|
|
return
|
|
}
|
|
|
|
if [[ -s $F ]]; then
|
|
grep -q '\$OpenBSD.*\$' "$F" &&
|
|
err "$F should not contain \$OpenBSD\$ tag"
|
|
else
|
|
err "$F is empty and should be removed"
|
|
fi
|
|
|
|
check_dos_line_endings "$F"
|
|
}
|
|
|
|
# Checks made:
|
|
# * Patches should not contain OpenBSD RCS tags.
|
|
# * Directory is not empty and consists only of plain files starting
|
|
# with 'patch-' and not ending with '.orig'.
|
|
check_patches_dir() {
|
|
$debugging && echo "CALLED: check_patches_dir($*)" >&2
|
|
|
|
local empty=true
|
|
local F
|
|
|
|
check_perms_in_dir "$1"
|
|
|
|
for F in "$1"/* "$1"/.*; do case ${F##*/} in
|
|
patch-*.orig)
|
|
handle_extra_file "$F"
|
|
;;
|
|
|
|
patch-*)
|
|
empty=false
|
|
$rootrun || check_patch "$F"
|
|
;;
|
|
|
|
*)
|
|
handle_extra_file "$F"
|
|
;;
|
|
esac; done
|
|
|
|
$empty && err "there are no patches, please remove the $1 directory instead"
|
|
}
|
|
|
|
# Checks made:
|
|
# * Directory is not empty and consist only of plain files with fixed names.
|
|
# * Files should not contain OpenBSD RCS tags.
|
|
# * PFRAG.shared should be merged into PLIST.
|
|
# * No trailing whitespace for DESCR, MESSAGE, README, UNMESSAGE and
|
|
# .rc files (PLIST and PFRAG are better checked with "make package").
|
|
# * See also check_plist_file().
|
|
check_pkg_dir() {
|
|
$debugging && echo "CALLED: check_pkg_dir($*)" >&2
|
|
|
|
local dir=$1; shift
|
|
local subst_cmd
|
|
if (($# > 0)); then
|
|
# XXX should find the way to always obtain SUBST_CMD
|
|
subst_cmd=$1
|
|
shift
|
|
fi
|
|
local empty=true
|
|
local F
|
|
local plist
|
|
|
|
check_perms_in_dir "$dir"
|
|
|
|
dir="${dir#./}"
|
|
for F in "$dir"/* "$dir"/.*; do case ${F##*/} in
|
|
DESCR?(-*))
|
|
empty=false
|
|
[[ -f $F ]] ||
|
|
err "$F is not a file"
|
|
check_trailing_whitespace "$F"
|
|
check_newline_at_eof "$F"
|
|
check_long_lines "$F"
|
|
check_hardcoded "$F"
|
|
[[ -n $subst_cmd ]] && check_subst_vars "$F" "$subst_cmd"
|
|
grep -q '\$OpenBSD.*\$' "$F" &&
|
|
err "$F should not contain \$OpenBSD\$ tag"
|
|
;;
|
|
|
|
PFRAG.shared?(-*))
|
|
empty=false
|
|
[[ -n $subst_cmd ]] && check_subst_vars "$F" "$subst_cmd"
|
|
check_plist_file "$F"
|
|
plist=PLIST${F##*/PFRAG.+([!-])}
|
|
err "$F should be merged into $plist"
|
|
;;
|
|
|
|
PFRAG.*|PLIST?(-*))
|
|
empty=false
|
|
[[ -n $subst_cmd ]] && check_subst_vars "$F" "$subst_cmd"
|
|
check_plist_file "$F"
|
|
;;
|
|
|
|
README?(-*))
|
|
[[ -f $F ]] ||
|
|
err "$F is not a file"
|
|
[[ -n $subst_cmd ]] && check_subst_vars "$F" "$subst_cmd"
|
|
check_trailing_whitespace "$F"
|
|
check_newline_at_eof "$F"
|
|
check_long_lines "$F"
|
|
check_hardcoded "$F"
|
|
grep -q '\$OpenBSD.*\$' "$F" &&
|
|
err "$F should not contain \$OpenBSD\$ tag"
|
|
;;
|
|
|
|
*.rc)
|
|
[[ -f $F ]] ||
|
|
err "$F is not a file"
|
|
[[ ${F##*/} == [A-Za-z_]*([A-Za-z0-9_]).rc ]] ||
|
|
err "$F name will not work in rc.subr(8)"
|
|
check_trailing_whitespace "$F"
|
|
check_long_lines "$F"
|
|
check_hardcoded "$F"
|
|
check_rcscript "$dir" "${F##*/}"
|
|
grep -q '\$OpenBSD.*\$' "$F" &&
|
|
err "$F should not contain \$OpenBSD\$ tag"
|
|
;;
|
|
|
|
MESSAGE?(-*)|UNMESSAGE?(-*))
|
|
[[ -f $F ]] ||
|
|
err "$F is not a file"
|
|
[[ -n $subst_cmd ]] && check_subst_vars "$F" "$subst_cmd"
|
|
check_trailing_whitespace "$F"
|
|
check_newline_at_eof "$F"
|
|
check_long_lines "$F"
|
|
check_hardcoded "$F"
|
|
grep -q '\$OpenBSD.*\$' "$F" &&
|
|
err "$F should not contain \$OpenBSD\$ tag"
|
|
;;
|
|
|
|
*)
|
|
handle_extra_file "$F"
|
|
;;
|
|
esac; done
|
|
|
|
$empty && err "$dir directory does not contain either DESCR, PFRAG or PLIST files"
|
|
}
|
|
|
|
# Checks made:
|
|
# * There are no hardcoded /usr/local or /var paths in file.
|
|
# /var/log, /var/run and /var/tmp are perfectly fine, though.
|
|
check_hardcoded() {
|
|
$debugging && echo "CALLED: check_hardcoded($*)" >&2
|
|
|
|
perl -n -e 'BEGIN { $ec=0; }
|
|
if (m,/usr/local\b,o) { $ec=1; close ARGV; }
|
|
if (m,/var((?:/+[^/\s]+)*)(?:\s.*)?$,o) {
|
|
unless ($1 =~ m,^/+(?:log|run|tmp),o) {
|
|
$ec=1; close ARGV;
|
|
}
|
|
}
|
|
END { $? = $ec; }' \
|
|
"$1" || err "hardcoded paths detected in $1, consider using" \
|
|
"SUBST_VARS and TRUEPREFIX/LOCALBASE/LOCALSTATEDIR/VARBASE"
|
|
}
|
|
|
|
# Checks made:
|
|
# * All pkg/foo.rc files are found in some PLIST* or PFRAG*.
|
|
check_rcscript() {
|
|
$debugging && echo "CALLED: check_rcscript($*)" >&2
|
|
local dir="$1" rcname="$2"
|
|
|
|
fgrep -xsq "@rcscript \${RCDIR}/${rcname%.rc}" \
|
|
"$dir"/PLIST* "$dir"/PFRAG* || err \
|
|
"$F is not mentioned in any packing list"
|
|
}
|
|
|
|
# Checks made:
|
|
# * There are no lines longer than 80 characters that have at least
|
|
# one space (avoids warnings on long URLs etc.).
|
|
check_long_lines() {
|
|
$debugging && echo "CALLED: check_long_lines($*)" >&2
|
|
local file=$1; shift
|
|
|
|
local n=$(awk <"$file" \
|
|
'/[[:space:]]/ && length > 80 { n++ } END { print n+0 }')
|
|
(($n > 0 )) &&
|
|
err "$n line(s) longer than 80 chars in $file"
|
|
}
|
|
|
|
# Checks made:
|
|
# * Contains no OpenBSD RCS tag.
|
|
# * No items with ${FULLPKGNAME} are allowed, except readme.
|
|
# * No empty lines.
|
|
check_plist_file() {
|
|
$debugging && echo "CALLED: check_plist_file($*)" >&2
|
|
|
|
[[ -f $1 ]] ||
|
|
err "$1 is not a file"
|
|
grep -q '\$OpenBSD.*\$' "$1" &&
|
|
err "$1 should not contain \$OpenBSD\$ tag"
|
|
|
|
# Do not match just '${FULLPKGNAME}' because many ports use the
|
|
# following trick:
|
|
# @cwd ${LOCALBASE}/share/doc/pkg-readmes
|
|
# ${FULLPKGNAME}
|
|
egrep -v '^(share/doc/pkg-readmes/\$\{FULLPKGNAME\}|@comment .*)$' "$1" |
|
|
egrep '.\$\{FULLPKGNAME\}|\$\{FULLPKGNAME\}.' >&2 &&
|
|
err "$1 contains item(s) with \${FULLPKGNAME} in it, see above"
|
|
|
|
egrep -q '^[[:space:]]*$' "$1" && err "$1 contains empty lines"
|
|
}
|
|
|
|
# Checks made:
|
|
# * Every variable referenced by ${[A-Z]+} should be in ${SUBST_VARS}.
|
|
check_subst_vars() {
|
|
$debugging && echo "CALLED: check_subst_vars($*)" >&2
|
|
|
|
local F=$1; shift
|
|
local subst_cmd=$1; shift
|
|
|
|
# Add variables sometimes referenced in port docs.
|
|
eval "$subst_cmd" -DPATH=test -DWRKSRC=test <"$F" |
|
|
egrep '\$\{[A-Z]+\}' >&2 &&
|
|
err "looks like misspelled variables in $F, see above"
|
|
}
|
|
|
|
# Checks made:
|
|
# * Contains no OpenBSD RCS tag.
|
|
# * No REVISION marks present in given file (unless in update mode).
|
|
# * Each REVISION mark presents only once.
|
|
# * BUILD_DEPENDS, MODULES and PERMIT_DISTFILES are not defined in
|
|
# VAR-subpkg manner.
|
|
# * No trailing whitespace.
|
|
# * SHARED_LIBS are not defined inside ".if" statements.
|
|
# * Variables are not assigned via "=" twice outside of .if statements.
|
|
# * No user settings present.
|
|
# * SHARED_ONLY not defined
|
|
# * Check for usage of obsolete PERMIT_PACKAGE_* and PERMIT_DISTFILES_FTP
|
|
check_makefile() {
|
|
$debugging && echo "CALLED: check_makefile($*)" >&2
|
|
|
|
local F="$1"
|
|
check_trailing_whitespace "$F"
|
|
check_long_lines "$F"
|
|
check_hardcoded "$F"
|
|
grep -q '\$OpenBSD.*\$' "$F" &&
|
|
err "$F should not contain \$OpenBSD\$ tag"
|
|
|
|
local iflevel=0 l lnum=0 revs= t r mkvars= var duprevfound
|
|
# do not unset mkvars, having empty element(-s) is fine
|
|
unset revs[0]
|
|
local tab="$(print '\t')"
|
|
while IFS= read -r l; do ((++lnum))
|
|
set -A t -- $l
|
|
duprevfound=false
|
|
|
|
if echo "$l" | egrep -q "^ *($user_settings)[[:>:]].*\$"; then
|
|
err "user settings in port: $l"
|
|
fi
|
|
|
|
case $l in
|
|
*(" ")REVISION*)
|
|
$existing_port ||
|
|
err "REVISION mark found at $F:$lnum"
|
|
var=${t[0]%=}
|
|
if ((${#revs[@]} > 0)); then
|
|
for r in "${revs[@]}"; do
|
|
if [[ $var == "$r" ]]; then
|
|
err "duplicated $r in $F"
|
|
# avoid dup error messages
|
|
duprevfound=true
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
revs[${#revs[@]}]=${t[0]}
|
|
;;
|
|
*(" ")@(BUILD_DEPENDS|MODULES|PERMIT_DISTFILES)-*)
|
|
err "${l%%-*} is not a subpackageble variable, see $F:$lnum"
|
|
;;
|
|
*(" ").*(" "|"$tab")if*)
|
|
((++iflevel))
|
|
;;
|
|
*(" ").*(" "|"$tab")endif*)
|
|
((iflevel--))
|
|
;;
|
|
*(" ")SHARED_LIBS*(" "|"$tab")*(+|:|!)=*)
|
|
if ((iflevel > 0)); then
|
|
err "should not be inside .if block ($F:$lnum): $l"
|
|
fi
|
|
;;
|
|
*(" ")SHARED_ONLY*(" "|"$tab")*(+|:|!|\?)=*)
|
|
err "SHARED_ONLY is deprecated ($F:$lnum)"
|
|
;;
|
|
*(" ")PERMIT_PACKAGE_CDROM*(" "|"$tab")*(+|:|!|\?)=*)
|
|
err "PERMIT_PACKAGE_CDROM is deprecated," \
|
|
"use PERMIT_PACKAGE ($F:$lnum)"
|
|
;;
|
|
*(" ")PERMIT_PACKAGE_FTP*(" "|"$tab")*(+|:|!|\?)=*)
|
|
err "PERMIT_PACKAGE_FTP is deprecated," \
|
|
"use PERMIT_PACKAGE ($F:$lnum)"
|
|
;;
|
|
*(" ")PERMIT_DISTFILES_FTP*(" "|"$tab")*(+|:|!|\?)=*)
|
|
err "PERMIT_DISTFILES_FTP is deprecated," \
|
|
"use PERMIT_DISTFILES ($F:$lnum)"
|
|
;;
|
|
esac
|
|
|
|
if [[ $l == *(" ")+([A-Za-z0-9_-])*(" "|"$tab")?(\?)=* ]] &&
|
|
((iflevel == 0)) && ! $duprevfound; then
|
|
var=${t[0]%?(\?)=*}
|
|
for v in "${mkvars[@]}"; do
|
|
if [[ $v == "$var" ]]; then
|
|
err "duplicated assignment of $v" \
|
|
"at $F:$lnum"
|
|
break
|
|
fi
|
|
done
|
|
mkvars[${#mkvars[@]}]=$var
|
|
fi
|
|
done <"$F"
|
|
}
|
|
|
|
# Checks made:
|
|
# * None of executable bits (111) are set on plain files.
|
|
check_perms_in_dir() {
|
|
$debugging && echo "CALLED: check_perms_in_dir($*)" >&2
|
|
|
|
(find -f "$1" -- -maxdepth 1 -type f \
|
|
\( -perm -100 -or -perm -010 -or -perm 001 \) \
|
|
</dev/null || true) |&
|
|
local F
|
|
while read -pr F; do
|
|
F=${F#./}
|
|
ignoring "$F" && continue
|
|
err "executable file: ${F#./}"
|
|
done
|
|
}
|
|
|
|
|
|
############################################################
|
|
# Run checks. Also calculate and show pkgpath variable,
|
|
# unless we're checking the ports tree root dir.
|
|
#
|
|
|
|
for D; do
|
|
if [[ $D == /* ]]; then
|
|
err "absolute path $D ignored"
|
|
continue
|
|
fi
|
|
if [[ $D == *(*/)..*(/*) ]]; then
|
|
err "too many .. in $D, skipping"
|
|
continue
|
|
fi
|
|
check_port_dir "$D"
|
|
done
|
|
|
|
if ! $rootrun; then
|
|
[[ -z $pkgpath ]] && pkgpath=${PWD##"$portsdir/"}
|
|
|
|
if [[ $pkgpath == "$PWD" ]]; then
|
|
cat >&2 <<EOE
|
|
${0##*/}: could not determine PKGPATH. Please help me with the -p option.
|
|
EOE
|
|
exit 2
|
|
fi
|
|
|
|
echo "$pkgpath"
|
|
fi
|
|
|
|
! $error
|