/commands/apply.go

https://gitlab.com/jslee1301/hub · Go · 113 lines · 100 code · 12 blank · 1 comment · 14 complexity · b9006914fe3706129e2d119b3606ae63 MD5 · raw file

  1. package commands
  2. import (
  3. "io"
  4. "io/ioutil"
  5. "regexp"
  6. "github.com/github/hub/github"
  7. "github.com/github/hub/utils"
  8. )
  9. var cmdApply = &Command{
  10. Run: apply,
  11. GitExtension: true,
  12. Usage: "apply <GITHUB-URL>",
  13. Long: `Download a patch from GitHub and apply it locally.
  14. ## Options:
  15. <GITHUB-URL>
  16. A URL to a pull request or commit on GitHub.
  17. ## Examples:
  18. $ hub apply https://github.com/jingweno/gh/pull/55
  19. > curl https://github.com/jingweno/gh/pull/55.patch -o /tmp/55.patch
  20. > git apply /tmp/55.patch
  21. ## See also:
  22. hub-am(1), hub(1), git-apply(1)
  23. `,
  24. }
  25. var cmdAm = &Command{
  26. Run: apply,
  27. GitExtension: true,
  28. Usage: "am [-3] <GITHUB-URL>",
  29. Long: `Replicate commits from a GitHub pull request locally.
  30. ## Options:
  31. -3
  32. (Recommended) See git-am(1).
  33. <GITHUB-URL>
  34. A URL to a pull request or commit on GitHub.
  35. ## Examples:
  36. $ hub am -3 https://github.com/jingweno/gh/pull/55
  37. > curl https://github.com/jingweno/gh/pull/55.patch -o /tmp/55.patch
  38. > git am -3 /tmp/55.patch
  39. ## See also:
  40. hub-apply(1), hub-cherry-pick(1), hub(1), git-am(1)
  41. `,
  42. }
  43. func init() {
  44. CmdRunner.Use(cmdApply)
  45. CmdRunner.Use(cmdAm)
  46. }
  47. func apply(command *Command, args *Args) {
  48. if !args.IsParamsEmpty() {
  49. transformApplyArgs(args)
  50. }
  51. }
  52. func transformApplyArgs(args *Args) {
  53. gistRegexp := regexp.MustCompile("^https?://gist\\.github\\.com/([\\w.-]+/)?([a-f0-9]+)")
  54. pullRegexp := regexp.MustCompile("^(pull|commit)/([0-9a-f]+)")
  55. for _, arg := range args.Params {
  56. var (
  57. patch io.ReadCloser
  58. apiError error
  59. )
  60. projectURL, err := github.ParseURL(arg)
  61. if err == nil {
  62. gh := github.NewClient(projectURL.Project.Host)
  63. match := pullRegexp.FindStringSubmatch(projectURL.ProjectPath())
  64. if match != nil {
  65. if match[1] == "pull" {
  66. patch, apiError = gh.PullRequestPatch(projectURL.Project, match[2])
  67. } else {
  68. patch, apiError = gh.CommitPatch(projectURL.Project, match[2])
  69. }
  70. }
  71. } else {
  72. match := gistRegexp.FindStringSubmatch(arg)
  73. if match != nil {
  74. // TODO: support Enterprise gist
  75. gh := github.NewClient(github.GitHubHost)
  76. patch, apiError = gh.GistPatch(match[2])
  77. }
  78. }
  79. utils.Check(apiError)
  80. if patch == nil {
  81. continue
  82. }
  83. idx := args.IndexOfParam(arg)
  84. patchFile, err := ioutil.TempFile("", "hub")
  85. utils.Check(err)
  86. _, err = io.Copy(patchFile, patch)
  87. utils.Check(err)
  88. patchFile.Close()
  89. patch.Close()
  90. args.Params[idx] = patchFile.Name()
  91. }
  92. }