package cli import ( "fmt" "io" "net/http" "strings" "time" "github.com/urfave/cli/v2" ) // isHTTPURL returns true if the string starts with http:// or https://. func isHTTPURL(s string) bool { return strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://") } // openManifestReader opens a manifest from a path or URL and returns a ReadCloser. // The caller must close the returned reader. func (mfa *CLIApp) openManifestReader(pathOrURL string) (io.ReadCloser, error) { if isHTTPURL(pathOrURL) { client := &http.Client{Timeout: 30 * time.Second} resp, err := client.Get(pathOrURL) //nolint:gosec // user-provided URL is intentional if err != nil { return nil, fmt.Errorf("failed to fetch %s: %w", pathOrURL, err) } if resp.StatusCode != http.StatusOK { _ = resp.Body.Close() return nil, fmt.Errorf("failed to fetch %s: HTTP %d", pathOrURL, resp.StatusCode) } return resp.Body, nil } f, err := mfa.Fs.Open(pathOrURL) if err != nil { return nil, err } return f, nil } // resolveManifestArg resolves the manifest path from CLI arguments. // HTTP(S) URLs are returned as-is. Directories are searched for index.mf/.index.mf. // If no argument is given, the current directory is searched. func (mfa *CLIApp) resolveManifestArg(ctx *cli.Context) (string, error) { if ctx.Args().Len() > 0 { arg := ctx.Args().Get(0) if isHTTPURL(arg) { return arg, nil } info, statErr := mfa.Fs.Stat(arg) if statErr == nil && info.IsDir() { return findManifest(mfa.Fs, arg) } return arg, nil } return findManifest(mfa.Fs, ".") }