This patch adds the following functionality to portimport(1):

  * More checks to catch some common cases: UPDATE and TODO files,
    *.core files, REVISIONs being set, SHARED_LIBS containing
    non-0.0 items, Mercurial repo directories.

  * Support for importing a subtree with Makefile.inc at the root
    of it. No support for more than 1 levels of nesting, though.

  * Ability to be run on cvs.openbsd.org as well as on your own
    machine.

  * -f option, to force import even if some checks failed. This is
    useful, e.g., when moving stuff around the whole tree.

  * -p option, to set root ports directory manually. Very helpful
    when you have temporary "clean" directory without extra changes
    under some custom path, like: /home/joe/cvs/wk4/www/webkit-4.

I have even more ideas but I think it's enough for now. :) Most of
this functionality tested on 10+ imports already.

Reviewers are welcome.

--
  WBR,
    Vadim Zhukov


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      11 Aug 2013 20:28:53 -0000
@@ -22,48 +22,134 @@
 set -e
 
 usage() {
-       echo "usage: $(basename $0) [-u username]" >&2
+       echo "usage: $(basename $0) [-f] [-p portsdir] [-u username]" >&2
        exit 1
 }
 
 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)
+               if [ "${PWD##${OPTARG}}" = "${PWD}" ]; then
+                       cat >&2 <<EOE
+$(basename "$0"): the root directory specified (${OPTARG})
+could not be found in current directory path: ${PWD}
+EOE
+                       exit 3
+               fi
+               portsdir="$OPTARG"
+               ;;
+
+       u)
+               user="$OPTARG"
+               ;;
+
+       *)
+               usage
+               ;;
        esac
 done
 
-cvsroot=$u...@cvs.openbsd.org:/cvs
-error=false
-fulldir=$(pwd)
-importname="ports/${fulldir##*/ports/*(mystuff/|openbsd-wip/|p5-ports-wip/)}"
+if [ -z "$portsdir" ]; then
+       portsdir="${portsdir:-$(make show=PORTSDIR 2>/dev/null || true)}"
+fi
+echo "PORTSDIR is: $portsdir" >&2
+
+make_args="PORTSDIR_PATH=${portsdir}:$(cd /usr/ports && make -V PORTSDIR_PATH)"
+echo "make(1) args are: $make_args" >&2
+
+pkgpath="$(make $make_args show=PKGPATH 2>/dev/null || true)"
+if [ -z "$pkgpath" ]; then
+       if [ -n "$portsdir" ]; then
+               pkgpath="${PWD##${portsdir}/}"
+       else
+               # pure heuristics
+               pkgpath="${PWD##*/ports/*(mystuff/|openbsd-wip/|p5-ports-wip/)}"
+       fi
+fi
+echo "PKGPATH is: $pkgpath" >&2
+
+if [ X"$pkgpath" = X"$PWD" ]; then
+       cat >&2 <<EOE
+$(basename "$0"): could not detect root ports directory.
+Please provide one with -p option.
+EOE
+       exit 2
+fi
+
 timestamp=$(date '+%Y%m%d')
+if [ cvs.openbsd.org = "`hostname`" ]; then
+       is_cvs=true
+       cvsroot=/cvs
+else
+       is_cvs=false
+       cvsroot=${user}@cvs.openbsd.org:/cvs
+fi
+
+error=false
 
 err() { echo "$*"; error=true; }
 
-[[ -f Makefile && -f distinfo && -f pkg/DESCR  && -f pkg/PLIST ]] || err "No 
ports files?"
+check_dir() {
+       ls $1/Makefile $1/distinfo $1/pkg/DESCR* $1/pkg/PLIST* >/dev/null || \
+           err "No ports files in $dir directory?"
+}
+
+if [ -f Makefile.inc ]; then
+       for d in */; do check_dir $d; done
+       egrep -q '^[[:space:]]*SUBDIR[[:space:]]*=' Makefile || err "missing 
subdir Makefile"
+else
+       check_dir .
+fi
+
 find . -name .git          -print|read i && err "You git!"
+find . -name .hg           -print|read i && err "You hog!"
 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 *.core -print|read i && err "core dump file found"
 find . -type f -name .todo -print|read i && err "devtodo file found"
