On Wed, Aug 14, 2013 at 5:15 AM, Vadim Zhukov <[email protected]> wrote:
> Index: bin/portimport
> ===================================================================
> RCS file: /cvs/ports/infrastructure/bin/portimport,v
> retrieving revision 1.2
> diff -u -p -r1.2 portimport
> --- bin/portimport 11 Apr 2013 15:18:00 -0000 1.2
> +++ bin/portimport 14 Aug 2013 09:30:11 -0000
> @@ -2,6 +2,7 @@
> #
> # $OpenBSD: portimport,v 1.2 2013/04/11 15:18:00 zhuk Exp $
> # Copyright (c) 2013 Robert Peichaer
> +# 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
> @@ -18,52 +19,447 @@
> # Based on Marc Espie's portimport.
> # sthen: Modified to handle imports from mystuff/ and do a dry run first.
> # rpe: rewrite based on sthen@'s version
> +# zhuk: rewrite based on rpe@'s version
>
> set -e
>
> usage() {
> - echo "usage: $(basename $0) [-u username]" >&2
> + echo "usage: ${0##*/} [-f] [-p portsdir] [-u username]" >&2
> exit 1
> }
>
> +
> +############################################################
> +# Parsing command line options
> +#
> +
> user=$(id -un)
> +force=false
> +portsdir=
>
> -while getopts "u:" OPT; do
> +while getopts "fp:u:" OPT; do
> case $OPT in
> - u) user="$OPTARG";;
> - *) usage;;
> + f)
> + force=true
> + ;;
> +
> + p)
> + set -f
> + if [ "${PWD##$OPTARG}" == "${PWD}" ]; then
> + cat >&2 <<EOE
> +${0##*/}: current directory does not seem to be under the
> +specified root directory: $OPTARG
> +EOE
> + exit 3
> + fi
> + set +f
there's no need to toggle ``noglob''
use ${PWD##"$OPTARG"} to suppress the globbing in the RHS of ``##''
> + portsdir="$OPTARG"
> + ;;
> +
> + u)
> + user="$OPTARG"
> + ;;
> +
> + *)
> + usage
> + ;;
> esac
> done
>
> [email protected]:/cvs
> +
> +############################################################
> +# 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 polish your port on cvs.openbsd.org,
> +# where you cannot just override mk.conf.
> +#
> +
> +pkgpath=
> +make_args=MASTER_SITE_OPENBSD=
> +
> +if [[ -z $portsdir ]]; then
> + set +e
> + portsdir=$(make -V PORTSDIR 2>/dev/null)
> + (($? == 0)) && portsdir=
> + set -e
> +fi
there's no need to toggle ``errexit''
use portsdir=$(make -V PORTSDIR 2>/dev/null) && portsdir=
if the LHS of ``&&'' fails, the shell won't exit even if ``errexit''
is under effect
> +
> +if [[ -z $portsdir ]]; then
> + # heuristics mode ON
> + pkgpath="${PWD##*/ports/*(mystuff/|openbsd-wip/|p5-ports-wip/)}"
> + set -f
> + portsdir="${PWD%/$pkgpath}"
> + set +f
same as previous unnecessary ``noglob'' toggling
> +
> + # This way we can run all checks even on cvs.openbsd.org
> + make_args="PORTSDIR_PATH=$portsdir:$(cd /usr/ports && make -V
> PORTSDIR_PATH || true)"
> +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
> +
> +############################################################
> +# Check and fail routines
> +#
> +
> error=false
> -fulldir=$(pwd)
> -importname="ports/${fulldir##*/ports/*(mystuff/|openbsd-wip/|p5-ports-wip/)}"
> -timestamp=$(date '+%Y%m%d')
>
> -err() { echo "$*"; error=true; }
> +err() {
> + echo "$@" >&2
> + error=true
> +}
> +
> +err_duplicated() {
> + err "$2 has \"$1\", as well as one of the parent directories"
> +}
> +
> +err_core_found() {
> + err "file or directory name \"core\" found in $1, CVS will ignore it"
> +}
> +
> +err_coredump_found() {
> + err "core dump file found in $1"
> +}
> +
> +is_vcs_item() {
> + [[ $1 == @(.git|.hg|.svn|CVS|.fossil) ]]
> +}
> +
> +handle_extra_file() {
> + # avoid warning, e.g., about ".*"
> + test -e "$1" || return 0
> +
> + if is_vcs_item "${1##*/}"; then
> + err "VCS item detected: $1"
> + elif [[ ${1##*/} == core ]]; then
> + err_core_found "${1%/*}"
> + elif [[ $1 == *.core ]]; then
> + err_coredump_found "${1%/*}"
> + else
> + err "extra file: $1"
> + fi
> +}
> +
> +check_port_hier() {
> + local pkg_lives_upper=$1; shift
> + local distinfo_lives_upper=$1; shift
> +
> + local pkg_exists=false
> + [[ -d $1/pkg ]] && pkg_exists=true
> + $pkg_exists && $pkg_lives_upper &&
> + err_duplicated pkg/ "$1"
> + $pkg_lives_upper && pkg_exists=true
> +
> + local distinfo_exists=false
> + [[ -f $1/distinfo ]] && distinfo_exists=true
> + $distinfo_exists && $distinfo_lives_upper &&
> + err_duplicated distinfo "$1"
> + $distinfo_lives_upper && distinfo_exists=true
> +
> + local F
> + local npkgpath
> +
> + for F in "$1"/* "$1"/.*; do
> + F="${F#./}"
> + if is_vcs_item "${F##*/}"; then
> + err "VCS item detected: $F"
> + elif [[ -d $F ]]; then
> + case "${F##*/}" in
> + files)
> + check_files_dir "$F"
> + ;;
> +
> + patches)
> + check_patches_dir "$F"
> + ;;
> +
> + pkg)
> + check_pkg_dir "$F"
> + ;;
> +
> + *)
> + [[ ${F##*/} == core ]] && err_core_found "$F"
> + npkgpath=${npkgpath:-$(cd -- "$F" && make
> $make_args show=PKGPATH 2>/dev/null || true)}
> + check_port_dir $pkg_exists $distinfo_exists
> "$F"
> + ;;
> + esac
> + else
> + case "${F##*/}" in
> + Makefile?(.inc)|*.port.mk)
> + check_makefile "$F"
> + ;;
> +
> + distinfo)
> + ;;
> +
> + *)
> + handle_extra_file "$F"
> + ;;
> + esac
> + fi
> + done
> + pkgpath=${pkgpath:-${npkgpath%/*}}
> + egrep -q '^[[:space:]]*SUBDIR[[:space:]]*=' Makefile ||
> + err missing subdir Makefile
> +}
> +
> +check_port_dir() {
> + local pkg_lives_upper=$1; shift
> + local distinfo_lives_upper=$1; shift
> +
> + if [[ -f $1/Makefile.inc ]]; then
> + check_port_hier $pkg_lives_upper $distinfo_lives_upper
> "${1#./}"
> + return
> + fi
> +
> + local F
> + local distinfo_exists=false
> + local mk_exists=false
> + local pkg_exists=false
> +
> + for F in "$1"/* "$1"/.*; do F="${F#./}"; case "${F##*/}" in
> + Makefile)
> + test -f "$F" || err "$F is not a file"
> + check_makefile "$F"
> + mk_exists=true
> + ;;
> +
> + distinfo)
> + $distinfo_lives_upper && err_duplicated distinfo "$1"
> + distinfo_exists=true
> + test -f "$F" || err "$F is not a file"
> + ;;
> +
> + *.port.mk)
> + test -f "$F" || err "$F is not a file"
> + check_makefile "$F"
> + ;;
>
> -[[ -f Makefile && -f distinfo && -f pkg/DESCR && -f pkg/PLIST ]] || err "No
> ports files?"
> -find . -name .git -print|read i && err "You git!"
> -find . -name .\*.swp -print|read i && err "Found vim swap file"
> -find . -name \*.orig -print|read i && err "Found .orig file, ouch"
> -find . -name typescript -print|read i && err "Found typescript file, ouch"
> -find . -path ./w-\* -print|read i && err "Please wipe out work
> directory before importing"
> -find . -type d -name core -print|read i && err "directory named core found,
> cvs will ignore it"
> -find . -type f -name .todo -print|read i && err "devtodo file found"
> -find . -type d -name CVS -print|read i && err "Some CVS stuff already in
> there, very funky"
> -$error && exit 1
> + systrace.filter)
> + test -f "$F" || err "$F is not a file"
> + ;;
> +
> + files)
> + if [[ -d $F ]]; then
> + check_files_dir "$F"
> + else
> + err "$F" is not a directory
> + fi
> + ;;
> +
> + patches)
> + if [[ -d $F ]]; then
> + check_patches_dir "$F"
> + else
> + err "$F" is not a directory
> + fi
> + ;;
> +
> + pkg)
> + $pkg_lives_upper && err_duplicated pkg/ "$1"
> + pkg_exists=true
> + if [[ -d $F ]]; then
> + check_pkg_dir "$F"
> + else
> + err "$F" is not a directory
> + fi
> + ;;
> +
> + *)
> + handle_extra_file "$F"
> + ;;
> + esac; done
> +
> + $mk_exists || err no Makefile in "$1"
> +
> + $pkg_lives_upper && pkg_exists=true
> + $pkg_exists || err "no pkg/ in $1"
> +
> + $distinfo_lives_upper && distinfo_exists=true
> + $distinfo_exists || err "no distinfo in $1"
> +
> + local show_items="SHARED_LIBS DISTFILES DIST_SUBDIR"
> + local shlibs distfiles dist_subdir master_sites
> +
> + # Do not try to use co-processes, there is some bug related
> + # to redirection of error stream seen on big number of
> + # nested ports (100 or so). and we need to redirect &2 to
> + # avoid noising about accessing dead co-processes.
> +
> + (cd "$1"; make $make_args show="$show_items" || true) | {
> + read shlibs
> + read distfiles
> + read dist_subdir
> +
> + check_shlibs "$1" $shlibs
> + check_distfiles "$1" "$dist_subdir" $distfiles
> + }
> +}
> +
> +check_shlibs() {
> + local dir="$1"; shift
> + local lib
> + local libver
> +
> + local portref=
> + [[ $dir != . ]] && portref="in \"${dir#./}\" port "
> + while (($# > 1)); do
> + lib=$1
> + libver=$2
> + if [[ $libver != 0.0 ]]; then
> + err "${portref}library $lib has version $libver" \
> + "instead of 0.0"
> + fi
> + shift 2
> + done
> +}
> +
> +check_distfiles() {
> + local dir="$1"; shift
> + local dist_subdir="$1"; shift
> +
> + # do not care about absent distfiles, this is fine for meta ports
> + while (($# > 1)); do
> + if [[ $1 == [0-9]* && -z $dist_subdir && $1 != *\{*\} ]]; then
> + err "badly named distfile $1 without DIST_SUBDIR" \
> + "or {url} postfix"
> + fi
> + shift
> + done
> +}
> +
> +check_files_dir() {
> + if (($(ls -A "$1" | wc -l) == 0)); then
> + err "there are no files, please remove the $1 directory
> instead"
> + return
> + fi
> +
> + find "$1" -type f -name *.core -print | read i &&
> + err_coredump_found "$1"
> +}
> +
> +check_patches_dir() {
> + local empty=true
> + local F
> +
> + for F in "$1"/* "$1"/.*; do case "${F##*/}" in
> + patch-*.orig)
> + handle_extra_file "$F"
> + ;;
> +
> + patch-*)
> + empty=false
> + test -f "$F" || err "$F is not a file"
> + ;;
> +
> + *)
> + handle_extra_file "$F"
> + ;;
> + esac; done
> +
> + $empty && err "there are no patches, please remove the $1 directory
> instead"
> +}
> +
> +check_pkg_dir() {
> + local empty=true
> + local F
> +
> + for F in "$1"/* "$1"/.*; do case "${F##*/}" in
> + DESCR?(-*)|PLIST?(-*))
> + empty=false
> + test -f "$F" || err "$F" is not a file
> + ;;
> +
> + MESSAGE?(-*)|PFRAG.*|README?(-*)|SECURITY?(-*)|UNMESSAGE?(-*)|*.rc)
> + empty=false
> + test -f "$F" || err "$F" is not a file
> + ;;
> +
> + *)
> + handle_extra_file "$F"
> + ;;
> + esac; done
> +
> + $empty && err "$1 directory does not contain any DESCR or PLIST files"
> +}
> +
> +check_makefile() {
> + grep -q ^REVISION "$1" 2>/dev/null &&
> + err "REVISION(-s) found in $1"
> +}
> +
> +
> +############################################################
> +# Run checks and calculate pkgpath variable, that represents
> +# subdirectory under root ports directory where the port(-s)
> +# will be imported.
> +#
> +
> +pkgpath=${pkgpath:-$(make $make_args show=PKGPATH 2>/dev/null || true)}
> +check_port_dir false false .
> +
> +if [[ -z $pkgpath ]]; then
> + if [[ -n $portsdir ]]; then
> + set -f
> + pkgpath="${PWD##$portsdir/}"
> + set +f
same as previous unnecessary ``noglob'' toggling