# 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 bash-completion) 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 elif ! cmp -s "$MIAOU_BASH_DIR"/etc/skel/.bashrc "$user_bashrc"; then 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 </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/zz-miaou-bash.sh link_etc bash.bashrc link_etc bash_completion.d/miaou-bash.complete 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 /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]}" if [[ ! -d "$user_home" ]]; then >&2 echo "WARNING: home directory: $user_home missing for user: $user! bypassing..." continue fi 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 2>&1; then echo 'WARNING: hook failure, bypassed' fi echo ---------------------- done } function apply_mode { if [[ "$MIAOU_BASH_MODE" == hosted ]]; then sudo mkdir /var/lib/miaou-bash -p sudo cp "$MIAOU_BASH_DIR"/.semver_git_tag /var/lib/miaou-bash/semver_current fi } # MAIN source "$MIAOU_BASH_DIR"/lib/functions.bash assert_root fetch_distro_like install_required_packages fix_users_bashrc fix_terminfo_ghostty ghostty_global_config link_config_files link_miaou_bash create_sudoers fetch_mode apply_mode launch_hooks