Something went wrong. Try again.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242package main
import ( "bytes" "crypto/rand" "encoding/base32" "fmt" "html/template" "io" "os" "os/exec" "path/filepath" "reflect" "slices" "strings"
"codeberg.org/marcig/riploy/slag")
var ( ErrNoHash = fmt.Errorf("must provide a valid hash (docker tag) for the template") ErrNoServerPort = fmt.Errorf("must provide a port for the server (-server-port)") ErrNoFrontendPort = fmt.Errorf("must provide a port for the frontend (-svelte-port)") ErrNoDebuggerPort = fmt.Errorf("must provide a port for the debugger (-debugger-port)") ErrNoDockerhubUserName = fmt.Errorf("docker hub username must be provided (-docker-user)") ErrNoProjectName = fmt.Errorf("project name must be provided (-stack-name)") ErrNoVCS = fmt.Errorf("must provide a vcs url (ex: tangled.org/marcig.com/riploy) (-vcs)") ErrNoDomain = fmt.Errorf("project name must be provided (-domain)"))
func RandomHash(length int) (string, error) { randomBytes := make([]byte, length) _, err := rand.Read(randomBytes)
if err != nil { return "", err } token := base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(randomBytes) return token, nil}
func exitln(v any) { fmt.Printf("%v\n", v) os.Exit(1)}
func exit() { os.Exit(1)}
func warnln(format string, a ...any) { warnFormat := fmt.Sprintf("[WARN]: %v\n", format) fmt.Printf(warnFormat, a...)}
func errorln(format string, a ...any) { warnFormat := fmt.Sprintf("[ERROR]: %v\n", format) fmt.Printf(warnFormat, a...)}
func exitIfAnyError(errs []error) { if errs == nil { return } for _, e := range errs { fmt.Printf("%v\n", e) } os.Exit(1)}
func okExit(v any) { fmt.Printf("%v\n", v) os.Exit(0)}
func isFlagOn(f *bool) bool { return *f}
func isFlagOff(f *bool) bool { return !*f}
func runOrDie(name string, arg ...string) { run := exec.Command(name, arg...) run.Stdout = os.Stdout run.Stderr = os.Stderr fmt.Printf("running: [%v]\n", run) err := run.Run() if err != nil { exitln(err) }}
func runGetOrDie(name string, arg ...string) []byte { var b []byte out := bytes.NewBuffer(b) run := exec.Command(name, arg...) run.Stdout = out run.Stderr = os.Stderr fmt.Printf("%v\n", run) err := run.Run() if err != nil { exitln(err) } o, err := io.ReadAll(out) if err != nil { exitln(err) } return o}
func readFileOrDie(name string) []byte { b, err := os.ReadFile(name) if err != nil { exitln(err) } return b}
func getHome() string { home, ok := os.LookupEnv("HOME") if !ok { exitln("no home env") } return home}
func writeFileString(filename string, content string, shouldOverwrite bool) { if shouldOverwrite { err := os.WriteFile(filename, []byte(content), 0666) if err != nil { exitln(err) } }}
func writeFileOrDie(filename string, content []byte) { err := os.WriteFile(filename, []byte(content), 0666) if err != nil { exitln(err) }}
func createFileOrDie(filename string) *os.File { f, err := os.Create(filename) if err != nil { exitln(err) } return f}
func pwd() string { path, err := os.Getwd() if err != nil { exitln(err) } return path}
func cd(dir string) { err := os.Chdir(dir) if err != nil { exitln(err) }}
// @Warn: i think docker requires you to just use _ for stack namesfunc generateNameFromDir(separator string) string { genericDirs := []string{"frontend", "backend"} cwd := pwd() path := strings.Split(cwd, "/") base := filepath.Base(cwd) if slices.Contains(genericDirs, base) { parent := path[len(path)-2] return fmt.Sprintf("%v%v%v", parent, separator, base) } else { return base }}
func getIdentityNameFromDir() string { genericDirs := []string{"frontend", "backend"} cwd := pwd() path := strings.Split(cwd, "/") base := filepath.Base(cwd) if slices.Contains(genericDirs, base) { parent := path[len(path)-2] return parent } else { return base }}
func sourceFile() string { ex, err := os.Executable() if err != nil { exitln(err) } exPath := filepath.Dir(ex) return exPath}
func getFileChecksumOrDie(filename string) string { sum := runGetOrDie("md5sum", filename) parts := bytes.Split(sum, []byte{' '}) return string(parts[0])}
func createFileFromTemplate(tmpl *template.Template, templateName string, filepath string, data any) error { f := createFileOrDie(filepath) err := tmpl.ExecuteTemplate(f, templateName, data) return err}
// @Warn this is not deep!func mergo(dst, src any) error { tmp := reflect.ValueOf(dst) kind := tmp.Kind()
if kind != reflect.Pointer { return slag.ErrNoPointer }
out := tmp.Elem()
if out.Kind() != reflect.Struct { return slag.ErrNoStructUnderneath }
rSrc := reflect.ValueOf(src)
for f, v := range out.Fields() { sf := rSrc.FieldByName(f.Name) if v.IsZero() { v.Set(sf) } }
return nil}