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  }