This directory contains shared Bash libraries that provide common functionality across all Dev-Control scripts. Using these libraries ensures consistency, reduces code duplication, and makes maintenance easier.
ANSI colour code definitions for terminal output.
source "$SCRIPT_DIR/lib/colours.sh"
echo -e "${GREEN}Success!${NC}"Exports: RED, GREEN, YELLOW, BLUE, CYAN, MAGENTA, WHITE, BOLD, DIM, NC, RESET, background colours, etc.
Consistent print functions for headers, messages, and formatting.
source "$SCRIPT_DIR/lib/colours.sh" # Required first
source "$SCRIPT_DIR/lib/print.sh"
print_header "My Tool"
print_info "Starting..."
print_success "Done!"
print_header_success "Completed!"Functions:
print_header "title"- Blue header boxprint_header_success "title"- Green header boxprint_header_warning "title"- Yellow header boxprint_info "msg"- [INFO] messageprint_success "msg"- [SUCCESS] messageprint_warning "msg"- [WARNING] messageprint_error "msg"- [ERROR] message (stderr)print_debug "msg"- [DEBUG] message (if DEBUG=true)print_step "msg"- Step indicatorprint_separator [width]- Horizontal lineprint_kv "key" "value"- Key-value pairprint_section "title"- Section headerprint_menu_item "num" "desc"- Numbered menu itemprint_list_item "text"- Bullet list itemprint_detail "label" "value"- Indented detailprint_command_hint "desc" "cmd"- Command suggestionprint_box "text"- Simple box around textconfirm "prompt" [default]- Yes/no confirmationread_input "prompt" "default"- Input with default
Git repository utilities and checks.
source "$SCRIPT_DIR/lib/git-utils.sh"
require_git_repo # Exit if not in git repo
require_gh_cli # Exit if gh not installed/authenticated
require_feature_branch # Exit if on main/master
branch=$(get_current_branch)
owner=$(get_repo_owner)Functions:
is_git_repo [dir]- Check if directory is a git repoin_git_worktree- Check if in git worktreegit_root- Get repository root pathrequire_git_repo- Exit with error if not in reporequire_clean_worktree- Exit if uncommitted changesrequire_git- Exit if git not installedrequire_gh_cli- Exit if gh not installed/authenticatedrequire_feature_branch- Exit if on default branchget_remote_url [dir]- Get origin URLparse_github_url "url"- Extract owner/repo from URLget_repo_owner [dir]- Get GitHub ownerget_repo_name [dir]- Get repository nameget_current_branch- Get current branch nameget_default_branch- Get main/master/Mainbranch_exists "name"- Check if local branch existsremote_branch_exists "name"- Check if remote branch existshas_uncommitted_changes- Check for uncommitted changeshas_staged_changes- Check for staged changeshas_untracked_files- Check for untracked fileslist_submodules [dir]- List all submodulesget_short_hash "ref"- Get short commit hashget_commit_subject "ref"- Get commit message
Git-control metadata management via dc-init.* git config.
source "$SCRIPT_DIR/lib/config.sh"
load_gc_metadata # Sets PROJECT_NAME, REPO_SLUG, etc.
save_gc_metadata "licence-type" "MIT"Functions:
load_gc_metadata- Load all dc-init.* values into variablessave_gc_metadata "key" "value"- Save single valuesave_all_gc_metadata- Save all metadata variablesclear_gc_metadata- Remove all dc-init.* configget_gc_metadata "key"- Get single valuehas_gc_metadata- Check if any metadata existsshow_gc_metadata- Display all metadata
Licence detection and management.
source "$SCRIPT_DIR/lib/licence.sh"
licence_info=$(detect_licence "/path/to/repo")
spdx=$(detect_spdx_from_content "/path/to/LICENSE")Functions:
find_licence_file "dir"- Find LICENCE filedetect_spdx_from_content "file"- Detect SPDX ID from contentdetect_local_licence "dir"- Detect licence from local filesdetect_github_licence "owner" "repo"- Detect via GitHub APIdetect_licence "dir"- Full detection (local + remote)scan_submodule_licences "dir" [recursive]- Scan all submodulescheck_licence_compatibility "target" "licences..."- Check compatibility
CLI argument parsing and script utilities.
source "$SCRIPT_DIR/lib/cli.sh"
SCRIPT_DIR=$(get_script_dir "${BASH_SOURCE[0]}")
parse_common_flags "$@"
if [[ "$SHOW_HELP" == "true" ]]; then
show_help
exit 0
fiFunctions:
resolve_script_path "path"- Resolve symlinksget_script_dir "path"- Get directory containing scriptis_flag "arg"- Check if argument is a flagparse_common_flags "args..."- Parse -h, -v, --debug, --dry-rundispatch_command "cmd" "args..."- Run cmd_* functionis_devcontainer- Check if running in devcontaineris_interactive- Check if running interactivelyversion_gte "v1" "v2"- Compare semantic versionsgit_version_at_least "version"- Check git version
Input validation helpers.
source "$SCRIPT_DIR/lib/validation.sh"
require_var "REPO_NAME" "$REPO_NAME"
require_command "jq"
if is_valid_slug "my-repo"; then
echo "Valid!"
fiFunctions:
is_empty "str"- Check if empty/whitespaceis_valid_identifier "str"- Check alphanumeric+underscoreis_valid_slug "str"- Check lowercase-with-hyphensto_slug "str"- Convert to slugis_directory "path"- Check if directory existsis_file "path"- Check if file existsis_readable/is_writable "path"- Check permissionsto_absolute_path "path"- Convert to absoluteis_url/is_git_url/is_github_url "str"- URL validationis_positive_integer "str"- Number validationis_iso_date "str"- Date validationrequire_var "name" "value"- Exit if emptyrequire_file "path"- Exit if missingrequire_directory "path"- Exit if missingrequire_command "cmd"- Exit if not available
All scripts should follow this pattern:
#!/usr/bin/env bash
set -e
# Get script location
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DEV_CONTROL_DIR="$(dirname "$SCRIPT_DIR")"
# Source shared libraries
source "$SCRIPT_DIR/lib/colours.sh"
source "$SCRIPT_DIR/lib/print.sh"
source "$SCRIPT_DIR/lib/git-utils.sh" # Optional
# Your script code...
main() {
print_header "My Tool"
require_git_repo
# ...
print_header_success "Complete!"
}
main "$@"By using shared libraries, we eliminate redundant code across all scripts:
| Pattern | Occurrences | Lines Saved |
|---|---|---|
| Hardcoded print_* functions | 3 scripts | ~60 lines |
| Hardcoded header boxes | 10 occurrences | ~40 lines |
| Git repo checks | 8 scripts | ~80 lines |
| URL parsing | 5 scripts | ~50 lines |
| Colour definitions | Previously inline | ~40 lines |
| Input validation | Various | ~30 lines |
| Total | ~300 lines |
More importantly, changes to common functionality now only need to be made in one place.