diff --git a/CHANGELOG.md b/CHANGELOG.md index 2131da3..84b8ac2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,21 @@ # Changelog -All notable changes to git-control will be documented in this file. +All notable changes to dev-control will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- Renamed project from git-control to dev-control +- Main command changed from `gc` to `dc` +- Config directory changed from `~/.config/git-control/` to `~/.config/dev-control/` +- Project config file changed from `.gc-init.yaml` to `.dc-init.yaml` +- All aliases now use `dc-` prefix instead of `gc-` + ### Added -- Modular CLI framework with `gc` entry point +- Modular CLI framework with `dc` entry point - Hierarchical configuration system (global + project) - Plugin architecture with auto-discovery - Interactive TUI mode with gum/fzf support @@ -27,7 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Initial release -- git-control.sh - main orchestration script +- dev-control.sh - main orchestration script - create-repo.sh - GitHub repository creation - create-pr.sh - Pull request automation - template-loading.sh - Template management @@ -46,5 +53,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - GPG commit signing support - SSH key management -[Unreleased]: https://github.com/xaoscience/git-control/compare/v1.0.0...HEAD -[1.0.0]: https://github.com/xaoscience/git-control/releases/tag/v1.0.0 +[Unreleased]: https://github.com/xaoscience/dev-control/compare/v1.0.0...HEAD +[1.0.0]: https://github.com/xaoscience/dev-control/releases/tag/v1.0.0 diff --git a/config/example-global.config.yaml b/config/example-global.config.yaml index 11ee9f5..e1c4b3c 100644 --- a/config/example-global.config.yaml +++ b/config/example-global.config.yaml @@ -1,5 +1,5 @@ -# git-control global configuration -# Location: ~/.config/git-control/config.yaml +# dev-control global configuration +# Location: ~/.config/dev-control/config.yaml default-license: MIT default-branch: main diff --git a/config/example.container.yaml b/config/example.container.yaml index c07f86d..34df62e 100644 --- a/config/example.container.yaml +++ b/config/example.container.yaml @@ -1,5 +1,5 @@ -# git-control container configuration -# Copy to ~/.config/git-control/container.yaml for global defaults +# dev-control container configuration +# Copy to ~/.config/dev-control/container.yaml for global defaults # or to your project root as .devcontainer.yaml for project-specific settings # # NOTE: You can enter custom values not listed in the interactive menus. @@ -113,8 +113,8 @@ mount-docker-socket: true # Install GitHub CLI in container install-gh-cli: true -# Install git-control in container -install-git-control: true +# Install dev-control in container +install-dev-control: true -# git-control version to install (tag or 'latest') -git-control-version: latest +# dev-control version to install (tag or 'latest') +dev-control-version: latest diff --git a/config/example.dc-init.yaml b/config/example.dc-init.yaml new file mode 100644 index 0000000..8cf3285 --- /dev/null +++ b/config/example.dc-init.yaml @@ -0,0 +1,18 @@ +# dev-control project configuration +# Copy to your project root as .dc-init.yaml + +project-name: my-project +repo-slug: my-project +description: A short description + +default-license: MIT +default-branch: main + +github-org: my-org +visibility: public +topics: cli,automation,bash + +template-set: default +auto-sign-commits: true +license-deep-scan: true +auto-push-after-fix: false diff --git a/dc b/dc new file mode 100644 index 0000000..9431d7b --- /dev/null +++ b/dc @@ -0,0 +1,321 @@ +#!/usr/bin/env bash +# +# Dev-Control (dc) - Main Entry Point +# Unified CLI for all dev-control tools +# +# Usage: +# dc [options] # Run a specific command +# dc # Interactive menu +# dc --help # Show help +# dc --version # Show version +# +# Commands: +# init, repo, pr, fix, modules, licenses, mcp, container, aliases +# +# SPDX-License-Identifier: GPL-3.0-or-later +# SPDX-FileCopyrightText: 2024-2026 xaoscience + +set -e + +# Version +DC_VERSION="2.0.0" +DC_BUILD_DATE="2026-01-12" + +# Resolve symlinks and get script directory +resolve_path() { + local path="$1" + while [[ -L "$path" ]]; do + local dir + dir=$(dirname "$path") + path=$(readlink "$path") + [[ "$path" != /* ]] && path="$dir/$path" + done + echo "$path" +} + +SCRIPT_PATH=$(resolve_path "${BASH_SOURCE[0]}") +DC_ROOT="$(cd "$(dirname "$SCRIPT_PATH")" && pwd)" +SCRIPTS_DIR="$DC_ROOT/scripts" +COMMANDS_DIR="$DC_ROOT/commands" +PLUGINS_DIR="$DC_ROOT/plugins" +LIB_DIR="$SCRIPTS_DIR/lib" + +# Source core libraries +source "$LIB_DIR/colors.sh" +source "$LIB_DIR/print.sh" + +# Global options +DC_QUIET=false +DC_VERBOSE=false +DC_JSON=false +DC_DEBUG=false + +# ============================================================================ +# COMMAND REGISTRY +# ============================================================================ + +# Map command names to scripts +declare -A COMMAND_MAP=( + ["init"]="template-loading.sh" + ["template"]="template-loading.sh" + ["templates"]="template-loading.sh" + ["repo"]="create-repo.sh" + ["create"]="create-repo.sh" + ["pr"]="create-pr.sh" + ["pull-request"]="create-pr.sh" + ["fix"]="fix-history.sh" + ["history"]="fix-history.sh" + ["modules"]="module-nesting.sh" + ["nest"]="module-nesting.sh" + ["submodules"]="module-nesting.sh" + ["licenses"]="licenses.sh" + ["lic"]="licenses.sh" + ["license"]="licenses.sh" + ["mcp"]="mcp-setup.sh" + ["container"]="containerise.sh" + ["containerise"]="containerise.sh" + ["containerize"]="containerise.sh" + ["aliases"]="alias-loading.sh" + ["alias"]="alias-loading.sh" + ["menu"]="dev-control.sh" +) + +# Command descriptions for help +declare -A COMMAND_DESC=( + ["init"]="Initialize repository with templates (README, LICENSE, etc.)" + ["repo"]="Create GitHub repository from current folder" + ["pr"]="Create pull request from current branch" + ["fix"]="Fix commit history (reorder, edit, sign, drop)" + ["modules"]="Manage git submodules and .gitmodules" + ["licenses"]="Audit and manage licenses across repo/submodules" + ["mcp"]="Configure Model Context Protocol servers" + ["container"]="Setup devcontainer for project" + ["aliases"]="Install bash aliases for dev-control" + ["menu"]="Open interactive menu (default)" +) + +# ============================================================================ +# HELP & VERSION +# ============================================================================ + +show_version() { + if [[ "$DC_JSON" == "true" ]]; then + cat < [options] + dc Interactive menu + dc --help Show this help + dc --version Show version info + +${BOLD}COMMANDS${NC} +EOF + + # Print commands in a formatted table + local commands=("init" "repo" "pr" "fix" "modules" "licenses" "mcp" "container" "aliases") + for cmd in "${commands[@]}"; do + printf " ${CYAN}%-12s${NC} %s\n" "$cmd" "${COMMAND_DESC[$cmd]}" + done + + cat << EOF + +${BOLD}GLOBAL OPTIONS${NC} + -h, --help Show help (for dc or specific command) + -v, --version Show version + -q, --quiet Suppress non-essential output + --verbose Enable verbose output + --json Output in JSON format (where supported) + --debug Enable debug mode + +${BOLD}EXAMPLES${NC} + dc init Initialize repo with templates + dc repo Create GitHub repo from current folder + dc pr Create pull request + dc fix --range HEAD=5 Fix last 5 commits + dc licenses --deep Audit licenses including submodules + dc aliases Install bash aliases + +${BOLD}ALIASES${NC} + After running 'dc aliases', these shortcuts are available: + dc-init, dc-repo, dc-pr, dc-fix, dc-modules, dc-licenses, dc-mcp + +${BOLD}CONFIGURATION${NC} + Global config: ~/.config/dev-control/config.yaml + Project config: .dc-init.yaml (in repository root) + +${BOLD}MORE INFO${NC} + https://github.com/xaoscience/dev-control +EOF +} + +# ============================================================================ +# COMMAND DISCOVERY & DISPATCH +# ============================================================================ + +# Find command script (built-in or plugin) +find_command() { + local cmd="$1" + + # Check built-in command map first + if [[ -n "${COMMAND_MAP[$cmd]}" ]]; then + local script="$SCRIPTS_DIR/${COMMAND_MAP[$cmd]}" + if [[ -f "$script" ]]; then + echo "$script" + return 0 + fi + fi + + # Check commands directory + if [[ -f "$COMMANDS_DIR/${cmd}.sh" ]]; then + echo "$COMMANDS_DIR/${cmd}.sh" + return 0 + fi + + # Check plugins + for plugin_dir in "$PLUGINS_DIR"/*/; do + if [[ -f "${plugin_dir}commands/${cmd}.sh" ]]; then + echo "${plugin_dir}commands/${cmd}.sh" + return 0 + fi + done + + return 1 +} + +# List all available commands +list_commands() { + local commands=() + + # Built-in commands + for cmd in "${!COMMAND_MAP[@]}"; do + commands+=("$cmd") + done + + # Commands directory + if [[ -d "$COMMANDS_DIR" ]]; then + for script in "$COMMANDS_DIR"/*.sh; do + [[ -f "$script" ]] || continue + local name + name=$(basename "$script" .sh) + commands+=("$name") + done + fi + + # Plugin commands + for plugin_dir in "$PLUGINS_DIR"/*/; do + [[ -d "$plugin_dir" ]] || continue + for script in "${plugin_dir}commands/"*.sh; do + [[ -f "$script" ]] || continue + local name + name=$(basename "$script" .sh) + commands+=("plugin:$name") + done + done + + # Unique and sorted + printf '%s\n' "${commands[@]}" | sort -u +} + +# Run a command +run_command() { + local cmd="$1" + shift + + local script + if script=$(find_command "$cmd"); then + # Export global options for child scripts + export DC_QUIET DC_VERBOSE DC_JSON DC_DEBUG DC_ROOT + + # Execute the script + exec bash "$script" "$@" + else + print_error "Unknown command: $cmd" + echo "" + echo "Available commands:" + list_commands | while read -r c; do + echo " $c" + done + echo "" + echo "Run 'dc --help' for usage information." + exit 1 + fi +} + +# ============================================================================ +# MAIN +# ============================================================================ + +main() { + # Parse global options first + local args=() + while [[ $# -gt 0 ]]; do + case "$1" in + -h|--help) + if [[ ${#args[@]} -gt 0 ]]; then + # Help for a specific command + run_command "${args[0]}" --help + else + show_help + fi + exit 0 + ;; + -v|--version) + show_version + exit 0 + ;; + -q|--quiet) + DC_QUIET=true + shift + ;; + --verbose) + DC_VERBOSE=true + shift + ;; + --json) + DC_JSON=true + shift + ;; + --debug) + DC_DEBUG=true + set -x + shift + ;; + --list-commands) + list_commands + exit 0 + ;; + -*) + # Unknown global option - might be for subcommand + args+=("$1") + shift + ;; + *) + args+=("$1") + shift + ;; + esac + done + + # No command specified - run interactive menu + if [[ ${#args[@]} -eq 0 ]]; then + run_command "menu" + exit 0 + fi + + # Run specified command + local cmd="${args[0]}" + run_command "$cmd" "${args[@]:1}" +} + +main "$@" diff --git a/install.sh b/install.sh index 2f8e3f1..a765ed2 100644 --- a/install.sh +++ b/install.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash # -# Git-Control Installer +# Dev-Control Installer # Single-file installer for easy distribution # # Usage: -# curl -sSL https://raw.githubusercontent.com/xaoscience/git-control/Main/install.sh | bash +# curl -sSL https://raw.githubusercontent.com/xaoscience/dev-control/Main/install.sh | bash # curl -sSL ... | bash -s -- --prefix=/custom/path # curl -sSL ... | bash -s -- --uninstall # @@ -14,9 +14,9 @@ set -e # Configuration -GC_REPO="xaoscience/git-control" -GC_BRANCH="Main" -DEFAULT_PREFIX="$HOME/.local/share/git-control" +DC_REPO="xaoscience/dev-control" +DC_BRANCH="Main" +DEFAULT_PREFIX="$HOME/.local/share/dev-control" DEFAULT_BIN="$HOME/.local/bin" # Colors @@ -47,16 +47,16 @@ QUIET=false show_help() { cat << EOF -Git-Control Installer +Dev-Control Installer USAGE: - curl -sSL https://raw.githubusercontent.com/$GC_REPO/$GC_BRANCH/install.sh | bash + curl -sSL https://raw.githubusercontent.com/$DC_REPO/$DC_BRANCH/install.sh | bash ./install.sh [OPTIONS] OPTIONS: --prefix=PATH Installation directory (default: $DEFAULT_PREFIX) - --bin=PATH Binary directory for 'gc' symlink (default: $DEFAULT_BIN) - --uninstall Remove git-control + --bin=PATH Binary directory for 'dc' symlink (default: $DEFAULT_BIN) + --uninstall Remove dev-control --upgrade Update existing installation --no-aliases Skip bash aliases installation --quiet Minimal output @@ -64,10 +64,10 @@ OPTIONS: EXAMPLES: # Install to default location - curl -sSL https://raw.githubusercontent.com/$GC_REPO/$GC_BRANCH/install.sh | bash + curl -sSL https://raw.githubusercontent.com/$DC_REPO/$DC_BRANCH/install.sh | bash # Install to custom location - ./install.sh --prefix=/opt/git-control --bin=/usr/local/bin + ./install.sh --prefix=/opt/dev-control --bin=/usr/local/bin # Update existing installation ./install.sh --upgrade @@ -121,8 +121,8 @@ check_prerequisites() { # INSTALLATION # ============================================================================ -install_git_control() { - print_info "Installing git-control to $PREFIX" +install_dev_control() { + print_info "Installing dev-control to $PREFIX" # Create directories mkdir -p "$PREFIX" @@ -133,29 +133,29 @@ install_git_control() { if [[ "$UPGRADE" == "true" ]]; then print_info "Updating existing installation..." git -C "$PREFIX" fetch origin - git -C "$PREFIX" reset --hard "origin/$GC_BRANCH" + git -C "$PREFIX" reset --hard "origin/$DC_BRANCH" else - print_error "git-control already installed at $PREFIX" + print_error "dev-control already installed at $PREFIX" print_info "Use --upgrade to update, or --uninstall first" exit 1 fi else print_info "Cloning repository..." - git clone --depth 1 -b "$GC_BRANCH" "https://github.com/$GC_REPO.git" "$PREFIX" + git clone --depth 1 -b "$DC_BRANCH" "https://github.com/$DC_REPO.git" "$PREFIX" fi # Make scripts executable print_info "Setting permissions..." - chmod +x "$PREFIX/gc" + chmod +x "$PREFIX/dc" chmod +x "$PREFIX/scripts/"*.sh chmod +x "$PREFIX/commands/"*.sh 2>/dev/null || true # Create symlink - print_info "Creating symlink: $BIN_DIR/gc -> $PREFIX/gc" - ln -sf "$PREFIX/gc" "$BIN_DIR/gc" + print_info "Creating symlink: $BIN_DIR/dc -> $PREFIX/dc" + ln -sf "$PREFIX/dc" "$BIN_DIR/dc" # Create config directory - local config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/git-control" + local config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/dev-control" mkdir -p "$config_dir" # Copy example config if doesn't exist @@ -171,7 +171,7 @@ install_git_control() { install_aliases fi - print_success "git-control installed successfully!" + print_success "dev-control installed successfully!" } install_aliases() { @@ -179,28 +179,28 @@ install_aliases() { local bash_aliases="$HOME/.bash_aliases" local bashrc="$HOME/.bashrc" - local marker="# git-control aliases" + local marker="# dev-control aliases" # Check if already installed if grep -q "$marker" "$bash_aliases" 2>/dev/null; then print_info "Aliases already installed, updating..." # Remove old aliases - sed -i "/$marker/,/# end git-control/d" "$bash_aliases" + sed -i "/$marker/,/# end dev-control/d" "$bash_aliases" fi # Append aliases cat >> "$bash_aliases" << EOF $marker -alias gc='$PREFIX/gc' -alias gc-init='$PREFIX/gc init' -alias gc-repo='$PREFIX/gc repo' -alias gc-pr='$PREFIX/gc pr' -alias gc-fix='$PREFIX/gc fix' -alias gc-modules='$PREFIX/gc modules' -alias gc-licenses='$PREFIX/gc licenses' -alias gc-mcp='$PREFIX/gc mcp' -alias gc-aliases='$PREFIX/gc aliases' -# end git-control +alias dc='$PREFIX/dc' +alias dc-init='$PREFIX/dc init' +alias dc-repo='$PREFIX/dc repo' +alias dc-pr='$PREFIX/dc pr' +alias dc-fix='$PREFIX/dc fix' +alias dc-modules='$PREFIX/dc modules' +alias dc-licenses='$PREFIX/dc licenses' +alias dc-mcp='$PREFIX/dc mcp' +alias dc-aliases='$PREFIX/dc aliases' +# end dev-control EOF # Ensure .bashrc sources .bash_aliases @@ -222,13 +222,13 @@ EOF # UNINSTALLATION # ============================================================================ -uninstall_git_control() { - print_info "Uninstalling git-control..." +uninstall_dev_control() { + print_info "Uninstalling dev-control..." # Remove symlink - if [[ -L "$BIN_DIR/gc" ]]; then - rm "$BIN_DIR/gc" - print_info "Removed symlink: $BIN_DIR/gc" + if [[ -L "$BIN_DIR/dc" ]]; then + rm "$BIN_DIR/dc" + print_info "Removed symlink: $BIN_DIR/dc" fi # Remove installation @@ -239,13 +239,13 @@ uninstall_git_control() { # Remove aliases local bash_aliases="$HOME/.bash_aliases" - if grep -q "# git-control aliases" "$bash_aliases" 2>/dev/null; then - sed -i '/# git-control aliases/,/# end git-control/d' "$bash_aliases" + if grep -q "# dev-control aliases" "$bash_aliases" 2>/dev/null; then + sed -i '/# dev-control aliases/,/# end dev-control/d' "$bash_aliases" print_info "Removed aliases from .bash_aliases" fi - print_success "git-control uninstalled" - print_info "Note: Configuration in ~/.config/git-control was preserved" + print_success "dev-control uninstalled" + print_info "Note: Configuration in ~/.config/dev-control was preserved" } # ============================================================================ @@ -258,25 +258,25 @@ show_post_install() { echo "" echo -e "${BOLD}Quick Start:${NC}" echo " 1. Reload your shell: source ~/.bashrc" - echo " 2. Run: gc --help" + echo " 2. Run: dc --help" echo "" echo -e "${BOLD}Available Commands:${NC}" - echo " gc init - Initialize repo with templates" - echo " gc repo - Create GitHub repository" - echo " gc pr - Create pull request" - echo " gc fix - Fix commit history" - echo " gc modules - Manage submodules" - echo " gc licenses - Audit licenses" - echo " gc mcp - Configure MCP servers" - echo " gc config - Manage configuration" - echo " gc status - Show status" + echo " dc init - Initialize repo with templates" + echo " dc repo - Create GitHub repository" + echo " dc pr - Create pull request" + echo " dc fix - Fix commit history" + echo " dc modules - Manage submodules" + echo " dc licenses - Audit licenses" + echo " dc mcp - Configure MCP servers" + echo " dc config - Manage configuration" + echo " dc status - Show status" echo "" echo -e "${BOLD}Configuration:${NC}" - echo " Global: ~/.config/git-control/config.yaml" - echo " Project: .gc-init.yaml (in repo root)" + echo " Global: ~/.config/dev-control/config.yaml" + echo " Project: .dc-init.yaml (in repo root)" echo "" echo -e "${BOLD}More Info:${NC}" - echo " https://github.com/$GC_REPO" + echo " https://github.com/$DC_REPO" echo "" } @@ -289,17 +289,17 @@ main() { echo -e "${BOLD}${CYAN}" echo " ╔═══════════════════════════════════════╗" - echo " ║ Git-Control Installer ║" + echo " ║ Dev-Control Installer ║" echo " ╚═══════════════════════════════════════╝" echo -e "${NC}" if [[ "$UNINSTALL" == "true" ]]; then - uninstall_git_control + uninstall_dev_control exit 0 fi check_prerequisites - install_git_control + install_dev_control if [[ "$QUIET" != "true" ]]; then show_post_install