A => LICENSE +25 -0
@@ 1,25 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org/>
+
A => README.md +99 -0
@@ 1,99 @@
+# bashcfg
+A bash function for parsing config files.
+
+Sometimes, when bash scripts grow, you'll find yourself in the situation where
+you ~~want to have~~ definitely need a config file.
+But of course, you being the nerd that writes ~~too complex~~ advanced bash
+scripts, you're not interested in a third-party tool for parsing said config
+files.
+
+`bashcfg` to the rescue!
+
+It's a small(ish) bash function that you can add to your script to parse a
+config file.
+
+## Usage
+Take a look at `bashcfg.sh` file and copy the function and related variables.
+Read the code and adjust as necessary.
+
+## Config file format
+- All values are strings
+- First `=` sign splits the key and the value
+- Leading and trailing whitespace of keys and values are trimmed (whitespace around `=` is allowed)
+- Lines beginning with a `#` (whitespace ignored) are comments
+- Empty lines are ignored
+- Should be fairly safe (does not execute subshells, etc.)
+- Empty values are respected
+- Lines without a delimiter (`=`) are ignored
+
+### Example
+**`myscript.conf`**
+```
+foo=bar
+foo2 = bar2
+
+
+
+# This is a comment
+ # indented comment
+#another comment
+
+ indented = config line
+
+some_more_weirdness = lots of spaces
+
+value_with_trailing_whitespace = value with trailing whitespace
+
+empty=
+
+evil = $(ping 9.9.9.9)
+$(ping 1.1.1.1)
+```
+
+**output**
+```
+empty has the value ''
+foo has the value 'bar'
+bar has the value 'baz'
+evil has the value '$(ping 9.9.9.9)'
+some_more_weirdness has the value 'lots of spaces'
+indented has the value 'config line'
+foo2 has the value 'bar2'
+notice_the_trailing_whitespace_of_the_value has the value 'value with trailing whitespace'
+
+```
+
+## Contribute
+You are more than welcome to contribute to this project. Please
+[send patches](https://git-send-email.io) to `~kolletzki/patches@lists.sr.ht`.
+Thanks!
+
+## License
+This script is released as public domain under the [Unlicense](https://unlicense.org/).
+
+```
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org/>
+```
A => bashcfg.sh +72 -0
@@ 1,72 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+CONFIG_FILE="bashcfg/bashcfg.conf"
+DEFAULT_CONFIG="$(cat << EOF
+# Value for Foo
+foo = bar
+EOF
+)"
+
+declare -A config
+
+function load_config() {
+ # Ensure that directory and file exist
+ local config_home="${XDG_CONFIG_HOME:-}"
+ if [[ -z "${config_home}" ]]; then
+ config_home="${HOME}/.config"
+ fi
+
+ local config_dir="${config_home}/${CONFIG_FILE%/*}"
+ local config_file="${CONFIG_FILE##*/}"
+ if [[ ! -d "${config_dir}" ]]; then
+ mkdir "${config_dir}"
+ fi
+
+ local config_path="${config_dir}/${config_file}"
+ if [[ ! -f "${config_path}" ]]; then
+ cat > "${config_path}" <<< "${DEFAULT_CONFIG:-}"
+ fi
+
+ function _trim_leading() {
+ printf "%s" "${1#"${1%%[![:space:]]*}"}"
+ }
+ function _trim_trailing() {
+ printf "%s" "${1%"${1##*[![:space:]]}"}"
+ }
+
+ # Read config file
+ while read -r l; do
+ l="$(_trim_leading "${l}")"
+
+ # Skip comments and empty lines
+ if [[ "${l:0:1}" == "#" ]] || [[ -z "${l}" ]]; then
+ continue
+ fi
+
+ local key="$(cut -d "=" -f 1 <<< "${l}")"
+ # Leading spaces are already trimmed from $l
+ key="$(_trim_trailing "${key}")"
+
+ # Skip lines without =
+ if [[ "${key}" == "${l}" ]]; then
+ continue
+ fi
+
+ local value="$(cut -d "=" -f 2- <<< "${l}")"
+ value="$(_trim_leading "${value}")"
+ value="$(_trim_trailing "${value}")"
+
+ config["${key}"]="${value}"
+ done < "${config_path}"
+
+ # Ensure all config options are set or set defaults
+ [[ -n "${config["foo"]:-}" ]] || ( printf "foo not set\n"; exit 1 )
+ [[ -n "${config["bar"]:-}" ]] || config["bar"]="baz"
+}
+
+load_config
+
+for k in "${!config[@]}"; do
+ printf "%s has the value '%s'\n" "${k}" "${config["${k}"]}"
+done