[haiku-commits] r35327 - haiku/trunk/data/bin

  • From: coling@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 28 Jan 2010 12:25:25 +0100 (CET)

Author: colin
Date: 2010-01-28 12:25:25 +0100 (Thu, 28 Jan 2010)
New Revision: 35327
Changeset: http://dev.haiku-os.org/changeset/35327/haiku
Ticket: http://dev.haiku-os.org/ticket/5248
Ticket: http://dev.haiku-os.org/ticket/5315

Modified:
   haiku/trunk/data/bin/installoptionalpackage
Log:
* Recursive dependencies are now correctly handled, so Subversion and BeHappy
  should now be able to be installed gracefully. This fixes ticket #5248.
* Enhancement of the -a parameter, so that it accepts multiple packages at once.
  Multiple packages have to be included in double quotes, due to the way getopts
  handles options. This fixes ticket #5315.
* Thanks mmadia for this patch!


Modified: haiku/trunk/data/bin/installoptionalpackage
===================================================================
--- haiku/trunk/data/bin/installoptionalpackage 2010-01-28 09:55:41 UTC (rev 
35326)
+++ haiku/trunk/data/bin/installoptionalpackage 2010-01-28 11:25:25 UTC (rev 
35327)
@@ -1,6 +1,6 @@
-#!/bin/sh
+#!/bin/bash
 #
-# Copyright (c) 2009 Haiku Inc. All rights reserved.
+# Copyright (c) 2009-2010 Haiku Inc. All rights reserved.
 # Distributed under the terms of the MIT License.
 #
 # Authors:
@@ -20,17 +20,17 @@
 #     http://dev.haiku-os.org/wiki/PackageManagerIdeas
 #     http://dev.haiku-os.org/wiki/PackageFormat
 #
-# Usage: ./installoptionalpackage [-l] [-a]
+# Usage: ./installoptionalpackage [-l] [-a "<pkg> [<pkg> ...]"]
 # -l      List installable packages
-# -a      Add a package and all of its dependencies
+# -a      Add one or more packages and all dependencies
 
 
-declare -a packagesToInstall   
-declare -a availablePackages
+declare -A availablePackages
+declare availablePackagesKeys=""
 # Some Packages cannot be installed,
 # as they require either the source code or compiled binaries
-declare -a packageIgnoreList=( 'Bluetooth' 'Development' 'DevelopmentMin' \
-       'DevelopmentBase' 'NetFS' 'P7zip' 'UserlandFS' 'Welcome')
+declare packageIgnoreList='Bluetooth Development DevelopmentMin \
+DevelopmentBase P7zip UserlandFS Welcome Wifi-ipw2100+fw Wifi-iprowifi2200+fw'
 
 
 function CreateInstallerScript()
@@ -40,7 +40,7 @@
 
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        cat << EOF > ${tmpDir}/install-optpkg.sh
-#!/bin/sh
+#!/bin/bash
 
 tmpDir=${tmpDir}
 HAIKU_GCC_VERSION[1]=${HAIKU_GCC_VERSION[1]}
@@ -143,8 +143,8 @@
        done
        echo "Unzipping \$zipFile ..."
        unzipDir="\${dirTokens}"
-       unzip -q -d "\$unzipDir" "\$zipFile"
-       # TODO should .OptionalPackageDescription be added to AboutSystem?
+       unzip -q -o  -d "\$unzipDir" "\$zipFile"
+       
        if [ -f '/boot/.OptionalPackageDescription' ] ; then
                rm '/boot/.OptionalPackageDescription'
        fi
@@ -170,7 +170,9 @@
        local linkName="\${functionArgs[2]}"
        TrimLeadingSpace linkName
        TrimEndingSpace linkName
-                       
+       
+       mkdir -p "${dirTokens}"
+       
        if [ "\${linkName}" == '' ] ; then
                ln -sf "\${linkTarget}" -t "\${dirTokens}"
        else
@@ -225,215 +227,227 @@
 }
 
 
