submodule.go 1.5 KB

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