forked from
rockorager.dev/knit
this repo has no description
1package repo
2
3import (
4 "context"
5 "errors"
6 "fmt"
7 "net/http"
8 "net/url"
9 "strings"
10 "sync"
11
12 "github.com/charmbracelet/huh"
13 "github.com/charmbracelet/huh/spinner"
14 "github.com/spf13/cobra"
15 "github.com/zalando/go-keyring"
16
17 "tangled.sh/rockorager.dev/knit"
18 "tangled.sh/rockorager.dev/knit/auth"
19 "tangled.sh/rockorager.dev/knit/config"
20)
21
22func Create(cmd *cobra.Command, args []string) error {
23 handle := config.DefaultHandleForHost(knit.DefaultHost)
24 if handle == "" {
25 return knit.ErrRequiresAuth
26 }
27
28 client, err := auth.NewClient(knit.DefaultHost, handle)
29 if errors.Is(err, keyring.ErrNotFound) {
30 return knit.ErrRequiresAuth
31 }
32
33 var (
34 knot string
35 repo string
36 description string
37 branch string
38 )
39
40 repoInput := huh.NewInput().
41 Title("Repository Name").
42 Value(&repo)
43
44 if err := repoInput.Run(); err != nil {
45 return fmt.Errorf("getting repo name: %w", err)
46 }
47
48 descriptionInput := huh.NewInput().
49 Title("Description").
50 Value(&description)
51
52 if err := descriptionInput.Run(); err != nil {
53 return fmt.Errorf("getting description: %w", err)
54 }
55
56 branchInput := huh.NewInput().
57 Title("Default Branch").
58 Placeholder("main").
59 Value(&branch)
60
61 if err := branchInput.Run(); err != nil {
62 return fmt.Errorf("getting branch: %w", err)
63 }
64
65 if branch == "" {
66 branch = "main"
67 }
68
69 knotSelect := huh.NewSelect[string]().
70 Title("Select a knot").
71 Options(
72 huh.NewOption(knit.DefaultKnot, knit.DefaultKnot),
73 ).
74 Value(&knot)
75 if err := knotSelect.Run(); err != nil {
76 return fmt.Errorf("getting knot: %w", err)
77 }
78
79 ctx, stop := context.WithCancel(cmd.Context())
80 defer stop()
81
82 wg := &sync.WaitGroup{}
83 wg.Add(1)
84
85 go func(wg *sync.WaitGroup) {
86 spinner.New().
87 Context(ctx).
88 Title("Creating repo...").
89 Run()
90 wg.Done()
91 }(wg)
92
93 err = create(client, knot, repo, branch, description)
94 if err != nil {
95 return err
96 }
97
98 stop()
99 wg.Wait()
100 fmt.Printf("\x1b[32m✔\x1b[m %s created!\r\n", repo)
101 return nil
102}
103
104func create(
105 client *http.Client,
106 domain string,
107 name string,
108 branch string,
109 description string,
110) error {
111 form := url.Values{}
112 form.Set("domain", domain)
113 form.Set("name", name)
114 form.Set("branch", branch)
115 form.Set("description", description)
116
117 u := url.URL{
118 Scheme: "https",
119 Host: knit.DefaultHost,
120 Path: "/repo/new",
121 }
122
123 resp, err := client.Post(
124 u.String(),
125 "application/x-www-form-urlencoded",
126 strings.NewReader(form.Encode()),
127 )
128 if err != nil {
129 return err
130 }
131 defer resp.Body.Close()
132
133 if resp.StatusCode != http.StatusOK {
134 return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
135 }
136
137 return nil
138}