FreeBSD has a package system to manage installations and dependencies, and so does perl. Perl on FreeBSD, therefore, causes these to intersect in interesting, and sometimes suboptimal ways.
CPAN can be used to install perl packages that aren’t in the ports tree, and FreeBSD handles this with relative grace by including them in its package database with the prefix “bsdpan,” and be excluded from updates. An identical package installed from the ports tree will be prefixed with “p5” instead, and be treated as any other port, with dependencies and upgrades handled as part of the ports system.
After trying out a few CPAN modules (which in turn installed their own dependencies) I found myself with a great many “bsdpan” packages, which I’d prefer to tuck neatly into the bsd ports tree rather than continue to manage with CPAN, therefore, I whanged together a shell script to do it:
#!/bin/sh pkg_info | grep ^bsdpan | awk '{print $1}' > /tmp/bsdpan-to-p5.tmp > /tmp/bsdpan-to-p5-2.tmp cd /usr/ports while read bsdname; do name=$(echo $bsdname | cut -c 8- ) portpath=$(make search name=p5-$name | grep ^Path | awk '{print $2}' | sed -r 's/\/usr\/ports\///') shortname=$(echo $name | sed -r 's/(.*)-.*/\1/'); if [ "$portpath" ]; then echo -n p5-$name is in ports, echo " adding to list" echo portupgrade -o $portpath -f bsdpan-$shortname >> /tmp/bsdpan-to-p5-2.tmp else echo p5-$name not in ports portpath=$(make search name=p5-$shortname- | grep ^Path | awk '{print $2}' | sed -r 's/\/usr\/ports\///') if [ "$portpath" ]; then paths=$(echo $portpath | wc -w) if [ "$paths" -eq "1" ]; then p5name=$(make search name=p5-$shortname- | grep Port | awk '{print $2}') echo " ... $p5name found, using that" echo portupgrade -o $portpath -f bsdpan-$shortname >> /tmp/bsdpan-to-p5-2.tmp fi fi fi done < /tmp/bsdpan-to-p5.tmp rm /tmp/bsdpan-to-p5.tmp echo echo "Starting conversion ..." echo sh /tmp/bsdpan-to-p5-2.tmp rm /tmp/bsdpan-to-p5-2.tmp
The script tries to automate a manual process of finding the corresponding “p5” port for each “bsdpan” port, and builds a script that replaces each one using the portupgrade tool.
It doesn’t make any attempt to resolve dependencies, so it may take a few passes. It also can’t help where a search for the port name returns more than one possibility (usually part of a longer name) or when the “p5” name happens to be nothing like the “bsdpan” name, but in practice, there are only a handful of exceptions.