github.com/dennys-bd/goals@v0.0.0-20210328114421-251a004d41e3/cmd/project.go (about) 1 package cmd 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "runtime" 8 "strings" 9 10 "github.com/BurntSushi/toml" 11 "github.com/dennys-bd/goals/core" 12 errs "github.com/dennys-bd/goals/shortcuts/errors" 13 oss "github.com/dennys-bd/goals/shortcuts/os" 14 ) 15 16 type goalsToml struct { 17 Project core.Project 18 } 19 20 // newProject returns Project with specified project name. 21 func newProject(projectName string) *core.Project { 22 if projectName == "" { 23 errs.Ex("can't create project with blank name") 24 } 25 26 p := new(core.Project) 27 28 p.GoVersion = getGoVersion() 29 p.AppMode = "gateway" 30 31 // 1. Find already created protect. 32 p.AbsPath = findPackage(projectName) 33 34 // 2. If there are no created project with this path, and user is in GOPATH/src, 35 // then use working directory. 36 if p.AbsPath == "" { 37 wd, err := os.Getwd() 38 errs.CheckEx(err) 39 40 for _, srcPath := range srcPaths { 41 goPath := filepath.Dir(srcPath) 42 if filepathHasPrefix(wd, goPath) { 43 p.AbsPath = filepath.Join(wd, projectName) 44 break 45 } 46 } 47 } 48 49 // 3. If user is not in GOPATH, then use (first GOPATH)/src/projectName. 50 if p.AbsPath == "" { 51 p.AbsPath = filepath.Join(srcPaths[0], projectName) 52 } 53 54 p.Name = filepath.Base(p.AbsPath) 55 56 goPath := os.Getenv("GOPATH") + "/src/" 57 p.ImportPath = strings.TrimPrefix(p.AbsPath, goPath) 58 59 return p 60 } 61 62 // recreateProjectFromGoals return the project configs from Goals.toml 63 func recreateProjectFromGoals() core.Project { 64 wd, err := os.Getwd() 65 errs.CheckEx(err) 66 67 data, err := ioutil.ReadFile(filepath.Join(wd, "config/Goals.toml")) 68 if err != nil { 69 errs.Ex("This is not a goals project") 70 } 71 72 p, err := recreateProject(string(data)) 73 errs.CheckEx(err) 74 75 p.AbsPath = wd 76 77 return p 78 } 79 80 // recreateProject returns the project configs based on a Project String 81 func recreateProject(projectString string) (core.Project, error) { 82 var m goalsToml 83 _, err := toml.Decode(projectString, &m) 84 return m.Project, err 85 } 86 87 // findPackage returns full path to existing go package in GOPATHs. 88 func findPackage(packageName string) string { 89 for _, srcPath := range srcPaths { 90 packagePath := filepath.Join(srcPath, packageName) 91 if oss.Exists(packagePath) { 92 return packagePath 93 } 94 } 95 return "" 96 } 97 98 func filepathHasPrefix(path string, prefix string) bool { 99 if len(path) <= len(prefix) { 100 return false 101 } 102 if runtime.GOOS == "windows" { 103 // Paths in windows are case-insensitive. 104 return strings.EqualFold(path[0:len(prefix)], prefix) 105 } 106 return path[0:len(prefix)] == prefix 107 108 }