Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 74 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ If you've noticed a bug or have a question, search the <a href="https://github.c
* To download the full source code after forking
```bash
git clone https://github.com/yourusernamehere/Bash-Snippets
```
```


#### 2. Implement your fix, feature or new component
Expand Down Expand Up @@ -45,3 +45,76 @@ If there are none submit the request and give details as to what you changed or

#### 5. Bask In All The Glory Of Adding To A FOSS Application
![Had to do it to em](https://68.media.tumblr.com/2dfc3369827df9b981e111d7fd8fc732/tumblr_mvemcyarmn1rslphyo1_400.gif)


# Style Guide
## *Before* contributing, please implement the following style guidelines

## Function

function declaration should be in Camel_Case, and library function declaration should prefixed with underscore '_'
use two blank lines separator between each function declaration

Each function declaration should have the following comment documentation

1. brief description
2. Globals: global variables function relays on
3. Inputs: argument(s) passed, else nothing
4. Outputs: write to file, modifies global variable, else nothing
5. Returns: function return(s) value, else nothing

Each function should followed by 'end of function FUNC_NAME'


### Example:

The following example declare shared function `Foo`

```sh
# print Foo n times
# Globals: nothing
# leave blank line for readability
# Inputs:
# n: number of times to print 'Foo'
#
# Outputs: nothing
# Returns: nothing
_Foo() {

# leave one blank line after openening and before closing curly bracket
n="$1" # variable declaration/assignment should placed at the beginning

# function body
while (( n-- )); do
echo "Foo"
done

} # end of function _Foo


```

## Variable

predefined global variables should placed at the beginning of script in ALL_CAPS

local variables in lower_case

you should place variables declaration at start the start of function or code block


### Example:

```sh
if $bar; then
i=1
j=3

echo "\$i: i\t\$j: $j"
fi
```

> [!NOTE]
> - By default variables in bash are global, except when you declare them otherwise with `local bar` or `declare bar`
> - Please use tabs instead of whitespace for indentation

268 changes: 268 additions & 0 deletions bash-snippets.lib
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
#!/usr/bin/env bash
# bash-snippets.lib -- Bash-Snippets library
#
# Author: Essam 'https://github.com/e55am'
# Repo: https://github.com/alexanderepstein/Bash-Snippets


### Globals variables
PROGRAM="${0##*/}" # bash version of `basename'
VERSION="$PROGRAM v1.23.0"
UPSTREAM="https://github.com/alexanderepstein/Bash-Snippets"
declare -i USAGE_LINE_COUNT=1 # number of lines from Help represent usage


### Function declaration
## library function prefixed with underscore '_' and in Camel_Case
## use two blank lines and a function separator between each function declaration
## each function declaration should have the following doc
# . brief description
# . Globals: global variables function relays on
# . Inputs: argument(s) passed, else nothing
# . Outputs: write to file, modifies global variable, else nothing
# . Returns: function return(s) value, else nothing
# each function should followed by `end of function FUNC_NAME'
#
#
#
# check if user have root permission
#
# Globals: nothing
# Inputs: nothing
# Outputs: nothing
#
# Returns:
# 0 (success) if root
# 1 (error) if non root
_Check_User_Perm() {
[[ $EUID -eq 0 ]]
} # end of function _Check_User_Perm


# check internet connection
# Globals: PROGRAM
# Inputs: nothing
# Outputs: nothing
#
# Returns:
# 0 (success) on active internet connection
# 1 (error) if no active internet connection and exit
_Check_Internet() {

ping -c 1 "example.org" &> /dev/null || {
_Echo_Err "$PROGRAM: no active internet connection"
exit 1
}

} # end of function _Check_Internet


