// SPDX-FileCopyrightText: 2021 Luke Granger-Brown // // SPDX-License-Identifier: Apache-2.0 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 }) }, } )