diff --git a/HelperResources/version b/HelperResources/version index cc8eeec..eb6ca1c 100644 --- a/HelperResources/version +++ b/HelperResources/version @@ -1 +1 @@ -v8.0~23 +v8.0~24 diff --git a/PackageManager.py b/PackageManager.py index d6c43f3..b3ce029 100755 --- a/PackageManager.py +++ b/PackageManager.py @@ -944,14 +944,18 @@ def UpdatePackageCount (self): self.DbusSettings['packageCount'] = count def GetPackageCount (self): return self.DbusSettings['packageCount'] - def SetAutoDownload (self, value): + def SetAutoDownloadMode (self, value): self.DbusSettings['autoDownload'] = value def GetAutoDownloadMode (self): return self.DbusSettings['autoDownload'] def GetAutoInstall (self): - return self.DbusSettings['autoInstall'] + return self.DbusSettings['autoInstall'] == 1 def SetAutoInstall (self, value): - self.DbusSettings['autoInstall'] = value + if value == True: + dbusValue = 1 + else: + dbusValue = 0 + self.DbusSettings['autoInstall'] = dbusValue def SetPmStatus (self, value): self.DbusService['/PmStatus'] = value def SetMediaStatus (self, value): @@ -1493,7 +1497,7 @@ def __init__( self, section, packageName = None ): self.ActionNeeded = '' - self.lastConflictCheck = 0 + self.lastScriptPrecheck = 0 self.lastGitHubRefresh = 0 @@ -1797,7 +1801,7 @@ def RemovePackage (cls, packageName=None, packageIndex=None, isDuplicate=False ) toPackage.DependencyErrors = fromPackage.DependencyErrors toPackage.FileConflicts = fromPackage.FileConflicts toPackage.PatchCheckErrors = fromPackage.PatchCheckErrors - toPackage.lastConflictCheck = fromPackage.lastConflictCheck + toPackage.lastScriptPrecheck = fromPackage.lastScriptPrecheck toPackage.lastGitHubRefresh = fromPackage.lastGitHubRefresh toPackage.ActionNeeded = fromPackage.ActionNeeded @@ -1857,7 +1861,7 @@ def RemovePackage (cls, packageName=None, packageIndex=None, isDuplicate=False ) # # must be called while LOCKED !! - def UpdateVersionsAndFlags (self, doConflictChecks=False, doScriptChecks=False): + def UpdateVersionsAndFlags (self, doConflictChecks=False, doScriptPreChecks=False): global VersionToNumber global VenusVersion global VenusVersionNumber @@ -2020,8 +2024,8 @@ def UpdateVersionsAndFlags (self, doConflictChecks=False, doScriptChecks=False): continue # if a package list for an active file changes, # run script checks again to uncover new or resolved conflicts - if os.path.getmtime (packagesList) > self.lastConflictCheck: - doScriptChecks = True + if os.path.getmtime (packagesList) > self.lastScriptPrecheck: + doScriptPreChecks = True try: with open (packagesList, 'r') as plFile: for entry2 in plFile: @@ -2092,9 +2096,9 @@ def UpdateVersionsAndFlags (self, doConflictChecks=False, doScriptChecks=False): # make sure script checks are run once at boot # (eg patched errors, but there are others) - if self.lastConflictCheck == 0: - doScriptChecks = True - self.lastConflictCheck = time.time () + if self.lastScriptPrecheck == 0: + doScriptPreChecks = True + self.lastScriptPrecheck = time.time () # end if doConflictChecks # if no incompatibilities found, clear incompatible dbus parameters @@ -2103,7 +2107,7 @@ def UpdateVersionsAndFlags (self, doConflictChecks=False, doScriptChecks=False): self.SetIncompatible ("") # run setup script to check for file conflicts (can't be checked here) - if doScriptChecks and os.path.exists ("/data/" + packageName + "/setup"): + if doScriptPreChecks and os.path.exists ("/data/" + packageName + "/setup"): PushAction ( command='check' + ':' + packageName, source='AUTO' ) # end UpdateVersionsAndFlags # end Package @@ -2529,7 +2533,7 @@ def GitHubDownload (self, packageName= None, source=None): PushAction ( command='install' + ':' + packageName, source=source ) # no install after, do full version/flag update else: - package.UpdateVersionsAndFlags (doConflictChecks=True, doScriptChecks=True) + package.UpdateVersionsAndFlags (doConflictChecks=True, doScriptPreChecks=True) DbusIf.UNLOCK ("GitHubDownload - update status") # report errors / success @@ -2850,6 +2854,10 @@ def InstallPackage ( self, packageName=None, source=None , action='install' ): if source == 'GUI': DbusIf.AcknowledgeGuiEditAction ( 'ERROR' ) + # installs do script conflict checks + # update last check time here so checks aren't run right away + package.lastScriptPrecheck = time.time () + package.UpdateVersionsAndFlags () DbusIf.UNLOCK ("InstallPackage - update status") @@ -3749,7 +3757,6 @@ def mainLoop (): holdOffScan = True # not doing boot install - use dbus values else: - holdOffScan = False autoInstall = DbusIf.GetAutoInstall () # save mode before chaning so changes can be detected below lastDownloadMode = currentDownloadMode @@ -3760,6 +3767,8 @@ def mainLoop (): and ( currentDownloadMode == ONE_DOWNLOAD or lastDownloadMode == AUTO_DOWNLOADS_OFF ): holdOffScan = True UpdateGitHubVersion.SetPriorityGitHubVersion ('REFRESH') + else: + holdOffScan = False # make sure a new scan starts at beginning of list if holdOffScan: @@ -3773,7 +3782,7 @@ def mainLoop (): packageIndex = 0 # end of ONCE download - switch auto downloads off if currentDownloadMode == ONE_DOWNLOAD: - DbusIf.SetAutoDownload (AUTO_DOWNLOADS_OFF) + DbusIf.SetAutoDownloadMode (AUTO_DOWNLOADS_OFF) currentDownloadMode = AUTO_DOWNLOADS_OFF # end of boot install if bootInstall: @@ -3786,7 +3795,8 @@ def mainLoop (): packageName = package.PackageName packageIndex += 1 - package.UpdateVersionsAndFlags (doConflictChecks=True) + # skip conflict checks if boot-time checks are bening made + package.UpdateVersionsAndFlags (doConflictChecks = not bootInstall) # disallow operations on this package if anything is pending packageOperationOk = not package.DownloadPending and not package.InstallPending @@ -4194,7 +4204,7 @@ def main(): elif SystemReboot: DbusIf.UpdateStatus ( message="REBOOTING SYSTEM ...", where='PmStatus') DbusIf.UpdateStatus ( message="REBOOTING SYSTEM ...", where='Editor' ) - logging.warning (">>>> REBOOTING SYSTEM: to complete package installation") + logging.warning (">>>> REBOOTING SYSTEM") # remaining tasks are handled in packageManagerEnd.sh because # SetupHelper uninstall needs to be done after PackageManager.py exists diff --git a/blindInstall/SetupHelperVersion b/blindInstall/SetupHelperVersion index cc8eeec..eb6ca1c 100644 --- a/blindInstall/SetupHelperVersion +++ b/blindInstall/SetupHelperVersion @@ -1 +1 @@ -v8.0~23 +v8.0~24 diff --git a/changes b/changes index 80cd54d..314a589 100644 --- a/changes +++ b/changes @@ -1,6 +1,6 @@ v8.0: (beta) allow multiple packages to modify the same file - multiple patch files for each active file are permitted + allow multiple patch files for each active file fixed: PackageManager hangs if there is no setup script in package directory fixed: package conflict message disappears fixed: "Once" download scan doesn't check all packages @@ -11,6 +11,8 @@ v8.0: (beta) to separate script add TailscaleGX to default package list updatePackage: changed HelperResources version checking to minimize prompts + updatePackage: added patch options including MANUAL to prevent automatic patch updates + updatePackage: rewrite main file set loop for speed improvement v7.18: fixed: only first service is uninstalled diff --git a/updatePackage b/updatePackage index ba612d3..fd114af 100755 --- a/updatePackage +++ b/updatePackage @@ -281,8 +281,9 @@ function getFileLists () fi if [ ! -z "$dupsAll" ]; then for dup in "$dupsAll" ; do - logMessage "WARNING $package: duplicate in combined file lists $dup - ignored" + logMessage "ERROR $package: duplicate in combined file lists $dup - can't continue" done + exit fi } @@ -640,46 +641,42 @@ for package in $packageList; do # if any version-dependent files, create missing file sets or flag incompatible if ! [ -z $fileList ]; then for entry in ${stockVersionList[@]}; do - IFS=':' read version1 version1number <<< "$entry" - fileSet1="$workingFiles/$version1" - stockFileSet1="$stockFiles/$version1" + IFS=':' read version versionNumber <<< "$entry" + fileSet="$workingFiles/$version" + stockFileSet="$stockFiles/$version" - if (( $version1number >= $obsoleteVersionNumber )) || (( $version1number < $firstVersionNumber )); then - touch "$fileSet1/INCOMPATIBLE_VERSION" + if (( $versionNumber >= $obsoleteVersionNumber )) || (( $versionNumber < $firstVersionNumber )); then + touch "$fileSet/INCOMPATIBLE_VERSION" compatible=false else compatible=true fi - if $compatible && ! [ -e "$fileSet1" ]; then - mkdir "$fileSet1" - touch "$fileSet1/NEW_FILE_SET" - logMessage "$package: $version1 new file set" + if $compatible && ! [ -e "$fileSet" ]; then + mkdir "$fileSet" + touch "$fileSet/NEW_FILE_SET" + logMessage "$package: $version new file set" fi done fi - # append the package's existing file sets NOT in the stock versions - # to the END of the stock files list - # this insures these file sets contain only files used by that or other unused versions - # these file sets are marted as unused since they are not in the stock files and can be removed + # add the package's existing file sets NOT in the stock versions + # and mark them unused + # replacement files will not be moved to these unused file sets sourceFileSets=($(ls -d "$workingFiles"/v[0-9]* 2> /dev/null)) - tempList=() + tempList=(${stockVersionList[@]}) for entry in ${sourceFileSets[@]} ; do - version1=$(basename $entry) - if [ ! -d "$stockFiles/$version1" ]; then - if ! versionStringToNumber $version1 ; then + version=$(basename $entry) + if [ ! -d "$stockFiles/$version" ]; then + if ! versionStringToNumber $version ; then logMessage "ERROR $package: file set name $versionStringToNumberStatus - can't continue" exit fi - tempList+=($version1:$versionNumber) - touch "$workingFiles/$version1/UNUSED_FILE_SET" + tempList+=($version:$versionNumber) + touch "$workingFiles/$version/UNUSED_FILE_SET" fi done - existingFileSets=( $(echo ${tempList[@]} | tr ' ' '\n' | sort -t ':' -r -n -k 2 | uniq ) ) - allFileSets=(${stockVersionList[@]}) - allFileSets+=(${existingFileSets[@]}) - + allFileSets=( $(echo ${tempList[@]} | tr ' ' '\n' | sort -t ':' -r -n -k 2 | uniq ) ) # move incompatible versions to the end of the list # so that real files end up in a supported file set @@ -739,6 +736,168 @@ for package in $packageList; do done fi + # create and test patch files + # the option to skip creation exists in case the patch file needs to be hand edited + # + # in order to create a patch file, both an unmodified file without the changes + # and an 'result' file WITH the desired changes are required + # + # multiple sets can exist and are of the form + # result $baseName* eg PageSettings.qml-1 + # orig $baseName*.orig eg PageSettings.qml-1.orig + # patch $baseName*.patch eg PageSettings.qml-1.patch + # + # legacy .edited and .source, will be converted to the new format + patchSourceDir="$workingFiles/PatchSource" + if (( ${#fileListPatched[@]} > 0 )); then + beginProgress "checking patch files" + for file in ${fileListPatched[@]} ; do + outputProgressTick "." + baseName=$( basename $file ) + patchOptionsFile="$patchSourceDir/$baseName.patchOptions" + if [ -f "$patchOptionsFile" ]; then + patchOptions=$( cat "$patchOptionsFile" ) + optionsModTime=$( date -r "$patchOptionsFile" '+%s' ) + else + patchOptions='-u' + optionsModTime=0 + fi + # convert old name formats + oldPath="$patchSourceDir/$baseName" + newPath="$oldPath-1" + if [ -e "$oldPath.source" ] || [ -e "$oldPath.edited" ]; then + if [ -e "$newPath*" ]; then + logMessage "WARNING $package: can't move .source and .edited patch files - ...-1... already exists" + else + if [ -e "$oldPath.source" ]; then + logMessage "$package: renaming $baseName.source to $baseName.orig" + mv "$oldPath.source" "$newPath.orig" + fi + if [ -e "$oldPath.edited" ]; then + logMessage "$package: renaming $baseName.edited to $baseName" + mv "$oldPath.edited" "$newPath" + fi + fi + fi + + if [ "$patchOptions" == "MANUAL" ]; then + logMessage "WARNING $package: $baseName patch options set to MANUAL - skipping patch update" + else + patchOrigFiles=( $( ls "$patchSourceDir/$baseName"*.orig ) ) + for patchOrig in ${patchOrigFiles[@]}; do + patchResult="${patchOrig/.orig/}" + patchFile="${patchOrig/.orig/.patch}" + + if ! [ -f "$patchResult" ]; then + continue + fi + + updatePatch=false + if [ -f "$patchFile" ]; then + origModTime=$( date -r "$patchOrig" '+%s' ) + resultModTime=$( date -r "$patchResult" '+%s' ) + patchModTime=$( date -r "$patchFile" '+%s' ) + if (( origModTime > patchModTime )); then + updatePatch=true + elif (( resultModTime > patchModTime )); then + updatePatch=true + elif (( optionsModTime > patchModTime )); then + updatePatch=true + else + updatePatch=false + fi + else + logMessage "$package: creating $( basename $patchFile )" + updatePatch=true + fi + if $updatePatch ; then + diff $patchOptions "$patchOrig" "$patchResult" > "$patchFile" + fi + done + fi + + # test each patch on all versions - need one to succeed for each version + # both foward and reverse patchs must succeed + # and reverse patch result must match stock file + patchFiles=( $( ls "$patchSourceDir/$baseName"*.patch ) ) + for (( i1 = 0; i1 < $allFileSetsLength; i1++ )); do + IFS=':' read version versionNumber <<< "${allFileSets[$i1]}" + stockFile="$stockFiles/$version/$file" + replacement="$workingFiles/$version/$baseName" + if ! [ -f "$stockFile" ]; then + continue + fi + foundPatch=false + for patchFile in ${patchFiles[@]}; do + patchResultFile="$patchSourceDir/$baseName.patchResult" + reversePatchResultFile="$patchSourceDir/$baseName.reversePatchResult" + patchOk=true + + if ! yes 'no' | patch -N -o "$patchResultFile" "$stockFile" "$patchFile" > /dev/null ; then + patchOk=false + fi + if $patchOK && ! yes 'no' | patch -R -o "$reversePatchResultFile" "$patchResultFile" "$patchFile" > /dev/null ; then + patchOk=false + fi + if $patchOK && ! cmp -s "$stockFile" "$reversePatchResultFile" > /dev/null ; then + patchOk=false + fi + rm -f "$patchResultFile"* "$reversePatchResultFile"* + # found a patch that works - stop looking + if $patchOk ; then + foundPatch=true + break + fi + done + # if patch succeeded, remove any replacement and orig files in this file set + # they won't be looked at below since fileList won't include them + # checks above insure there the same file is not in multiple file lists + if $foundPatch; then + replacementFile="$workingFiles/$version/$baseName" + if [ -e "$replacement" ] && ! [ -L "$replacement" ] || [ -e "$replacement.USE_ORIGINAL" ]; then + logMessage "WARNING $package: removing $baseName from $version" + rm -f "$replacement"* + fi + else + logMessage "ERROR: $packageName no patch file for $baseName $version" + fi + done + done # for file in fileListPatched + fi # check patch files + + # update the package's copy of helper resources + if [ -f "$workingDirectory/HelperResources/version" ]; then + pkgHelperVersion=$( cat "$workingDirectory/HelperResources/version" ) + versionStringToNumber $pkgHelperVersion + pkgHelperVersionNumber=$versionNumber + else + pkgHelperVersion="" + pkgHelperVersionNumber=0 + fi + updateHelperResources=false + if (( helperVersionNumber > pkgHelperVersionNumber )); then + updateHelperResources=true + # if versions are the same, compare file mod dates + elif (( helperVersionNumber == pkgHelperVersionNumber )); then + for file in $( ls "$packageRoot/HelperResources" ); do + baseName=$( basename $file ) + if [[ "$packageRoot/HelperResources/$baseName" -nt "$workingDirectory/HelperResources/$baseName" ]]; then + updateHelperResources=true + break + fi + done + fi + if $updateHelperResources ; then + logMessage "$package: updating HelperResources to $helperVersion" + cp -r "$packageRoot/HelperResources" "$workingDirectory" + fi + + if ((packageErrors > 0 )); then + logMessage "$packageErrors errors so far" + if ! yesNoPrompt "continue with file set checks anyway (y/n)? " ; then + continue # next package + fi + fi beginProgress "$package: updating file sets" @@ -746,7 +905,6 @@ for package in $packageList; do for file in ${fileList[@]} ; do outputProgressTick "." baseName=$(basename "$file") - versionedFileExists=false # use alternate original if present in AlternateOriginals @@ -762,226 +920,200 @@ for package in $packageList; do altOrigFile="" fi - # move real files to newest file set - # use allFileSets because i1 is used to start the i2 inner loop !!! - for (( i1 = 0; i1 < $allFileSetsLength; i1++ )); do - IFS=':' read version1 version1number <<< "${allFileSets[$i1]}" - fileSet1="$workingFiles/$version1" - stockFileSet1="$stockFiles/$version1" - - # if stock file set does not exist or this version is not compatible, don't move files here - # this will allow file sets for versions no longer supported to be removed - # an error will result if a replacement in this version is needed for other file sets - if [ ! -d "$stockFileSet1" ] || [ -f "$fileSet1/INCOMPATIBLE_VERSION" ]; then continue; fi - - replacement1="$fileSet1/$baseName" - replacement1isRealFile=false - useOrigFlag1=false - if [ -f "$replacement1" ] && ! [ -L "$replacement1" ]; then - replacement1isRealFile=true - versionedFileExists=true - elif [ -f "$replacement1.USE_ORIGINAL" ]; then - useOrigFlag1=true - fi - orig1="$fileSet1/$baseName.orig" - # select appropirate stock file - if $useAltOrig ; then - stockFile1="$stockFileSet1$altOrigFile" - else - stockFile1="$stockFileSet1$file" - fi - - if [ ! -f "$stockFile1" ]; then + # locate groups of file sets with matching stock(or .orig) files + (( start = 0 )); + while (( start < $allFileSetsLength )); do + # locate one group of file sets that will use the same replacement file + (( end = start )); (( to = -1 )) + toFileSet="" + compareReference="" + startVersion="-" + toVersion="-" + endVersion="-" + oldReplacementVersion="-" + oldReplacementIsFile=false + oldReplacementIsUseOrig=false + for (( i1 = start; i1 < $allFileSetsLength; i1++ )); do + IFS=':' read version versionNumber <<< "${allFileSets[$i1]}" + fileSet="$workingFiles/$version" + replacement="$fileSet/$baseName" + stockFileSet="$stockFiles/$version" + orig="$fileSet/$baseName.orig" if $useAltOrig ; then - logMessage "ERROR $package: $version1 $baseName stock file missing (move) - check ALT_ORIG" - touch "$fileSet1/$baseName.CHECK_ALT_ORIG" + stockFile="$stockFileSet$altOrigFile" else - logMessage "ERROR $package: $version1 $baseName stock file missing (move) - consider using an ALT_ORIG" + stockFile="$stockFileSet$file" fi - touch "$fileSet1/$baseName.NO_STOCK_FILE" - touch "$fileSet1/INCOMPLETE" - logMessage "can't continue" - exit - fi - - # look for a stock file match in older file sets and relocate FS 2 replacement/orig fo FS 1 if found - relinkCheck=false - for (( i2 = $i1 + 1; i2 < $allFileSetsLength; i2++ )); do - IFS=':' read version2 version2number <<< "${allFileSets[$i2]}" - fileSet2="$workingFiles/$version2" - replacement2="$fileSet2/$baseName" - orig2="$fileSet2/$baseName.orig" - - if [ -L "$replacement2" ] ; then - replacement2isLink=true - replacement2isRealFile=false - elif [ -f "$replacement2" ] ; then - replacement2isRealFile=true - replacement2isLink=false - else - replacement2isRealFile=false - replacement2isLink=false + replacementIsLink=false + replacementIsFile=false + useOrig=false + if [ -L "$replacement" ]; then + replacementIsLink=true + elif [ -f "$replacement" ]; then + replacementIsFile=true + elif [ -f "$replacement.USE_ORIGINAL" ]; then + useOrig=true fi - # USE_ORIGINAL is valid only if the original file also exists (and is not a sym link) - if [ -f "$replacement2.USE_ORIGINAL" ] && [ -f $orig2 ] && [ ! -L $orig2 ]; then - useOrigFlag2=true - else - useOrigFlag2=false + if (( i1 == start )); then + startVersion=$version fi - if [ -f "$fileSet2/NEW_FILE_SET" ]; then - newFileSet2=true + + if [ -e "$stockFile" ]; then + thisOrig="$stockFile" + # error if file set exists but no stock file + elif [ -e "$stockFileSet" ]; then + if $useAltOrig ; then + logMessage "ERROR $package: $version $baseName stock file missing - check ALT_ORIG - can't continue" + touch "$fileSet/$baseName.CHECK_ALT_ORIG" + else + logMessage "ERROR $package: $version $baseName stock file missing - consider using an ALT_ORIG - can't continue" + fi + touch "$fileSet/$baseName.NO_STOCK_FILE" + touch "$fileSet/INCOMPLETE" + exit + # no stock file - use orig in file set + elif [ -e "$orig" ]; then + thisOrig="$orig" else - newFileSet2=false + thisOrig="" + fi + if [ -z "$compareReference" ] && ! [ -z "$thisOrig" ]; then + compareReference="$thisOrig" + fi + includeInBlock=false + # nothing to compare - include in same block + if [ -z "$compareReference" ] || [ -z "$thisOrig" ]; then + includeInBlock=true + elif [ "$thisOrig" == "$compareReference" ]; then + includeInBlock=true + # orig exists and DOES match others in block + elif cmp -s "$thisOrig" "$compareReference" > /dev/null ; then + includeInBlock=true fi - # check for valid and matching (stock file) replacement/orig in FS 2 and relocate to FS 1 if so - stockMatch=false - if $replacement2isRealFile || $useOrigFlag2 ; then - if [ -d "$stockFiles/$version2" ]; then - # select appropirate original file - if $useAltOrig ; then - stockFile2="$stockFiles/$version2$altOrigFile" - else - stockFile2="$stockFiles/$version2$file" - fi - if [ ! -f "$stockFile2" ]; then - if $useAltOrig ; then - logMessage "ERROR $package: $version2 $baseName stock file missing - check ALT_ORIG" - touch "$fileSet2/$baseName.CHECK_ALT_ORIG" - else - logMessage "ERROR $package: $version2 $baseName stock file missing - consider using an ALT_ORIG" - fi - touch "$fileSet2/$baseName.NO_STOCK_FILE" - touch "$fileSet2/INCOMPLETE" - logMessage "can't continue" - exit - fi - - # stock files match - if cmp -s "$stockFile2" "$stockFile1" > /dev/null ; then - stockMatch=true - fi - # no stock files but original in existing file set - elif $replacement2isRealFile && [ -f "$orig2" ] ; then - # existing orig matches stock - if cmp -s "$orig2" "$stockFile1" > /dev/null ;then - stockMatch=true - fi - fi - - if $stockMatch ; then - if $replacement2isRealFile ; then - if $replacement1isRealFile ; then - if ! cmp -s "$replacement1" "$replacement2" &> /dev/null ; then - logMessage "ERROR $package: $baseName $version1 and $version2 replacements differ but same stock files" - touch "$fileSet1/$baseName.CHECK_REPLACEMENT" - touch "$fileSet2/$baseName.CHECK_REPLACEMENT" - stockMatch=false - fi - fi - if $stockMatch ; then - mv -f "$replacement2" "$replacement1" - rm -f "$fileSet1/$baseName.USE_ORIGINAL" - ln -sf "../$version1/$baseName" "$replacement2" - if [ -f "$stockFile1" ]; then - cp -f "$stockFile1" "$orig1" - elif [ -f "$orig2" ] && ! [ -L "$orig2" ]; then - mv -f "$orig2" "$orig1" - fi - rm -f "$orig2" - previousLink="../$version2/$baseName" - relinkCheck=true - fi - elif $useOrigFlag2 ; then - if $replacement1isRealFile ; then - logMessage "ERROR $package $basename file in $version1 conflicts with USE_ORIGINAL in $version2" - touch "$fileSet1/$baseName.CHECK_REPLACEMENT" - touch "$fileSet2/$baseName.CHECK_REPLACEMENT" - else - touch "$replacement1.USE_ORIGINAL" - rm -f "$replacement1" - touch "$replacement2.USE_ORIGINAL" - rm -f "$replacement2" - relinkCheck=true - fi - fi - fi + # start a new block + if ! $includeInBlock ; then + break + fi - # check for and relink replacements to new location if approprite - # relinkCheck is set in a previous pass if replacement was relocated - # which invalidates links to the prevous FS 1 - # needs to be done while the original link is still known - # but skipped if FS 2 was updated above - elif $relinkCheck && $replacement2isLink; then - if [ "$(readlink "$replacement2")" == "$previousLink" ]; then - ln -sf "../$version1/$baseName" "$replacement2" - rm -f "$orig2" - rm -f "$replacement2.USE_ORIGINAL" + # save version of old replacement files for next loop + if $replacementIsFile ; then + if ! $oldReplacementIsFile || [ "$oldReplacementVersion" == "-" ]; then + oldReplacementVersion=$version + oldReplacementIsFile=true + oldReplacementIsUseOrig=false fi + elif $useOrig && [ "$oldReplacementVersion" == "-" ]; then + oldReplacementVersion=$version + oldReplacementIsFile=false + oldReplacementIsUseOrig=true fi - done # for i2 - done # for i1 (update) - - # make another pass and fill in links that were missed in the first pass - # this second pass allows all file to be relcated to new file sets first - for (( i1 = 0; i1 < $allFileSetsLength; i1++ )); do - IFS=':' read version1 version1number <<< "${allFileSets[$i1]}" - fileSet1="$workingFiles/$version1" - if [ -e "$fileSet1/UNUSED_FILE_SET" ] || [ -e "$fileSet1/INCOMPATIBLE_VERSION" ]; then continue; fi - replacement1="$fileSet1/$baseName" - replacement1isRealFile=false - useOrigFlag1=false - # skip links - they can't be the source of a link - if [ -L "$replacement1" ]; then - continue - elif [ -f "$replacement1" ]; then - replacement1isRealFile=true - elif [ -f "$replacement1.USE_ORIGINAL" ]; then - useOrigFlag1=true - else - touch "$replacement1.CHECK_REPLACEMENT" - fi - # select appropirate stock file - stockFileSet1="$stockFiles/$version1" - if $useAltOrig ; then - stockFile1="$stockFileSet1$altOrigFile" - else - stockFile1="$stockFileSet1$file" - fi - - # relink files that match FS 1 - for (( i2 = $i1 + 1; i2 < $allFileSetsLength; i2++ )); do - IFS=':' read version2 version2number <<< "${allFileSets[$i2]}" - fileSet2="$workingFiles/$version2" - if ! [ -e "$fileSet2" ]; then continue; fi - replacement2="$fileSet2/$baseName" - # if real replacement found, this indicates remaining FS 2s don't need to be checked - if ( [ -e "$replacement2" ] && ! [ -L "$replacement2" ] ); then break; fi - # skip if USE_ORIGINAL is already set or if there was already an probelm with FS 1's file - if [ -e "$replacement2.USE_ORIGINAL" ]; then - continue + (( end = i1 )) + endVersion=$version + + # first compatible file set - move replacements here + # unused file sets are permitted for the destination file set + # but if a used file set is later found, it is preferred + if [ -e "$fileSet/INCOMPATIBLE_VERSION" ]; then + updateTo=false + elif (( to == -1 )); then + updateTo=true + elif ! [ -e "$fileSet/UNUSED_FILE_SET" ] && [ -e "$toFileSet/UNUSED_FILE_SET" ]; then + updateTo=true + else + updateTo=false + fi + if $updateTo ; then + (( to = i1 )) + toFileSet="$fileSet" + toVersion=$( basename "$toFileSet" ) fi + done # end locate block - # select appropirate stock file - stockFileSet2="$stockFiles/$version2" + if (( to == -1 )); then + logMessage "ERROR $package: $baseName no destination file set - can't reloate files" + else + toReplacement="$toFileSet/$baseName" + oldReplacement="$workingFiles/$oldReplacementVersion/$baseName" + toStockFileSet="$stockFiles/$toVersion" if $useAltOrig ; then - stockFile2="$stockFileSet2$altOrigFile" + toStockFile="$toStockFileSet$altOrigFile" else - stockFile2="$stockFileSet2$file" + toStockFile="$toStockFileSet$file" fi - # stock files match - create/update link - if cmp -s "$stockFile2" "$stockFile1" > /dev/null ; then - if $replacement1isRealFile || [ -f "$fileSet1/NEW_FILE_SET" ]; then ################ - ln -sf "../$version1/$baseName" "$replacement2" - rm -f "$replacement2.USE_ORIGINAL" - elif $useOrigFlag1 ; then - touch "$replacement2.USE_ORIGINAL" - rm -f "$replacement2" + + # relocate replacement & orig + if $oldReplacementIsUseOrig ; then + rm -f "$toReplacement"* + touch "$toReplacement.USE_ORIGINAL" + versionedFileExists=true + elif $oldReplacementIsFile; then + if [ "$oldReplacementVersion" != "$toVersion" ]; then + rm -f "$toReplacement"* + mv "$oldReplacement" "$toReplacement" fi + versionedFileExists=true + if [ -f "$toStockFile" ]; then + cp "$toStockFile" "$toReplacement.orig" + elif [ -f "$oldReplacement.orig" ]; then + mv "$oldReplacement.orig" "$toReplacement.orig" + else + logMessage "ERROR $package $baseName: $toVersion no original" + touch "$toReplacement.NO_ORIG" + fi + else + touch "$toReplacement.CHECK_REPLACEMENT" fi - done # for i2 - done # for i1 (missing sym links) + + # update links and look for additional replacements + for (( i1 = start; i1 <= end; i1++ )); do + # skip to -- it's alredy updated + if (( i1 == to )); then continue; fi + + IFS=':' read version versionNumber <<< "${allFileSets[$i1]}" + fileSet="$workingFiles/$version" + replacement="$fileSet/$baseName" + replacementIsLink=false + replacementIsFile=false + useOrig=false + if [ -L "$replacement" ]; then + replacementIsLink=true + elif [ -f "$replacement" ]; then + replacementIsFile=true + elif [ -f "$replacement.USE_ORIGINAL" ]; then + useOrig=true + fi + + if $useOrig && ! $oldReplacementIsUseOrig ; then + logMessage "WARNING $package: $baseName has replacement - USE_ORIGINAL removed" + rm -f "$replacement.USE_ORIGINAL" + fi + + # a second replacement is found - remove if matches, error if different + updateReplacements=true + if $replacementIsFile && $oldReplacementIsFile; then + if ! cmp "$replacement" "$toReplacement" ; then + logMessage "ERROR $package: $baseName $version second replacement differs - check replacements" + touch "$replacement.CHECK_REPLACEMENT" + touch "$toReplacement.CHECK_REPLACEMENT" + updateReplacements=false + fi + fi + if $updateReplacements ; then + rm -f "$replacement"* + if $oldReplacementIsUseOrig; then + touch "$toReplacement.USE_ORIGINAL" + # links are created even if replacement does not exist + else + ln -sf "../$toVersion/$baseName" "$replacement" + fi + fi + done + fi + # continue looking for blocks with file set after the end of this block + (( start = end + 1 )) + done # while start ... # both versioned and version-independent files exist - report this (no action taken) if $versionedFileExists; then @@ -991,325 +1123,121 @@ for package in $packageList; do fi fi - done # for file (update) + done # for file beginProgress "$package: final checks" for (( i1 = 0; i1 < $allFileSetsLength; i1++ )); do - IFS=':' read version1 version1number <<< "${allFileSets[$i1]}" + IFS=':' read version versionNumber <<< "${allFileSets[$i1]}" - if (( $version1number >= $obsoleteVersionNumber )) || (( $version1number < $firstVersionNumber )); then + if (( $versionNumber >= $obsoleteVersionNumber )) || (( $versionNumber < $firstVersionNumber )); then incompatibleVersion=true else incompatibleVersion=false fi - fileSet1="$workingFiles/$version1" + fileSet="$workingFiles/$version" # file set should exist so this shouldn't happen but report and skip checks anyway - if ! [ -d "$fileSet1" ]; then + if ! [ -d "$fileSet" ]; then if ! $incompatibleVersion && ! [ -z $fileList ]; then - logMessage "ERROR: $package $version1 missing file set - skipping" + logMessage "ERROR: $package $version missing file set - skipping" fi continue fi outputProgressTick "." replacementFilesExist=false - replacmentSymLinksExist=false - - # do final checks on versioned files only for file in ${fileList[@]} ; do baseName=$(basename "$file") - # use alternate original if present in AlternateOriginals - if [ -f "$altOrigFileDir/$baseName.ALT_ORIG" ]; then - useAltOrig=true - altOrigFile=$(cat "$altOrigFileDir/$baseName.ALT_ORIG") - # or if in FileSets - elif [ -f "$workingFiles/$baseName.ALT_ORIG" ]; then - useAltOrig=true - altOrigFile=$(cat "$workingFiles/$baseName.ALT_ORIG") - else - useAltOrig=false - altOrigFile="" + replacement="$fileSet/$baseName" + if [ -f "$replacement" ] && [ -L "$replacement" ]; then + replacementFilesExist=true + break fi + done + # LINKS_ONLY is not used for anything but helps identify file sets + # that don't contain real files + if ! $replacementFilesExist ; then + touch "$fileSet/LINKS_ONLY" + fi - replacement1="$fileSet1/$baseName" - orig1="$fileSet1/$baseName.orig" - - # do final checks -- must be file, link or USE_ORIG but not more than one - realReplacement=false - symLinkReplacement=false - badLink=false - if [ -L "$replacement1" ]; then - symLinkReplacement=true - # resolive symlink then check to make sure that file is valid - linkedFile=$( realpath "$replacement1" 2> /dev/null ) - if [ -z "$linkedFile" ]; then - badLink=true - else - linkedFileSet=$( dirname "$linkedFile" ) - if [ -z "$linkedFileSet" ]; then - badLink=true - elif [ -f "$linkedFileSet/UNUSED_FILE_SET" ] || [ -f "$linkedFileSet/INCOMPATIBLE_VERSION" ]; then - badLink=true - fi - fi - if $badLink ; then - logMessage "ERROR $package: $baseName $version1 bad link" - touch "$replacement1.BAD_LINK" - fi - elif [ -f "$replacement1" ]; then - realReplacement=true - fi + doFsChecks=true - # fill in missing original file if stock file exists - if ( $realReplacement || [ -f "$replacement1.CHECK_REPLACEMENT" ] ); then - stockFileSet1="$stockFiles/$version1" - if $useAltOrig ; then - stockFile1="$stockFileSet1$altOrigFile" - else - stockFile1="$stockFileSet1$file" - fi - if [ -f "$stockFile1" ]; then - if ! [ -e "$orig1" ]; then - updateOrig=true - elif ! cmp -s "$orig1" "$stockFile1" ; then - logMessage "WARNING $package: $baseName $version1 original differs from stock - updating orig" - updateOrig=true - else - updateOrig=false - fi - if $updateOrig ; then - cp "$stockFile1" "$orig1" - fi - fi + # remove file sets for incompatible Venus OS versions + if [ -e "$fileSet/INCOMPATIBLE_VERSION" ]; then + if [ ! -f "$fileSet/NEW_FILE_SET" ]; then + logMessage "WARNING $package: not compatible with Venus $version - file set removed" fi - if [ -f "$orig1" ]; then - origExists=true - else - origExists=false + rm -Rf "$fileSet" + # remove empty unused file sets + elif [ -f "$fileSet/UNUSED_FILE_SET" ]; then + # log removal of a previous file set if not created with this run + # if it was created with this run, delete it silently + if [ ! -f "$fileSet/NEW_FILE_SET" ]; then + logMessage "WARNING $package: $version - removing unused file set" fi - - if [ -f "$replacement1.USE_ORIGINAL" ]; then - if $symLinkReplacement || $realReplacement ; then - logMessage "WARNING $package $version1 $baseName replacement exists - removing USE_ORIGINAL flag" - rm "$replacement1.USE_ORIGINAL" - fi - useOrigFlag=true - else - useOrigFlag=false - fi - - if ! $symLinkReplacement && ! $realReplacement && ! $useOrigFlag ; then - logMessage "ERROR $package: $baseName $version1 no replacement" - touch "$replacement1.CHECK_REPLACEMENT" - stockFileSet1="$stockFiles/$version1" - if $useAltOrig ; then - stockFile1="$stockFileSet1$altOrigFile" + rm -Rf "$fileSet" + # do final checks on versioned files only + else + for file in ${fileList[@]} ; do + baseName=$(basename "$file") + # use alternate original if present in AlternateOriginals + if [ -f "$altOrigFileDir/$baseName.ALT_ORIG" ]; then + useAltOrig=true + altOrigFile=$(cat "$altOrigFileDir/$baseName.ALT_ORIG") + # or if in FileSets + elif [ -f "$workingFiles/$baseName.ALT_ORIG" ]; then + useAltOrig=true + altOrigFile=$(cat "$workingFiles/$baseName.ALT_ORIG") else - stockFile1="$stockFileSet1$file" + useAltOrig=false + altOrigFile="" fi - elif $realReplacement && ! $origExists ; then - logMessage "ERROR $package: $baseName $version1 must contain real file AND orig file" - touch "$replacement1.NO_ORIG" - fi - if $symLinkReplacement && $origExists ; then - logMessage "WARNING $package: $baseName $version1 should NOT contain link AND orig file - removing orig" - rm -f "$orig1" - fi - - if [ -f "$replacement1.CHECK_REPLACEMENT" ] || [ -f "$replacement1.NO_ORIG" ] \ - || [ -f "$replacement1.BAD_LINK" ] ; then - touch "$fileSet1/INCOMPLETE" - fi - - # identify real file & symlink in file set for later - if $symLinkReplacement ; then - replacmentSymLinksExist=true - fi - if $realReplacement || ( $useOrigFlag && $origExists ) ; then - replacementFilesExist=true - fi - done # for file - - # remove file sets for incompatible Venus OS versions - if [ -e "$fileSet1/INCOMPATIBLE_VERSION" ]; then - if $replacementFilesExist ; then - logMessage "WARNING $package: not compatible with Venus $version1 but not empty - consider manual removal" - else - if [ ! -f "$fileSet1/NEW_FILE_SET" ]; then - logMessage "WARNING $package: not compatible with Venus $version1 - file set removed" + replacement="$fileSet/$baseName" + orig="$fileSet/$baseName.orig" + + # validate sym link + symLinkReplacement=false + badLink=false + if [ -L "$replacement" ]; then + symLinkReplacement=true + # resolive symlink then check to make sure that file is valid + linkedFile=$( realpath "$replacement" 2> /dev/null ) + if [ -z "$linkedFile" ]; then + badLink=true + else + linkedFileSet=$( dirname "$linkedFile" ) + if [ -z "$linkedFileSet" ]; then + badLink=true + elif [ -f "$linkedFileSet/UNUSED_FILE_SET" ] || [ -f "$linkedFileSet/INCOMPATIBLE_VERSION" ]; then + badLink=true + fi + fi + if $badLink ; then + logMessage "ERROR $package: $baseName $version bad link" + touch "$replacement.BAD_LINK" + fi fi - rm -Rf "$fileSet1" - - fi - - elif [ -f "$fileSet1/UNUSED_FILE_SET" ]; then - if $replacementFilesExist ; then - logMessage "WARNING $package: $version1 no longer used but not empty - manual remove is OK" - # no files (empty file set) - else - # log removal of a previous file set if not created with this run - # if it was created with this run, delete it silently - if [ ! -f "$fileSet1/NEW_FILE_SET" ]; then - logMessage "WARNING $package: $version1 no longer used and contains only links - removing file set" + # flag file set incomplete + if [ -f "$replacement.CHECK_REPLACEMENT" ] || [ -f "$replacement.NO_ORIG" ] \ + || [ -f "$replacement.BAD_LINK" ] ; then + touch "$fileSet/INCOMPLETE" fi - rm -Rf "$fileSet1" - fi - fi + done # for file - # if file set still exists ... - if [ -e "$fileSet1" ]; then # if all replacement files are in place, mark the file set COMPLETE # so _checkFileSets can skip all checks # COMPLETE tells _checkFileSets to skip all checks and accept the file set as is - if [ -f "$fileSet1/INCOMPLETE" ]; then - rm -f "$fileSet1/COMPLETE" + if [ -f "$fileSet/INCOMPLETE" ]; then + rm -f "$fileSet/COMPLETE" else - touch "$fileSet1/COMPLETE" + touch "$fileSet/COMPLETE" fi - # LINKS_ONLY is not used for anything but helps identify file sets - # that don't contain real files - if ! $replacementFilesExist && $replacmentSymLinksExist ; then - touch "$fileSet1/LINKS_ONLY" - fi - - rm -f "$fileSet1/NEW_FILE_SET" + rm -f "$fileSet/NEW_FILE_SET" fi - done # for i1 (final checks) - # create and test patch files - # the option to skip creation exists in case the patch file needs to be hand edited - # - # in order to create a patch file, both an unmodified file without the changes - # and an 'result' file WITH the desired changes are required - # - # multiple sets can exist and are of the form - # result $baseName* eg PageSettings.qml-1 - # orig $baseName*.orig eg PageSettings.qml-1.orig - # patch $baseName*.patch eg PageSettings.qml-1.patch - # - # legacy .edited and .source, will be converted to the new format - patchSourceDir="$workingFiles/PatchSource" - logMessage "create patch files" - for file in ${fileListPatched[@]} ; do - baseName=$( basename $file ) - # convert old name formats - oldPath="$patchSourceDir/$baseName" - newPath="$oldPath-1" - if [ -e "$oldPath.source" ] || [ -e "$oldPath.edited" ]; then - if [ -e "$newPath*" ]; then - logMessage "can't move .source and .edited patch files - ...-1... already exists" - else - if [ -e "$oldPath.source" ]; then - logMessage " renaming $baseName.source to $baseName.orig" - mv "$oldPath.source" "$newPath.orig" - fi - if [ -e "$oldPath.edited" ]; then - logMessage " renaming $baseName.edited to $baseName" - mv "$oldPath.edited" "$newPath" - fi - fi - fi - - patchOrigFiles=( $( ls "$patchSourceDir/$baseName"*.orig ) ) - for patchOrig in ${patchOrigFiles[@]}; do - patchResult="${patchOrig/.orig/}" - patchFile="${patchOrig/.orig/.patch}" - createPatch=true - - if ! [ -f "$patchResult" ]; then - continue - fi - if $createPatch && [ -f "$patchFile" ]; then - logMessage "$package $( basename $patchFile ) already exists" - if ! yesNoPrompt "recreate it (y/n}? " ;then - createPatch=false - fi - fi - if $createPatch ; then - logMessage "$package: creating $( basename $patchFile )" - diff -u "$patchOrig" "$patchResult" > "$patchFile" - fi - done - done - - beginProgress "check patch files" - for file in ${fileListPatched[@]} ; do - outputProgressTick "." - baseName=$( basename $file ) - - # test each patch on all versions - need one to succeed for each version - # both foward and reverse patchs must succeed - # and reverse patch result must match stock file - patchFiles=( $( ls "$patchSourceDir/$baseName"*.patch ) ) - for (( i1 = 0; i1 < $allFileSetsLength; i1++ )); do - IFS=':' read version1 version1number <<< "${allFileSets[$i1]}" - stockFile1="$stockFiles/$version1/$file" - origFile1="$workingFiles/$version1/$baseName" - if ! [ -f "$stockFile1" ]; then - continue - fi - foundPatch=false - - for patchFile in ${patchFiles[@]}; do - message="" - patchResultFile="$patchSourceDir/$baseName.patchResult" - reversePatchResultFile="$patchSourceDir/$baseName.reversePatchResult" - patchOk=true - - if ! yes 'no' | patch -N -o "$patchResultFile" "$stockFile1" "$patchFile" > /dev/null ; then - patchOk=false - fi - if $patchOK && ! yes 'no' | patch -R -o "$reversePatchResultFile" "$patchResultFile" "$patchFile" > /dev/null ; then - patchOk=false - fi - if $patchOK && ! cmp -s "$stockFile1" "$reversePatchResultFile" > /dev/null ; then - patchOk=false - fi - rm -f "$patchResultFile" "$reversePatchResultFile" - # found a patch that works - stop looking - if $patchOk ; then - foundPatch=true - break - fi - done - if ! $foundPatch; then - logMessage "ERROR: $packageName no patch file for $baseName $version1" - fi - done - done - - # update the package's copy of helper resources - if [ -f "$workingDirectory/HelperResources/version" ]; then - pkgHelperVersion=$( cat "$workingDirectory/HelperResources/version" ) - versionStringToNumber $pkgHelperVersion - pkgHelperVersionNumber=$versionNumber - else - pkgHelperVersion="" - pkgHelperVersionNumber=0 - fi - updateHelperResources=false - if (( helperVersionNumber > pkgHelperVersionNumber )); then - updateHelperResources=true - # if versions are the same, compare file mod dates - elif (( helperVersionNumber == pkgHelperVersionNumber )); then - for file in $( ls "$packageRoot/HelperResources" ); do - baseName=$( basename $file ) - if [[ "$packageRoot/HelperResources/$baseName" -nt "$workingDirectory/HelperResources/$baseName" ]]; then - updateHelperResources=true - break - fi - done - fi - if $updateHelperResources ; then - logMessage "$package: updating HelperResources to $helperVersion" - cp -r "$packageRoot/HelperResources" "$workingDirectory" - fi - - if (( $packageErrors == 0 )); then errorText="no errors " else diff --git a/venus-data-UninstallPackages.tgz b/venus-data-UninstallPackages.tgz index 484c222..4b82159 100644 Binary files a/venus-data-UninstallPackages.tgz and b/venus-data-UninstallPackages.tgz differ diff --git a/venus-data.tgz b/venus-data.tgz index e6d470b..175053d 100644 Binary files a/venus-data.tgz and b/venus-data.tgz differ diff --git a/version b/version index cc8eeec..eb6ca1c 100644 --- a/version +++ b/version @@ -1 +1 @@ -v8.0~23 +v8.0~24