162 lines
3.8 KiB
Go
162 lines
3.8 KiB
Go
package util
|
|
|
|
import (
|
|
"archive/tar"
|
|
"bytes"
|
|
"cmp"
|
|
"compress/gzip"
|
|
"crypto/tls"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"os/exec"
|
|
"slices"
|
|
"strings"
|
|
)
|
|
|
|
// Wrapper function to simplify checking if a path exists.
|
|
func PathExists(path string) (bool, error) {
|
|
_, err := os.Stat(path)
|
|
if err == nil {
|
|
return true, nil
|
|
}
|
|
if os.IsNotExist(err) {
|
|
return false, nil
|
|
}
|
|
return false, err
|
|
}
|
|
|
|
// Wrapper function to simplify checking if a path is a directory.
|
|
func IsDirectory(path string) (bool, error) {
|
|
// This returns an *os.FileInfo type
|
|
fileInfo, err := os.Stat(path)
|
|
if err != nil {
|
|
return false, fmt.Errorf("failed to stat path (%s): %v", path, err)
|
|
}
|
|
|
|
// IsDir is short for fileInfo.Mode().IsDir()
|
|
return fileInfo.IsDir(), nil
|
|
}
|
|
|
|
// Wrapper function to confine making a HTTP request into a single function
|
|
// instead of multiple.
|
|
func MakeRequest(url string, httpMethod string, body []byte, headers map[string]string) (*http.Response, []byte, error) {
|
|
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
|
req, err := http.NewRequest(httpMethod, url, bytes.NewBuffer(body))
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("could not create new HTTP request: %v", err)
|
|
}
|
|
req.Header.Add("User-Agent", "configurator")
|
|
for k, v := range headers {
|
|
req.Header.Add(k, v)
|
|
}
|
|
res, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("could not make request: %v", err)
|
|
}
|
|
b, err := io.ReadAll(res.Body)
|
|
res.Body.Close()
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("could not read response body: %v", err)
|
|
}
|
|
return res, b, err
|
|
}
|
|
|
|
// Returns the git commit string by executing command.
|
|
// NOTE: This currently requires git to be installed.
|
|
// TODO: Change how this is done to not require executing a command.
|
|
func GitCommit() string {
|
|
c := exec.Command("git", "rev-parse", "--short=8", "HEAD")
|
|
stdout, err := c.Output()
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
|
|
return strings.TrimRight(string(stdout), "\n")
|
|
}
|
|
|
|
// General function to remove element by a given index.
|
|
// NOTE: would it be better to use slices.DeleteFunc instead?
|
|
func RemoveIndex[T comparable](s []T, index int) []T {
|
|
ret := make([]T, 0)
|
|
ret = append(ret, s[:index]...)
|
|
return append(ret, s[index+1:]...)
|
|
}
|
|
|
|
func RemoveDuplicates[T cmp.Ordered](s []T) []T {
|
|
slices.Sort(s)
|
|
return slices.Compact(s)
|
|
}
|
|
|
|
// General function to copy elements from slice if condition is true.
|
|
func CopyIf[T comparable](s []T, condition func(t T) bool) []T {
|
|
var f = make([]T, 0)
|
|
for _, e := range s {
|
|
if condition(e) {
|
|
f = append(f, e)
|
|
}
|
|
}
|
|
return f
|
|
}
|
|
|
|
func CreateArchive(files []string, buf io.Writer) error {
|
|
// Create new Writers for gzip and tar
|
|
// These writers are chained. Writing to the tar writer will
|
|
// write to the gzip writer which in turn will write to
|
|
// the "buf" writer
|
|
gw := gzip.NewWriter(buf)
|
|
defer gw.Close()
|
|
tw := tar.NewWriter(gw)
|
|
defer tw.Close()
|
|
|
|
// Iterate over files and add them to the tar archive
|
|
for _, file := range files {
|
|
err := addToArchive(tw, file)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func addToArchive(tw *tar.Writer, filename string) error {
|
|
// open file to write to archive
|
|
file, err := os.Open(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
|
|
// get FileInfo for file size, mode, etc.
|
|
info, err := file.Stat()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// create a tar Header from the FileInfo data
|
|
header, err := tar.FileInfoHeader(info, info.Name())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// use full path as name (FileInfoHeader only takes the basename) to
|
|
// preserve directory structure
|
|
// see for more info: https://golang.org/src/archive/tar/common.go?#L626
|
|
header.Name = filename
|
|
|
|
// Write file header to the tar archive
|
|
err = tw.WriteHeader(header)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// copy file content to tar archive
|
|
_, err = io.Copy(tw, file)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|