package cmd import ( "fmt" "net/http" "net/url" "os" "path/filepath" "strings" "time" "git.towk2.me/towk/makeshift/pkg/client" "github.com/rs/zerolog/log" "github.com/spf13/cobra" ) var downloadCmd = cobra.Command{ Use: "download", Example: ` # set up environment export MAKESHIFT_HOST=http://localhost:5050 export MAKESHIFT_PATH=test # download a file or directory (as archive) makeshift download makeshift download --host http://localhost:5050.com --path test # download a file or directory and run plugins with profile data makeshift download --plugins smd,jinja2 --profile compute curl $MAKESHIFT_HOST/download/test?plugins=smd,jinja2&profile=test # download directory and extract it's contents automatically makeshift download --extract `, Short: "Download and modify files with plugins", PreRun: func(cmd *cobra.Command, args []string) { setenv(cmd, "host", "MAKESHIFT_HOST") setenv(cmd, "path", "MAKESHIFT_PATH") }, Run: func(cmd *cobra.Command, args []string) { var ( host, _ = cmd.Flags().GetString("host") path, _ = cmd.Flags().GetString("path") outputPath, _ = cmd.Flags().GetString("output") pluginNames, _ = cmd.Flags().GetStringSlice("plugins") profileIDs, _ = cmd.Flags().GetStringSlice("profiles") c = client.New(host) res *http.Response query string body []byte err error ) // set output path to match path if empty if outputPath == "" { if path != "." || path != "" { outputPath = filepath.Base(path) } else { outputPath = fmt.Sprintf("%d.file", time.Now().Unix()) } } query = fmt.Sprintf("/download/%s?", path) if len(pluginNames) > 0 { query += "plugins=" + url.QueryEscape(strings.Join(pluginNames, ",")) } if len(profileIDs) > 0 { query += "&profiles=" + url.QueryEscape(strings.Join(profileIDs, ",")) } log.Debug(). Str("host", host). Str("path", path). Str("query", query). Str("output", outputPath). Strs("profiles", profileIDs). Strs("plugins", pluginNames). Send() res, body, err = c.MakeRequest(client.HTTPEnvelope{ Path: query, Method: http.MethodGet, }) if err != nil { log.Error().Err(err). Str("host", host). Str("path", path). Str("output", outputPath). Msg("failed to make request") os.Exit(1) } if res.StatusCode != http.StatusOK { log.Error(). Any("status", map[string]any{ "code": res.StatusCode, "message": res.Status, }). Str("host", host). Str("path", path). Str("output", outputPath). Msg("response returned bad status") os.Exit(1) } if outputPath != "" { err = os.WriteFile(outputPath, body, 0o755) if err != nil { log.Error().Err(err).Msg("failed to write file(s) from download") os.Exit(1) } } else { fmt.Println(string(body)) } }, } var downloadProfileCmd = &cobra.Command{ Use: "profile", } var downloadPluginCmd = &cobra.Command{ Use: "plugin", } func init() { downloadCmd.Flags().String("host", "http://localhost:5050", "Set the makeshift remote host (can be set with MAKESHIFT_HOST)") downloadCmd.Flags().StringP("path", "p", ".", "Set the path to list files (can be set with MAKESHIFT_PATH)") downloadCmd.Flags().StringP("output", "o", "", "Set the output path to write files") downloadCmd.Flags().StringSlice("profiles", []string{}, "Set the profile to use to populate data store") downloadCmd.Flags().StringSlice("plugins", []string{}, "Set the plugins to run before downloading files") downloadCmd.Flags().Bool("extract", false, "Set whether to extract archive locally after downloading") downloadCmd.AddCommand(downloadProfileCmd, downloadPluginCmd) rootCmd.AddCommand(&downloadCmd) }