+function ContainsSubstring()
+{
+       # ContainsSubstring <stringToLookIn> <stringToLookFor>
+       local string="$1"
+       local substring="$2"
+       local newString=${string/${substring}/''}
+       if [ ${#string} -eq `expr ${#newString} + ${#substring}` ] ; then
+               return 0
+       fi
+       return 1
+}
+
+
+function Init()
+{
+       
+       # Set up some directory paths
+       baseDir=`finddir B_COMMON_DATA_DIRECTORY`/optional-packages
+       tmpDir=`finddir B_COMMON_TEMP_DIRECTORY`
+       libDir=`finddir B_SYSTEM_LIB_DIRECTORY`
+
+       # Make sure these files are empty.
+       echo "" > ${tmpDir}/optpkg.jam
+       echo "" > ${tmpDir}/optpkg.stage1
+       
+       if ! [ -d ${baseDir} ] ; then
+               mkdir -p ${baseDir}
+       fi
+       
+       # Retreive the necessary jam files from svn.
+       local buildFiles="OptionalPackages OptionalPackageDependencies \
+               OptionalBuildFeatures"
+       for file in ${buildFiles} ; do
+               GetBuildFile ${file}
+       done
+
+       DetectSystemConfiguration
+       ReadPackageNamesIntoMemory
+}
+
+
 function GetBuildFile()
 {
        # GetBuildFile <file>
-       # Downloads files from Haiku's svn 
-       if ! [ -f ${baseDir}/${1} ] ; then
-               echo "Fetching ${1} ..."
+       # Downloads files from Haiku's svn
+       local buildfile="$1"
+       if ! [ -f ${baseDir}/${buildfile} ] ; then
+               echo "Fetching ${buildfile} ..."
                cd ${baseDir}
                local baseURL=http://dev.haiku-os.org/export/
                local revision=`uname -v | awk '{print $1}' | sed -e 's/r//'`
-               wget ${baseURL}${revision}/haiku/trunk/build/jam/${file} 2>&1 > 
/dev/null
+               local 
url="${baseURL}${revision}/haiku/trunk/build/jam/${buildfile}"
+               wget -nv ${url} 2>&1 > /dev/null
        fi 
 }
 
 
-function GeneratePackageNames()
+function DetectSystemConfiguration()
 {
-       # GeneratePackageNames
-       # Creates a file containing available package names
-       local outfile="${baseDir}/OptionalPackageNames"
-       
-       if ! [ -f ${outfile} ] ; then
-               echo "Generating a list of Package Names ..."
-               
-               touch ${outfile}
-               local regExp='/^if\ \[\ IsOptionalHaikuImagePackageAdded/p'
-               sed -n -e "$regExp" ${baseDir}/OptionalPackages > 
${outfile}.temp
-               while read line ; do
-                       local pkg=`echo ${line} | awk '{print $4}'`
-                       
-                       if ! IspackageIgnoreListed ${pkg} ; then
-                               echo ${pkg} >> ${outfile}
-                       fi
-                       
-               done < ${outfile}.temp
-               rm ${outfile}.temp
-       fi 
-       
-       # read list into array
-       local count=0
-       while read line ; do
-               availablePackages[$count]=$line
-               ((count++))
-       done < ${outfile}
+       # Determine which GCC we're running and if we're a hybrid
+       if [ -d "$libDir"/gcc4 ] ; then
+               HAIKU_GCC_VERSION[1]=2
+               isHybridBuild=1
+       elif [ -d "$libDir"/gcc2 ] ; then
+               HAIKU_GCC_VERSION[1]=4
+               isHybridBuild=1
+       elif [ -f "$libDir"/libsupc++.so ] ; then
+               HAIKU_GCC_VERSION[1]=4
+               isHybridBuild=0
+       else
+               HAIKU_GCC_VERSION[1]=2
+               isHybridBuild=0
+       fi
+
+       # Determine the Architecture.
+       if [ `uname -m` == "BePC" ] ; then
+               TARGET_ARCH='x86'
+       fi
 }
 
 
-function IspackageIgnoreListed()
+function ReadPackageNamesIntoMemory()
 {
-       # IspackageIgnoreListed <pkg>
-       # Check if this package or any of its deps cannot be installed
+       local file="${baseDir}/OptionalPackageNames"
+       if ! [ -f ${file} ] ; then
+               GeneratePackageNames
+       fi
        
-       GetPackageDependencies ${1}
-       
-       local mustIgnore=1
-       for ignoreThisPackage in ${packageIgnoreList[*]} ; do
-               if [ ${1} == ${ignoreThisPackage} ] ; then
-                       mustIgnore=0
-                       break
-               else
-                       for dep in ${tempDeps} ; do
-                               if [ ${dep} == ${ignoreThisPackage} ] ; then
-                                       mustIgnore=0
-                                       break
-                               fi
-                       done
-               fi
-       done
-       return $mustIgnore
+       # read list into associative array
+       while read line ; do
+               local pkg=`echo ${line} | awk '{print $1}'`
+               local pkgDeps=${line/':'/}
+               availablePackages[${pkg}]="${pkgDeps}"
+               availablePackagesKeys="${availablePackagesKeys} ${pkg}"
+       done < ${file}
 }
 
 
-function IsPackageNameValid()
+function GeneratePackageNames()
 {
-       # IsPackageNameValid <name>
-       if IspackageIgnoreListed "$1" ; then    
-               echo "Due to limitations, the package \"$1\" cannot be 
installed."
-               exit 1
-       fi
+       # GeneratePackageNames
+       # Creates a file containing available package names
+       # Each line shows a pakage and all of its recrusive dependencies
+       # "<pkg> : <dep1> <dep2> ..."
+       echo "Generating a list of Package Names ..."
        
-       local packageExists=1
-       for name in ${availablePackages[*]} ; do
-               if [ "$1" == "$name" ] ; then
-                       packageExists=0
-                       packagesToInstall[0]=${1}
-                       GetPackageDependencies "$1"
-                                               
-                       # move deps into packagesToInstall
-                       if [ ${#tempDeps} -gt 0 ] ; then
-                               for dep in ${tempDeps} ; do
-                                       if [ ';' == "$dep" ] ; then
-                                               break
-                                       fi
-                                       gPDi=${#packagesToInstall[@]}
-                                       ((gPDi++))
-                                       packagesToInstall[$gPDi]=${dep}
-                                       GetPackageDependencies ${dep}
-                               done
-                       fi
-                       echo "Packages to be installed:"
-                       echo "    ${packagesToInstall[*]}"
-                       return 0
+       local file="${baseDir}/OptionalPackageNames"
+       touch ${file}
+       
+       local regExp='/^if\ \[\ IsOptionalHaikuImagePackageAdded/p'
+       sed -n -e "$regExp" ${baseDir}/OptionalPackages > ${file}.temp
+       while read line ; do
+               # in each non-filtered line, the 4th word is the optional 
package
+               local pkg=`echo ${line} | awk '{print $4}'`
+               
+               nonRepeatingDeps=""
+               GetPackageDependencies "$pkg"
+               if IsPackageAndDepsOkToInstall ${pkg} ; then
+                       echo "${pkg} : ${nonRepeatingDeps}"  >> ${file}
                fi
-       done
-       
-       if [ $packageExists -gt 0 ] ; then
-               echo "Package \"$1\" does not exist."
-               echo ''
-               exit 1
-       fi
-       return 1
+               
+       done < ${file}.temp
+       rm ${file}.temp
 }
 
 
 function GetPackageDependencies()
 {
-       # getPackageDependecies <pkg>
-       # parse OptionalPackageDependencies for <pkg>'s dependencies
-       local regExp="^OptionalPackageDependencies\ ${1}"
+       # GetPackageDependencies <pkg>
+       
+       # parse OptionalPackageDependencies for the single line that defines 
+       # this optional package's dependencies.
+       local regExp="^OptionalPackageDependencies\ ${1}\ \:"
        local inputFile="${baseDir}/OptionalPackageDependencies"
+       
+       # print that single line
        sed -n -e "/${regExp}\ /p" ${inputFile} > ${tmpDir}/optpkg.temp
-       tempDeps=`sed -e "s/${regExp}\ :\ //" ${tmpDir}/optpkg.temp`
-       rm ${tmpDir}/optpkg.temp
-}
-
-
-function ContainsSubstring()
-{
-       # ContainsSubstring <stringToLookIn> <stringToLookFor>
-       local newString=${1/${2}/''}
-       if [ ${#1} -eq `expr ${#newString} + ${#2}` ] ; then
-               return 0
-       fi
-       return 1
-}
-
-function ReplaceComparators()
-{
-       # ReplaceComparators <line>
-       # One of the Jam-to-Bash conversion functions.
        
-       # Preserve string comparators for TARGET_ARCH.
-       if ! ContainsSubstring "$line" 'TARGET_ARCH' ; then
-               line=${line//'>='/'-ge'}
-               line=${line//'<='/'-le'}
-               line=${line//'>'/'-gt'}
-               line=${line//'<'/'-lt'}
-               line=${line//'!='/'-ne'}
-       fi
+       # strip out "OptionalPackageDependencies PackageName :"
+       # this leaves "<dep1> .... ;"
+       tempDeps=`sed -e "s/${regExp}\ //" ${tmpDir}/optpkg.temp`
+       
+       for foo in ${tempDeps%' ;'} ; do
+               # Prevent duplicate entries of the same dependency package.
+               if ! ContainsSubstring "${nonRepeatingDeps} " "${foo} " ; then
+                       nonRepeatingDeps="$foo $nonRepeatingDeps "
+                       nonRepeatingDeps="${nonRepeatingDeps//  / }"
+               fi 
+       done 
+       
+       # Recursively get the dependencies of these dependencies.
+       for dep in ${tempDeps%' ;'} ; do
+               GetPackageDependencies "$dep"
+       done
+       
 }
 
 
-function ConvertVariables()
+function IsPackageAndDepsOkToInstall()
 {
-       # ConvertVariables
-       # One of the Jam-to-Bash conversion functions.
-       # NOTE: jam's variables are normally '$(VARIABLE)'. \n
-       #               The issue is with '(' and ')', so let's replace them 
globally.
-       
-       if ContainsSubstring "$line" '$(' ; then
-               line=${line//'('/'{'}
-               line=${line//')'/'}'}
+       # IsPackageAndDepsOkToInstall <pkg>
+       if ContainsSubstring "${packageIgnoreList}" "${1}"; then
+               echo "...warning: ${1} cannot be installed"
+               return 1
        fi
+       for foo in ${nonRepeatingDeps} ; do
+               if ContainsSubstring "${packageIgnoreList}" "${foo}"; then
+                       echo "...warning: ${1} cannot be installed because of 
${foo}"
+                       return 1
+               fi
+       done
+       return 0
 }
 
 
-function ConvertVariableDeclarationLines()
+function AddPackage()
 {
-       # ConvertVariableDeclarationLines <regex> <variable>
-       # One of the Jam-to-Bash conversion functions.
-       # Jam lines that define variables need to be parsed differently.
-       eval local input='$'"$2"
-       local regex="$1"
-       local _outvar="$2"
+       # AddPackage <name>
+       packagesToInstall=""
+       proceedWithInstallation=false
        
-       input=${input/\ =\ /=}
-       input=${input/\;/''}
-       input=${input//\(/'{'}
-       input=${input//\)/'}'}
+       for desiredPackage in ${1}; do
+               if IsPackageNameValid $desiredPackage  ; then
+                       for item in ${availablePackages[${desiredPackage}]} ; do
+                               if ! ContainsSubstring "${packagesToInstall}" 
"${item}" ; then
+                                       packagesToInstall="${packagesToInstall} 
${item}"
+                               fi
+                       done
+                       proceedWithInstallation=true
+               fi
+       done
        
-       eval $_outvar="'$input'"
+       # If one or more packages can be installed, do it.
+       if $proceedWithInstallation  ; then
+               echo "To be installed: ${packagesToInstall}"
+               
+               for package in ${packagesToInstall} ; do
+                       # output the "if [ IsOptionalHaikuImagePackageAdded..." 
code block
+                       local regExp="if\ \[\ IsOptionalHaikuImagePackageAdded\ 
${package}"
+                       local inputFile="${baseDir}/OptionalPackages"
+                       sed -n "/^$regExp/,/^\}/p" ${inputFile} >> 
${tmpDir}/optpkg.jam
+               done
+               
+               ConvertJamToBash "${tmpDir}/optpkg.jam"
+               rm "${tmpDir}/optpkg.jam"
+       CreateInstallerScript
+       sh ${tmpDir}/install-optpkg.sh
+       rm ${tmpDir}/install-optpkg.sh
+       fi
 }
 
 
-
-function ConvertIfStatements()
+function IsPackageNameValid()
 {
-       # ConvertIfStatements <line>    
-       # One of the Jam-to-Bash conversion functions.
-       line=${line//'} else {'/'else '}
-       line=${line//'} else if '/'elif '}
-       if ContainsSubstring "$line" "if " ; then
-               if ! ContainsSubstring "$line" "if [" ; then
-                       line=${line/'if '/'if [ '}
+       # IsPackageNameValid <name>
+       for name in ${availablePackagesKeys} ; do
+               if [ "$1" == "$name" ] ; then
+                       return 0
                fi
-               
-               if ContainsSubstring "$line" '] {' ; then
-                       line=${line/'{'/' ; then'}
-               elif ContainsSubstring "$line" '{' ; then
-                       line=${line/'{'/' ] ; then'}
-               fi
-               
-               for compound in '&&' '||' ; do
-                       if ContainsSubstring "$line" "$compound" ; then
-                               line=${line/"$compound"/"] $compound ["}
-                       fi
-               done
-       fi
-       # Assume all remaining closing braces are part of if statements
-       line=${line/'}'/'fi'}
+       done
+       return 1
 }
 
 
@@ -513,100 +527,115 @@
 }
 
 
-function ListPackages()
+function ConvertVariableDeclarationLines()
 {
-       # ListPackages
-       echo "Available Optional Packages:"
-       for package in ${availablePackages[*]} ; do
-               echo ${package}
-       done
+       # ConvertVariableDeclarationLines <regex> <variable>
+       # One of the Jam-to-Bash conversion functions.
+       # Jam lines that define variables need to be parsed differently.
+       eval local input='$'"$2"
+       local regex="$1"
+       local _outvar="$2"
+       
+       input=${input/\ =\ /=}
+       input=${input/\;/''}
+       input=${input//\(/'{'}
+       input=${input//\)/'}'}
+       
+       eval $_outvar="'$input'"
 }
 
 
-function AddPackage()
+function ConvertIfStatements()
 {
-       # AddPackage <name>
-       if IsPackageNameValid $1  ; then
-               for package in ${packagesToInstall[*]} ; do
-                       local regExp="if\ \[\ IsOptionalHaikuImagePackageAdded\ 
${package}"
-                       local inputFile="${baseDir}/OptionalPackages"
-                       sed -n "/^$regExp/,/^\}/p" ${inputFile} >> 
${tmpDir}/optpkg.jam
+       # ConvertIfStatements <line>    
+       # One of the Jam-to-Bash conversion functions.
+       line=${line//'} else {'/'else '}
+       line=${line//'} else if '/'elif '}
+       if ContainsSubstring "$line" "if " ; then
+               if ! ContainsSubstring "$line" "if [" ; then
+                       line=${line/'if '/'if [ '}
+               fi
+               
+               if ContainsSubstring "$line" '] {' ; then
+                       line=${line/'{'/' ; then'}
+               elif ContainsSubstring "$line" '{' ; then
+                       line=${line/'{'/' ] ; then'}
+               fi
+               
+               for compound in '&&' '||' ; do
+                       if ContainsSubstring "$line" "$compound" ; then
+                               line=${line/"$compound"/"] $compound ["}
+                       fi
                done
-               ConvertJamToBash "${tmpDir}/optpkg.jam"
-               rm "${tmpDir}/optpkg.jam"
-       CreateInstallerScript
-       sh ${tmpDir}/install-optpkg.sh
-       rm ${tmpDir}/install-optpkg.sh
        fi
+       # Assume all remaining closing braces are part of if statements
+       line=${line/'}'/'fi'}
 }
 
 
-function DisplayUsage()
+function ConvertVariables()
 {
-       echo ''
-       echo 'Disclaimer:'
-       echo '  This is a temporary solution for installing OptionalPackages.'
-       echo '  In time, there will be an official package manager.'
-       echo "  See these URL's for info on the in-development package manager."
-       echo '    http://dev.haiku-os.org/wiki/PackageManagerIdeas'
-       echo '    http://dev.haiku-os.org/wiki/PackageFormat'
-       echo ''
-       echo "Usage: $0 [-l] [-a]"
-       echo "-l        List installable packages"
-       echo "-a        Add a package and all of its dependencies"
-       echo ''
+       # ConvertVariables
+       # One of the Jam-to-Bash conversion functions.
+       
+       # NOTE: jam's variables are normally '$(VARIABLE)'. \n
+       #               The issue is with '(' and ')', so let's replace them 
globally.
+       if ContainsSubstring "$line" '$(' ; then
+               line=${line//'('/'{'}
+               line=${line//')'/'}'}
+       fi
 }
 
 
-function DetectSystemConfiguration()
+function ReplaceComparators()
 {
-       # Determine which GCC we're running and if we're a hybrid
-       if [ -d "$libDir"/gcc4 ] ; then
-               HAIKU_GCC_VERSION[1]=2
-               isHybridBuild=1
-       elif [ -d "$libDir"/gcc2 ] ; then
-               HAIKU_GCC_VERSION[1]=4
-               isHybridBuild=1
-       elif [ -f "$libDir"/libsupc++.so ] ; then
-               HAIKU_GCC_VERSION[1]=4
-               isHybridBuild=0
-       else
-               HAIKU_GCC_VERSION[1]=2
-               isHybridBuild=0
+       # ReplaceComparators <line>
+       # One of the Jam-to-Bash conversion functions.
+       
+       # Preserve string comparators for TARGET_ARCH.
+       if ! ContainsSubstring "$line" 'TARGET_ARCH' ; then
+               line=${line//'>='/'-ge'}
+               line=${line//'<='/'-le'}
+               line=${line//'>'/'-gt'}
+               line=${line//'<'/'-lt'}
+               line=${line//'!='/'-ne'}
        fi
+}
 
-       # Determine the Architecture.
-       if [ `uname -m` == "BePC" ] ; then
-               TARGET_ARCH='x86'
-       fi
+
+function DisplayUsage()
+{
+       cat << EOF
+
+Disclaimer:
+  This is a temporary solution for installing OptionalPackages.
+  In time, there will be an official package manager.
+  See these URL's for information on the in-development package manager.
+    http://dev.haiku-os.org/wiki/PackageManagerIdeas
+    http://dev.haiku-os.org/wiki/PackageFormat
+
+Usage: ./installoptionalpackage [-l] [-a "<pkg> [<pkg> ...]"]
+-l      List installable packages
+-a      Add one or more packages and all dependencies
+
+EOF
 }
 
-function Init()
+
+function ListPackages()
 {
+       # ListPackages
+       echo ""
+       echo ""
+       echo "Available Optional Packages:"
        
-       # Set up some directory paths
-       baseDir=`finddir B_COMMON_DATA_DIRECTORY`/optional-packages
-       tmpDir=`finddir B_COMMON_TEMP_DIRECTORY`
-       libDir=`finddir B_SYSTEM_LIB_DIRECTORY`
-
-       # Make sure these files are empty.
-       echo "" > ${tmpDir}/optpkg.jam
-       echo "" > ${tmpDir}/optpkg.stage1
+       # single line:
+       echo ${availablePackagesKeys}
        
-       
-       if ! [ -d ${baseDir} ] ; then
-               mkdir -p ${baseDir}
-       fi
-       
-       # Retreive the necessary jam files from svn.
-       local buildFiles=( 'OptionalPackages' 'OptionalPackageDependencies' \
-               'OptionalBuildFeatures')
-       for file in ${buildFiles[*]} ; do
-               GetBuildFile ${file}
-       done
-
-       DetectSystemConfiguration
-       GeneratePackageNames
+       # one per line:
+       #for package in ${availablePackagesKeys} ; do
+       #       echo ${package}
+       #done
 }
 
 
@@ -622,7 +651,7 @@
 while getopts "a:lh" opt; do
        case $opt in
                a)
-                       AddPackage $OPTARG
+                       AddPackage "$OPTARG"
                        exit 0
                        ;;
                h)


Other related posts:

  • » [haiku-commits] r35327 - haiku/trunk/data/bin - coling