Skip to content
Merged
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
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
██╔══██╗██╔════╝██║ ██║██╔════╝██╔════╝╚══██╔══╝██║ ██║██╔══██╗
██║ ██║█████╗ ██║ ██║███████╗█████╗ ██║ ██║ ██║██████╔╝
██║ ██║██╔══╝ ╚██╗ ██╔╝╚════██║██╔══╝ ██║ ██║ ██║██╔═══╝
██║ ██║██╔══╝ ╚██╗ ██╔╝╚════██║██╔══╝ ██║ ██║ ██║██╔═╝
██████╔╝███████╗ ╚████╔╝ ███████║███████╗ ██║ ╚██████╔╝██║
╚═════╝ ╚══════╝ ╚═══╝ ╚══════╝╚══════╝ ╚═╝ ╚═════╝ ╚═╝
```

**One-command setup for your entire DevOps environment.**

[![Version](https://img.shields.io/badge/version-1.0.1-indigo?style=flat-square)](https://github.com/Silver595/DevSetUp/releases)
[![Version](https://img.shields.io/badge/version-1.0.5-indigo?style=flat-square)](https://github.com/Silver595/DevSetUp/releases)
[![License](https://img.shields.io/badge/license-MIT-green?style=flat-square)](LICENSE)
[![Shell](https://img.shields.io/badge/shell-bash%204%2B-blue?style=flat-square)](https://www.gnu.org/software/bash/)
[![OS](https://img.shields.io/badge/OS-Debian%20·%20Ubuntu%20·%20Fedora%20·%20Arch-orange?style=flat-square)](#-supported-operating-systems)
Expand Down Expand Up @@ -385,16 +386,16 @@ devsetup/

## 🌐 TUI Backends

`devsetup` auto-detects the best available interface:
The pure-bash arrow-key TUI is the **default** — it works everywhere: sudo, SSH, tmux, any terminal.

| Backend | Experience | Install |
| Backend | Experience | How to use |
|---|---|---|
| `whiptail` | ✔ Dialog boxes | `apt install whiptail` |
| `dialog` | ✔ Dialog boxes | `apt install dialog` |
| `fzf` | ✔ Fuzzy finder | `devsetup --install fzf` |
| **Pure bash** | ✔ Arrow-key TUI | **Built-in — always works** |
| **Pure bash** | ✔ Arrow keys, built-in | Default — always works |
| `whiptail` | ✔ Dialog boxes | `DEVSETUP_TUI=whiptail devsetup` |
| `dialog` | ✔ Dialog boxes | `DEVSETUP_TUI=dialog devsetup` |
| `fzf` | ✔ Fuzzy search | `DEVSETUP_TUI=fzf devsetup` |

The pure-bash fallback supports: `↑↓` / `j k` navigate · `Space` toggle · `Enter` confirm · `a` select all · `n` clear · `q` quit
**Pure-bash controls:** `↑↓` / `j k` navigate · `Space` toggle · `Enter` confirm · `a` select all · `n` clear · `q` quit

---

Expand Down
6 changes: 3 additions & 3 deletions devsetup
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ unset _lib
DRY_RUN="${DRY_RUN:-false}"
export DRY_RUN

DEVSETUP_VERSION="1.0.4"
DEVSETUP_VERSION="1.0.5"

# ── Lock file (prevent concurrent runs) ──────────────────────────────────────
LOCK_FILE="/tmp/devsetup.lock"
Expand Down Expand Up @@ -268,9 +268,9 @@ run_interactive() {

# Brief non-blocking doctor
log_section "Pre-flight"
check_internet 2>/dev/null || log_warn "Internet may be offline — installs could fail."
check_internet || log_warn "Internet offline — installs will fail."
check_sudo; check_disk_space /; check_pkg_lock
printf "\n" >&2
echo >&2

# Temp file: all TUI backends write their selection here directly (no subshell tricks)
_tui_out_file="$(mktemp /tmp/devsetup_sel.XXXXXX)"
Expand Down
Binary file added devsetup_1.0.5_all.deb
Binary file not shown.
157 changes: 109 additions & 48 deletions install.sh
Original file line number Diff line number Diff line change
@@ -1,58 +1,100 @@
#!/usr/bin/env bash
# =============================================================================
# install.sh — One-liner remote installer for devsetup
# install.sh — One-liner curl installer for devsetup v1.0.5
#
# Usage (once hosted on a server or GitHub):
# curl -fsSL https://raw.githubusercontent.com/YOU/devsetup/main/install.sh | bash
#
# What it does:
# 1. Downloads the devsetup repo (or just the required files)
# 2. Installs to /usr/local/bin/devsetup
# 3. Puts lib/ and config/ into /usr/share/devsetup/
# Usage:
# curl -fsSL https://raw.githubusercontent.com/Silver595/DevSetUp/main/install.sh | bash
# curl -fsSL https://raw.githubusercontent.com/Silver595/DevSetUp/main/install.sh | sudo bash
# =============================================================================
set -euo pipefail

REPO_URL="https://github.com/Silver595/DevSetUp"
RAW_URL="https://raw.githubusercontent.com/Silver595/DevSetUp/main"
INSTALL_BIN="/usr/local/bin/devsetup"
INSTALL_SHARE="/usr/share/devsetup"
INSTALLER_VERSION="1.0.3"
INSTALLER_VERSION="1.0.5"

# ── Colors ────────────────────────────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m'
RED=$'\033[0;31m'; GREEN=$'\033[0;32m'; YELLOW=$'\033[1;33m'
CYAN=$'\033[0;36m'; BOLD=$'\033[1m'; DIM=$'\033[2m'; RESET=$'\033[0m'

info() { echo -e "${CYAN} ➜${RESET} $*"; }
ok() { echo -e "${GREEN} ✔${RESET} $*"; }
warn() { echo -e "${YELLOW} ⚠${RESET} $*"; }
die() { echo -e "${RED} ✘ ERROR:${RESET} $*" >&2; exit 1; }
info() { printf "${CYAN} ➜${RESET} %s\n" "$*"; }
ok() { printf "${GREEN} ✔${RESET} %s\n" "$*"; }
warn() { printf "${YELLOW} ⚠${RESET} %s\n" "$*"; }
die() { printf "${RED} ✘ ERROR:${RESET} %s\n" "$*" >&2; exit 1; }
step() { printf "\n${BOLD} ── %s${RESET}\n" "$*"; }

# ── Privilege detection ───────────────────────────────────────────────────────
SUDO_CMD=""
[[ "$EUID" -ne 0 ]] && SUDO_CMD="sudo"
if [[ "$EUID" -ne 0 ]]; then
command -v sudo &>/dev/null || die "This script must be run as root or with sudo."
SUDO_CMD="sudo"
fi

# ── Pre-flight ────────────────────────────────────────────────────────────────
printf "\n${BOLD} ╔══════════════════════════════════════╗\n"
printf " ║ devsetup Installer v%-12s ║\n" "$INSTALLER_VERSION"
printf " ╚══════════════════════════════════════╝${RESET}\n\n"

step "Pre-flight checks"

# curl is mandatory
command -v curl &>/dev/null || die "curl is required. Install it: sudo apt install curl"
ok "curl found"

# ── Preflight ─────────────────────────────────────────────────────────────────
command -v curl &>/dev/null || die "curl is required. Install it first: sudo apt install curl"
# Internet check
if curl -fsSL --max-time 6 --retry 2 https://1.1.1.1 &>/dev/null \
|| curl -fsSL --max-time 6 --retry 2 https://google.com &>/dev/null; then
ok "Internet connection OK"
else
die "No internet connection. Cannot download devsetup."
fi

# OS detection
if [[ -f /etc/os-release ]]; then
# shellcheck source=/dev/null
source /etc/os-release
_os="${ID,,}"
else
_os="$(uname -s | tr '[:upper:]' '[:lower:]')"
fi

echo ""
echo -e "${BOLD} DevSetup Installer v${INSTALLER_VERSION}${RESET}"
echo " ─────────────────────────────────"
echo ""
case "$_os" in
ubuntu|debian|linuxmint|pop|kali|elementary|zorin|raspbian)
_pkg_mgr="apt" ;;
fedora|rhel|centos|almalinux|rocky)
command -v dnf &>/dev/null && _pkg_mgr="dnf" || _pkg_mgr="yum" ;;
arch|manjaro|endeavouros|garuda|artix)
_pkg_mgr="pacman" ;;
opensuse*|sles)
_pkg_mgr="zypper" ;;
darwin|macos)
_pkg_mgr="brew" ;;
*)
_pkg_mgr="unknown"
warn "Unknown OS: $_os — installation may have issues."
;;
esac
ok "OS detected: $_os (package manager: $_pkg_mgr)"

# ── Download ──────────────────────────────────────────────────────────────────
step "Downloading devsetup"

# ── Download method: prefer git clone, fall back to curl ─────────────────────
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT

SRC="$TMP_DIR/devsetup"

if command -v git &>/dev/null; then
info "Cloning devsetup repository..."
git clone --depth=1 "$REPO_URL" "$TMP_DIR/devsetup" 2>/dev/null \
|| die "Failed to clone $REPO_URL — check the URL or your internet connection."
SRC="$TMP_DIR/devsetup"
info "Cloning repository (git)..."
git clone --depth=1 --quiet "$REPO_URL" "$SRC" \
|| die "Failed to clone $REPO_URL — check your internet connection."
ok "Repository cloned"
else
info "git not found — downloading files directly..."
SRC="$TMP_DIR/devsetup"
info "git not found — downloading individual files..."
mkdir -p "$SRC/lib" "$SRC/config"

FILES=(
_files=(
"devsetup"
"lib/logger.sh"
"lib/detect.sh"
Expand All @@ -64,37 +106,56 @@ else
"config/aliases.conf"
"config/folders.conf"
)
for f in "${FILES[@]}"; do
info " Downloading $f..."
mkdir -p "$SRC/$(dirname "$f")"
curl -fsSL "$RAW_URL/$f" -o "$SRC/$f" \
|| die "Failed to download $f"
for _f in "${_files[@]}"; do
mkdir -p "$SRC/$(dirname "$_f")"
curl -fsSL --retry 3 "$RAW_URL/$_f" -o "$SRC/$_f" \
|| die "Failed to download $_f — check your internet connection."
done
ok "${#_files[@]} files downloaded"
fi

# ── Install files ─────────────────────────────────────────────────────────────
info "Installing devsetup to $INSTALL_BIN ..."
# Basic sanity check — make sure we got the right thing
[[ -f "$SRC/devsetup" ]] || die "Download failed: main script not found in $SRC"
[[ -d "$SRC/lib" ]] || die "Download failed: lib/ directory not found in $SRC"
[[ -d "$SRC/config" ]] || die "Download failed: config/ directory not found in $SRC"

# ── Install ───────────────────────────────────────────────────────────────────
step "Installing to system"

$SUDO_CMD mkdir -p "$INSTALL_SHARE/lib" "$INSTALL_SHARE/config"

# Rewrite path vars so the installed binary finds its libraries
# Rewrite the path vars so the installed binary finds its libs correctly
sed \
-e "s|^DEVSETUP_DIR=.*|DEVSETUP_DIR=\"${INSTALL_SHARE}\"|" \
-e "s|^LIB_DIR=.*|LIB_DIR=\"\${DEVSETUP_DIR}/lib\"|" \
-e "s|^CONF_DIR=.*|CONF_DIR=\"\${DEVSETUP_DIR}/config\"|" \
"$SRC/devsetup" > "$TMP_DIR/devsetup_patched"

$SUDO_CMD install -m 755 "$TMP_DIR/devsetup_patched" "$INSTALL_BIN"
$SUDO_CMD cp -r "$SRC/lib/." "$INSTALL_SHARE/lib/"
$SUDO_CMD cp -r "$SRC/config/." "$INSTALL_SHARE/config/"
$SUDO_CMD cp -r "$SRC/lib/." "$INSTALL_SHARE/lib/"
$SUDO_CMD cp -r "$SRC/config/." "$INSTALL_SHARE/config/"
$SUDO_CMD chmod +x "$INSTALL_SHARE/lib/"*.sh

ok "Installed: $INSTALL_BIN"
ok "Data dir: $INSTALL_SHARE"
ok "Binary: $INSTALL_BIN"
ok "Data dir: $INSTALL_SHARE"

# ── Verify ────────────────────────────────────────────────────────────────────
echo ""
devsetup --version && ok "devsetup is ready!" || warn "Installation may have issues — run 'devsetup --help' to check."
# ── Make sure /usr/local/bin is in PATH ───────────────────────────────────────
if [[ ":$PATH:" != *":/usr/local/bin:"* ]]; then
warn "/usr/local/bin is not in your PATH — adding it..."
export PATH="/usr/local/bin:$PATH"
warn "Add this to your ~/.bashrc or ~/.zshrc to make it permanent:"
warn " export PATH=\"/usr/local/bin:\$PATH\""
fi

# ── Final verification ────────────────────────────────────────────────────────
step "Verification"

if "$INSTALL_BIN" --version &>/dev/null; then
_ver="$("$INSTALL_BIN" --version 2>/dev/null)"
ok "$_ver installed successfully"
else
die "Installation verification failed. Try running: $INSTALL_BIN --version"
fi

echo ""
echo -e "${BOLD} ✨ Run: devsetup${RESET}"
echo ""
printf "\n${BOLD}${GREEN} ✨ Done! Run:${RESET} ${CYAN}${BOLD}devsetup${RESET}\n\n"
printf " ${DIM}Tip: run 'devsetup --doctor' first to verify your system is ready.${RESET}\n\n"
Loading