hook.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package cmd
  5. import (
  6. "bufio"
  7. "bytes"
  8. "os"
  9. "os/exec"
  10. "path/filepath"
  11. "github.com/urfave/cli"
  12. "github.com/gogits/gogs/models"
  13. )
  14. var (
  15. CmdHook = cli.Command{
  16. Name: "hook",
  17. Usage: "Delegate commands to corresponding Git hooks",
  18. Description: "All sub-commands should only be called by Git",
  19. Flags: []cli.Flag{
  20. stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
  21. },
  22. Subcommands: []cli.Command{
  23. subcmdHookPreReceive,
  24. subcmdHookUpadte,
  25. subcmdHookPostReceive,
  26. },
  27. }
  28. subcmdHookPreReceive = cli.Command{
  29. Name: "pre-receive",
  30. Usage: "Delegate pre-receive Git hook",
  31. Description: "This command should only be called by Git",
  32. Action: runHookPreReceive,
  33. }
  34. subcmdHookUpadte = cli.Command{
  35. Name: "update",
  36. Usage: "Delegate update Git hook",
  37. Description: "This command should only be called by Git",
  38. Action: runHookUpdate,
  39. }
  40. subcmdHookPostReceive = cli.Command{
  41. Name: "post-receive",
  42. Usage: "Delegate post-receive Git hook",
  43. Description: "This command should only be called by Git",
  44. Action: runHookPostReceive,
  45. }
  46. )
  47. func runHookPreReceive(c *cli.Context) error {
  48. if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
  49. return nil
  50. }
  51. setup(c, "hooks/pre-receive.log")
  52. buf := bytes.NewBuffer(nil)
  53. scanner := bufio.NewScanner(os.Stdin)
  54. for scanner.Scan() {
  55. buf.Write(scanner.Bytes())
  56. buf.WriteByte('\n')
  57. }
  58. customHooksPath := os.Getenv(_ENV_REPO_CUSTOM_HOOKS_PATH)
  59. hookCmd := exec.Command(filepath.Join(customHooksPath, "pre-receive"))
  60. hookCmd.Stdout = os.Stdout
  61. hookCmd.Stdin = buf
  62. hookCmd.Stderr = os.Stderr
  63. if err := hookCmd.Run(); err != nil {
  64. fail("Internal error", "Fail to execute custom pre-receive hook: %v", err)
  65. }
  66. return nil
  67. }
  68. func runHookUpdate(c *cli.Context) error {
  69. if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
  70. return nil
  71. }
  72. setup(c, "hooks/update.log")
  73. args := c.Args()
  74. if len(args) != 3 {
  75. fail("Arguments received are not equal to three", "Arguments received are not equal to three")
  76. } else if len(args[0]) == 0 {
  77. fail("First argument 'refName' is empty", "First argument 'refName' is empty")
  78. }
  79. uuid := os.Getenv(_ENV_UPDATE_TASK_UUID)
  80. if err := models.AddUpdateTask(&models.UpdateTask{
  81. UUID: uuid,
  82. RefName: args[0],
  83. OldCommitID: args[1],
  84. NewCommitID: args[2],
  85. }); err != nil {
  86. fail("Internal error", "Fail to add update task '%s': %v", uuid, err)
  87. }
  88. customHooksPath := os.Getenv(_ENV_REPO_CUSTOM_HOOKS_PATH)
  89. hookCmd := exec.Command(filepath.Join(customHooksPath, "update"), args...)
  90. hookCmd.Stdout = os.Stdout
  91. hookCmd.Stdin = os.Stdin
  92. hookCmd.Stderr = os.Stderr
  93. if err := hookCmd.Run(); err != nil {
  94. fail("Internal error", "Fail to execute custom pre-receive hook: %v", err)
  95. }
  96. return nil
  97. }
  98. func runHookPostReceive(c *cli.Context) error {
  99. if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
  100. return nil
  101. }
  102. setup(c, "hooks/post-receive.log")
  103. customHooksPath := os.Getenv(_ENV_REPO_CUSTOM_HOOKS_PATH)
  104. hookCmd := exec.Command(filepath.Join(customHooksPath, "post-receive"))
  105. hookCmd.Stdout = os.Stdout
  106. hookCmd.Stdin = os.Stdin
  107. hookCmd.Stderr = os.Stderr
  108. if err := hookCmd.Run(); err != nil {
  109. fail("Internal error", "Fail to execute custom post-receive hook: %v", err)
  110. }
  111. return nil
  112. }