-
Notifications
You must be signed in to change notification settings - Fork 2
/
freetype-envision.sh
executable file
·213 lines (178 loc) · 5.86 KB
/
freetype-envision.sh
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
#!/bin/bash
set -e
NAME="freetype-envision"
SRC_DIR=src
VERSION="0.6.0"
# profile.d
PROFILED_DIR="$SRC_DIR/profile.d"
PROFILED_NORMAL="freetype-envision-normal.sh"
PROFILED_FULL="freetype-envision-full.sh"
DEST_PROFILED_FILE="/etc/profile.d/freetype-envision.sh"
# fontconfig
FONTCONFIG_DIR="$SRC_DIR/fontconfig"
DEST_FONTCONFIG_DIR="/etc/fonts/conf.d"
# ("<NAME>" "<PRIORITY>")
FONTCONFIG_GRAYSCALE=("freetype-envision-grayscale.conf" 11)
FONTCONFIG_DROID_SANS=("freetype-envision-droid-sans.conf" 70)
# Storing the manual (from script) installation info on target system.
# Disable by setting the STORE_STATE env variable to false, but only do it when
# using some other tool (package manager, etc) for project management, where
# this script is only used to install the project files to target system.
STORE_STATE="${STORE_STATE:-true}"
DEST_CONF_DIR="/etc/freetype-envision"
DEST_STATE_FILE="state"
# Global variables
declare g_selected_mode # Selected project mode
declare -A g_state # Associative array to store values from state file
__require_root () {
if [[ $(/usr/bin/id -u) -ne 0 ]]; then
echo "This action requires the root privileges"
exit 1
fi
}
# Check if the provided by user mode is valid and assign it globally
__verify_mode () {
local sel_mode="${1:-normal}"
case $sel_mode in
normal|full)
g_selected_mode=$sel_mode
echo "-> Mode '$g_selected_mode' selected."
;;
*)
echo "Wrong mode provided."
exit 1
esac
}
# Load the local state file into global var safely, allowing only the valid
# values to be parsed.
__load_state_file () {
while read -r line; do
if [[ $line =~ ^state\[([a-zA-Z0-9_]+)\]=\'?([^\']*)\'?$ ]]; then
# Only allow "state[key]='value'"
local key="${BASH_REMATCH[1]}"
local value="${BASH_REMATCH[2]}"
g_state["$key"]="$value"
else
echo "Warning: Skipping invalid state file line '$line'" >&2
fi
done < "$DEST_CONF_DIR/$DEST_STATE_FILE"
}
# Check the state file values to decide if user is allowed to install the project
__verify_ver () {
if [[ -f $DEST_CONF_DIR/$DEST_STATE_FILE ]]; then
# State file exists, checking if the version is same
__load_state_file
if [[ ${g_state[version]} != $VERSION ]]; then
cat <<EOF
Manually installed project of a previous or newer version already exists on the
system. Remove it with a script from the version corresponding to the installed
one.
Detected version: '${g_state[version]}'.
EOF
exit 1
fi
unset state
else
if [[ -f $DEST_PROFILED_FILE ]]; then
# Project files exist on the taget system, but no state file.
# ? Checking only for one profile.d script should be enough, but
# something weird may happen. Anyway... ( ͡° ͜ʖ ͡°)
cat <<EOF
Project is already installed on the system, probably with package manager or an
installation script for the version below '0.5.0'. Remove it using the original
installation method.
EOF
exit 1
fi
fi
}
show_header () {
echo "$NAME, version $VERSION"
}
show_help () {
cat <<EOF
Usage: $0 [COMMAND]
COMMANDS:
install <mode> : Install the project.
remove : Remove the installed project.
help : Show this help message.
OPTIONS:
mode (optional) : 'normal' (default),
'full'.
ENV:
STORE_STATE <bool> : Storing the manual (from script) installation info on
target system. (true by default)
EOF
}
project_install () {
echo "-> Begin project install."
__verify_ver
__require_root
echo "--> Installing the profile.d scripts:"
if [[ $g_selected_mode == "normal" ]]; then
install -v -m 644 "$PROFILED_DIR/$PROFILED_NORMAL" "$DEST_PROFILED_FILE"
elif [[ $g_selected_mode == "full" ]]; then
install -v -m 644 "$PROFILED_DIR/$PROFILED_FULL" "$DEST_PROFILED_FILE"
fi
echo "--> Installing the fontconfig configurations:"
install -v -m 644 \
"$FONTCONFIG_DIR/${FONTCONFIG_GRAYSCALE[0]}" \
"$DEST_FONTCONFIG_DIR/${FONTCONFIG_GRAYSCALE[1]}-${FONTCONFIG_GRAYSCALE[0]}"
install -v -m 644 \
"$FONTCONFIG_DIR/${FONTCONFIG_DROID_SANS[0]}" \
"$DEST_FONTCONFIG_DIR/${FONTCONFIG_DROID_SANS[1]}-${FONTCONFIG_DROID_SANS[0]}"
if [[ $STORE_STATE = true ]]; then
echo "--> Storing installation info to '$DEST_CONF_DIR/$DEST_STATE_FILE':"
mkdir -pv "$DEST_CONF_DIR"
tee "$DEST_CONF_DIR/$DEST_STATE_FILE" <<EOF
state[version]='$VERSION'
state[mode]='$g_selected_mode'
EOF
fi
echo "-> Success! Reboot to apply the changes."
}
project_remove () {
echo "-> Begin project removal."
__verify_ver
__require_root
echo "--> Removing the profile.d scripts:"
rm -fv "$DEST_PROFILED_FILE"
echo "--> Removing the fontconfig configurations:"
rm -fv "$DEST_FONTCONFIG_DIR/${FONTCONFIG_GRAYSCALE[1]}-${FONTCONFIG_GRAYSCALE[0]}"
rm -fv "$DEST_FONTCONFIG_DIR/${FONTCONFIG_DROID_SANS[1]}-${FONTCONFIG_DROID_SANS[0]}"
echo "--> Removing the configurations directory:"
rm -rfv "$DEST_CONF_DIR"
echo "-> Success! Reboot to apply the changes."
}
# Main logic below
arg_1="$1"
arg_2="$2"
show_header
# Deprecate short commands.
# ! Remove on 1.0.0
case $arg_1 in
i|r|h)
cat <<EOF
--------
Warning: Argument '$1', short command, is considered deprecated and will be
removed in '1.0.0' project release.
--------
EOF
;;
esac
case $arg_1 in
i|install)
__verify_mode $arg_2
project_install
;;
r|remove)
project_remove
;;
h|help)
show_help
;;
*)
echo "Error: Invalid argument: \"$1\"."
echo "Use \"help\" to get the list of commands"
exit 1
esac