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