Replace the curl-based Taskfile download task with a Go binary that concurrently fetches datastar.js, datastar.js.map, daisyui.mjs, and daisyui-theme.mjs. Update vendored libs to latest versions.
101 lines
2.3 KiB
Go
101 lines
2.3 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"log/slog"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
)
|
|
|
|
// Asset directories, relative to project root.
|
|
const (
|
|
jsDir = "assets/js"
|
|
cssDir = "assets/css"
|
|
)
|
|
|
|
// files maps download URLs to local destination paths.
|
|
var files = map[string]string{
|
|
"https://raw.githubusercontent.com/starfederation/datastar/main/bundles/datastar.js": jsDir + "/datastar.js",
|
|
"https://raw.githubusercontent.com/starfederation/datastar/main/bundles/datastar.js.map": jsDir + "/datastar.js.map",
|
|
"https://github.com/saadeghi/daisyui/releases/latest/download/daisyui.mjs": cssDir + "/daisyui.mjs",
|
|
"https://github.com/saadeghi/daisyui/releases/latest/download/daisyui-theme.mjs": cssDir + "/daisyui-theme.mjs",
|
|
}
|
|
|
|
func main() {
|
|
if err := run(); err != nil {
|
|
slog.Error("failure", "error", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func run() error {
|
|
dirs := []string{jsDir, cssDir}
|
|
|
|
for _, dir := range dirs {
|
|
if err := os.MkdirAll(dir, 0755); err != nil {
|
|
return fmt.Errorf("create directory %s: %w", dir, err)
|
|
}
|
|
}
|
|
|
|
return download(files)
|
|
}
|
|
|
|
func download(files map[string]string) error {
|
|
var wg sync.WaitGroup
|
|
errCh := make(chan error, len(files))
|
|
|
|
for url, dest := range files {
|
|
wg.Go(func() {
|
|
base := filepath.Base(dest)
|
|
slog.Info("downloading...", "file", base, "url", url)
|
|
if err := downloadFile(url, dest); err != nil {
|
|
errCh <- fmt.Errorf("download %s: %w", base, err)
|
|
} else {
|
|
slog.Info("finished", "file", base)
|
|
}
|
|
})
|
|
}
|
|
|
|
wg.Wait()
|
|
close(errCh)
|
|
|
|
var errs []error
|
|
for err := range errCh {
|
|
errs = append(errs, err)
|
|
}
|
|
|
|
return errors.Join(errs...)
|
|
}
|
|
|
|
func downloadFile(url, dest string) error {
|
|
resp, err := http.Get(url) //nolint:gosec,noctx // static URLs, simple tool
|
|
if err != nil {
|
|
return fmt.Errorf("GET %s: %w", url, err)
|
|
}
|
|
defer resp.Body.Close() //nolint:errcheck
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return fmt.Errorf("GET %s: status %s", url, resp.Status)
|
|
}
|
|
|
|
out, err := os.Create(dest) //nolint:gosec // paths are hardcoded constants
|
|
if err != nil {
|
|
return fmt.Errorf("create %s: %w", dest, err)
|
|
}
|
|
|
|
if _, err := io.Copy(out, resp.Body); err != nil {
|
|
out.Close() //nolint:errcheck
|
|
return fmt.Errorf("write %s: %w", dest, err)
|
|
}
|
|
|
|
if err := out.Close(); err != nil {
|
|
return fmt.Errorf("close %s: %w", dest, err)
|
|
}
|
|
|
|
return nil
|
|
}
|