Here's another approach. I believe I do not need more than @option is-branch
to actually mark branched ports... The current tree is clean enough that the last component of the pkgpath is always enough to disambiguate the path (even though there are some surprising choices of names). Follows a quick script to test that theory and the results... Index: OpenBSD/PackingElement.pm =================================================================== RCS file: /cvs/src/usr.sbin/pkg_add/OpenBSD/PackingElement.pm,v retrieving revision 1.243 diff -u -p -r1.243 PackingElement.pm --- OpenBSD/PackingElement.pm 3 Feb 2016 18:30:15 -0000 1.243 +++ OpenBSD/PackingElement.pm 25 Jun 2016 13:23:49 -0000 @@ -894,6 +894,8 @@ sub new return OpenBSD::PackingElement::Firmware->new; } elsif ($args eq 'always-update') { return OpenBSD::PackingElement::AlwaysUpdate->new; + } elsif ($args eq 'is-branch') { + return OpenBSD::PackingElement::IsBranch->new; } else { die "Unknown option: $args"; } @@ -941,6 +943,13 @@ sub category() 'always-update'; } +package OpenBSD::PackingElement::IsBranch; +our @ISA=qw(OpenBSD::PackingElement::UniqueOption); + +sub category() +{ + 'is-branch'; +} # The special elements that don't end in the right place package OpenBSD::PackingElement::ExtraInfo; our @ISA=qw(OpenBSD::PackingElement::Unique OpenBSD::PackingElement::Comment); Index: OpenBSD/PackingList.pm =================================================================== RCS file: /cvs/src/usr.sbin/pkg_add/OpenBSD/PackingList.pm,v retrieving revision 1.136 diff -u -p -r1.136 PackingList.pm --- OpenBSD/PackingList.pm 14 Jun 2016 15:41:31 -0000 1.136 +++ OpenBSD/PackingList.pm 25 Jun 2016 13:23:49 -0000 @@ -257,7 +257,7 @@ sub ExtraInfoOnly { my ($fh, $cont) = @_; while (<$fh>) { - if (m/^\@(?:name|pkgpath|comment\s+(?:subdir|pkgpath)\=)\b/o) { + if (m/^\@(?:name|pkgpath|comment\s+(?:subdir|pkgpath)\=|option\s+is-branch)\b/o) { &$cont($_); # XXX optimization } elsif (m/^\@(?:depend|wantlib|newgroup|newuser|cwd)\b/o) { @@ -446,7 +446,7 @@ sub match_pkgpath } our @unique_categories = - (qw(name url signer digital-signature no-default-conflict manual-installation firmware always-update extrainfo localbase arch)); + (qw(name url signer digital-signature no-default-conflict manual-installation firmware always-update is-branch extrainfo localbase arch)); our @list_categories = (qw(conflict pkgpath ask-update depend Index: OpenBSD/PkgInfo.pm =================================================================== RCS file: /cvs/src/usr.sbin/pkg_add/OpenBSD/PkgInfo.pm,v retrieving revision 1.38 diff -u -p -r1.38 PkgInfo.pm --- OpenBSD/PkgInfo.pm 22 Jun 2016 12:18:21 -0000 1.38 +++ OpenBSD/PkgInfo.pm 25 Jun 2016 13:23:50 -0000 @@ -407,6 +407,28 @@ sub may_check_data $handle->{checked} = 1; } +sub print_branch +{ + my ($self, $state, $pkg, $handle) = @_; + unless (defined $handle) { + $state->errsay("Error printing info for #1: no info ?", $pkg); + return; + } + require OpenBSD::PackingList; + require OpenBSD::PackageName; + + my $plist = $handle->plist(\&OpenBSD::PackingList::ExtraInfoOnly); + my $name = OpenBSD::PackageName->new_from_string($plist->pkgname); + my $stem = $name->{stem}; + my $compose = $stem."--".join('-', sort keys %{$name->{flavors}}); + if ($plist->has('is-branch')) { + if ($plist->fullpkgpath =~ m/\/(.*?)(,.*)?$/) { + $compose .= "%$1"; + } + } + $state->say("#1", $compose); +} + sub print_info { my ($self, $state, $pkg, $handle) = @_; @@ -567,8 +589,8 @@ sub parse_and_run } }; $state->{no_exports} = 1; - $state->handle_options('cCdfF:hIKLmPQ:qr:RsSUe:E:Ml:aAt', - '[-AaCcdfIKLMmPqRSstUv] [-D nolock][-E filename] [-e pkg-name] ', + $state->handle_options('cCdfF:hIKLmPQ:qr:RsSUe:E:Ml:aAtz', + '[-AaCcdfIKLMmPqRSstUvz] [-D nolock][-E filename] [-e pkg-name] ', '[-l str] [-Q query] [-r pkgspec] [pkg-name ...]'); if ($state->opt('r')) { @@ -607,6 +629,9 @@ sub parse_and_run $state->setopts('cdMR'); } } + if ($state->opt('z')) { + $state->setopts('am'); + } if ($state->opt('Q')) { require OpenBSD::Search; @@ -674,7 +699,11 @@ sub parse_and_run } if (!$self->find_pkg($state, $pkg, sub { - $self->print_info($state, @_); + if ($state->opt('z')) { + $self->print_branch($state, @_); + } else { + $self->print_info($state, @_); + } })) { $exit_code = 1; } ----------------------------------- #! /usr/bin/perl use OpenBSD::PackageName; open(my $fh, "echo 'select fullpkgpath, fullpkgname from ports;'|sqlite3 /usr/local/share/sqlports|"); while(<$fh>) { chomp; ($fullpkgpath, $fullpkgname) = split(/\|/, $_); my $name = OpenBSD::PackageName->new_from_string($fullpkgname); $stemmed = $name->{stem}."--".join('-', sort keys %{$name->{flavors}}); $h->{$stemmed}{$fullpkgname} = $fullpkgpath; } for my $k (sort keys %$h) { my @ks = keys %{$h->{$k}}; if (@ks > 1) { print $k, ": "; while (my ($k2, $v) = each %{$h->{$k}}) { print "$k2->$v "; } print "\n"; } } autoconf--: autoconf-2.58p4->devel/autoconf/2.58 autoconf-2.13p3->devel/autoconf/2.13 autoconf-2.59p4->devel/autoconf/2.59 autoconf-2.56p3->devel/autoconf/2.56 autoconf-2.61p4->devel/autoconf/2.61 autoconf-2.69p1->devel/autoconf/2.69 autoconf-2.67p0->devel/autoconf/2.67 autoconf-2.54p4->devel/autoconf/2.54 autoconf-2.62p1->devel/autoconf/2.62 autoconf-2.63p0->devel/autoconf/2.63 autoconf-2.64p0->devel/autoconf/2.64 autoconf-2.65p0->devel/autoconf/2.65 autoconf-2.57p3->devel/autoconf/2.57 autoconf-2.68p0->devel/autoconf/2.68 autoconf-2.52p5->devel/autoconf/2.52 autoconf-2.60p4->devel/autoconf/2.60 automake--: automake-1.8.5p8->devel/automake/1.8 automake-1.14.1->devel/automake/1.14 automake-1.4.6p4->devel/automake/1.4 automake-1.13.4p0->devel/automake/1.13 automake-1.12.6p0->devel/automake/1.12 automake-1.10.3p7->devel/automake/1.10 automake-1.15->devel/automake/1.15 automake-1.9.6p11->devel/automake/1.9 automake-1.11.6p1->devel/automake/1.11 db--: db-4.6.21p2v0->databases/db/v4,no_java,no_tcl db-3.1.17p1v0->databases/db/v3,-main db-tcl--: db-tcl-3.1.17v0->databases/db/v3,-tcl db-tcl-4.6.21p0v0->databases/db/v4,no_java,no_tcl,-tcl drupal--: drupal-7.32p2->www/drupal7/core drupal-6.36p0->www/drupal6/core emacs--no_x11: emacs-24.5p4-no_x11->editors/emacs,no_x11 emacs-21.4p34-no_x11->editors/emacs21,no_x11,-main enlightenment--: enlightenment-1.0.9p4->x11/enlightenment enlightenment-0.17.6p4v1->x11/e17/e erlang--: erlang-16b.03p9v0->lang/erlang/16,-main erlang-17.5p5v0->lang/erlang/17,-main erlang-18.1p0v0->lang/erlang/18,-main erlang-wx--: erlang-wx-16b.03p0v0->lang/erlang/16,-wx erlang-wx-18.1p0v0->lang/erlang/18,-wx erlang-wx-17.5p0v0->lang/erlang/17,-wx facter--: facter-3.1.8p0->sysutils/facter facter-2.4.6->sysutils/ruby-facter freeradius--: freeradius-2.2.9p3->net/freeradius,-main freeradius-3.0.11->net/freeradius3,-main freeradius-iodbc--: freeradius-iodbc-2.2.9p2->net/freeradius,-iodbc freeradius-iodbc-3.0.11->net/freeradius3,-iodbc freeradius-ldap--: freeradius-ldap-3.0.11->net/freeradius3,-ldap freeradius-ldap-2.2.9p2->net/freeradius,-ldap freeradius-mysql--: freeradius-mysql-2.2.9p2->net/freeradius,-mysql freeradius-mysql-3.0.11->net/freeradius3,-mysql freeradius-pgsql--: freeradius-pgsql-2.2.9p2->net/freeradius,-pgsql freeradius-pgsql-3.0.11->net/freeradius3,-pgsql g++--: g++-4.9.3p6->lang/gcc/4.9,-c++ g++-4.6.4p16->lang/gcc/4.6,-c++ g95--: g95-4.9.3p6->lang/gcc/4.9,-f95 g95-4.6.4p16->lang/gcc/4.6,-f95 gcc--: gcc-4.9.3p6->lang/gcc/4.9,-main gcc-4.6.4p16->lang/gcc/4.6,-main gcj--: gcj-4.6.4p17->lang/gcc/4.6,-java gcj-4.9.3p7->lang/gcc/4.9,-java gnat--: gnat-4.6.4p16->lang/gcc/4.6,-ada gnat-4.9.3p6->lang/gcc/4.9,-ada gnupg--: gnupg-1.4.19p1->security/gnupg gnupg-2.1.9->security/gnupg2 gobjc--: gobjc-4.6.4p16->lang/gcc/4.6,-objc gobjc-4.9.3p6->lang/gcc/4.9,-objc ices--: ices-2.0.2p0->net/ices2 ices-0.4p10->net/ices jdk--: jdk-1.8.0.72v0->devel/jdk/1.8,-main jdk-1.7.0.80p0v0->devel/jdk/1.7,-main jenkins--: jenkins-1.656->devel/jenkins/devel jenkins-1.651.2->devel/jenkins/stable jre--: jre-1.7.0.80p0v0->devel/jdk/1.7,-jre jre-1.8.0.72v0->devel/jdk/1.8,-jre kdegames--: kdegames-3.5.10p16->x11/kde/games3 kdegames-4.14.3->meta/kde4,-games kdelibs--: kdelibs-4.14.10p4->x11/kde4/libs,-main kdelibs-3.5.10p39->x11/kde/libs3,-main libnet--: libnet-1.1.2.1p2v0->net/libnet/1.1 libnet-1.0.2ap2v0->net/libnet/1.0 lua--: lua-5.2.4p0->lang/lua/5.2 lua-5.1.5p5->lang/lua/5.1 lua-5.3.3->lang/lua/5.3 mono-icon-theme--: mono-icon-theme-4.14.3p1->x11/kde4/artwork,-mono mono-icon-theme-3.5.10p0->x11/kde/accessibility3,-mono netatalk--: netatalk-3.1.8p0->net/netatalk3 netatalk-2.2.5p6->net/netatalk openldap-server--: openldap-server-2.3.43p17->databases/openldap23 openldap-server-2.4.44->databases/openldap,-server oxygen-icons--: oxygen-icons-4.14.3p0->x11/kde4/oxygen-icons oxygen-icons-5.21.0->devel/kf5/oxygen-icons pgp--: pgp-2.6.3p0->security/pgp pgp-5.0i->security/pgp5 php--: php-5.6.22->lang/php/5.6,-main php-5.5.36->lang/php/5.5,-main php-7.0.7->lang/php/7.0,-main php-bz2--: php-bz2-5.5.36->lang/php/5.5,-bz2 php-bz2-5.6.22->lang/php/5.6,-bz2 php-bz2-7.0.7->lang/php/7.0,-bz2 php-curl--: php-curl-7.0.7->lang/php/7.0,-curl php-curl-5.6.22->lang/php/5.6,-curl php-curl-5.5.36->lang/php/5.5,-curl php-dba--: php-dba-5.6.22->lang/php/5.6,-dba php-dba-5.5.36->lang/php/5.5,-dba php-dba-7.0.7->lang/php/7.0,-dba php-fastcgi--: php-fastcgi-5.5.36->lang/php/5.5,-fastcgi php-fastcgi-7.0.7->lang/php/7.0,-fastcgi php-fastcgi-5.6.22->lang/php/5.6,-fastcgi php-gd--: php-gd-5.5.36->lang/php/5.5,-gd php-gd-5.6.22->lang/php/5.6,-gd php-gd-7.0.7->lang/php/7.0,-gd php-gmp--: php-gmp-5.6.22->lang/php/5.6,-gmp php-gmp-7.0.7->lang/php/7.0,-gmp php-gmp-5.5.36->lang/php/5.5,-gmp php-imap--: php-imap-7.0.7->lang/php/7.0,-imap php-imap-5.6.22->lang/php/5.6,-imap php-imap-5.5.36->lang/php/5.5,-imap php-intl--: php-intl-5.5.36->lang/php/5.5,-intl php-intl-7.0.7->lang/php/7.0,-intl php-intl-5.6.22->lang/php/5.6,-intl php-ldap--: php-ldap-5.6.22->lang/php/5.6,-ldap php-ldap-5.5.36->lang/php/5.5,-ldap php-ldap-7.0.7->lang/php/7.0,-ldap php-mcrypt--: php-mcrypt-5.6.22->lang/php/5.6,-mcrypt php-mcrypt-5.5.36->lang/php/5.5,-mcrypt php-mcrypt-7.0.7->lang/php/7.0,-mcrypt php-mssql--: php-mssql-5.6.22->lang/php/5.6,-mssql php-mssql-5.5.36->lang/php/5.5,-mssql php-mysql--: php-mysql-5.6.22->lang/php/5.6,-mysql php-mysql-5.5.36->lang/php/5.5,-mysql php-mysqli--: php-mysqli-7.0.7->lang/php/7.0,-mysqli php-mysqli-5.5.36->lang/php/5.5,-mysqli php-mysqli-5.6.22->lang/php/5.6,-mysqli php-odbc--: php-odbc-5.5.36->lang/php/5.5,-odbc php-odbc-7.0.7->lang/php/7.0,-odbc php-odbc-5.6.22->lang/php/5.6,-odbc php-pcntl--: php-pcntl-5.5.36->lang/php/5.5,-pcntl php-pcntl-5.6.22->lang/php/5.6,-pcntl php-pcntl-7.0.7->lang/php/7.0,-pcntl php-pdo_dblib--: php-pdo_dblib-5.5.36->lang/php/5.5,-pdo_dblib php-pdo_dblib-5.6.22->lang/php/5.6,-pdo_dblib php-pdo_dblib-7.0.7->lang/php/7.0,-pdo_dblib php-pdo_mysql--: php-pdo_mysql-5.5.36->lang/php/5.5,-pdo_mysql php-pdo_mysql-7.0.7->lang/php/7.0,-pdo_mysql php-pdo_mysql-5.6.22->lang/php/5.6,-pdo_mysql php-pdo_pgsql--: php-pdo_pgsql-7.0.7->lang/php/7.0,-pdo_pgsql php-pdo_pgsql-5.5.36->lang/php/5.5,-pdo_pgsql php-pdo_pgsql-5.6.22->lang/php/5.6,-pdo_pgsql php-pgsql--: php-pgsql-5.6.22->lang/php/5.6,-pgsql php-pgsql-7.0.7->lang/php/7.0,-pgsql php-pgsql-5.5.36->lang/php/5.5,-pgsql php-pspell--: php-pspell-7.0.7->lang/php/7.0,-pspell php-pspell-5.6.22->lang/php/5.6,-pspell php-pspell-5.5.36->lang/php/5.5,-pspell php-shmop--: php-shmop-5.6.22->lang/php/5.6,-shmop php-shmop-7.0.7->lang/php/7.0,-shmop php-shmop-5.5.36->lang/php/5.5,-shmop php-snmp--: php-snmp-5.6.22->lang/php/5.6,-snmp php-snmp-5.5.36->lang/php/5.5,-snmp php-snmp-7.0.7->lang/php/7.0,-snmp php-soap--: php-soap-5.6.22->lang/php/5.6,-soap php-soap-5.5.36->lang/php/5.5,-soap php-soap-7.0.7->lang/php/7.0,-soap php-sybase_ct--: php-sybase_ct-5.6.22->lang/php/5.6,-sybase_ct php-sybase_ct-5.5.36->lang/php/5.5,-sybase_ct php-tidy--: php-tidy-7.0.7->lang/php/7.0,-tidy php-tidy-5.6.22->lang/php/5.6,-tidy php-tidy-5.5.36->lang/php/5.5,-tidy php-xmlrpc--: php-xmlrpc-5.5.36->lang/php/5.5,-xmlrpc php-xmlrpc-7.0.7->lang/php/7.0,-xmlrpc php-xmlrpc-5.6.22->lang/php/5.6,-xmlrpc php-xsl--: php-xsl-5.6.22->lang/php/5.6,-xsl php-xsl-7.0.7->lang/php/7.0,-xsl php-xsl-5.5.36->lang/php/5.5,-xsl php-zip--: php-zip-5.5.36->lang/php/5.5,-zip php-zip-5.6.22->lang/php/5.6,-zip php-zip-7.0.7->lang/php/7.0,-zip postfix--: postfix-3.2.20160515->mail/postfix/snapshot postfix-3.1.1->mail/postfix/stable postfix--ldap: postfix-3.2.20160515-ldap->mail/postfix/snapshot,ldap postfix-3.1.1-ldap->mail/postfix/stable,ldap postfix--ldap-sasl2: postfix-3.2.20160515-sasl2-ldap->mail/postfix/snapshot,ldap,sasl2 postfix-3.1.1-sasl2-ldap->mail/postfix/stable,ldap,sasl2 postfix--mysql: postfix-3.2.20160515-mysql->mail/postfix/snapshot,mysql postfix-3.1.1-mysql->mail/postfix/stable,mysql postfix--mysql-sasl2: postfix-3.2.20160515-sasl2-mysql->mail/postfix/snapshot,mysql,sasl2 postfix-3.1.1-sasl2-mysql->mail/postfix/stable,mysql,sasl2 postfix--pgsql: postfix-3.2.20160515-pgsql->mail/postfix/snapshot,pgsql postfix-3.1.1-pgsql->mail/postfix/stable,pgsql postfix--pgsql-sasl2: postfix-3.1.1-sasl2-pgsql->mail/postfix/stable,pgsql,sasl2 postfix-3.2.20160515-sasl2-pgsql->mail/postfix/snapshot,pgsql,sasl2 postfix--sasl2: postfix-3.1.1-sasl2->mail/postfix/stable,sasl2 postfix-3.2.20160515-sasl2->mail/postfix/snapshot,sasl2 puppet--: puppet-3.8.7p5->sysutils/ruby-puppet/3 puppet-4.5.2->sysutils/ruby-puppet/4 puppetdb--: puppetdb-2.3.8p0->databases/puppetdb,-main puppetdb-4.1.0p0->databases/puppetdb4,-main python--: python-3.5.1p1->lang/python/3.5,-main python-3.4.4p1->lang/python/3.4,-main python-2.7.11p1->lang/python/2.7,-main python-gdbm--: python-gdbm-3.5.1p1->lang/python/3.5,-gdbm python-gdbm-2.7.11p1->lang/python/2.7,-gdbm python-gdbm-3.4.4p1->lang/python/3.4,-gdbm python-idle--: python-idle-3.5.1p1->lang/python/3.5,-idle python-idle-3.4.4p1->lang/python/3.4,-idle python-idle-2.7.11p1->lang/python/2.7,-idle python-tests--: python-tests-3.5.1p1->lang/python/3.5,-tests python-tests-2.7.11p2->lang/python/2.7,-tests python-tests-3.4.4p1->lang/python/3.4,-tests python-tkinter--: python-tkinter-3.5.1p1->lang/python/3.5,-tkinter python-tkinter-2.7.11p1->lang/python/2.7,-tkinter python-tkinter-3.4.4p1->lang/python/3.4,-tkinter ruby--: ruby-2.1.9->lang/ruby/2.1,-main ruby-2.2.5->lang/ruby/2.2,-main ruby-1.8.7.374p5->lang/ruby/1.8,-main ruby-2.0.0.648->lang/ruby/2.0,-main ruby-2.3.1->lang/ruby/2.3,-main ruby21-rspec--: ruby21-rspec-3.4.0->devel/ruby-rspec/3/rspec,ruby21 ruby21-rspec-1.3.2p5->devel/ruby-rspec/1,ruby21 ruby22-rspec--: ruby22-rspec-1.3.2p5->devel/ruby-rspec/1,ruby22 ruby22-rspec-3.4.0->devel/ruby-rspec/3/rspec,ruby22 ruby23-rspec--: ruby23-rspec-1.3.2p5->devel/ruby-rspec/1,ruby23 ruby23-rspec-3.4.0->devel/ruby-rspec/3/rspec,ruby23 spidermonkey--: spidermonkey-24.2.0p4->devel/spidermonkey spidermonkey-1.9.2.28p3v0->lang/spidermonkey tcl--: tcl-8.5.18p0->lang/tcl/8.5 tcl-8.6.4p0->lang/tcl/8.6 tk--: tk-8.5.18p0->x11/tk/8.5 tk-8.6.4p0->x11/tk/8.6 tomcat--: tomcat-8.0.36->www/tomcat/v8,-main tomcat-6.0.45->www/tomcat/v6,-main tomcat-7.0.70->www/tomcat/v7,-main tomcat-examples--: tomcat-examples-6.0.45->www/tomcat/v6,-examples tomcat-examples-8.0.36->www/tomcat/v8,-examples tomcat-examples-7.0.70->www/tomcat/v7,-examples