From 0f76f93bd286c46d281a574a6db67e038b6d42a7 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Thu, 2 Oct 2008 14:19:29 +0200 Subject: [PATCH] Simplified loading of config files by using a function. source_config() first tries to load the given file and then if unsuccessful the .local file for that file. For more information look at the comments of source_config(). Also added tests for source_config() and Makefile to run them. --- Makefile | 6 ++++ bash/rc | 25 ++++++-------- shell/env | 66 ++++++++++++++++++++++++++++++++++++ tests/run.zsh | 25 ++++++++++++++ tests/source_config.test | 38 +++++++++++++++++++++ tests/source_config.test.out | 25 ++++++++++++++ zsh/env | 24 +++++-------- zsh/env.local | 5 +-- zsh/rc | 10 ++---- 9 files changed, 184 insertions(+), 40 deletions(-) create mode 100644 Makefile create mode 100644 tests/run.zsh create mode 100644 tests/source_config.test create mode 100644 tests/source_config.test.out diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0778297 --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +# Makefile for shell configuration files. At the moment only used for running +# tests. + + +test: + cd tests; zsh run.zsh diff --git a/bash/rc b/bash/rc index eb67288..cafc77f 100644 --- a/bash/rc +++ b/bash/rc @@ -5,27 +5,22 @@ host=$(echo $(hostname) | sed -e 's/\..*$//') # Load environmental related settings used by all shells. -# If the default file exists, load it. if [ -f ~/.shell/env ]; then source ~/.shell/env +else + function source_config() { + echo "Couldn't load source_config(), can't source files." >&2 + } fi -# If an env file for the current hostname (first part before a dot) exists load -# it, otherwise load env.local if available. -if [ -f ~/.shell/env.$host ]; then - source ~/.shell/env.$host -elif [ -f ~/.shell/env.local ]; then - source ~/.shell/env.local -fi + +# Load global env file for current hostname (first part before a dot) or +# global env.local. +source_config ~/.shell "" env $host # Use Vi(m) style in bash. set -o vi -# If a rc file for the current hostname (first part before a dot) exists load -# it, otherwise load rc.local if available. -if [ -f ~/.bash/rc.$host ]; then - source ~/.bash/rc.$host -elif [ -f ~/.bash/rc.local ]; then - source ~/.bash/rc.local -fi +# Load rc file for current hostname (first part before a dot) or rc.local. +source_config ~/.bash "" rc $host diff --git a/shell/env b/shell/env index 2d89b53..a7f7405 100644 --- a/shell/env +++ b/shell/env @@ -20,3 +20,69 @@ export PAGER # See `dircolors --print-database` for possible colors. LS_COLORS='no=00:fi=00:di=34;01:ln=36:pi=00:so=00:bd=00:cd=00:ex=31;01' export LS_COLORS + + +# Sources a configuration file if it exists; loads a fallback .local file if +# it doesn't. If the .local files doesn't exist nothing is sourced. +# +# $1: Path to directory where configuration files are located. +# $2: Directory name in $1 where the non .local files are stored, can be +# empty. If empty both configuration files (normal and .local) are stored +# in $1. +# $3: Base name of file in $2, for example "rc" or "env". +# $4: Extension for $3, if this file doesn't exist "$1/$3.local" is sourced. +# $5: Additional options, set to nolocal to prevent loading of "$1/$3.local" +# if "$1/$2/$3.$4" doesn't exist. +# +# Example with the following directory/file structure, $os is Darwin and +# $hostname is marvin. +# +# ~/.zsh +# ~/.zsh/env +# ~/.zsh/env.local +# ~/.zsh/rc +# ~/.zsh/rc.local +# ~/.zsh/host/rc.marvin +# ~/.zsh/os/rc.Darwin +# +# To load additional rc files from within ~/.zsh/rc use the following: +# +# source_config ~/.zsh os rc $os # loads os/rc.Darwin +# source_config ~/.zsh host rc $hostname # loads host/rc.marvin +# +# To load additional env files from within ~/.zsh/env use the following (note +# nolocal to prevent loading env.local two times if os and host files don't +# exist): +# +# source_config zsh os env $os nolocal # loads os/rc.Darwin +# source_config zsh host env $hostname # loads env.local +# +# Doesn't fit perfectly in this file, but this is the best place to make it +# available everywhere. +function source_config() { + # Path to the file to source and its local counterpart. + local source_file=$1/$2/$3.$4 + local source_file_local=$1/$3.local + + # Additional debug output. + if [ x$DEBUG != x ]; then + echo "source_config(): checking if $source_file exists" + echo "source_config(): checking if $source_file_local exists" + fi + + # If the file does exist then source it. + if [ -f $source_file ]; then + if [ x$DEBUG != x ]; then + echo "source_config(): sourcing $source_file" + fi + source $source_file + + # Otherwise load the .local file if it exists and .local files are + # allowed. + elif [ -f $source_file_local -a x$5 != xnolocal ]; then + if [ x$DEBUG != x ]; then + echo "source_config(): sourcing $source_file_local" + fi + source $source_file_local + fi +} diff --git a/tests/run.zsh b/tests/run.zsh new file mode 100644 index 0000000..a34281b --- /dev/null +++ b/tests/run.zsh @@ -0,0 +1,25 @@ +# Runs all tests. + + +# Get all test files. +for file in *.test; do + # Run the test file in zsh and sh and get its output. + zsh $file &> $file.out.zsh + sh $file &> $file.out.sh + + # Check if the output matches the expected one. If not abort with exit + # code 1. + diff -u $file.out $file.out.zsh + if [[ $? -ne 0 ]]; then + exit 1 + fi + diff -u $file.out $file.out.sh + if [[ $? -ne 0 ]]; then + exit 1 + fi +done + +# Remove all temporary files. +rm -rf tmp +rm *.out.zsh +rm *.out.sh diff --git a/tests/source_config.test b/tests/source_config.test new file mode 100644 index 0000000..7d062cf --- /dev/null +++ b/tests/source_config.test @@ -0,0 +1,38 @@ +# Test file for source_config(). + + +# Load source_config(). +source ../shell/env + + +# Make sure the old temporary directory is removed. +rm -rf tmp +# Create the test directories/files. +mkdir tmp +mkdir tmp/bash +mkdir tmp/shell +mkdir tmp/zsh tmp/zsh/host tmp/zsh/os +echo echo loaded bash/env.zucker > tmp/shell/env.zucker +echo echo loaded shell/env.zucker > tmp/shell/env.zucker +echo echo loaded zsh.env.local > tmp/zsh/env.local +echo echo loaded zsh/rc.local > tmp/zsh/rc.local +echo echo loaded zsh/host/rc.zucker > tmp/zsh/host/rc.zucker +echo echo loaded zsh/os/rc.Darwin > tmp/zsh/os/rc.Darwin + + +function tests() { + source_config tmp/zsh os rc Darwin nolocal + source_config tmp/zsh host rc zucker + + source_config tmp/zsh os env Darwin nolocal + source_config tmp/zsh host env zucker + + source_config tmp/bash host rc zucker + + source_config tmp/shell "" env zucker +} + +# Run tests without and with debug output. +tests +echo +DEBUG=1 tests diff --git a/tests/source_config.test.out b/tests/source_config.test.out new file mode 100644 index 0000000..dcadd7f --- /dev/null +++ b/tests/source_config.test.out @@ -0,0 +1,25 @@ +loaded zsh/os/rc.Darwin +loaded zsh/host/rc.zucker +loaded zsh.env.local +loaded shell/env.zucker + +source_config(): checking if tmp/zsh/os/rc.Darwin exists +source_config(): checking if tmp/zsh/rc.local exists +source_config(): sourcing tmp/zsh/os/rc.Darwin +loaded zsh/os/rc.Darwin +source_config(): checking if tmp/zsh/host/rc.zucker exists +source_config(): checking if tmp/zsh/rc.local exists +source_config(): sourcing tmp/zsh/host/rc.zucker +loaded zsh/host/rc.zucker +source_config(): checking if tmp/zsh/os/env.Darwin exists +source_config(): checking if tmp/zsh/env.local exists +source_config(): checking if tmp/zsh/host/env.zucker exists +source_config(): checking if tmp/zsh/env.local exists +source_config(): sourcing tmp/zsh/env.local +loaded zsh.env.local +source_config(): checking if tmp/bash/host/rc.zucker exists +source_config(): checking if tmp/bash/rc.local exists +source_config(): checking if tmp/shell//env.zucker exists +source_config(): checking if tmp/shell/env.local exists +source_config(): sourcing tmp/shell//env.zucker +loaded shell/env.zucker diff --git a/zsh/env b/zsh/env index a3cb729..a3725b3 100644 --- a/zsh/env +++ b/zsh/env @@ -5,23 +5,17 @@ host=${$(hostname)//.*/} # Load environmental related settings used by all shells. -# If the default file exists, load it. if [[ -f ~/.shell/env ]]; then source ~/.shell/env -fi -# If an env file for the current hostname (first part before a dot) exists load -# it, otherwise load env.local if available. -if [[ -f ~/.shell/env.$host ]]; then - source ~/.shell/env.$host -elif [[ -f ~/.shell/env.local ]]; then - source ~/.shell/env.local +else + function source_config() { + echo "Couldn't load source_config(), can't source files." >&2 + } fi +# Load global env file for current hostname (first part before a dot) or +# global env.local. +source_config ~/.shell "" env $host -# If an env file for the current hostname (first part before a dot) exists load -# it, otherwise load env.local if available. -if [[ -f ~/.zsh/env.$host ]]; then; - source ~/.zsh/env.$host -elif [[ -f ~/.zsh/env.local ]]; then; - source ~/.zsh/env.local -fi +# Load env file for current hostname (first part before a dot) or env.local. +source_config ~/.zsh "" env $host diff --git a/zsh/env.local b/zsh/env.local index a3cdc6a..6eb88a4 100644 --- a/zsh/env.local +++ b/zsh/env.local @@ -6,8 +6,9 @@ MYUNIX=~/Documents/unix # Add my bin/ directory, macports bin/ and sbin/ and the X11 bin/ directory to -# the default PATH. -typeset -U path +# the default PATH. -g is necessary as the file is loaded by source_config(), +# otherwise the path wouldn't be changed outside the function. +typeset -g -U path path=($MYUNIX/bin /opt/local/bin /opt/local/sbin $path /usr/X11R6/bin) # Necessary for xterm to find man pages through PATH. diff --git a/zsh/rc b/zsh/rc index 6fd54ee..52318bc 100644 --- a/zsh/rc +++ b/zsh/rc @@ -110,11 +110,5 @@ function ll() { } -# If a rc file for the current hostname (first part before a dot) exists load -# it, otherwise load rc.local if available. -host=${$(hostname)//.*/} -if [[ -f ~/.zsh/rc.$host ]]; then; - source ~/.zsh/rc.$host -elif [[ -f ~/.zsh/rc.local ]]; then; - source ~/.zsh/rc.local -fi +# Load rc file for current hostname (first part before a dot) or rc.local. +source_config ~/.zsh "" rc ${$(hostname)//.*/} -- 2.43.2