-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathupdatePackage
executable file
·1391 lines (1288 loc) · 45.2 KB
/
updatePackage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/bash
# this script updates the package contents for all packages specified on the command line
# or in the list below if 'all' is specified
# file sets are updated/created for all Venus OS versions in the stockFiles directory
#
# NOTE: this script will create packages that will NOT work with SetupHelper prior to v6.0~2
# however helper resources are included in the package and are used instead of those provided by SH < v6.0~2
# the setup script for the package should source the local InstallHelpers file not CommonResources in SH
#
# if fileListVersionIndependent is present,
# files are moved from the package directory to the VersionIndependent file set
#
# any .ALT_ORIG files are moved from the package directory to the AlternateOriginals directory
#
# replacement files may optionally be created from the original with a patch file
# the files to be patched are listed in fileListPatched
# patch files exist in FileSets/PatchSource
# in order to create a patch file here, a source and edited file must also reside there
#
# patched replacement files are created in CommonResources prior to returning control to the setup script
#
# This is a unix bash script and should be run on a host computer, not a GX device
# Windows will not run this script natively.
# However Windows 10 apparently supports bash:
# https://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/
#
# packages to be evaulated may be specified on the command line
# use 'all' to process all packages in the allPackages list below
#
# file sets which contain real files (not just links and flags)
# for a version NOT contained in StockFiles will be flagged with UNUSED_FILE_SET
# this can occur if you remove versions from StockFiles.
# For example, you may wish to remove beta versions after a beta test cycle.
# file sets which do not contain any real files (just symbolic links or flag files) are removed
# stockFiles contains excerpts from Venus OS file systems
# and must be stored on the host
# within a directory with name of the exact Venus OS version
# and within the stockFiles directory defined below.
#
# 1) missing file set directories are created
# 2) if any files in fileList don't exist (eg, a new file was added to file list),
# the original file in stockFiles is copied to the version directory
# 3) if the original file does not exist, the file is so marked with .NO_STOCK_FILE
# this situation must be corrected:
# version-dependent files without an original MUST use an "alternate original"
# specified in FileSets. This permits version checks for these files too
# replacement files that do not replace a stock file should be placed in version-indpendent file storage
# (FileSets/).
# If these replacement files vary with Venus OS versions, they MUST include an "alternate original".
# This permits version checks for these files too
#
# when a stock file set does not exist, this script will check files from existing file sets
# for a matching original file.
# If a match is found, the replacement file is automatically placed in the new file set
# If no match is found, the missing replacement is flagged and a suitable replacement must be created manually.
#
# existing file sets not in the stockFiles are checked. If empty, they are removed.
# If not empty they are marked UNUSED_FILE_SET and flagged for manual removal.
#
# file sets will include all files listed in fileList.
# this allows the setup script to always have a replacement for known versions
# without searching other file sets for a matching original file
# (there have been cases where installation fails because the search for a matching original could not be found)
# if the stock file matches a previous version, a symbolic link for the replacement is created
# rather than duplicating the file
# this also makes maintanence easier since matching replacement can be identified
#
# original files in the file set are not normally used when installing the package
# however, they are retained so that the setup script can attempt to create a file set for an unknown Venus OS version
# this of course may fail if a matching original file can not be found
#
# if no end action is specified on the command line, the user is prompted for how to proceed for each package processed
# end actions specified will bypass this prompt and proceed with the next package
# end actions:
# -p do not update the package but preserve the working copy
# -d do not update the package and deete the working copy
# -u update the package with changes in the working copy's file sets
#
# -r restore package from backup if present - no processing is performed on the packge, backup or working copy
# backups are automatically created when updating a package
# Note: the restore option is not offered at the end prompt since the update has not been applied yet.
#
# if errors occur, the needed corrections may be more obvious by comparing the package and the working copy
# for this reason, preserving the working copy is recommended if errors are expected
# set allPackages to all packages this script should evalueate if no options are included
allPackages="SetupHelper TailscaleGX ShutdownMonitor VeCanSetup RpiDisplaySetup RpiGpioSetup GuiMods"
## ExtTransferSwitch GeneratorConnector TankRepeater are obsolete and file sets should not be updated.
# attempt to locate SharedUtilities based on the location of this script
# (it is assumed to be in the SetupHelper directory)
# also sets the package root directory based on this also
# and also the stock files base directory
#
# if these are not correct, edit the lines below to set the appropriate values
scriptDir="$( cd $(dirname "$0") >/dev/null 2>&1 ; /bin/pwd -P )"
packageRoot="$( dirname $scriptDir )"
stockFiles="$packageRoot/StockVenusOsFiles"
#### set these as appropriate to your system if the values set above are not correct
#### packageRoot=FILL_THIS_IN_AND_UNCOMMENT_LINE
#### stockFiles=FILL_THIS_IN_AND_UNCOMMENT_LINE
if [ ! -e "$packageRoot" ]; then
echo "unable to locate package root - can't continue"
exit
elif [ ! -e "$stockFiles" ]; then
echo "unable to locate stock files - can't continue"
exit
fi
# convert a version string to an integer to make comparisions easier
#
# Note: copied from VersionResources
# but also includes code to report duplcates not in the VersionResources version
function versionStringToNumber ()
{
local version="$*"
local numberParts
local versionParts
local numberParts
local otherParts
local other
local number=0
local type='release'
# split incoming string into
# an array of numbers: major, minor, prerelease, etc
# and an array of other substrings
# the other array is searched for releasy type strings and the related offest added to the version number
read -a numberParts <<< $(echo $version | tr -cs '0-9' ' ')
numberPartsLength=${#numberParts[@]}
if (( $numberPartsLength == 0 )); then
versionNumber=0
versionStringToNumberStatus="$version: invalid, missing major version"
return 1
fi
if (( $numberPartsLength >= 2 )); then
read -a otherParts <<< $(echo $version | tr -s '0-9' ' ')
for other in ${otherParts[@]}; do
case $other in
'b' | '~')
type='beta'
(( number += 60000 ))
break ;;
'a')
type='alpha'
(( number += 30000 ))
break ;;
'd')
type='develop'
break ;;
esac
done
fi
# if release all parts contribute to the main version number
# and offset is greater than all prerelease versions
if [ "$type" == "release" ] ; then
(( number += 90000 ))
# if pre-release, last part will be the pre release part
# and others part will be part the main version number
else
(( numberPartsLength-- ))
(( number += 10#${numberParts[$numberPartsLength]} ))
fi
# include core version number
(( number += 10#${numberParts[0]} * 10000000000000 ))
if (( numberPartsLength >= 2)); then
(( number += 10#${numberParts[1]} * 1000000000 ))
fi
if (( numberPartsLength >= 3)); then
(( number += 10#${numberParts[2]} * 100000 ))
fi
versionNumber=$number
versionStringToNumberStatus="$version:$number $type"
return 0
}
# getFileLists reads the file list from files in the FileSets directory
#
# 'fileList' file must only list version-dependent files
# 'fileListVersionIndependent' file must list only version-independent files
# prior to SetupHelper v6.0, this list is ignored
#
# $1 specifies where the path to the fileList files
#
# three composite file lists are returned in global arrays:
# fileList contains only version-dependent files
# fileListVersionIndependent contains only version-independent files
# fileListAll contains both versioned and version-independent files
#
# Note: copied from CommonResources
function getFileLists ()
{
local verListFile="$1/fileList"
local indListFile="$1/fileListVersionIndependent"
local patchListFile="$1/fileListPatched"
local tempListVer=()
local tempListInd=()
local tempListPatched=()
if [ -f "$verListFile" ]; then
while read -r line || [[ -n "$line" ]]; do
read -a params <<< $line
# parse line into space-separted parameters then discard any that don't begin with /
# this strips all comments beginning with # as well as any leading or trailing spaces
for param in ${params[@]} ; do
case $param in
/*)
tempListVer+=("$param")
;;
esac
done
done < "$verListFile"
fi
if [ -f "$indListFile" ]; then
while read -r line || [[ -n "$line" ]]; do
read -a params <<< $line
for param in ${params[@]} ; do
case $param in
/*)
tempListInd+=("$param")
;;
esac
done
done < "$indListFile"
fi
if [ -f "$patchListFile" ]; then
while read -r line || [[ -n "$line" ]]; do
read -a params <<< $line
for param in ${params[@]} ; do
case $param in
/*)
tempListPatched+=("$param")
;;
esac
done
done < "$patchListFile"
fi
# remove duplicate files from each list
fileList=($(printf "%s\n" "${tempListVer[@]}" | sort -u))
fileListVersionIndependent=($(printf "%s\n" "${tempListInd[@]}" | sort -u))
fileListPatched=($(printf "%s\n" "${tempListPatched[@]}" | sort -u))
tempListAll=(${fileList[@]})
tempListAll+=(${fileListVersionIndependent[@]})
tempListAll+=(${fileListPatched[@]})
fileListAll=($(printf "%s\n" "${tempListAll[@]}" | sort -u))
# report duplicates
local dupsVer=($(printf "%s\n" "${tempListVer[@]}" | sort | uniq -d ))
local dupsInd=($(printf "%s\n" "${tempListInd[@]}" | sort | uniq -d ))
local dupsPatched=($(printf "%s\n" "${tempListPatched[@]}" | sort | uniq -d ))
local dupsAll=($(printf "%s\n" "${tempListAll[@]}" | sort | uniq -d ))
if [ ! -z "$dupsVer" ]; then
for dup in "$dupsVer" ; do
logMessage "WARNING $package: duplicate in fileList $dup - ignored"
done
fi
if [ ! -z "$dupsInd" ]; then
for dup in "$dupsInd" ; do
logMessage "WARNING $package: duplicate in fileListVersionIndependent $dup - ignored"
done
fi
if [ ! -z "$dupsPatched" ]; then
for dup in "$dupsPatched" ; do
logMessage "WARNING $package: duplicate in fileListPatched $dup - ignored"
done
fi
if [ ! -z "$dupsAll" ]; then
for dup in "$dupsAll" ; do
logMessage "ERROR $package: duplicate in combined file lists $dup - can't continue"
done
exit
fi
}
totalErrors=0
totalWarnings=0
packageErrors=0
packageWarnings=0
outputtingProgress=false
function logMessage ()
{
if $outputtingProgress ; then
clearProgress
fi
echo "$*"
if [[ "$*" == "ERROR"* ]]; then
((totalErrors++))
((packageErrors++))
elif [[ "$*" == "WARNING"* ]]; then
((totalWarnings++))
((packageWarnings++))
fi
}
function outputProgressTick ()
{
if ! $outputtingProgress ; then
echo -en "$beginProgressString"
fi
echo -en "$1"
outputtingProgress=true
}
function clearProgress ()
{
# start a new line if outputting ticks
if $outputtingProgress; then
echo
# echo -ne "\r\033[2K" #### erase line
fi
outputtingProgress=false
}
beginProgressString=""
function beginProgress ()
{
# erase the line but stay on it
if $outputtingProgress ; then
clearProgress
fi
if [ ! -z "$1" ]; then
beginProgressString="$1 "
echo -en "$beginProgressString"
outputtingProgress=true
fi
}
# removing a nested set of directories sometimes results in permission denied the first time
# so try several times to be sure
function deleteNestedDirectories ()
{
rm -rf "$1" &> /dev/null
if [ -d "$1" ] ; then
rm -rf "$1" &> /dev/null
if [ -d "$1" ] ; then
rm -rf "$1"
fi
fi
}
yesNoPrompt ()
{
response=''
while true; do
/bin/echo -n "$*"
read response
case $response in
[yY]*)
return 0
break
;;
[nN]*)
return 1
break
;;
*)
esac
done
}
#### script code begins here
packageList=""
doAllPackages=false
globalEndAction=''
for param in $* ; do
case $param in
-[pP]*)
logMessage "working copies will be preserved - packages will not be updated"
globalEndAction='preserve'
;;
-[dD]*)
logMessage "working copies will be deleted - packages will not be updated"
globalEndAction='delete'
;;
-[uU]*)
logMessage "packages will be updated after updating"
globalEndAction='update'
;;
-[rR]*)
logMessage "packages will be restored from backups"
globalEndAction='restore'
;;
all)
doAllPackages=true
;;
*)
packageList+=" "$1
esac
shift
done
if $doAllPackages ; then
packageList=$allPackages
elif [ -z "$packageList" ]; then
logMessage "ERROR no packages specified - use 'all' for all packages"
exit
fi
if [ "$globalEndAction" == "restore" ]; then
for package in $packageList; do
sourceDirectory="$packageRoot/$package"
sourceFiles="$sourceDirectory/FileSets"
backupDirectory="$packageRoot/$package.backup"
backupFiles="$backupDirectory/FileSets"
sourceVeLib="$sourceDirectory/velib_python"
backupVeLib="$backupDirectory/velib_python"
if [ ! -d "$backupDirectory" ]; then
logMessage "WARNING $package: no backup found - package NOT restored"
continue
fi
logMessage "WARNING $package: restored from backup"
deleteNestedDirectories "$sourceFiles"
deleteNestedDirectories "$sourceVeLib"
mv "$backupFiles" "$sourceFiles"
if [ -e "$backupVeLib" ]; then
mv -f "$backupVeLib" "$sourceVeLib"
fi
deleteNestedDirectories $backupDirectory
done
exit
fi
# get helper resources version for later
if [ -f "$packageRoot/SetupHelper/version" ]; then
shVersion=$( cat "$packageRoot/SetupHelper/version" )
versionStringToNumber $shVersion
shVersionNumber=$versionNumber
else
shVersion=""
shVersionNumber=0
fi
# make the version list from the directories in stock files
# version lists are sorted so the most recent version is first
tempList=()
stockVersionList=($(ls -d "$stockFiles"/v[0-9]* 2> /dev/null))
for entry in ${stockVersionList[@]} ; do
version=$(basename $entry)
versionFile="$stockFiles/$version/opt/victronenergy/version"
if [ -f "$versionFile" ]; then
realVersion=$(cat "$versionFile" | head -n 1)
else
logMessage "ERROR version file missing from stock files $version - can't continue"
exit
fi
if [ $version != $realVersion ]; then
logMessage "ERROR $version name does not mactch Venus $realVersion - can't continue"
exit
fi
if versionStringToNumber $version ; then
tempList+=("$version:$versionNumber")
else
logMessage "ERROR invalid version $versionStringToNumberStatus - not added to list"
fi
done
stockVersionList=( $(echo ${tempList[@]} | tr ' ' '\n' | sort -t ':' -r -n -k 2 | uniq ) )
stockVersionListLength=${#stockVersionList[@]}
for package in $packageList; do
packageErrors=0
packageWarnings=0
sourceDirectory="$packageRoot/$package"
sourceFiles="$sourceDirectory/FileSets"
workingDirectory="$packageRoot/$package.copy"
workingFiles="$workingDirectory/FileSets"
backupDirectory="$packageRoot/$package.backup"
backupFiles="$backupDirectory/FileSets"
versionIndependentFileSet="$workingFiles/VersionIndependent"
sourceVeLib="$sourceDirectory/velib_python"
workingVeLib="$workingDirectory/velib_python"
if [ ! -d "$sourceDirectory" ] || [ ! -f "$sourceDirectory/version" ]; then
logMessage "WARNING: $sourceDirectory - not a package directory - skipping"
continue # next package
fi
if [ ! -d "$sourceFiles" ]; then
logMessage "$package: no file sets"
fi
if ! [ -f "$sourceFiles/fileList" ]; then
logMessage "$package: no version-dependent files"
fi
if ! [ -f "$sourceFiles/fileListVersionIndependent" ]; then
logMessage "$package: no version-independent files"
fi
if ! [ -f "$sourceFiles/fileListPatched" ]; then
logMessage "$package: no patches"
fi
# validate package version number
tempVersion=$(cat "$sourceDirectory/version")
if ! versionStringToNumber $tempVersion ; then
logMessage "ERROR $package: version $versionStringToNumberStatus - skipping package"
continue # next package
fi
# compute compatible version range - use values in original package
if [ -f "$sourceDirectory/obsoleteVersion" ]; then
obsoleteVersio=$(cat "$sourceDirectory/obsoleteVersion")
if versionStringToNumber $obsoleteVersio ; then
obsoleteVersionNumber=$versionNumber
else
logMessage "ERROR $package obsoleteVersion $versionStringToNumberStatus - skipping package"
continue # next package
fi
else
obsoleteVersionNumber=9999999999999999
fi
if [ -f "$sourceDirectory/firstCompatibleVersion" ]; then
firstCompatibleVersion=$(cat "$sourceDirectory/firstCompatibleVersion")
# limit packages to v2.71 and newer
else
firstCompatibleVersion='v2.71'
fi
if versionStringToNumber $firstCompatibleVersion ; then
firstVersionNumber=$versionNumber
else
logMessage "ERROR $package: firstCompatibleVersion $versionStringToNumberStatus - skipping package"
continue # next package
fi
# make copy of source package FileSets
replaceCopy=false
if [ -e "$workingDirectory" ]; then
logMessage "$(basename $workingDirectory) already exists"
if yesNoPrompt " replace it (y) or continue updating the copy (n)? " ; then
replaceCopy=true
else
logMessage "$package: checking existing working copy"
fi
fi
if $replaceCopy || ! [ -e "$workingDirectory" ]; then
if $replaceCopy ;then
logMessage "$package: replacing working copy"
else
logMessage "$package: making working copy"
fi
deleteNestedDirectories "$workingDirectory"
mkdir -p "$workingDirectory"
if [ -d "$sourceFiles" ]; then
cp -pR "$sourceFiles" "$workingFiles"
fi
if [ -d "$sourceVeLib" ]; then
cp -pR "$sourceVeLib" "$workingVeLib"
fi
fi
# clean up flag files from a previous run
rm -f "$workingFiles"/*/INCOMPATIBLE_VERSION
rm -f "$workingFiles"/*/UNUSED_FILE_SET
rm -f "$workingFiles"/*/INCOMPLETE
rm -f "$workingFiles"/*/COMPLETE
rm -f "$workingFiles"/*/LINKS_ONLY
rm -f "$workingFiles"/*/*.NO_ORIG
rm -f "$workingFiles"/*/*.CHECK_REPLACEMENT
rm -f "$workingFiles"/*/*.BAD_LINK
rm -f "$workingFiles"/*/NEW_FILE_SET
rm -f "$workingFiles"/*VERSIONED_AND_INDEPENDENT_EXIST
rm -f "$workingFiles"/*/*VERSIONED_AND_INDEPENDENT_EXIST
rm -f "$workingFiles"/*CHECK_VERSION_INDEPENDENT
rm -f "$workingFiles"/*/*CHECK_VERSION_INDEPENDENT
rm -f "$workingFiles"/*CHECK_ALT_ORIG
rm -f "$workingFiles"/*/*CHECK_ALT_ORIG
# update velib_python
if [ -e "$workingVeLib" ]; then
beginProgress "updating velib_python"
pythonLibSoureDir="opt/victronenergy/dbus-systemcalc-py/ext/velib_python"
veLibFiles=( vedbus.py dbusmonitor.py settingsdevice.py ve_utils.py )
rm -rf "$workingVeLib"
mkdir "$workingVeLib"
for (( i1 = 0; i1 < $stockVersionListLength; i1++ )); do
newVersion=false
IFS=':' read version versionNumber <<< "${stockVersionList[$i1]}"
if (( i1 == 0 )); then
newVersion=true
else
for file in ${veLibFiles[@]} ; do
file1="$stockFiles/$version/$pythonLibSoureDir/$file"
file2="$stockFiles/$previousVersion/$pythonLibSoureDir/$file"
if ! cmp -s "$file1" "$file2" > /dev/null ; then
newVersion=true
fi
done
fi
if $newVersion ; then
outputProgressTick "."
if (( i1 == 0 ));then
velibDir="$workingVeLib/latest"
prevVelibDir="$workingVeLib/latest"
else
velibDir="$workingVeLib/$version"
fi
mkdir "$velibDir"
for file in ${veLibFiles[@]} ; do
file1="$stockFiles/$version/$pythonLibSoureDir/$file"
file2="$velibDir/$file"
cp -f "$file1" "$file2"
done
newVersion=false
previousVersion=$version
prevVelibDir="$velibDir"
fi
echo $version > "$prevVelibDir/oldestVersion"
done
fi
getFileLists "$workingFiles"
# if any version-dependent files, create missing file sets or flag incompatible
if ! [ -z $fileList ]; then
for entry in ${stockVersionList[@]}; do
IFS=':' read version versionNumber <<< "$entry"
fileSet="$workingFiles/$version"
stockFileSet="$stockFiles/$version"
if (( $versionNumber >= $obsoleteVersionNumber )) || (( $versionNumber < $firstVersionNumber )); then
touch "$fileSet/INCOMPATIBLE_VERSION"
compatible=false
else
compatible=true
fi
if $compatible && ! [ -e "$fileSet" ]; then
mkdir "$fileSet"
touch "$fileSet/NEW_FILE_SET"
fi
done
fi
# 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=(${stockVersionList[@]})
for entry in ${sourceFileSets[@]} ; do
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+=($version:$versionNumber)
touch "$workingFiles/$version/UNUSED_FILE_SET"
fi
done
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
obsoleteFileSets=()
tempList=()
for entry in ${allFileSets[@]} ; do
IFS=':' read version versionNumber <<< "$entry"
if (( $versionNumber >= $obsoleteVersionNumber )) || (( $versionNumber < $firstVersionNumber )); then
obsoleteFileSets+=($version:$versionNumber)
else
tempList+=($version:$versionNumber)
fi
done
allFileSets=(${tempList[@]})
allFileSets+=(${obsoleteFileSets[@]})
allFileSetsLength=${#allFileSets[@]}
# relocate version-independent files to VersionIndependent file set
for file in ${fileListVersionIndependent[@]}; do
baseName=$(basename $file)
if [ -f "$workingFiles/$baseName" ]; then
if [ ! -d "$workingFiles/VersionIndependent" ]; then
mkdir -p "$workingFiles/VersionIndependent"
fi
if [ -f "$workingFiles/VersionIndependent/$baseName" ]; then
logMessage "$package: $baseName exists in FileSets AND VersionIndependent - not moved"
touch "$workingFiles/VersionIndependent/$baseName.CHECK_VERSION_INDEPENDENT"
touch "$workingFiles/$baseName.CHECK_VERSION_INDEPENDENT"
else
logMessage "$package: moving $baseName to version-independent file set"
mv "$workingFiles/$baseName" "$workingFiles/VersionIndependent"
fi
elif ! [ -f "$workingFiles/VersionIndependent/$baseName" ]; then
logMessage "ERROR $package: $baseName missing version independent file"
fi
done
# relocate ALT_ORIG files to .../FileSets/AlternateOriginals
# do as a loop so each move is reported
# must have some alt orig files in FileSets for this to happen
altOrigFileDir="$workingFiles/AlternateOriginals"
oldAltOrigList=( $( ls "$workgingFiles"/*.ALT_ORIG 2> /dev/null) )
if ! [ -z "$oldAltOrigList" ] && yesNoPrompt "move alternate originals to AlternateOriginal directory (y/n)? " ; then
if ! [ -d "$altOrigFileDir" ]; then
mkdir -p "$altOrigFileDir"
fi
for file in ${altOrigList[@]} ; do
baseName=$(basename "$file")
if [ -f "$altOrigFileDir/$baseName" ]; then
logMessage "$package: $baseName exists in FileSets AND AlternateOriginals - not moved"
touch "$altOrigFileDir/$baseName.CHECK_ALT_ORIG"
touch "$workingFiles/$baseName.CHECK_ALT_ORIG"
else
logMessage "$package: moving $baseName.ALT_ORIG to AlternateOriginals"
mv "$file" "$altOrigFileDir"
fi
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
diff $patchOptions "$patchOrig" "$patchResult" > "$patchFile"
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 file set"
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
beginProgress "$package: updating file sets"
# process only versioned files
for file in ${fileList[@]} ; do
outputProgressTick "."
baseName=$(basename "$file")
versionedFileExists=false
# use alternate original if present in AlternateOriginals
if [ -f "$altOrigFileDir/$baseName.ALT_ORIG" ]; then
useAltOrig=true
altOrigFile=$(cat "$altOrigFileDir/$baseName.ALT_ORIG")
# or in FileSets
elif [ -f "$workingFiles/$baseName.ALT_ORIG" ]; then
useAltOrig=true
altOrigFile=$(cat "$workingFiles/$baseName.ALT_ORIG")
else
useAltOrig=false
altOrigFile=""
fi
# 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
addOrigToFileSet=false
blockIsUsed=false
for (( i1 = start; i1 < $allFileSetsLength; i1++ )); do
IFS=':' read version versionNumber <<< "${allFileSets[$i1]}"
fileSet="$workingFiles/$version"
if [ -e "$fileSet/INCOMPATIBLE_VERSION" ] || [ -e "$fileSet/UNUSED_FILE_SET" ]; then
fileSetUsed=false
else
fileSetUsed=true
fi
replacement="$fileSet/$baseName"
stockFileSet="$stockFiles/$version"
orig="$fileSet/$baseName.orig"
if $useAltOrig ; then
stockFile="$stockFileSet$altOrigFile"
else
stockFile="$stockFileSet$file"
fi
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
# skip this version if parent directory does not exist
if ! [ -e $( dirname "$stockFile" ) ]; then
fileSetUsed=false
fi
if (( i1 == start )); then
startVersion=$version
fi
if ! $fileSetUsed ; then
thisOrig=""
elif [ -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
thisOrig=""
fi
if [ -z "$compareReference" ] && ! [ -z "$thisOrig" ]; then
compareReference="$thisOrig"
fi
includeInBlock=false
# nothing to compare - include in same block
if $fileSetUsed ; then
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
fi
# start a new block
if ! $includeInBlock ; then
break
fi
if $fileSetUsed ; then
blockIsUsed=true
fi
# save version of old replacement files for next loop
if $replacementIsFile ; then
if ! $oldReplacementIsFile || [ "$oldReplacementVersion" == "-" ]; then
oldReplacementVersion=$version
oldReplacementIsFile=true
oldReplacementIsUseOrig=false
addOrigToFileSet=true
fi
elif $useOrig && [ "$oldReplacementVersion" == "-" ]; then
oldReplacementVersion=$version
oldReplacementIsFile=false
oldReplacementIsUseOrig=true
# retain .orig so that SetupHelper can create USE_ORIGINAL flag files for missing file sets
addOrigToFileSet=true
fi
(( 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 (( to == -1 )) && $fileSetUsed; then
(( to = i1 ))
toFileSet="$fileSet"
toVersion=$( basename "$toFileSet" )
fi
done # end locate block
if (( to == -1 )); then
if $blockIsUsed; then
logMessage "ERROR $package: $baseName no destination file set for block $startVersion $endVersion - can't relocate files"
fi
else
toReplacement="$toFileSet/$baseName"
oldReplacement="$workingFiles/$oldReplacementVersion/$baseName"
toStockFileSet="$stockFiles/$toVersion"
if $useAltOrig ; then
toStockFile="$toStockFileSet$altOrigFile"
else
toStockFile="$toStockFileSet$file"
fi