forked from
tangled.org/core
fork
Configure Feed
Select the types of activity you want to include in your feed.
Monorepo for Tangled
fork
Configure Feed
Select the types of activity you want to include in your feed.
1package hook
2
3import (
4 "bufio"
5 "context"
6 "encoding/json"
7 "fmt"
8 "net/http"
9 "os"
10 "strings"
11
12 "github.com/urfave/cli/v3"
13)
14
15type HookResponse struct {
16 Messages []string `json:"messages"`
17}
18
19// The hook command is nested like so:
20//
21// knot hook --[flags] [hook]
22func Command() *cli.Command {
23 return &cli.Command{
24 Name: "hook",
25 Usage: "run git hooks",
26 Flags: []cli.Flag{
27 &cli.StringFlag{
28 Name: "git-dir",
29 Usage: "base directory for git repos",
30 },
31 &cli.StringFlag{
32 Name: "user-did",
33 Usage: "git user's did",
34 },
35 &cli.StringFlag{
36 Name: "user-handle",
37 Usage: "git user's handle",
38 },
39 &cli.StringFlag{
40 Name: "internal-api",
41 Usage: "endpoint for the internal API",
42 Value: "http://localhost:5444",
43 },
44 &cli.StringSliceFlag{
45 Name: "push-option",
46 Usage: "any push option from git",
47 },
48 },
49 Commands: []*cli.Command{
50 {
51 Name: "post-recieve",
52 Usage: "sends a post-recieve hook to the knot (waits for stdin)",
53 Action: postRecieve,
54 },
55 },
56 }
57}
58
59func postRecieve(ctx context.Context, cmd *cli.Command) error {
60 gitDir := cmd.String("git-dir")
61 userDid := cmd.String("user-did")
62 userHandle := cmd.String("user-handle")
63 endpoint := cmd.String("internal-api")
64 pushOptions := cmd.StringSlice("push-option")
65
66 payloadReader := bufio.NewReader(os.Stdin)
67 payload, _ := payloadReader.ReadString('\n')
68
69 client := &http.Client{}
70
71 req, err := http.NewRequest("POST", "http://"+endpoint+"/hooks/post-receive", strings.NewReader(payload))
72 if err != nil {
73 return fmt.Errorf("failed to create request: %w", err)
74 }
75
76 req.Header.Set("Content-Type", "text/plain; charset=utf-8")
77 req.Header.Set("X-Git-Dir", gitDir)
78 req.Header.Set("X-Git-User-Did", userDid)
79 req.Header.Set("X-Git-User-Handle", userHandle)
80 if pushOptions != nil {
81 for _, option := range pushOptions {
82 req.Header.Add("X-Git-Push-Option", option)
83 }
84 }
85
86 resp, err := client.Do(req)
87 if err != nil {
88 return fmt.Errorf("failed to execute request: %w", err)
89 }
90 defer resp.Body.Close()
91
92 if resp.StatusCode != http.StatusOK {
93 return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
94 }
95
96 var data HookResponse
97 if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
98 return fmt.Errorf("failed to decode response: %w", err)
99 }
100
101 for _, message := range data.Messages {
102 fmt.Println(message)
103 }
104
105 return nil
106}