package devops import ( "fmt" "io/ioutil" "os" "path/filepath" "strings" "github.com/pkg/errors" ) // findProjectGoModFile finds the project root directory from the current working directory. func findProjectGoModFile() (string, error) { var err error projectRoot, err := os.Getwd() if err != nil { return "", errors.WithMessage(err, "failed to get current working directory") } // Try to find the project root for looking for the go.mod file in a parent directory. var goModFile string testDir := projectRoot for i := 0; i < 3; i++ { if goModFile != "" { testDir = filepath.Join(testDir, "../") } goModFile = filepath.Join(testDir, "go.mod") ok, _ := exists(goModFile) if ok { projectRoot = testDir break } } // Verify the go.mod file was found. ok, err := exists(goModFile) if err != nil { return "", errors.WithMessagef(err, "failed to load go.mod for project using project root %s") } else if !ok { return "", errors.Errorf("failed to locate project go.mod in project root %s", projectRoot) } return goModFile, nil } // findServiceDockerFile finds the service directory. func findServiceDockerFile(projectRoot, targetService string) (string, error) { checkDirs := []string{ filepath.Join(projectRoot, "cmd", targetService), filepath.Join(projectRoot, "tools", targetService), } var dockerFile string for _, cd := range checkDirs { // Check to see if directory contains Dockerfile. tf := filepath.Join(cd, "Dockerfile") ok, _ := exists(tf) if ok { dockerFile = tf break } } if dockerFile == "" { return "", errors.Errorf("failed to locate Dockerfile for service %s", targetService) } return dockerFile, nil } // getTargetEnv checks for an env var that is prefixed with the current target env. func getTargetEnv(targetEnv, envName string) string { k := fmt.Sprintf("%s_%s", strings.ToUpper(targetEnv), envName) if v := os.Getenv(k); v != "" { // Set the non prefixed env var with the prefixed value. os.Setenv(envName, v) return v } return os.Getenv(envName) } // loadGoModName parses out the module name from go.mod. func loadGoModName(goModFile string) (string, error) { ok, err := exists(goModFile) if err != nil { return "", errors.WithMessage(err, "Failed to load go.mod for project") } else if !ok { return "", errors.Errorf("Failed to locate project go.mod at %s", goModFile) } b, err := ioutil.ReadFile(goModFile) if err != nil { return "", errors.WithMessagef(err, "Failed to read go.mod at %s", goModFile) } var name string lines := strings.Split(string(b), "\n") for _, l := range lines { if strings.HasPrefix(l, "module ") { name = strings.TrimSpace(strings.Split(l, " ")[1]) break } } return name, nil } // exists returns a bool as to whether a file path exists. func exists(path string) (bool, error) { _, err := os.Stat(path) if err == nil { return true, nil } if os.IsNotExist(err) { return false, nil } return true, err } /* type EnvVars []string // execCmds executes a set of commands. func execCmds(workDir string, envVars *EnvVars, cmds ...[]string) ([]string, error) { if envVars == nil { ev := EnvVars(os.Environ()) envVars = &ev } var results []string for _, cmdVals := range cmds { cmd := exec.Command(cmdVals[0], cmdVals[1:]...) cmd.Dir = workDir cmd.Env = *envVars out, err := cmd.CombinedOutput() fmt.Println(string(out )) if err != nil { return results, errors.WithMessagef(err, "failed to execute %s\n%s", strings.Join(cmdVals, " "), string(out)) } results = append(results, string(out)) // Update the current env vars after command has been executed. ev := EnvVars(cmd.Env) envVars = &ev } return results, nil } */