small pixel drawing of a pufferfish zoa

main.go

package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"

	"j3s.sh/zoa/git"
	"j3s.sh/zoa/shell"
	"j3s.sh/zoa/utils"
)

func main() {
	// git vars
	var branch string
	// if os.Geteuid() != 0 {
	// 	fmt.Println("! you are running zoa as a non-root user. not ideal tbh. !")
	// }
	if len(os.Args) < 2 {
		printUsage()
	}
	if len(os.Args) > 2 {
		branch = os.Args[2]
	}

	command := os.Args[1]
	if command == "-h" || command == "--help" || command == "help" {
		printUsage()
	}

	if command == "deploy" {
		if len(os.Args) < 3 {
			fmt.Println("please supply one or more servers to deploy to")
			os.Exit(1)
		}
		hosts := os.Args[2:]

		zoaPath, err := exec.LookPath("zoa")
		if err != nil {
			log.Fatal("(TODO) please install zoa to /usr/local/bin and ensure it's in your PATH")
		}

		// TODO: replace remote binary if newer
		// err = shell.SSH("command -v zoa", hosts)
		// if err != nil {
		// Install Zoa
		err = shell.SCP(zoaPath, hosts)
		if err != nil {
			log.Fatal(err)
		}
		err = shell.SSH("chmod +x zoa", hosts)
		if err != nil {
			log.Fatal(err)
		}
		err = shell.SSH("mv zoa /usr/local/bin/", hosts)
		if err != nil {
			subErr := shell.SSH("sudo mv zoa /usr/local/bin/", hosts)
			if subErr != nil {
				log.Fatal(err)
			}
		}

		err = shell.SCP("main", hosts)
		if err != nil {
			log.Fatal(err)
		}
		err = shell.SCPDir("scripts", hosts)
		if err != nil {
			log.Fatal(err)
		}
		err = shell.SCPDir("files", hosts)
		if err != nil {
			log.Fatal(err)
		}
		err = shell.SSH("sudo zoa .", hosts)
		if err != nil {
			log.Fatal(err)
		}
		os.Exit(0)
	}

	gitMode := git.GitMode(command)

	if gitMode {
		utils.SetZoaRoot("/var/lib/zoa/repo")
		err := os.MkdirAll(utils.ZoaRoot, 0755)
		if err != nil {
			log.Fatal(err)
		}
		// check the path & branch, make sure it's correct
		// then clone
		git.Clone(command, branch)
	} else {
		utils.SetZoaRoot(command)
	}

	// TODO: this writer is responsible for the random stdout
	// maybe save the stdout for debug mode somehow

	main := filepath.Join(utils.ZoaRoot, "main")
	shell.RunScript(main)
}

func printUsage() {
	// TODO: -v -h
	fmt.Println(`usage: zoa <path> || zoa deploy <remote host...>

sorry, this shit is a work in progress

details:
  zoa <path> will execute the code in the given zoa dir
		- if the path is a git repo, zoa will pull it
		- if the path is a dir, zoa will execute the code there

  zoa deploy <remote host...> will ssh to the given server and:
		- install zoa to /usr/local/bin/
		- copy the local zoa repo to the host
		- execute zoa on the remote host

examples:
  zoa ~/code/my-zoa-repo
  zoa .
  zoa https://git.sr.ht/~j3s/testy
  zoa deploy j3s.sh git.j3s.sh`)
	os.Exit(1)
}