dev: automated commit - 2025-06-08 23:28:55
This commit is contained in:
parent
33106ea4a6
commit
0ab9f62ace
13 changed files with 1255 additions and 715 deletions
102
main.go
102
main.go
|
@ -32,11 +32,12 @@ type Config struct {
|
|||
}
|
||||
|
||||
type Script struct {
|
||||
Path string // Full filesystem path
|
||||
Name string // Just filename (e.g. "install.sh")
|
||||
RelPath string // Relative path from runs/ (e.g. "tools/install.sh")
|
||||
Desc string // Description from script comment
|
||||
RequiresSudo bool // Whether script needs elevated privileges
|
||||
Path string // Full filesystem path
|
||||
Name string // Just filename (e.g. "install.sh")
|
||||
RelPath string // Relative path from runs/ (e.g. "tools/install.sh")
|
||||
Desc string // Description from script comment
|
||||
RequiresSudo bool // Whether script needs elevated privileges
|
||||
RequiresInteractive bool // Whether script needs interactive input
|
||||
}
|
||||
|
||||
var config Config
|
||||
|
@ -213,15 +214,20 @@ func handlePush() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getScriptMetadata(scriptPath string) (string, bool) {
|
||||
type ScriptMetadata struct {
|
||||
RequiresSudo bool
|
||||
RequiresInteractive bool
|
||||
}
|
||||
|
||||
func getScriptMetadata(scriptPath string) (string, ScriptMetadata) {
|
||||
file, err := os.Open(scriptPath)
|
||||
if err != nil {
|
||||
return "No description", false
|
||||
return "No description", ScriptMetadata{}
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var desc string
|
||||
var requiresSudo bool
|
||||
scriptMetadata := ScriptMetadata{}
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
|
@ -231,13 +237,9 @@ func getScriptMetadata(scriptPath string) (string, bool) {
|
|||
desc = strings.TrimSpace(strings.TrimPrefix(line, "# NAME:"))
|
||||
}
|
||||
|
||||
if strings.HasPrefix(line, "# REQUIRES: sudo") ||
|
||||
strings.HasPrefix(line, "# REQUIRES:sudo") ||
|
||||
strings.HasPrefix(line, "# ELEVATED: true") ||
|
||||
strings.HasPrefix(line, "# ELEVATED:true") ||
|
||||
strings.HasPrefix(line, "# SUDO: true") ||
|
||||
strings.HasPrefix(line, "# SUDO:true") {
|
||||
requiresSudo = true
|
||||
if strings.HasPrefix(line, "# REQUIRES:") {
|
||||
scriptMetadata.RequiresSudo = strings.Contains(line, "sudo")
|
||||
scriptMetadata.RequiresInteractive = strings.Contains(line, "interactive")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,7 +247,7 @@ func getScriptMetadata(scriptPath string) (string, bool) {
|
|||
desc = "No description"
|
||||
}
|
||||
|
||||
return desc, requiresSudo
|
||||
return desc, scriptMetadata
|
||||
}
|
||||
|
||||
func findScripts(filters []string) ([]Script, error) {
|
||||
|
@ -271,14 +273,15 @@ func findScripts(filters []string) ([]Script, error) {
|
|||
scriptName := filepath.Base(path)
|
||||
|
||||
if len(filters) == 0 || matchesFilters(relPath, scriptName, filters) {
|
||||
desc, requiresSudo := getScriptMetadata(path)
|
||||
desc, metaData := getScriptMetadata(path)
|
||||
|
||||
scripts = append(scripts, Script{
|
||||
Path: path,
|
||||
Name: scriptName,
|
||||
RelPath: relPath,
|
||||
Desc: desc,
|
||||
RequiresSudo: requiresSudo,
|
||||
Path: path,
|
||||
Name: scriptName,
|
||||
RelPath: relPath,
|
||||
Desc: desc,
|
||||
RequiresSudo: metaData.RequiresSudo,
|
||||
RequiresInteractive: metaData.RequiresInteractive,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -331,14 +334,15 @@ func executeScript(script Script, args []string, verbose bool) error {
|
|||
errorLog("sudo command not found - cannot run elevated script")
|
||||
return fmt.Errorf("sudo not available")
|
||||
}
|
||||
fullArgs := append([]string{script.Path}, args...)
|
||||
// Use -S to read password from stdin, and preserve environment
|
||||
fullArgs := append([]string{"-S", "-E", script.Path}, args...)
|
||||
cmd = exec.Command("sudo", fullArgs...)
|
||||
sudoLog("Running with sudo: %s", strings.Join(append([]string{script.Path}, args...), " "))
|
||||
} else {
|
||||
cmd = exec.Command(script.Path, args...)
|
||||
}
|
||||
|
||||
if config.Interactive {
|
||||
if config.Interactive || script.RequiresInteractive {
|
||||
cmd.Stdin = os.Stdin
|
||||
}
|
||||
|
||||
|
@ -348,7 +352,7 @@ func executeScript(script Script, args []string, verbose bool) error {
|
|||
}
|
||||
defer logFileHandle.Close()
|
||||
|
||||
showOutput := verbose || config.Interactive
|
||||
showOutput := verbose || config.Interactive || script.RequiresInteractive
|
||||
if showOutput {
|
||||
cmd.Stdout = io.MultiWriter(os.Stdout, logFileHandle)
|
||||
cmd.Stderr = io.MultiWriter(os.Stderr, logFileHandle)
|
||||
|
@ -371,6 +375,7 @@ func createNewScript(scriptName string) error {
|
|||
|
||||
if !strings.HasSuffix(scriptName, ".sh") {
|
||||
scriptName += ".sh"
|
||||
scriptPath = filepath.Join(config.RunsDir, scriptName)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(scriptPath); err == nil {
|
||||
|
@ -378,15 +383,52 @@ func createNewScript(scriptName string) error {
|
|||
}
|
||||
|
||||
template := fmt.Sprintf(`#!/usr/bin/env bash
|
||||
# NAME: %s script
|
||||
# REQUIRES: sudo
|
||||
# NAME: %s
|
||||
# REQUIRES: sudo interactive
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "Running %s script..."
|
||||
# Source common functions
|
||||
source "$(dirname "$0")/../common.sh" || {
|
||||
echo "[ERROR] Could not source common.sh" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo "✅ %s completed successfully"
|
||||
`, strings.TrimSuffix(scriptName, ".sh"), scriptName, strings.TrimSuffix(scriptName, ".sh"))
|
||||
check_requirements() {
|
||||
# Check required commands
|
||||
local required_commands=()
|
||||
# Add your required commands here
|
||||
# required_commands=(git curl wget)
|
||||
|
||||
for cmd in "${required_commands[@]}"; do
|
||||
if ! command_exists "$cmd"; then
|
||||
log_error "Required command not found: $cmd"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
main() {
|
||||
init_script
|
||||
|
||||
check_requirements
|
||||
|
||||
# Your main script logic goes here
|
||||
|
||||
|
||||
# Example operations:
|
||||
# if ! confirm "Proceed with operation?"; then
|
||||
# log_info "Operation cancelled"
|
||||
# finish_script 0
|
||||
# fi
|
||||
|
||||
# Add your implementation here
|
||||
|
||||
finish_script 0
|
||||
}
|
||||
|
||||
main "$@"
|
||||
`, strings.TrimSuffix(filepath.Base(scriptName), ".sh"))
|
||||
|
||||
err := os.WriteFile(scriptPath, []byte(template), 0o755)
|
||||
if err != nil {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue