apps/blobs/cmd_upload.go 2.1 K raw
1
package main
2
3
import (
4
	"context"
5
	"fmt"
6
	"mime"
7
	"os"
8
	"path/filepath"
9
	"strings"
10
)
11
12
func parseUploadArgs(args []string) (ClientFlags, string) {
13
	var (
14
		flags ClientFlags
15
		file  string
16
	)
17
	for i := 0; i < len(args); i++ {
18
		a := args[i]
19
		switch {
20
		case (a == "-b" || a == "--bucket") && i+1 < len(args):
21
			flags.Bucket = args[i+1]
22
			i++
23
		case strings.HasPrefix(a, "--bucket="):
24
			flags.Bucket = strings.TrimPrefix(a, "--bucket=")
25
		case a == "--prefix" && i+1 < len(args):
26
			flags.Prefix = args[i+1]
27
			i++
28
		case strings.HasPrefix(a, "--prefix="):
29
			flags.Prefix = strings.TrimPrefix(a, "--prefix=")
30
		case a == "--key" && i+1 < len(args):
31
			flags.Key = args[i+1]
32
			i++
33
		case strings.HasPrefix(a, "--key="):
34
			flags.Key = strings.TrimPrefix(a, "--key=")
35
		case !strings.HasPrefix(a, "-") && file == "":
36
			file = a
37
		}
38
	}
39
	return flags, file
40
}
41
42
func runUpload(args []string) {
43
	flags, file := parseUploadArgs(args)
44
	if file == "" {
45
		fmt.Fprintln(os.Stderr, "no file specified")
46
		os.Exit(2)
47
	}
48
49
	cfg, err := LoadClientConfig(flags)
50
	if err != nil {
51
		fmt.Fprintln(os.Stderr, "config:", err)
52
		os.Exit(1)
53
	}
54
	bucket := cfg.DefaultBucket
55
	if bucket == "" {
56
		fmt.Fprintln(os.Stderr, "no bucket: pass -b/--bucket or set BLOBS_DEFAULT_BUCKET")
57
		os.Exit(2)
58
	}
59
60
	s3, err := NewS3FromConfig(cfg)
61
	if err != nil {
62
		fmt.Fprintln(os.Stderr, "s3:", err)
63
		os.Exit(1)
64
	}
65
66
	f, err := os.Open(file)
67
	if err != nil {
68
		fmt.Fprintln(os.Stderr, "open:", err)
69
		os.Exit(1)
70
	}
71
	defer f.Close()
72
	info, err := f.Stat()
73
	if err != nil {
74
		fmt.Fprintln(os.Stderr, "stat:", err)
75
		os.Exit(1)
76
	}
77
78
	name := flags.Key
79
	if name == "" {
80
		name = filepath.Base(file)
81
	}
82
	prefix := flags.Prefix
83
	if prefix != "" && !strings.HasSuffix(prefix, "/") {
84
		prefix += "/"
85
	}
86
	key := prefix + name
87
88
	ct := mime.TypeByExtension(filepath.Ext(name))
89
	if ct == "" {
90
		ct = "application/octet-stream"
91
	}
92
93
	ctx := context.Background()
94
	if err := s3.Put(ctx, bucket, key, ct, f, info.Size()); err != nil {
95
		fmt.Fprintln(os.Stderr, "upload:", err)
96
		os.Exit(1)
97
	}
98
99
	url, err := ResolveURL(ctx, s3, bucket, key)
100
	if err != nil {
101
		fmt.Fprintln(os.Stderr, "url:", err)
102
		fmt.Println(key)
103
		return
104
	}
105
	fmt.Println(url)
106
}