forked from tangled.org/core
this repo has no description
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}