submodule.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package gitutil
  2. import (
  3. "fmt"
  4. "net/url"
  5. "strings"
  6. "github.com/gogs/git-module"
  7. "gogs.io/gogs/internal/lazyregexp"
  8. )
  9. var scpSyntax = lazyregexp.New(`^([a-zA-Z0-9_]+@)?([a-zA-Z0-9._-]+):(.*)$`)
  10. // InferSubmoduleURL returns the inferred external URL of the submodule at best effort.
  11. // The `baseURL` should be the URL of the current repository. If the submodule URL looks
  12. // like a relative path, it assumes that the submodule is another repository on the same
  13. // Gogs instance by appending it to the `baseURL` with the commit.
  14. func InferSubmoduleURL(baseURL string, mod *git.Submodule) string {
  15. if !strings.HasSuffix(baseURL, "/") {
  16. baseURL += "/"
  17. }
  18. raw := strings.TrimSuffix(mod.URL, "/")
  19. raw = strings.TrimSuffix(raw, ".git")
  20. if strings.HasPrefix(raw, "../") {
  21. return fmt.Sprintf("%s%s/commit/%s", baseURL, raw, mod.Commit)
  22. }
  23. parsed, err := url.Parse(raw)
  24. if err != nil {
  25. // Try parse as SCP syntax again
  26. match := scpSyntax.FindAllStringSubmatch(raw, -1)
  27. if len(match) == 0 {
  28. return mod.URL
  29. }
  30. parsed = &url.URL{
  31. Scheme: "http",
  32. Host: match[0][2],
  33. Path: match[0][3],
  34. }
  35. }
  36. switch parsed.Scheme {
  37. case "http", "https":
  38. raw = parsed.String()
  39. case "ssh":
  40. raw = fmt.Sprintf("http://%s%s", parsed.Hostname(), parsed.Path)
  41. default:
  42. return raw
  43. }
  44. return fmt.Sprintf("%s/commit/%s", raw, mod.Commit)
  45. }