gfile_source.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. package gfile
  7. import (
  8. "os"
  9. "runtime"
  10. "strings"
  11. "github.com/gogf/gf/text/gregex"
  12. )
  13. var (
  14. // goRootForFilter is used for stack filtering purpose.
  15. goRootForFilter = runtime.GOROOT()
  16. )
  17. func init() {
  18. if goRootForFilter != "" {
  19. goRootForFilter = strings.Replace(goRootForFilter, "\\", "/", -1)
  20. }
  21. }
  22. // MainPkgPath returns absolute file path of package main,
  23. // which contains the entrance function main.
  24. //
  25. // It's only available in develop environment.
  26. //
  27. // Note1: Only valid for source development environments,
  28. // IE only valid for systems that generate this executable.
  29. //
  30. // Note2: When the method is called for the first time, if it is in an asynchronous goroutine,
  31. // the method may not get the main package path.
  32. func MainPkgPath() string {
  33. // Only for source development environments.
  34. if goRootForFilter == "" {
  35. return ""
  36. }
  37. path := mainPkgPath.Val()
  38. if path != "" {
  39. return path
  40. }
  41. lastFile := ""
  42. for i := 1; i < 10000; i++ {
  43. if _, file, _, ok := runtime.Caller(i); ok {
  44. if goRootForFilter != "" && len(file) >= len(goRootForFilter) && file[0:len(goRootForFilter)] == goRootForFilter {
  45. continue
  46. }
  47. if gregex.IsMatchString(`/github.com/[^/]+/gf/`, file) &&
  48. !gregex.IsMatchString(`/github.com/[^/]+/gf/\.example/`, file) {
  49. continue
  50. }
  51. if Ext(file) != ".go" {
  52. continue
  53. }
  54. lastFile = file
  55. if gregex.IsMatchString(`package\s+main`, GetContents(file)) {
  56. mainPkgPath.Set(Dir(file))
  57. return Dir(file)
  58. }
  59. } else {
  60. break
  61. }
  62. }
  63. if lastFile != "" {
  64. for path = Dir(lastFile); len(path) > 1 && Exists(path) && path[len(path)-1] != os.PathSeparator; {
  65. files, _ := ScanDir(path, "*.go")
  66. for _, v := range files {
  67. if gregex.IsMatchString(`package\s+main`, GetContents(v)) {
  68. mainPkgPath.Set(path)
  69. return path
  70. }
  71. }
  72. path = Dir(path)
  73. }
  74. }
  75. return ""
  76. }