fup: add extractstatic command
This extracts the hash-named static assets into a directory. This is primarily useful if you have multiple instances of fup running and you therefore need to serve /static from a shared filesystem of some sort.
This commit is contained in:
parent
38d9449777
commit
a1bda601a9
1 changed files with 83 additions and 0 deletions
83
web/fup/cmd/extractstatic.go
Normal file
83
web/fup/cmd/extractstatic.go
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/fs"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"hg.lukegb.com/lukegb/depot/web/fup/fupstatic"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(extractstaticCmd)
|
||||||
|
|
||||||
|
extractstaticCmd.Flags().BoolVarP(&extractstaticForceOverwrite, "force", "f", false, "If set, will overwrite existing files.")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
extractstaticForceOverwrite bool
|
||||||
|
|
||||||
|
extractstaticCmd = &cobra.Command{
|
||||||
|
Use: "extractstatic dir",
|
||||||
|
Example: "extractstatic /srv/http/static",
|
||||||
|
Short: "Extracts static assets into a target directory.",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
targetDir := args[0]
|
||||||
|
log.Printf("extracting assets to %v", targetDir)
|
||||||
|
return fs.WalkDir(fupstatic.Static, ".", func(fpath string, d fs.DirEntry, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
targetPath := filepath.Join(targetDir, fpath)
|
||||||
|
fi, err := os.Stat(targetPath)
|
||||||
|
if err != nil && !os.IsNotExist(err) {
|
||||||
|
return fmt.Errorf("checking for existence of %q: %w", targetPath, err)
|
||||||
|
}
|
||||||
|
if d.IsDir() {
|
||||||
|
switch {
|
||||||
|
case fi != nil && !fi.IsDir():
|
||||||
|
return fmt.Errorf("%q already exists and is not a directory", targetPath)
|
||||||
|
case fi != nil:
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
// Ensure directory exists.
|
||||||
|
return os.Mkdir(filepath.Join(targetDir, fpath), 0755)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case fi != nil && fi.IsDir():
|
||||||
|
return fmt.Errorf("%q already exists and is a directory", targetPath)
|
||||||
|
case fi != nil && !extractstaticForceOverwrite:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
src, err := fupstatic.Static.Open(fpath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("open source %q: %w", fpath, err)
|
||||||
|
}
|
||||||
|
defer src.Close() // Don't care about errors for closing read-only file.
|
||||||
|
|
||||||
|
dst, err := os.Create(targetPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("create target %q: %w", targetPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := io.Copy(dst, src); err != nil {
|
||||||
|
return fmt.Errorf("copying from source %q to target %q: %w", fpath, targetPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := dst.Close(); err != nil {
|
||||||
|
return fmt.Errorf("close target %q: %w", targetPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
Loading…
Reference in a new issue