# check if dependencies installed, abort with error if any missing
# exit with error if any dependencies missing
#
# Globals:
# PROGRAM
#
# Inputs:
# dependency: array of string dependencies
#
# Outputs: nothing
#
# Returns:
# 0 (true): if all dependencies met
# 1 (false): on error and terminate the program
_Check_If_All_Dep() {
missing_dep=""

for dependency in "$@"; do
command -v "$dependency" &> /dev/null || {
missing_dep="$missing_dep, $dependency"
}
done

[[ -n "$missing_dep" ]] && {
_Echo_Err "$PROGRAM: unmet dependencies: '$missing_dep' not found"
_Echo_Err "Abort"
exit 1
}
return 0

} # end of _Check_If_All_Dep


# check if any of the dependencies installed, return first one
# exit with error if any dependency found
#
# Globals:
# PROGRAM
#
# Inputs:
# dependency: array of string dependencies
#
# Outputs: nothing
#
# Returns:
# dependency: first installed dependency met
# 1 (error) if any dependency met and terminate the program
_Check_For_Any_Dep() {

available_dep=
missing_dep=

for dependency in "$@"; do
if command -v "$dependency" &> /dev/null; then
available_dep="$dependency"
break
else
missing_dep="$missing_dep, $dependency"
fi
done

[[ -z "$available_dep" ]] && {
# remove first delimiter `, ' from missing_dep string
missing_dep="${missing_dep:2:${#missing_dep}}" # slice from second char to the end
_Echo_Err "$PROGRAM: could not find any of the following dependencies '$missing_dep'"
_Echo_Err "Abort"
exit 1
}
echo "$available_dep"

} # end of function _Check_For_Any_Dep


# set the default command that will be used to make HTTP GET request
# if no client found, exit with error
#
# Globals:
# PROGRAM
#
# Inputs: nothing
#
# Outputs:
# _HTTP_GET function
#
# Returns:
# 1 (false) if no client installed and terminate the program
_Config_HTTP_Client() {

dependency=$(_Check_For_Any_Dep "curl" "wget" "http" "fetch")
case $dependency in
curl )
_HTTP_GET() { curl --user-agent curl --silent "$*"; }
;;

wget )
_HTTP_GET() { wget --quiet --output-document - "$*"; }
;;

http )
_HTTP_GET() { http -b GET "$*"; }
;;

# TODO
# remove this case
* )
_Echo_Err "$PROGRAM: missing dependency: curl, wget, httpie or fetch not found!"
exit 1
;;
esac

} # end of function _Config_HTTP_Client


# display try help message, used after user error
#
# Globals:
# PROGRAM
#
# Inputs: nothing
# Outputs: nothing
# Returns: nothing
_Try_Help() {
echo "Try '$PROGRAM -h' for more information"
} >&2 # end of function try_help


# print string to stderr
#
# Globals: nothing
#
# Inputs:
# string
#
# Outputs: nothing
# Returns: nothing
_Echo_Err() {
echo "$*"
} >&2 # end of function _Echo_Err


# extract version from VERSION variable
#
# Globals:
# VERSION
#
# Inputs: nothing
# Outputs: nothing
#
# Returns:
# version string
_Extract_Version() {

echo "$VERSION" | grep --perl-regexp --only-matching '\d+.\d+.\d+'

} # end of function _Extract_Version


# TODO
# implement
# update bash-snippets scripts/tools
_Update() {

_Echo_Err "$PROGRAM: update functionality is not implement it yet"
exit 127
} # end of function _Update


# access property from json (response)
#
# Globals: nothing
#
# Inputs:
# data: json data
# filter: filter string (read man 1 jq) for more information)
#
# Outputs: nothing
#
# Returns:
# empty string if filter not found in data, else matched data
_Access_Json_Element() {

data="$1"
filter="$2"

res=$(echo "$data" | jq --raw-output --exit-status "$filter")
[[ $? -eq 0 ]] && echo "$res" || echo

} # end of function _Access_Json_Element


# Print first n lines from help message
#
# Globals:
# USAGE_LINE_COUNT
#
# Inputs: nothing
#
# Outputs:
# brief help message to stdout
#
# Returns: nothing
_Usage() {
USAGE_LINE_COUNT=${USAGE_LINE_COUNT:-1}
Help | head -n $USAGE_LINE_COUNT

} # End of function _Usage


_Config_HTTP_Client
Loading