Files
profile/profile.sh
2026-03-10 10:53:31 +01:00

236 lines
7.6 KiB
Bash

#!/usr/bin/env bash
# Begin profile
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2022 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
#
# * Redistribution and use in source and binary forms,
# * with or without modification, are permitted provided
# * that the following conditions are met:
# *
# * Redistributions of source code must retain the above
# * copyright notice, this list of conditions and the
# * following disclaimer.
# *
# * Redistributions in binary form must reproduce the above
# * copyright notice, this list of conditions and the following
# * disclaimer in the documentation and/or other materials
# * provided with the distribution.
# *
# * Neither the name of the copyright holder nor the names
# * of any other contributors may be used to endorse or
# * promote products derived from this software without
# * specific prior written permission.
# *
# * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# * OF SUCH DAMAGE.
# ------------------------------------------------------------------------------
if [[ ! $SHELL =~ bash|zsh ]]; then
echo "That environment script is designed to be used with bash or zsh being the shell."
echo "Please consider using bash or zsh instead, or patch me ;)!"
return 1
fi
# ------------------------------------------------------------------------------
# path* : private functions for PATH variable management
pathremove()
{
local IFS=':'
local newpath
local dir
local pathvar=${2:-PATH}
for dir in ${!pathvar}; do
if [ "$dir" != "$1" ]; then
newpath=${newpath:+$newpath:}$dir
fi
done
export $pathvar="$newpath"
}
pathprepend()
{
pathremove $1 $2
local pathvar=${2:-PATH}
export $pathvar="$1${!pathvar:+:${!pathvar}}"
}
pathappend()
{
pathremove $1 $2
local pathvar=${2:-PATH}
export $pathvar="${!pathvar:+${!pathvar}:}$1"
}
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Configuration file parser
parse_conf()
{
local config_file="$1"
local current_section=""
[[ ! -f "$config_file" ]] && return 1
while IFS='=' read -r key value || [[ -n "$key" ]]; do
# Clean key and value (strip CR and whitespace)
key=$(printf '%s' "$key" | tr -d '\r' | xargs 2>/dev/null)
value=$(printf '%s' "$value" | tr -d '\r' | xargs 2>/dev/null)
# Skip comments and empty lines
[[ -z "$key" || "$key" =~ ^[#\;] ]] && continue
# Section Detection: [section_name]
if [[ "$key" =~ ^\[(.*)\]$ ]]; then
current_section="${BASH_REMATCH[1]}"
# Dynamically declare the associative array for this section
declare -g -A "CONF_$current_section"
continue
fi
# If we have a key/value pair and are inside a section
if [[ -n "$current_section" && -n "$value" ]]; then
# Strip quotes from value
value="${value%\"}"; value="${value#\"}"
value="${value%\'}"; value="${value#\'}"
# Store in the dynamic array: CONF_sectionname[key]=value
eval "CONF_${current_section}['$key']='$value'"
fi
done < "$config_file"
}
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Load command aliases from configuration
load_alias()
{
local section_name="CONF_$1"
# Check if the associative array for this section exists
if [[ "$(declare -p "$section_name" 2>/dev/null)" != "declare -A"* ]]; then
return 1
fi
# Reference the array keys
eval "local keys=\"\${!$section_name[@]}\""
for key in $keys; do
# Fetch the value for this specific key
eval "local cmd=\"\${$section_name[$key]}\""
# Portability check: only alias if the command exists
local base_cmd=$(echo "$cmd" | awk '{print $1}')
if command -v "$base_cmd" >/dev/null 2>&1; then
alias "$key"="$cmd"
fi
done
}
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Load configuration values as environment variables
load_conf()
{
local section_name="CONF_$1"
if [[ "$(declare -p "$section_name" 2>/dev/null)" != "declare -A"* ]]; then
return 1
fi
eval "local keys=\"\${!$section_name[@]}\""
for key in $keys; do
eval "local val=\"\${$section_name[$key]}\""
# Export as a standard shell variable
export "$key"="$val"
done
}
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# ********************************** MAIN PROGRAM ******************************
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Store script's path (realpath -s resolve symlinks if profile.sh is a symlink)
if [[ -z "$PROFILE_PATH" ]]; then
export MYPATH=$(dirname "$(realpath -s "$0")")
else
export MYPATH="$PROFILE_PATH"
fi
if [[ ! -e "$MYPATH/profile.sh" ]]; then
echo "[ Warning ] Path detection failed, trying to use pwd..."
MYPATH=$(pwd)
if [[ ! -e "$MYPATH/profile.sh" ]]; then
echo "[ Error ] Impossible to determine installation path, pretty much nothing will work."
fi
fi
if [[ ! -s "$MYPATH/version" ]]; then
echo "[ Warning ] Impossible to determine running version of profile, your installation might be broken."
fi
export PROFVERSION=$(cat "$MYPATH"/version)
# Build PATH environment variable
if [[ $EUID -eq 0 ]]; then
pathappend /sbin:/usr/sbin
fi
[[ -d ~/bin ]] && pathappend ~/bin
[[ -d ~/.local/bin ]] && pathappend ~/.local/bin
# Parse and load general configuration
export PROFILE_CONF="$MYPATH/profile.conf"
parse_conf "$PROFILE_CONF"
load_conf system # Load Bash system behavior configuration (history, pager, etc.)
load_conf general # General purpose configuration (compilation flags, etc.)
# Load module scripts
for script in $MYPATH/profile.d/*.sh; do
if [[ -r $script ]]; then
. $script
fi
done
# Interactive shell detection, two methods available each one of those might have different result
# depending on distribution
#shopt -q login_shell && INTERACTIVE=1
[[ $- == *i* ]] && export INTERACTIVE=1
if [[ $INTERACTIVE ]]; then
# For compiling (as we often compile with LFS/0linux...)
#Aliases
load_alias aliases
# Define PS1
trap 'timer_start' DEBUG
PROMPT_COMMAND='set_prompt'
# Set default language
setfr
showinfo && printf "\n"
check_updates -q
disp I "Profile version $PROFVERSION chargé..."
fi
# Cleanup
unset pathremove pathprepend pathappend
#return 0
# End profile.sh