You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
235 lines
6.9 KiB
235 lines
6.9 KiB
#!/usr/bin/env miaou-bash
|
|
|
|
# CONSTANTS
|
|
|
|
readonly AZERTY_ZONES=(
|
|
'Europe/Paris'
|
|
'Indian/Reunion'
|
|
'Indian/Mayotte'
|
|
'America/Cayenne'
|
|
'America/Guadeloupe'
|
|
'America/Martinique'
|
|
'Pacific/Noumea'
|
|
'Pacific/Tahiti'
|
|
)
|
|
readonly REQUIRED_PKGS=(file jq vim git)
|
|
readonly BACKUP_SUFFIX='.ORIGINAL'
|
|
|
|
# FUNCTIONS
|
|
|
|
function usr_bin_miaou_bash {
|
|
ln -sf "$MIAOU_BASH_DIR/bin/miaou-bash" /usr/bin/miaou-bash
|
|
}
|
|
|
|
function install_required_packages {
|
|
. "$MIAOU_BASH_DIR"/tools/pkg_add "${REQUIRED_PKGS[@]}"
|
|
}
|
|
|
|
function fix_users_bashrc {
|
|
if [[ -f /etc/skel/.bashrc ]] && ! cmp -s /etc/skel/.bashrc "$MIAOU_BASH_DIR"/etc/skel/.bashrc; then
|
|
echo 'fixing users .bashrc...'
|
|
local skel_count_lines
|
|
skel_count_lines=$(wc -l /etc/skel/.bashrc | cut -d' ' -f1)
|
|
|
|
local appended_regex="^${skel_count_lines}a"
|
|
|
|
# for pre-existant users
|
|
build_associative_user_homes
|
|
for user in "${!USER_HOMES[@]}"; do
|
|
local user_bashrc="${USER_HOMES[$user]}/.bashrc"
|
|
local first_change
|
|
echo "read: $user_bashrc"
|
|
[[ ! -f "$user_bashrc" ]] && continue
|
|
if cmp -s /etc/skel/.bashrc "$user_bashrc"; then
|
|
echo 'no change: replaced by skel'
|
|
sudo -u "$user" -- cp "$MIAOU_BASH_DIR"/etc/skel/.bashrc "$user_bashrc"
|
|
elif first_change=$(diff /etc/skel/.bashrc "$user_bashrc" | head -n1); then
|
|
echo 'no change: should not occur'
|
|
elif [[ $first_change =~ $appended_regex ]]; then
|
|
if new_lines=$(diff /etc/skel/.bashrc "$user_bashrc" | grep '^> ' | sed 's/^> //'); then
|
|
echo 'no new lines: should not occur'
|
|
else
|
|
sudo -u "$user" -- cp "$MIAOU_BASH_DIR"/etc/skel/.bashrc "$user_bashrc"
|
|
echo -e "$new_lines" | sudo -u "$user" -- tee -a "$user_bashrc"
|
|
echo "INFO: .bashrc for user <$user> merged succesfully"
|
|
fi
|
|
else
|
|
local backup="$user_bashrc".ORIGINAL
|
|
sudo -u "$user" -- mv "$user_bashrc" "$backup"
|
|
sudo -u "$user" -- cp "$MIAOU_BASH_DIR"/etc/skel/.bashrc "$user_bashrc"
|
|
>&2 echo "WARN: .bashrc for user <$user> has forked from skeleton, please resolve conflict manually from backup: $backup"
|
|
fi
|
|
done
|
|
sudo mv /etc/skel/.bashrc /etc/skel/.bashrc.ORIGINAL
|
|
echo 'fixing users .bashrc...DONE'
|
|
fi
|
|
sudo ln -sf "$MIAOU_BASH_DIR"/etc/skel/.bashrc /etc/skel/.bashrc
|
|
}
|
|
|
|
function link_etc {
|
|
local source="$MIAOU_BASH_DIR/etc/$1"
|
|
local target="/etc/${2:-$1}"
|
|
|
|
if [[ -L "$target" ]]; then
|
|
if [[ "$(readlink "$target")" != "$source" ]]; then
|
|
sudo ln -sf "$source" "$target"
|
|
echo "link $target updated"
|
|
fi
|
|
else
|
|
if [[ -f "$target" ]]; then
|
|
sudo mv "$target" "$target$BACKUP_SUFFIX"
|
|
echo "$target$BACKUP_SUFFIX saved!"
|
|
fi
|
|
sudo mkdir -p "$(dirname "$target")"
|
|
sudo ln -s "$source" "$target"
|
|
echo "link $target created"
|
|
fi
|
|
}
|
|
|
|
function arch_profile {
|
|
if ! cmp -s /etc/profile "$MIAOU_BASH_DIR"/etc/profile.arch; then
|
|
sudo cp "$MIAOU_BASH_DIR"/etc/profile.arch /etc/profile
|
|
echo 'arch /etc/profile fixed!'
|
|
fi
|
|
}
|
|
|
|
function arch_vimrc {
|
|
mkdir -p /etc/vim
|
|
if ! grep -q '/etc/vim/vimrc.local' /etc/vimrc; then
|
|
cat >>/etc/vimrc <<EOF
|
|
" Source a global configuration file if available
|
|
if filereadable("/etc/vim/vimrc.local")
|
|
source /etc/vim/vimrc.local
|
|
endif
|
|
EOF
|
|
echo "vimrc source /etc/vim/vimrc.local if any"
|
|
fi
|
|
}
|
|
|
|
function is_arch_like {
|
|
[[ "$DISTRO_LIKE" == 'arch' ]]
|
|
}
|
|
|
|
function is_debian_like {
|
|
[[ "$DISTRO_LIKE" == 'debian' ]]
|
|
}
|
|
|
|
function link_config_files {
|
|
is_arch_like && arch_vimrc && arch_profile
|
|
|
|
link_etc vim/vimrc.core
|
|
link_etc vim/vimrc.miaou
|
|
link_etc vim/vimrc.rookie
|
|
|
|
if in_azerty_zone 2>/dev/null; then
|
|
link_etc vim/vimrc.azerty
|
|
link_etc vim/vimrc.local.azerty vim/vimrc.local
|
|
else
|
|
link_etc vim/vimrc.local
|
|
fi
|
|
link_etc profile.d/20-miaou-bash.sh
|
|
link_etc bash.bashrc
|
|
link_etc inputrc # last command required to detect successful installation
|
|
}
|
|
|
|
function in_azerty_zone {
|
|
[[ -L /etc/localtime ]] || return 4
|
|
|
|
local zone
|
|
zone=$(readlink /etc/localtime)
|
|
zone="${zone#/usr/share/zoneinfo/}" # remove prefix
|
|
for i in "${AZERTY_ZONES[@]}"; do [[ "$zone" == "$i" ]] && return; done
|
|
return 5
|
|
}
|
|
|
|
function fix_terminfo_ghostty {
|
|
if ! infocmp xterm-ghostty >/dev/null 2>&1; then
|
|
tic -x "$MIAOU_BASH_DIR"/assets/terminfo/ghostty 2>/dev/null
|
|
echo 'terminfo ghostty succesfully compiled'
|
|
fi
|
|
}
|
|
|
|
function build_associative_user_homes {
|
|
if [[ ! -v USER_HOMES ]]; then
|
|
declare -gA USER_HOMES
|
|
while IFS=: read -r user _ uid _ _ home _; do
|
|
if [[ $uid -ge 1000 && $user != 'nobody' ]]; then
|
|
USER_HOMES[$user]="$home"
|
|
fi
|
|
done </etc/passwd
|
|
fi
|
|
}
|
|
|
|
function ghostty_global_config {
|
|
! command -v ghostty >/dev/null && return # ghostty not yet installed!
|
|
|
|
link_etc ghostty/config
|
|
|
|
if [[ ! -f /etc/skell/.config/ghostty/config ]]; then
|
|
# ghostty config skeleton for new users
|
|
mkdir -p /etc/skel/.config/ghostty
|
|
echo 'config-file = /etc/ghostty/config' >/etc/skel/.config/ghostty/config
|
|
fi
|
|
|
|
# change ghostty configuration for any normal user
|
|
build_associative_user_homes
|
|
for user in "${!USER_HOMES[@]}"; do
|
|
local user_home="${USER_HOMES[$user]}"
|
|
local user_ghostty_config="$user_home"/.config/ghostty/config.ghostty
|
|
if [[ ! -f "$user_ghostty_config" ]]; then
|
|
sudo -u "$user" -- mkdir -p "$user_home"/.config/ghostty
|
|
echo -e "# global config\nconfig-file = /etc/ghostty/config\n" |
|
|
sudo -u "$user" -- tee "$user_ghostty_config" >/dev/null
|
|
echo "new predefined ghostty config file for user: $user"
|
|
elif ! grep -q 'config-file = /etc/ghostty/config' "$user_ghostty_config"; then
|
|
# prepend on top
|
|
echo -e "# global config\nconfig-file = /etc/ghostty/config\n" |
|
|
sudo -u "$user" -- tee "$user_ghostty_config".tmp >/dev/null
|
|
cat "$user_ghostty_config" |
|
|
sudo -u "$user" -- tee -a "$user_ghostty_config".tmp >/dev/null
|
|
rm "$user_ghostty_config"
|
|
sudo -u "$user" mv "$user_ghostty_config".tmp "$user_ghostty_config"
|
|
echo "modify pre-existant ghostty config file for user: $user"
|
|
fi
|
|
done
|
|
}
|
|
|
|
function link_miaou_bash {
|
|
sudo ln -sf "$MIAOU_BASH_DIR"/bin/miaou-bash /usr/bin/
|
|
}
|
|
|
|
function create_sudoers {
|
|
if [[ ! -f /etc/sudoers.d/miaou-bash ]]; then
|
|
echo 'Defaults:%sudo env_keep += "MIAOU_BASH_DIR"' | sudo tee /etc/sudoers.d/miaou-bash >/dev/null
|
|
sudo chmod 440 /etc/sudoers.d/miaou-bash
|
|
fi
|
|
}
|
|
|
|
function launch_hooks {
|
|
find "$MIAOU_BASH_DIR"/hooks.d -maxdepth 1 -name "after-upgrade*" -type f -executable |
|
|
sort |
|
|
while read -r hook; do
|
|
echo "Processing: $hook"
|
|
|
|
# shellcheck disable=SC1090
|
|
if ! miaou-bash "$hook" 3>/dev/null; then
|
|
echo 'WARNING: hook failure, bypassed'
|
|
fi
|
|
echo ----------------
|
|
done
|
|
}
|
|
|
|
# MAIN
|
|
|
|
source "$MIAOU_BASH_DIR"/lib/functions.bash
|
|
|
|
assert_root
|
|
DISTRO_LIKE=$(fetch_distro_like)
|
|
install_required_packages
|
|
fix_users_bashrc
|
|
fix_terminfo_ghostty
|
|
ghostty_global_config
|
|
link_config_files
|
|
link_miaou_bash
|
|
create_sudoers
|
|
launch_hooks
|