goc/pkg/build/tmpfolder.go
2020-05-26 00:21:54 +08:00

150 lines
3.8 KiB
Go

/*
Copyright 2020 Qiniu Cloud (qiniu.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package build
import (
"crypto/sha256"
"fmt"
"log"
"os"
"path/filepath"
"strings"
"github.com/qiniu/goc/pkg/cover"
)
func MvProjectsToTmp(target string, args []string) (newgopath string, newWorkingDir string, tmpBuildDir string, pkgs map[string]*cover.Package) {
listArgs := []string{"list", "-json"}
if len(args) != 0 {
listArgs = append(listArgs, args...)
}
listArgs = append(listArgs, "./...")
pkgs = cover.ListPackages(target, listArgs, "")
tmpBuildDir, newWorkingDir, isMod := mvProjectsToTmp(pkgs)
origopath := os.Getenv("GOPATH")
if isMod == true {
newgopath = ""
} else if origopath == "" {
newgopath = tmpBuildDir
} else {
newgopath = fmt.Sprintf("%v:%v", tmpBuildDir, origopath)
}
log.Printf("New GOPATH: %v", newgopath)
return
}
func mvProjectsToTmp(pkgs map[string]*cover.Package) (string, string, bool) {
path, err := os.Getwd()
if err != nil {
log.Fatalf("Cannot get current working directoy, the error is: %v", err)
}
tmpBuildDir := filepath.Join(os.TempDir(), TmpFolderName(path))
// Delete previous tmp folder and its content
os.RemoveAll(tmpBuildDir)
// Create a new tmp folder
err = os.MkdirAll(filepath.Join(tmpBuildDir, "src"), os.ModePerm)
if err != nil {
log.Fatalf("Fail to create the temporary build directory. The err is: %v", err)
}
log.Printf("Temp project generated in: %v", tmpBuildDir)
isMod := false
var tmpWorkingDir string
if checkIfLegacyProject(pkgs) {
cpLegacyProject(tmpBuildDir, pkgs)
tmpWorkingDir = getTmpwd(tmpBuildDir, pkgs, false)
} else {
cpGoModulesProject(tmpBuildDir, pkgs)
tmpWorkingDir = getTmpwd(tmpBuildDir, pkgs, true)
isMod = true
}
log.Printf("New working/building directory in: %v", tmpWorkingDir)
return tmpBuildDir, tmpWorkingDir, isMod
}
func TmpFolderName(path string) string {
sum := sha256.Sum256([]byte(path))
h := fmt.Sprintf("%x", sum[:6])
return "goc-" + h
}
// Check if it is go module project
// true legacy
// flase go mod
func checkIfLegacyProject(pkgs map[string]*cover.Package) bool {
for _, v := range pkgs {
if v.Module == nil {
return true
}
return false
}
log.Fatalln("Should never be reached....")
return false
}
func getTmpwd(tmpBuildDir string, pkgs map[string]*cover.Package, isMod bool) string {
for _, pkg := range pkgs {
path, err := os.Getwd()
if err != nil {
log.Fatalf("Cannot get current working directoy, the error is: %v", err)
}
index := -1
var parentPath string
if isMod == false {
index = strings.Index(path, pkg.Root)
parentPath = pkg.Root
} else {
index = strings.Index(path, pkg.Module.Dir)
parentPath = pkg.Module.Dir
}
if index == -1 {
log.Fatalf("goc install not executed in project directory.")
}
tmpwd := filepath.Join(tmpBuildDir, path[len(parentPath):])
// log.Printf("New building directory in: %v", tmpwd)
return tmpwd
}
log.Fatalln("Should never be reached....")
return ""
}
func FindWhereToInstall(pkgs map[string]*cover.Package) string {
if GOBIN := os.Getenv("GOBIN"); GOBIN != "" {
return GOBIN
}
// old GOPATH dir
GOPATH := os.Getenv("GOPATH")
if true == checkIfLegacyProject(pkgs) {
for _, v := range pkgs {
return filepath.Join(v.Root, "bin")
}
}
if GOPATH != "" {
return filepath.Join(strings.Split(GOPATH, ":")[0], "bin")
}
return filepath.Join(os.Getenv("HOME"), "go", "bin")
}