#!/bin/sh ############################################################################### # # Copyright (c) 2013 Yasushi Oshima, All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY YASUSHI OSHIMA. AND CONTRIBUTORS ``AS IS'' # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # ############################################################################### # # binpkgdepends.sh # # Recursive print binary packages dependency display tool # # version 0.20130123 - pre-alpha (very experimental) ############################################################################### # # TODO: # - Many error check is needed. # - Support for more complex dependency pacakage # - Verbose mode # - Download packages from remote site (without install any packages) # - and many... # # base PATH or URI of binary packages PKG_PATH=${PKG_PATH-"/usr/pkgsrc/packages/All"} export PKG_PATH execute_awk() { awk -v initial_pkglist="$*" ' ############################################################################### # # Remove conditinal clause of version @pkgdep style # Args: # pname : @pkgdep style required binary package version # Return: # Base package name # Example: # "gtk2+>=2.24.12nb3" to "gtk2+" # ############################################################################### function remove_version( pname ) { sub(/[<>=].*$/,"",pname); sub(/-[0-9\[\?].*$/,"",pname); return pname } ############################################################################### # # Remove file path element from full URI file-path string # Args: # pname : @pkgdep style required binary package version # Return: # file name part # Example: # "ftp://ftp.netbsd.org:21/pub/pkgsrc/packages/NetBSD/i386/6.0_2012Q3/All/gtk2+-2.24.12nb3.tgz" # to "gtk2+-2.24.12nb3.tgz" # ############################################################################### function remove_path( pname ) { sub(/^.*\//,"",pname); return pname } ############################################################################### # # Store dependency package names to Array # Args: # pname: base pacakge name # full: full dependecy style pkgname string # ############################################################################### function updatedeparray( pname, full ) { if (! pkgs[pname]){ # New package, add to array pkgs[pname] = full " "; } else { # Already exists. if (! match(pkgs[pname], full " ")) { # New version check condision # XXX: However, it does not use now. # What does it use for? pkgs[pname] = pkgs[pname] full " "; } } } ############################################################################### # # Store real binary package name to Array # Args: # pname: base package name # fullpkg: complete binary package name # Todo: # When binary package file is not equal from some different # packages... does it happen realy? # ############################################################################### function updatepkgname( pname, fullpkg ) { if ( ! pkgname[pname] ) { # New package, add to array pkgname[pname] = fullpkg; } } ############################################################################### # # Get dependency packages from pkg_info(1) -n -q # Args: # fillpkgname: Full path URI style binary package file name # ############################################################################### function getdepname(fullpkgname) { while( "pkg_info -q -n " fullpkgname | getline ) { if ( length($0) > 0) { updatedeparray(remove_version($0), $0); getpkgname(remove_version($0)); } } } ############################################################################### # # Get full package and best selected binary package filename # by pkg_admin(1) findbest command # Args: # pkg: base package name (Ex: only "gtk2" ) # ############################################################################### function getpkgname(pkg) { if ( pkgname[pkg] ) return; execcmd="pkg_admin findbest " pkg; while (execcmd | getline) { fullpkgname=$0; updatepkgname(pkg,fullpkgname); close(execcmd); break; } print remove_path(fullpkgname); getdepname(fullpkgname); } ############################################################################### # # Start awk-script with base package name # Interface-variable: # initial_pkglist: base package name list for check # ############################################################################### BEGIN { split(initial_pkglist, chkpkglist); for (i in chkpkglist) { getpkgname(chkpkglist[i]); } updatedeparray(chkpkglist[i],chkpkglist[i]); if ( debug ) { for (i in pkgs) { print i, remove_path(pkgname[i]), pkgname[i]; } } }' } usage() { echo "binpkgdepends.sh package_name [...]" } if [ $# -lt 1 ]; then usage exit 1 fi execute_awk $*