1package main
2
3import (
4 "context"
5 "fmt"
6 "io"
7 "log/slog"
8 "os"
9 "strings"
10
11 "github.com/bluesky-social/indigo/atproto/identity"
12 "github.com/bluesky-social/indigo/atproto/syntax"
13
14 "github.com/carlmjohnson/versioninfo"
15 "github.com/urfave/cli/v2"
16)
17
18func resolveIdent(ctx context.Context, arg string) (*identity.Identity, error) {
19 id, err := syntax.ParseAtIdentifier(arg)
20 if err != nil {
21 return nil, err
22 }
23
24 dir := identity.DefaultDirectory()
25 return dir.Lookup(ctx, *id)
26}
27
28const stdIOPath = "-"
29
30func getFileOrStdin(path string) (io.Reader, error) {
31 if path == stdIOPath {
32 return os.Stdin, nil
33 }
34 file, err := os.Open(path)
35 if err != nil {
36 return nil, err
37 }
38 return file, nil
39}
40
41func getFileOrStdout(path string) (io.WriteCloser, error) {
42 if path == stdIOPath {
43 return os.Stdout, nil
44 }
45 file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0666)
46 if err != nil {
47 return nil, err
48 }
49 return file, nil
50}
51
52func configLogger(cctx *cli.Context, writer io.Writer) *slog.Logger {
53 var level slog.Level
54 switch strings.ToLower(cctx.String("log-level")) {
55 case "error":
56 level = slog.LevelError
57 case "warn":
58 level = slog.LevelWarn
59 case "info":
60 level = slog.LevelInfo
61 case "debug":
62 level = slog.LevelDebug
63 default:
64 level = slog.LevelInfo
65 }
66 logger := slog.New(slog.NewJSONHandler(writer, &slog.HandlerOptions{
67 Level: level,
68 }))
69 slog.SetDefault(logger)
70 return logger
71}
72
73// returns a pointer because that is what xrpc.Client expects
74func userAgent() *string {
75 s := fmt.Sprintf("goat/%s", versioninfo.Short())
76 return &s
77}