// +build mage package main import ( "fmt" "io/ioutil" "os" "path/filepath" "runtime" "time" "github.com/magefile/mage/mg" "github.com/magefile/mage/sh" ) var ldflags = "-s -w -X main.version=$VERSION_TAG -X main.commit=$COMMIT_HASH -X main.date=$BUILD_TIME -X main.builtBy=$BUILDER" var Default = Generate func init() { // make sure we use Go 1.11 modules even if the source lives inside GOPATH os.Setenv("GO111MODULE", "on") } // Generate Go Bindings func Generate() error { mg.SerialDeps(RetrieveGodotDocumentation, Clean) apiPath := getCurrentFilePath() generateScript := filepath.Join(getCurrentFilePath(), "cmd", "generate", "main.go") err := sh.RunWith(map[string]string{"API_PATH": apiPath}, "go", "run", "-v", generateScript) if err != nil { return fmt.Errorf("could not genearate Go bindings: %w", err) } return Build() } // Clean cleans previous generations func Clean() error { fmt.Println("Cleaning previous generation...") path := filepath.Join(getCurrentFilePath(), "gdnative", "*.gen.*") files, globErr := filepath.Glob(path) if globErr != nil { return globErr } for _, filename := range files { if err := sh.Rm(filename); err != nil { return err } } return nil } // RetrieveGodotDocumentation retrieves latest Godot documentation to attach docstrings func RetrieveGodotDocumentation() error { localPath := getCurrentFilePath() docPath := filepath.Join(localPath, "doc") _, found := os.Stat(docPath) if found == nil { _ = os.Chdir(docPath) defer func() { _ = os.Chdir(localPath) }() fmt.Println("Godot documentation found. Pulling latest changes...") if err := sh.Run("git", "pull", "origin", "master"); err != nil { return fmt.Errorf("could not pull latest Godot documentation from git: %w", err) } return nil } fmt.Println("Godot documentation not found. Cloning the repository...") if err := os.MkdirAll(docPath, 0766); err != nil { return fmt.Errorf("could not create a new directory on the disk: %w", err) } _ = os.Chdir(docPath) defer func() { _ = os.Chdir(localPath) }() if err := sh.Run("git", "init"); err != nil { return fmt.Errorf("could not execute git init: %w", err) } if err := sh.Run("git", "remote", "add", "-f", "origin", "https://github.com/godotengine/godot.git"); err != nil { return fmt.Errorf("could not set origin remote for documentation: %w", err) } if err := sh.Run("git", "config", "core.sparseCheckout", "true"); err != nil { return fmt.Errorf("could not activate core.sparseCheckout: %w", err) } sparseCheckoutsConfigFile := filepath.Join(".", ".git", "info", "sparse-checkout") writeErr := ioutil.WriteFile(sparseCheckoutsConfigFile, []byte("doc/classes"), 0600) if writeErr != nil { return fmt.Errorf("could not write .git/info/sparse-checkout file: %w", writeErr) } if err := sh.Run("git", "pull", "origin", "master"); err != nil { return fmt.Errorf("error while pulling: %w", err) } return nil } // Build builds the gdnative-go compiler gogdc (also builds the library) func Build() error { return sh.RunWith(flagEnv(), "go", "build", "-ldflags", ldflags, "-x", "./cmd/gogdc") } // Install builds and installs the gdnative-go compiler gogdc in $GOPATH/bin func Install() error { return sh.RunWith(flagEnv(), "go", "install", "-ldflags", ldflags, "-x", "./cmd/gogdc") } // getCurrentFilePath constructs and returns the current file path on the drive func getCurrentFilePath() string { _, filename, _, ok := runtime.Caller(0) if !ok { panic(fmt.Errorf("could not get current file path")) } return filepath.Join(filepath.Dir(filename)) } // fills environment with build data func flagEnv() map[string]string { commitHash, _ := sh.Output("git", "rev-parse", "--short", "HEAD") buildAuthor, _ := sh.Output("git", "log", "-1", "--pretty=format:%ae") versionTag, _ := sh.Output("git", "describe", "--tags", "--abbrev=0") if versionTag == "" { versionTag = "v0.0.0-dev" } return map[string]string{ "COMMIT_HASH": commitHash, "VERSION_TAG": versionTag, "BUILD_TIME": time.Now().Format("2006-01-02T15:04:05Z0700"), "BUILDER": buildAuthor, "CGO_ENABLED": "1", } }