magefile.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // +build mage
  2. package main
  3. import (
  4. "fmt"
  5. "io/ioutil"
  6. "os"
  7. "path/filepath"
  8. "runtime"
  9. "time"
  10. "github.com/magefile/mage/mg"
  11. "github.com/magefile/mage/sh"
  12. )
  13. var ldflags = "-s -w -X main.version=$VERSION_TAG -X main.commit=$COMMIT_HASH -X main.date=$BUILD_TIME -X main.builtBy=$BUILDER"
  14. var Default = Generate
  15. func init() {
  16. // make sure we use Go 1.11 modules even if the source lives inside GOPATH
  17. os.Setenv("GO111MODULE", "on")
  18. }
  19. // Generate Go Bindings
  20. func Generate() error {
  21. mg.SerialDeps(RetrieveGodotDocumentation, Clean)
  22. apiPath := getCurrentFilePath()
  23. generateScript := filepath.Join(getCurrentFilePath(), "cmd", "generate", "main.go")
  24. err := sh.RunWith(map[string]string{"API_PATH": apiPath}, "go", "run", "-v", generateScript)
  25. if err != nil {
  26. return fmt.Errorf("could not genearate Go bindings: %w", err)
  27. }
  28. return Build()
  29. }
  30. // Clean cleans previous generations
  31. func Clean() error {
  32. fmt.Println("Cleaning previous generation...")
  33. path := filepath.Join(getCurrentFilePath(), "gdnative", "*.gen.*")
  34. files, globErr := filepath.Glob(path)
  35. if globErr != nil {
  36. return globErr
  37. }
  38. for _, filename := range files {
  39. if err := sh.Rm(filename); err != nil {
  40. return err
  41. }
  42. }
  43. return nil
  44. }
  45. // RetrieveGodotDocumentation retrieves latest Godot documentation to attach docstrings
  46. func RetrieveGodotDocumentation() error {
  47. localPath := getCurrentFilePath()
  48. docPath := filepath.Join(localPath, "doc")
  49. _, found := os.Stat(docPath)
  50. if found == nil {
  51. _ = os.Chdir(docPath)
  52. defer func() {
  53. _ = os.Chdir(localPath)
  54. }()
  55. fmt.Println("Godot documentation found. Pulling latest changes...")
  56. if err := sh.Run("git", "pull", "origin", "master"); err != nil {
  57. return fmt.Errorf("could not pull latest Godot documentation from git: %w", err)
  58. }
  59. return nil
  60. }
  61. fmt.Println("Godot documentation not found. Cloning the repository...")
  62. if err := os.MkdirAll(docPath, 0766); err != nil {
  63. return fmt.Errorf("could not create a new directory on the disk: %w", err)
  64. }
  65. _ = os.Chdir(docPath)
  66. defer func() {
  67. _ = os.Chdir(localPath)
  68. }()
  69. if err := sh.Run("git", "init"); err != nil {
  70. return fmt.Errorf("could not execute git init: %w", err)
  71. }
  72. if err := sh.Run("git", "remote", "add", "-f", "origin", "https://github.com/godotengine/godot.git"); err != nil {
  73. return fmt.Errorf("could not set origin remote for documentation: %w", err)
  74. }
  75. if err := sh.Run("git", "config", "core.sparseCheckout", "true"); err != nil {
  76. return fmt.Errorf("could not activate core.sparseCheckout: %w", err)
  77. }
  78. sparseCheckoutsConfigFile := filepath.Join(".", ".git", "info", "sparse-checkout")
  79. writeErr := ioutil.WriteFile(sparseCheckoutsConfigFile, []byte("doc/classes"), 0600)
  80. if writeErr != nil {
  81. return fmt.Errorf("could not write .git/info/sparse-checkout file: %w", writeErr)
  82. }
  83. if err := sh.Run("git", "pull", "origin", "master"); err != nil {
  84. return fmt.Errorf("error while pulling: %w", err)
  85. }
  86. return nil
  87. }
  88. // Build builds the gdnative-go compiler gogdc (also builds the library)
  89. func Build() error {
  90. return sh.RunWith(flagEnv(), "go", "build", "-ldflags", ldflags, "-x", "./cmd/gogdc")
  91. }
  92. // Install builds and installs the gdnative-go compiler gogdc in $GOPATH/bin
  93. func Install() error {
  94. return sh.RunWith(flagEnv(), "go", "install", "-ldflags", ldflags, "-x", "./cmd/gogdc")
  95. }
  96. // getCurrentFilePath constructs and returns the current file path on the drive
  97. func getCurrentFilePath() string {
  98. _, filename, _, ok := runtime.Caller(0)
  99. if !ok {
  100. panic(fmt.Errorf("could not get current file path"))
  101. }
  102. return filepath.Join(filepath.Dir(filename))
  103. }
  104. // fills environment with build data
  105. func flagEnv() map[string]string {
  106. commitHash, _ := sh.Output("git", "rev-parse", "--short", "HEAD")
  107. buildAuthor, _ := sh.Output("git", "log", "-1", "--pretty=format:%ae")
  108. versionTag, _ := sh.Output("git", "describe", "--tags", "--abbrev=0")
  109. if versionTag == "" {
  110. versionTag = "v0.0.0-dev"
  111. }
  112. return map[string]string{
  113. "COMMIT_HASH": commitHash,
  114. "VERSION_TAG": versionTag,
  115. "BUILD_TIME": time.Now().Format("2006-01-02T15:04:05Z0700"),
  116. "BUILDER": buildAuthor,
  117. "CGO_ENABLED": "1",
  118. }
  119. }