Chameleon

Chameleon Commit Details

Date:2012-01-16 00:17:34 (12 years 3 months ago)
Author:JrCs
Commit:1801
Parents: 1800
Message:Improved installer - Options are now automatically removed if deselected in installer
Changes:
A/trunk/package/Scripts.templates/AddOption
A/trunk/package/Scripts.templates/Pre/clean_bootplist.pl
A/trunk/package/Scripts.templates/InstallTheme/postinstall
A/trunk/package/Scripts.templates/InstallModule/postinstall
A/trunk/package/Scripts.templates/InstallTheme
A/trunk/package/Scripts.templates/InstallModule
A/trunk/package/Scripts.templates/AddOption/postinstall
M/trunk/package/Scripts.templates/Post/postinstall
M/trunk/package/Scripts.templates/Pre/preinstall
M/trunk/package/buildpkg.sh
M/trunk/package/Scripts/Sub/UnMountEFIvolumes.sh

File differences

trunk/package/Scripts.templates/AddOption/postinstall
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
#!/bin/bash
set -u
targetVolume="$3"
key="@optionKey@"
value="@optionValue@"
type="@optionType@"
logName="@LOG_FILENAME@"
logFile="${targetVolume}/$logName"
# Check if target volume exists
if [[ ! -d "$targetVolume" ]]; then
echo "$targetVolume volume does not exist!" >&2
exit 1
fi
exec >>"${logFile}" 2>&1
echo "Added boot option: ${key}=${value}"
key="${key// /\\ }" # Escape spaces
value="${value// /\\ }" # Escape spaces
bootPListFile="${targetVolume}/Extra/org.chameleon.Boot.plist"
case "$type" in
bool|text)
/usr/libexec/plistbuddy -c "Add :${key} string ${value}" "$bootPListFile"
;;
list)
current_values=$( /usr/libexec/plistbuddy -c "Print :${key}" \
"$bootPListFile" 2>/dev/null )
result=$?
current_values="${current_values// /\\ }" # Escape spaces
current_values="${current_values//\"/\\\"}" # Escape double quotes
if [[ $result -eq 0 ]]; then
# Append our new values
if [[ "$current_values" = "" ]]; then
new_values="${value}"
else
new_values="${current_values}\ ${value}"
fi
/usr/libexec/plistbuddy -c "Set :${key} ${new_values}" \
"$bootPListFile"
else
# Create a new option
new_values="${value}"
/usr/libexec/plistbuddy -c "Add :${key} string ${new_values}" \
"$bootPListFile"
fi
;;
esac
exit 0
trunk/package/Scripts.templates/Post/postinstall
11
22
3
4
5
6
3
4
5
6
77
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
318
32
33
34
9
10
3511
3612
3713
3814
3915
40
41
16
4217
4318
4419
4520
4621
22
23
24
25
26
4727
4828
4929
5030
5131
5232
53
54
33
34
35
5536
56
57
58
59
6037
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
24338
24439
24540
......
25348
25449
25550
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
51
27252
273
274
275
276
277
278
27953
280
281
282
283
54
28455
285
286
287
288
289
290
291
292
293
56
57
#!/bin/bash
mergeString () {
local src="${1}"
local new="${2}"
local result="$src"
# $1 = Full path to the installation package the installer app is processing
# $2 = Full path to the installation destination
# $3 = Installation volume (mountpoint) to receive the payload
# $4 = Root directory for the system
for newItem in $new ;do
local found=0
for srcItem in $src ;do
if [[ $newItem == $srcItem ]];then
found=1
break
fi
done
[[ $found -eq 0 ]] && result="$result $newItem"
done
echo "$result"
}
echo "==============================================="
echo "Post Post-Install Script"
echo "*********************************"
#echo "DEBUG: $ 1 = Full path to the installation package the installer app is processing: " $1
#echo "DEBUG: $ 2 = Full path to the installation destination: " $2
#echo "DEBUG: $ 3 = Installation volume (mountpoint) to receive the payload: " $3
#echo "DEBUG: $ 4 = Root directory for the system: " $4
# Check target exists
if [ ! -e "$3" ]
then
echo "$3 volume does not exist!"
if [ ! -d "$3" ]; then
echo "$3 volume does not exist !" >&2
exit 1
fi
# If target volume root of current system then replace
# / with volume name.
if [ "$3" == "/" ]
then
if [ "$3" == "/" ]; then
dest_vol="/Volumes/"$( ls -1F /Volumes | sed -n 's:@$::p' )
else
dest_vol="$3"
fi
logName="@LOG_FILENAME@"
logFile="${dest_vol}/$logName"
exec >>"${logFile}" 2>&1
# Find script location so to find the Install Log script.
MYLOCATION="${PWD}/${BASH_ARGV[0]}"
export MYLOCATION="${MYLOCATION%/*}"
scriptDir=$MYLOCATION
# Write some information to the Install Log
"$scriptDir"InstallLog.sh "${dest_vol}" "Running Post postinstall script"
"$scriptDir"InstallLog.sh "${dest_vol}" "Target volume = ${dest_vol}"
echo "======================================================"
echo "Running Post postinstall script"
echo "Target volume = ${dest_vol}"
# set temporary directory
chamTemp="$dest_vol/usr/local/chamTemp"
# ---------------------------------------------
# Build org.chameleon.Boot.plist
# ---------------------------------------------
# All options selected are now dummy files with
# the filename of the option and value residing
# in /usr/local/chamTemp/options/
# for example. Boot Banner=Yes
# Are there any options to build?
if [ "$(ls -A ${chamTemp}/options )" ]; then
# Check for temporary directory/Extra folder.
if [ ! -d "$chamTemp"/Extra ]; then
mkdir "$chamTemp"/Extra
fi
# Create template for org.chameleon.Boot.plist"
tempOCBP="$chamTemp"/Extra/org.chameleon.Boot.plist
cp "$4"/Library/Preferences/SystemConfiguration/com.apple.Boot.plist "$tempOCBP"
# Read list of all boot options the user added.
while IFS= read -r -d '' FILE; do
option="${FILE##*/}"
key="${option%%=*}"
value="${option#*=}"
# Check for 'Kernel Flags' key indicate that should be a kernel flag
if [[ "$key" = "Kernel Flags" ]];then
# plistbuddy only add's if the key doesn't already exist.
# So let's store any kernelflags and add them all at the
# same time once when we reach the end of the options list.
kernelflag[${#kernelflag[*]}]="$value"
"$scriptDir"InstallLog.sh "${dest_vol}" "Added kernel flag: $value"
else
# escape any spaces
keyToUse=$( echo "$key" | sed 's/ /\\ /g' )
sudo /usr/libexec/plistbuddy -c "Add :${keyToUse} string ${value}" "$tempOCBP"
returnValue=$?
if [ ${returnValue} -ne 1 ]; then
"$scriptDir"InstallLog.sh "${dest_vol}" "Added boot option: ${key}=${value}"
else
"$scriptDir"InstallLog.sh "${dest_vol}" "Can't add ${key}=${value} as an option already exists for: ${key}"
fi
fi
done < <( find "${chamTemp}/options" -type f -print0 )
# Add any kernel flags together in to one string.
kernelFlagString="${kernelflag[@]}"
# We add the final string in the next section.
fi
# ---------------------------------------------
# Add any installed modules to the Install Log
# ---------------------------------------------
if [ -e "${chamTemp}"/Extra/modules ]; then
ls "${chamTemp}"/Extra/modules | while read FILE
do
"$scriptDir"InstallLog.sh "${dest_vol}" "Added module: $FILE"
if [ "$FILE" == "Keylayout.dylib" ]; then
"$scriptDir"InstallLog.sh "${dest_vol}" "Also adding required Keymaps."
fi
done
fi
# ---------------------------------------------
# Add any installed themes to the Install Log
# ---------------------------------------------
if [ -e "${chamTemp}"/Extra/Themes ]; then
ls "${chamTemp}"/Extra/Themes | while read FILE
do
"$scriptDir"InstallLog.sh "${dest_vol}" "Added Theme: $FILE"
done
fi
# Does a temporary /Extra folder exist?
if [ -d "$chamTemp"/Extra ]; then
# ---------------------------------------------
# Merge /Extra folders?
# ---------------------------------------------
# Does the user want to upgrade an existing /Extra folder?
# If so, then merge their existing one in to the temp one.
if [ -e "$chamTemp/install_type_upgrade" ]; then
"$scriptDir"InstallLog.sh "${dest_vol}" "User selected to do an upgrade install."
# first move the new org.chameleon.Boot.plist out of tmp
# Extra folder so we can merge that separately.
mv "$tempOCBP" "$chamTemp/holding.plist"
# Check for an existing /Extra folder
# and merge existing /Extra with temp one.
if [ -e "$dest_vol"/.ChameleonEFI ]; then
if [ -e "/Volumes/EFI/Extra" ]; then
"$scriptDir"InstallLog.sh "${dest_vol}" "Merging existing /Volumes/EFI/Extra folder."
ditto --noextattr --noqtn /Volumes/EFI/Extra "$chamTemp"/Extra
fi
else
if [ -e "$dest_vol/Extra" ]; then
"$scriptDir"InstallLog.sh "${dest_vol}" "Merging existing ${dest_vol}/Extra folder."
ditto --noextattr --noqtn "${dest_vol}"/Extra "$chamTemp"/Extra
fi
fi
# Check existing plist name for old naming convention
# and change to new convention.
if [ -e "$chamTemp"/Extra/com.apple.Boot.plist ]; then
"$scriptDir"InstallLog.sh "${dest_vol}" "Renaming existing com.apple.Boot.plist to org.chameleon.Boot.plist."
mv "$chamTemp"/Extra/com.apple.Boot.plist "$tempOCBP"
fi
# Before merging org.chameleon.Boot.plist, copy any
# existing kernel flags, then delete the entry.
currentFlags=$( sudo /usr/libexec/plistbuddy -c "Print :Kernel\ Flags" "$tempOCBP" )
sudo /usr/libexec/plistbuddy -c "Delete :Kernel\ Flags" "$tempOCBP"
# Merge new org.chameleon.Boot.plist (holding.plist)
# with their currently existing one.
"$scriptDir"InstallLog.sh "${dest_vol}" "------
Merging new options into org.chameleon.Boot.plist.
NOTE: Please check the new merged org.chameleon.Boot.plist as
NOTE: any existing keys will NOT have been updated.
NOTE: For example: If you already had Wait=No as a boot option
NOTE: and chose Wait=Yes from the list, this will NOT be changed.
------"
sudo /usr/libexec/plistbuddy -c "Merge $chamTemp/holding.plist" "$tempOCBP"
if [[ -n "$currentFlags" ]];then
# Combine new kernel flags with old ones.
kernelFlagString=$( mergeString "$currentFlags" "${kernelFlagString}" )
fi
elif [ -e "$chamTemp/install_type_new" ]; then
"$scriptDir"InstallLog.sh "${dest_vol}" "User selected to make a new install."
fi
# Write kernel flags option
kernelFlagString=$(echo ${kernelFlagString}) # Remove leading and trailing spaces
if [[ -n "$kernelFlagString" ]];then
sudo /usr/libexec/plistbuddy -c "Add :Kernel\ Flags string $kernelFlagString" "$tempOCBP"
returnValue=$?
if [ ${returnValue} -ne 0 ]; then # key already exists.
sudo /usr/libexec/plistbuddy -c "Delete :Kernel\ Flags" "$tempOCBP"
sudo /usr/libexec/plistbuddy -c "Add :Kernel\ Flags string $kernelFlagString" "$tempOCBP"
fi
fi
# ---------------------------------------------
# Copy temp Extra folder to target destination
# ---------------------------------------------
# Check for an existing /Extra folder. If found, back it up
# before copying the temporary Extra folder to destination.
# Extra folder now resides in /usr/local/chamTemp/
# Copy /usr/local/chamTemp/Extra to correct location.
if [ ! -f "$dest_vol"/.ChameleonEFI ]; then
# The Standard install option chosen
rm -rf "$dest_vol/Extra" # Remove old Extra directory
"$scriptDir"InstallLog.sh "${dest_vol}" "Writing new Extra folder to: $dest_vol/"
echo "Copying $chamTemp/Extra TO $dest_vol"
cp -R "$chamTemp"/Extra "$dest_vol"
else
# The EFI system partition install option was chosen
rm -rf "/Volumes/EFI/Extra" # Remove old Extra directory
"$scriptDir"InstallLog.sh "${dest_vol}" "Writing new Extra folder to: /Volumes/EFI/"
cp -R "$chamTemp"/Extra "/Volumes/EFI"
fi
else
if [ ! -f "$dest_vol"/.ChameleonEFI ]; then
if [ -e "$dest_vol"/Extra ]; then
"$scriptDir"InstallLog.sh "${dest_vol}" "No elements selected for adding to an Extra folder,
so leaving existing $dest_vol/Extra folder untouched."
fi
else
if [ -e "/Volumes/EFI/Extra" ]; then
"$scriptDir"InstallLog.sh "${dest_vol}" "No elements selected for adding to an Extra folder,
so leaving existing /Volumes/EFI/Extra folder untouched."
fi
fi
fi
# ---------------------------------------------
# Update Rights
# ---------------------------------------------
chmod 777 ${dest_vol}/Extra 2>/dev/null
"$scriptDir"UnMountEFIvolumes.sh "${dest_vol}" "${scriptDir}"
# remove any temporary boot sector files if they exist
if [ -d /tmp/newbs ]; then
cleanUp="${cleanUp},1a"
rm /tmp/newbs
fi
if [ -d /tmp/origbs ]; then
cleanUp="${cleanUp},1b"
rm /tmp/origbs
fi
if [ -d /tmp/newBootSector ]; then
cleanUp="${cleanUp},1c"
rm /tmp/newbs
fi
if [ -d /tmp/originalBootSector ]; then
cleanUp="${cleanUp},1d"
rm /tmp/origbs
fi
rm -f /tmp/newbs /tmp/origbs /tmp/originalBootSector /tmp/newBootSector
# delete the temporary Chameleon folder
if [ -e "$chamTemp" ]; then
cleanUp="${cleanUp},2"
rm -rf "$chamTemp"
fi
# Remove /.ChameleonEFI file
if [ -f "$dest_vol"/.ChameleonEFI ]; then
cleanUp="${cleanUp},3"
rm "$dest_vol"/.ChameleonEFI
fi
rm -f "${dest_vol}/.ChameleonEFI"
"$scriptDir"InstallLog.sh "${dest_vol}" "Cleanup: ${cleanUp}"
"$scriptDir"InstallLog.sh "${dest_vol}" "LineBreak"
"$scriptDir"InstallLog.sh "${dest_vol}" "Post script complete"
echo "==============================================="
echo "END - Post Post-Install Script"
echo "*********************************"
echo "-----------------------------------------------"
echo ""
echo "======================================================"
echo "Post postinstall script complete"
trunk/package/Scripts.templates/Pre/clean_bootplist.pl
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
#!/usr/bin/perl
use strict;
use YAML::Syck;
our $target_volume;
our $boot_plist_filepath;
our $yaml_file="@YAML_FILE@";
if ($#ARGV < 0) {
print stderr "A target volume is needed\n";
} else {
$target_volume=$ARGV[0];
}
$boot_plist_filepath = "${target_volume}/Extra/org.chameleon.Boot.plist";
if ( -f "$boot_plist_filepath" ) {
main("$yaml_file");
}
sub _do_cmd {
my ($cmd, $key, $value) = @_;
my $out;
$key =~ s/([\s])/\\$1/g; # Escape characters in key
$value =~ s/([\s"])/\\$1/g; # Escape characters in value (space & ")
my $plistbuddy_command="$cmd :$key $value";
open ( OUTPUT, "-|", '/usr/libexec/plistbuddy', "-c", "$plistbuddy_command", "$boot_plist_filepath" );
my $exit_code = $?;
chomp($out = <OUTPUT>);
close OUTPUT;
return $out;
}
sub get_boot_plist_option {
my ($option) = @_;
return _do_cmd( "Print", "$option");
}
sub delete_boot_plist_option {
my ($option) = @_;
return _do_cmd( "Delete", "$option");
}
sub delete_boot_plist_text_option {
my ($option, $values) = @_;
my $current_value = get_boot_plist_option "$option";
if ( $current_value ne "") {
foreach my $recognized_value (@{$values}) {
if ($recognized_value eq $current_value) {
return _do_cmd( "Delete", "$option");
}
}
}
return "";
}
sub delete_boot_plist_list_option {
my ($option, $values) = @_;
my $current_value = get_boot_plist_option "$option";
if ( $current_value ne "") {
my %count;
my @new_list;
foreach my $value (@{$values}) {
$count{$value} = 1;
}
foreach my $value (split(/\s+/,$current_value)) {
if ( not exists $count{$value} ) {
push @new_list, $value;
}
}
return _do_cmd( "Set", $option, join(' ',@new_list) );
}
return "";
}
sub main() {
# Remove all options that installer can managed
my ($yaml_file) = @_;
my $hash_ref = LoadFile($yaml_file) or die "Can't open yaml file\n";
foreach my $option ( keys %{$hash_ref} ) {
my $type = $hash_ref->{$option}->{type};
if ( $type =~ /^bool$/i ) {
delete_boot_plist_option($option);
} elsif ( $type =~ /^text$/i ) {
delete_boot_plist_text_option( $option,
$hash_ref->{$option}->{values} );
} elsif ( $type =~ /^list$/i ) {
delete_boot_plist_list_option( $option,
$hash_ref->{$option}->{values} );
}
}
}
trunk/package/Scripts.templates/Pre/preinstall
7777
7878
7979
80
81
82
83
84
85
86
87
88
89
90
91
92
8093
8194
8295
echo "======================================================" >>"${logFile}"
# Check existing plist name for old naming convention and change to new convention.
if [[ -f "${targetVolume}/Extra/com.apple.Boot.plist" ]]; then
echo "Renaming existing com.apple.Boot.plist to org.chameleon.Boot.plist" >>"${logFile}"
mv "${targetVolume}/Extra/com.apple.Boot.plist" "${targetVolume}/Extra/org.chameleon.Boot.plist"
fi
# ---------------------------------------------
# Clearing options that Chameleon can managed
# ---------------------------------------------
echo "Clearing options..." >>"${logFile}"
"${PWD}/clean_bootplist.pl" "${targetVolume}" 2>&1 | grep -v 'Does Not Exist' >>"${logFile}"
echo "======================================================" >>"${logFile}"
echo "==============================================="
echo "END - Pre-Install Script"
echo "*********************************"
trunk/package/Scripts.templates/InstallTheme/postinstall
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash
set -u
targetVolume="$3"
themeName="@themeName@"
themeDir="@themeDir@"
logName="@LOG_FILENAME@"
logFile="${targetVolume}/$logName"
# Check if target volume exists
if [[ ! -d "$targetVolume" ]]; then
echo "$targetVolume volume does not exist!" >&2
exit 1
fi
exec >>"${logFile}" 2>&1
[[ -d "${targetVolume}/Extra/Themes/$themeDir" ]] && echo "Theme $themeName installed"
exit 0
trunk/package/Scripts.templates/InstallModule/postinstall
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash
set -u
targetVolume="$3"
moduleName="@moduleName@"
moduleFile="@moduleFile@"
logName="@LOG_FILENAME@"
logFile="${targetVolume}/$logName"
# Check if target volume exists
if [[ ! -d "$targetVolume" ]]; then
echo "$targetVolume volume does not exist!" >&2
exit 1
fi
exec >>"${logFile}" 2>&1
[[ -f "${targetVolume}/Extra/modules/$moduleFile" ]] && echo "Module $moduleName installed"
exit 0
trunk/package/Scripts/Sub/UnMountEFIvolumes.sh
22
33
44
5
65
76
87
......
1211
1312
1413
15
16
14
15
1716
18
17
1918
2019
2120
......
3433
3534
3635
37
38
39
echo "==============================================="
echo "Unmount all volumes named EFI"
echo "*****************************"
# loop through and un-mount ALL mounted 'EFI' system partitions - Thanks kizwan
if [ "$#" -eq 2 ]; then
targetVolumeChosenByUser="$1"
scriptDir="$2"
echo "DEBUG: passed argument for targetVolumeChosenByUser = $targetVolumeChosenByUser"
echo "DEBUG: passed argument for scriptDir = $scriptDir"
# echo "DEBUG: passed argument for targetVolumeChosenByUser = $targetVolumeChosenByUser"
# echo "DEBUG: passed argument for scriptDir = $scriptDir"
else
echo "Error - wrong number of values passed"
echo "Error - wrong number of values passed" >&2
exit 9
fi
fi
exit 0
trunk/package/buildpkg.sh
6767
6868
6969
70
71
72
73
7074
7175
7276
......
8892
8993
9094
91
9295
9396
9497
......
97100
98101
99102
100
101
102
103
104
105
106
107
108
109103
110104
111105
112106
113107
114
115108
116109
117110
......
134127
135128
136129
137
138130
139131
140132
......
178170
179171
180172
181
182173
183174
184175
......
192183
193184
194185
195
196186
197187
198188
......
381371
382372
383373
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
384421
385422
386423
......
393430
394431
395432
396
433
397434
398435
399436
400
401
402437
403438
404
405439
406
407440
441
442
443
408444
409445
410446
......
428464
429465
430466
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
458467
459468
460469
......
474483
475484
476485
486
487
488
489
477490
478491
479492
......
486499
487500
488501
489
502
490503
491504
492505
......
518531
519532
520533
534
521535
522
536
537
538
539
540
523541
524542
525
543
526544
527545
528546
......
533551
534552
535553
554
536555
537
556
557
558
559
560
538561
539562
540
563
541564
542565
543566
......
553576
554577
555578
579
556580
557
581
582
583
584
585
558586
559587
560
588
561589
562590
563591
......
570598
571599
572600
601
573602
574603
575604
......
579608
580609
581610
582
611
583612
584613
585614
586615
616
617
618
619
620
587621
588622
589
623
590624
591625
592626
......
659693
660694
661695
662
663
664
665696
666697
667698
......
670701
671702
672703
704
705
706
707
708
709
673710
674
711
675712
676713
677714
......
704741
705742
706743
707
708
709
744
745
746
747
748
749
710750
711
751
712752
713753
714754
......
727767
728768
729769
730
731
732
770
771
772
773
774
775
776
777
733778
734
735
736
779
780
781
737782
738783
739784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
740800
741801
742802
743803
744804
745
805
746806
747807
748808
# ====== GLOBAL VARIABLES ======
declare -r LOG_FILENAME="Chameleon_Installer_Log.txt"
declare -a chameleonOptionType
declare -a chameleonOptionKey
declare -a chameleonOptionValues
declare -a pkgrefs
declare -a choice_key
declare -a choice_options
# Package identifiers
declare -r chameleon_package_identity="org.chameleon"
declare -r modules_packages_identity="${chameleon_package_identity}.modules"
declare -r chamTemp="usr/local/chamTemp"
# ====== FUNCTIONS ======
echo "${result%"${result##*[![:space:]]}"}" # remove trailing whitespace characters
}
argument () {
local opt="$1"
if [[ $# -eq 0 ]];then
echo "$0: option requires an argument -- '$opt'" >&2; exit 1
fi
echo "$opt"
}
function makeSubstitutions () {
# Substition is like: Key=Value
#
# Optionnal arguments:
# --subst=<substition> : add a new substitution
# --subst <substition> : add a new substitution
#
# Last argument(s) is/are file(s) where substitutions must be made
while [[ $# -gt 0 ]];do
local option="$1"
case "$option" in
--subst) shift; addSubst "$(argument $@)"; shift ;;
--subst=*) shift; addSubst "${option#*=}" ;;
-*)
echo "Unrecognized makeSubstitutions option '$option'" >&2
#
# Optionnal arguments:
# --subst=<substition> : add a new substitution
# --subst <substition> : add a new substitution
#
# Substition is like: Key=Value
#
local option="$1"
case "$option" in
--pkg-rootdir=*) shift; pkgRootDir="${option#*=}" ;;
--subst) shift; allSubst[${#allSubst[*]}]="$option"; allSubst[${#allSubst[*]}]="$1" ; shift ;;
--subst=*) shift; allSubst[${#allSubst[*]}]="${option}" ;;
-*)
echo "Unrecognized addTemplateScripts option '$option'" >&2
echo "(my.choice.selected &amp;&amp; $(exclusive_one_choice ${@}))"
}
recordChameleonOption () {
local type="$1"
local key="$2"
local value="$3"
# Search for an existing key
local found=0
for (( idx=0 ; idx < ${#chameleonOptionKey[@]}; idx++ ));do
if [[ "$key" == "${chameleonOptionKey[$idx]}" ]];then
found=1
break
fi
done
# idx contain the index of a new key or an existing one
if [[ $found -eq 0 ]]; then
# Create a new one
chameleonOptionKey[$idx]="$key"
chameleonOptionType[$idx]="$type"
chameleonOptionValues[$idx]=""
fi
case "$type" in
bool) ;;
text|list) chameleonOptionValues[$idx]="${chameleonOptionValues[$idx]} $value" ;;
*) echo "Error unknown type '$type' for '$key'" >&2
exit 1
;;
esac
}
generate_options_yaml_file () {
local yamlFile="$1"
echo "---" > $yamlFile
for (( idx=0; idx < ${#chameleonOptionKey[@]}; idx++ ));do
printf "%s:\n type: %s\n" "${chameleonOptionKey[$idx]}" "${chameleonOptionType[$idx]}" >> $yamlFile
case ${chameleonOptionType[$idx]} in
text|list)
printf " values:\n" >> $yamlFile
for value in ${chameleonOptionValues[$idx]};do
printf " - %s\n" "$value" >> $yamlFile
done
;;
esac
done
}
main ()
{
echo -e $COL_CYAN" ----------------------------------"$COL_RESET
echo ""
# build pre install package
# Add pre install choice
echo "================= Preinstall ================="
packagesidentity="${chameleon_package_identity}"
choiceId="Pre"
mkdir -p ${PKG_BUILD_DIR}/${choiceId}/Root
addTemplateScripts --pkg-rootdir="${PKG_BUILD_DIR}/${choiceId}" ${choiceId}
packageRefId=$(getPackageRefId "${packagesidentity}" "${choiceId}")
buildpackage "$packageRefId" "${choiceId}" "${PKG_BUILD_DIR}/${choiceId}" "/"
addChoice --start-visible="false" --start-selected="true" --pkg-refs="$packageRefId" "${choiceId}"
# End build pre install package
# Package will be build at the end
# End pre install choice
# build core package
echo "================= Core ================="
packagesidentity="${chameleon_package_identity}"
addChoice --start-visible="false" --start-selected="true" --pkg-refs="$packageRefId" "${choiceId}"
# End build core package
# build install type
echo "================= Chameleon ================="
addGroupChoices --exclusive_one_choice "InstallType"
packagesidentity="${chameleon_package_identity}.type"
# build new install package
choiceId="New"
mkdir -p ${PKG_BUILD_DIR}/${choiceId}/Root
echo "" > "${PKG_BUILD_DIR}/${choiceId}/Root/install_type_new"
packageRefId=$(getPackageRefId "${packagesidentity}" "${choiceId}")
buildpackage "$packageRefId" "${choiceId}" "${PKG_BUILD_DIR}/${choiceId}" "/$chamTemp"
addChoice --group="InstallType" --start-selected="!choices['Upgrade'].selected" --pkg-refs="$packageRefId" "${choiceId}"
# End build new install package
# build upgrade package
choiceId="Upgrade"
mkdir -p ${PKG_BUILD_DIR}/${choiceId}/Root
echo "" > "${PKG_BUILD_DIR}/${choiceId}/Root/install_type_upgrade"
packageRefId=$(getPackageRefId "${packagesidentity}" "${choiceId}")
buildpackage "$packageRefId" "${choiceId}" "${PKG_BUILD_DIR}/${choiceId}" "/$chamTemp"
addChoice --group="InstallType" --start-selected="chameleon_boot_plist_exists()" --pkg-refs="$packageRefId" "${choiceId}"
# End build upgrade package
# End build install type
# build Chameleon package
echo "================= Chameleon ================="
addGroupChoices --exclusive_one_choice "Chameleon"
# End build standard package
# build efi package
if [[ 1 -eq 0 ]];then
# Only standard installation is currently supported
# We need to update the script to be able to install
# Chameleon on EFI partition
choiceId="EFI"
mkdir -p ${PKG_BUILD_DIR}/${choiceId}/Root
mkdir -p ${PKG_BUILD_DIR}/${choiceId}/Scripts/Resources
buildpackage "$packageRefId" "${choiceId}" "${PKG_BUILD_DIR}/${choiceId}" "/"
addChoice --group="Chameleon" --start-visible="systemHasGPT()" --start-selected="false" --pkg-refs="$packageRefId" "${choiceId}"
# End build efi package
fi
# build no bootloader choice package
choiceId="noboot"
mkdir -p ${PKG_BUILD_DIR}/${choiceId}/Root
{
# Start build Resolution package module
choiceId="AutoReso"
moduleFile="Resolution.dylib"
mkdir -p "${PKG_BUILD_DIR}/${choiceId}/Root"
ditto --noextattr --noqtn "${SYMROOT}/i386/modules/Resolution.dylib" "${PKG_BUILD_DIR}/${choiceId}/Root"
ditto --noextattr --noqtn "${SYMROOT}/i386/modules/$moduleFile" "${PKG_BUILD_DIR}/${choiceId}/Root"
addTemplateScripts --pkg-rootdir="${PKG_BUILD_DIR}/${choiceId}" \
--subst="moduleName=$choiceId" \
--subst="moduleFile=$moduleFile" \
InstallModule
packageRefId=$(getPackageRefId "${modules_packages_identity}" "${choiceId}")
buildpackage "$packageRefId" "${choiceId}" "${PKG_BUILD_DIR}/${choiceId}" "/$chamTemp/Extra/modules"
buildpackage "$packageRefId" "${choiceId}" "${PKG_BUILD_DIR}/${choiceId}" "/Extra/modules"
addChoice --group="Module" --start-selected="false" --pkg-refs="$packageRefId" "${choiceId}"
# End build Resolution package module
}
{
# Start build klibc package module
choiceId="klibc"
moduleFile="${choiceId}.dylib"
mkdir -p "${PKG_BUILD_DIR}/${choiceId}/Root"
ditto --noextattr --noqtn "${SYMROOT}/i386/modules/${choiceId}.dylib" ${PKG_BUILD_DIR}/${choiceId}/Root
ditto --noextattr --noqtn "${SYMROOT}/i386/modules/$moduleFile" ${PKG_BUILD_DIR}/${choiceId}/Root
addTemplateScripts --pkg-rootdir="${PKG_BUILD_DIR}/${choiceId}" \
--subst="moduleName=$choiceId" \
--subst="moduleFile=$moduleFile" \
InstallModule
packageRefId=$(getPackageRefId "${modules_packages_identity}" "${choiceId}")
buildpackage "$packageRefId" "${choiceId}" "${PKG_BUILD_DIR}/${choiceId}" "/$chamTemp/Extra/modules"
buildpackage "$packageRefId" "${choiceId}" "${PKG_BUILD_DIR}/${choiceId}" "/Extra/modules"
addChoice --group="Module" --start-selected="false" --pkg-refs="$packageRefId" "${choiceId}"
# End build klibc package module
}
fi
# Start build uClibc package module
choiceId="uClibc"
moduleFile="uClibcxx.dylib"
mkdir -p "${PKG_BUILD_DIR}/${choiceId}/Root"
ditto --noextattr --noqtn "${SYMROOT}/i386/modules/uClibcxx.dylib" "${PKG_BUILD_DIR}/${choiceId}/Root"
ditto --noextattr --noqtn "${SYMROOT}/i386/modules/$moduleFile" "${PKG_BUILD_DIR}/${choiceId}/Root"
addTemplateScripts --pkg-rootdir="${PKG_BUILD_DIR}/${choiceId}" \
--subst="moduleName=$choiceId" \
--subst="moduleFile=$moduleFile" \
InstallModule
packageRefId=$(getPackageRefId "${modules_packages_identity}" "${choiceId}")
buildpackage "$packageRefId" "${choiceId}" "${PKG_BUILD_DIR}/${choiceId}" "/$chamTemp/Extra/modules"
buildpackage "$packageRefId" "${choiceId}" "${PKG_BUILD_DIR}/${choiceId}" "/Extra/modules"
# Add the klibc package because the uClibc module is dependent of klibc module
addChoice --group="Module" --start-selected="false" --pkg-refs="$packageRefId $klibcPackageRefId" "${choiceId}"
# End build uClibc package module
{
# Start build Keylayout package module
choiceId="Keylayout"
moduleFile="${choiceId}.dylib"
mkdir -p ${PKG_BUILD_DIR}/${choiceId}/Root/Extra/{modules,Keymaps}
mkdir -p ${PKG_BUILD_DIR}/${choiceId}/Root/usr/local/bin
layout_src_dir="${SRCROOT}/i386/modules/Keylayout/layouts/layouts-src"
tar czf "${PKG_BUILD_DIR}/${choiceId}/Root/Extra/Keymaps/layouts-src.tar.gz" README *.slt)
fi
# Adding module
ditto --noextattr --noqtn ${SYMROOT}/i386/modules/${choiceId}.dylib ${PKG_BUILD_DIR}/${choiceId}/Root/Extra/modules
ditto --noextattr --noqtn ${SYMROOT}/i386/modules/$moduleFile ${PKG_BUILD_DIR}/${choiceId}/Root/Extra/modules
# Adding Keymaps
ditto --noextattr --noqtn ${SRCROOT}/Keymaps ${PKG_BUILD_DIR}/${choiceId}/Root/Extra/Keymaps
# Adding tools
ditto --noextattr --noqtn ${SYMROOT}/i386/cham-mklayout ${PKG_BUILD_DIR}/${choiceId}/Root/usr/local/bin
# Adding scripts
addTemplateScripts --pkg-rootdir="${PKG_BUILD_DIR}/${choiceId}" \
--subst="moduleName=$choiceId" \
--subst="moduleFile=$moduleFile" \
InstallModule
packageRefId=$(getPackageRefId "${modules_packages_identity}" "${choiceId}")
buildpackage "$packageRefId" "${choiceId}" "${PKG_BUILD_DIR}/${choiceId}" "/$chamTemp"
buildpackage "$packageRefId" "${choiceId}" "${PKG_BUILD_DIR}/${choiceId}" "/"
# Don't add a choice for Keylayout module
# addChoice "${choiceId}" "Module" --start-selected="false" "$packageRefId"
# create folders required for each boot option
mkdir -p "${PKG_BUILD_DIR}/$optionName/Root/"
# create dummy file with name of key/value
echo "" > "${PKG_BUILD_DIR}/$optionName/Root/${keyValue}"
case "$type" in
bool) startSelected="check_chameleon_bool_option('$key','$value')" ;;
text) startSelected="check_chameleon_text_option('$key','$value')" ;;
exit 1
;;
esac
recordChameleonOption "$type" "$key" "$value"
addTemplateScripts --pkg-rootdir="${PKG_BUILD_DIR}/$optionName" \
--subst="optionType=$type" \
--subst="optionKey=$key" \
--subst="optionValue=$value" \
AddOption
packageRefId=$(getPackageRefId "${packagesidentity}" "${optionName}")
buildpackage "$packageRefId" "${optionName}" "${PKG_BUILD_DIR}/${optionName}" "/$chamTemp/options"
buildpackage "$packageRefId" "${optionName}" "${PKG_BUILD_DIR}/${optionName}" "/"
addChoice --group="${builtOptionsList}" \
--start-selected="$startSelected" \
--pkg-refs="$packageRefId" "${optionName}"
choiceId="${availableOptions[i]}"
mkdir -p ${PKG_BUILD_DIR}/${choiceId}/Root
# create dummy file with name of key/value
echo "" > "${PKG_BUILD_DIR}/${choiceId}/Root/${chameleon_keylayout_key}=${availableOptions[i]}"
recordChameleonOption "text" "$chameleon_keylayout_key" "$choiceId"
addTemplateScripts --pkg-rootdir="${PKG_BUILD_DIR}/${choiceId}" \
--subst="optionType=text" \
--subst="optionKey=$chameleon_keylayout_key" \
--subst="optionValue=$choiceId" \
AddOption
packageRefId=$(getPackageRefId "${packagesidentity}" "${choiceId}")
buildpackage "$packageRefId" "${choiceId}" "${PKG_BUILD_DIR}/${choiceId}" "/$chamTemp/options"
buildpackage "$packageRefId" "${choiceId}" "${PKG_BUILD_DIR}/${choiceId}" "/"
# Add the Keylayout package because the Keylayout module is needed
addChoice --group="Keymaps" \
--start-selected="check_chameleon_text_option('${chameleon_keylayout_key}','${choiceId}')" \
artwork="${SRCROOT}/artwork/themes"
themes=($( find "${artwork}" -type d -depth 1 -not -name '.svn' ))
for (( i = 0 ; i < ${#themes[@]} ; i++ )); do
theme=$( echo ${themes[$i]##*/} | awk 'BEGIN{OFS=FS=""}{$1=toupper($1);print}' )
mkdir -p "${PKG_BUILD_DIR}/${theme}/Root/"
rsync -r --exclude=.svn --exclude="*~" "${themes[$i]}/" "${PKG_BUILD_DIR}/${theme}/Root/${theme}"
themeName=$( echo ${themes[$i]##*/} | awk 'BEGIN{OFS=FS=""}{$1=toupper($1);print}' )
themeDir="$themeName"
mkdir -p "${PKG_BUILD_DIR}/${themeName}/Root/"
rsync -r --exclude=.svn --exclude="*~" "${themes[$i]}/" "${PKG_BUILD_DIR}/${themeName}/Root/${themeName}"
addTemplateScripts --pkg-rootdir="${PKG_BUILD_DIR}/${themeName}" \
--subst="themeName=$themeName" \
--subst="themeDir=$themeDir" \
InstallTheme
packageRefId=$(getPackageRefId "${packagesidentity}" "${theme}")
buildpackage "$packageRefId" "${theme}" "${PKG_BUILD_DIR}/${theme}" "/$chamTemp/Extra/Themes"
addChoice --group="Themes" --start-selected="false" --pkg-refs="$packageRefId" "${theme}"
packageRefId=$(getPackageRefId "${packagesidentity}" "${themeName}")
buildpackage "$packageRefId" "${themeName}" "${PKG_BUILD_DIR}/${themeName}" "/Extra/Themes"
addChoice --group="Themes" --start-selected="false" --pkg-refs="$packageRefId" "${themeName}"
done
# End build theme packages# End build Extras package
# build pre install package
echo "================= Pre ================="
packagesidentity="${chameleon_package_identity}"
choiceId="Pre"
packageRefId=$(getPackageRefId "${packagesidentity}" "${choiceId}")
mkdir -p ${PKG_BUILD_DIR}/${choiceId}/Root
mkdir -p ${PKG_BUILD_DIR}/${choiceId}/Scripts/Resources
local yamlFile="Resources/chameleon_options.yaml"
addTemplateScripts --pkg-rootdir="${PKG_BUILD_DIR}/${choiceId}" \
--subst="YAML_FILE=${yamlFile}" ${choiceId}
generate_options_yaml_file "${PKG_BUILD_DIR}/${choiceId}/Scripts/$yamlFile"
buildpackage "$packageRefId" "${choiceId}" "${PKG_BUILD_DIR}/${choiceId}" "/"
# End build pre install package
# build post install package
echo "================= Post ================="
packagesidentity="${chameleon_package_identity}"
choiceId="Post"
mkdir -p ${PKG_BUILD_DIR}/${choiceId}/Root
addTemplateScripts --pkg-rootdir="${PKG_BUILD_DIR}/${choiceId}" ${choiceId} InstallerLog
addTemplateScripts --pkg-rootdir="${PKG_BUILD_DIR}/${choiceId}" ${choiceId}
cp -f ${PKGROOT}/Scripts/Sub/UnMountEFIvolumes.sh ${PKG_BUILD_DIR}/${choiceId}/Scripts
packageRefId=$(getPackageRefId "${packagesidentity}" "${choiceId}")

Archive Download the corresponding diff file

Revision: 1801