+find . -type f -name TODO  -print|read i && err "WIP TODO file found"
+find . -type f -name UPDATE -print|read i && err "WIP UPDATE file found"
 find . -type d -name CVS   -print|read i && err "Some CVS stuff already in 
there, very funky"
-$error && exit 1
+find . -name Makefile|xargs fgrep -q REVISION && err "Don't be a bug, remove 
REVISIONs"
+
+set -- $(make $make_args show=SHARED_LIBS)
+while [ $# -gt 1 ]; do
+       lib=$1
+       libver=$2
+       if [ X"$libver" != X0.0 ]; then
+               err "Library $lib has version $libver instead of 0.0"
+       fi
+       shift 2
+done
+
+if $error; then
+       if $force; then
+               echo "WARNING: forcing import even with warnings above" >&2
+       else
+               exit 1
+       fi
+fi
 
 echo -n "Import would go into: "
-cvs -n -d$cvsroot import $importname $user ${user}_$timestamp 2>/dev/null | \
+cvs -n -d$cvsroot import ports/$pkgpath $user ${user}_$timestamp 2>/dev/null | 
\
        grep Makefile | head -1 | awk '{print $2}' | xargs dirname
 
 read ans?'Correct path? [y/n] '
 if [[ $ans == +(y|Y) ]]; then
-       cvs -d$cvsroot import $importname $user ${user}_$timestamp
-       cd /usr/$importname/../
-       cvs -d$cvsroot update -AdP ${fulldir##*/}
+       cvs -d$cvsroot import ports/$pkgpath $user ${user}_$timestamp
+       cd "$portsdir/$(dirname $pkgpath)"
+       $is_cvs || cvs -d$cvsroot update -AdP $(basename $pkgpath)
        echo "Don't forget to commit the category Makefile when you're done!"
-       cd /usr/$importname/../
        pwd
 fi
Index: man/man1/portimport.1
===================================================================
RCS file: /cvs/ports/infrastructure/man/man1/portimport.1,v
retrieving revision 1.2
diff -u -p -r1.2 portimport.1
--- man/man1/portimport.1       11 Apr 2013 15:18:00 -0000      1.2
+++ man/man1/portimport.1       11 Aug 2013 20:28:53 -0000
@@ -22,6 +22,8 @@
 .Nd import a new port to the ports cvs repository
 .Sh SYNOPSIS
 .Nm
+.Op Fl f
+.Op Fl p Ar portsdir
 .Op Fl u Ar username
 .Sh DESCRIPTION
 .Nm
@@ -47,8 +49,36 @@ ports cvs repository.
 After the import, the new port is checked out in the respective directory
 of the local ports tree.
 .Pp
+By default,
+.Nm
+automatically picks up any direcrory named
+.Dq ports
+with optional
+.Dq mystuff ,
+.Dq openbsd-wip
+or
+.Dq p5-ports-wip
+subdirectory component, as ports root.
+.Pp
+For example: if the port being imported is located in
+.Pa /home/joe/cvs/ports/p5-ports-wip/devel/p5-Foo ,
+then root ports directory will be detected as being
+.Pa /home/joe/cvs/ports/p5-ports-wip
+automagically.
+To override this behaviour, see the
+.Fl p
+option description below.
+.Pp
 The following options are available:
 .Bl -tag -width Ds
+.It Fl f
+Forces import even if some checks fail.
+Should be used in corner cases, e.g., when moving ports in tree.
+.It Fl p Ar portsdir
+Forces the given directory to be treated as ports root directory.
+Cancels autodetection of root ports directory made by default.
+This option is useful, e.g., when you have temporary ports tree in
+non-standard location.
 .It Fl u Ar username
 Set the username used for
 .Xr ssh 1 ,
@@ -64,3 +94,8 @@ modified by Stuart Henderson and rewritt
 The
 .Ev CVSROOT
 environment variable is not used.
+.Sh BUGS
+.Nm doesn't handle complicated port hierarchies, only simple ones:
+single port directory, or
+.Pa Makefile.inc
+with subdirectories containing ports.

Reply via email to