func SshCertCopyCertToRemote(cert string, remoteList []RemoteServer) { kmgFile.MustWriteFile("/tmp/cert", []byte(cert)) defer kmgFile.MustDelete("/tmp/cert") for _, remote := range remoteList { cmd := []string{"ssh", "-t", "-p", strconv.Itoa(remote.SshPort), remote.UserName + "@" + remote.Address} kmgCmd.CmdSlice([]string{"scp", "-P", strconv.Itoa(remote.SshPort), "/tmp/cert", remote.UserName + "@" + remote.Address + ":~/"}).MustRun() authorizedKeysByte := kmgCmd.CmdSlice(append(cmd, "cat ~/.ssh/authorized_keys")).MustRunAndReturnOutput() if strings.Contains(string(authorizedKeysByte), cert) { fmt.Println("Cert has contains in authorized_keys") continue } kmgCmd.CmdSlice(append(cmd, "mkdir .ssh;cat cert >> .ssh/authorized_keys;rm cert")).MustRun() } }
func runGoCrossCompileInit() { kmgc, err := kmgConfig.LoadEnvFromWd() kmgConsole.ExitOnErr(err) GOROOT := kmgc.GOROOT if GOROOT == "" { //guess GOROOT out, err := exec.Command("go", "env", "GOROOT").CombinedOutput() kmgConsole.ExitOnErr(err) GOROOT = strings.TrimSpace(string(out)) if GOROOT == "" { kmgConsole.ExitOnErr(fmt.Errorf("you must set $GOROOT in environment to use GoCrossComplieInit")) } } var makeShellArgs []string var makeShellName string runCmdPath := filepath.Join(GOROOT, "src") if runtime.GOOS == "windows" { makeShellName = "cmd" makeShellArgs = []string{"/C", filepath.Join(GOROOT, "src", "make.bat"), "--no-clean"} } else { makeShellName = filepath.Join(GOROOT, "src", "make.bash") makeShellArgs = []string{"--no-clean"} } for _, target := range kmgc.CrossCompileTarget { err = kmgCmd.CmdSlice(append([]string{makeShellName}, makeShellArgs...)). MustSetEnv("GOOS", target.GetGOOS()). MustSetEnv("GOARCH", target.GetGOARCH()). SetDir(runCmdPath). Run() kmgConsole.ExitOnErr(err) } return }
// run go command in current project // 1.go build -i github.com/xxx/xxx use to get fastest speed of build. // 2.try remove pkg directory if you found you change is ignore. func GoCommand() { kmgc, err := kmgConfig.LoadEnvFromWd() kmgConsole.ExitOnErr(err) err = kmgCmd.CmdSlice(append([]string{"go"}, os.Args[1:]...)). MustSetEnv("GOPATH", kmgc.GOPATHToString()).StdioRun() kmgConsole.ExitOnErr(err) }
//不回显命令 func runCmdSliceWithGoPath(gopath string, cmdSlice []string) { err := kmgCmd.CmdSlice(cmdSlice). MustSetEnv("GOPATH", gopath).StdioRun() if err != nil { err = fmt.Errorf("kmg gorun: %s", err) kmgConsole.ExitOnErr(err) } }
func (command *GoTest) gobuild(path string) error { fmt.Printf("[gobuild] path[%s]\n", path) err := kmgCmd.CmdSlice([]string{"go", "build"}). MustSetEnv("GOPATH", command.gopath). SetDir(path). StdioRun() return err }
func CpuProfile(funcer func()) { selfPath, err := kmgSys.GetCurrentExecutePath() if err != nil { panic(err) } tmpPath := kmgFile.NewTmpFilePath() f, err := os.Create(tmpPath) if err != nil { panic(err) } defer f.Close() runtimePprof.StartCPUProfile(f) defer runtimePprof.StopCPUProfile() funcer() runtimePprof.StopCPUProfile() f.Close() kmgCmd.CmdSlice([]string{"go", "tool", "pprof", "-top", "-cum", selfPath, tmpPath}).MustRun() kmgCmd.CmdSlice([]string{"go", "tool", "pprof", "-top", "-cum", "-lines", selfPath, tmpPath}).MustRun() }
//返回这个导入路径的主Package的types.Package对象 //TODO 解决测试package的问题 func MustNewGoTypesMainPackageFromImportPath(importPath string) *types.Package { //TODO 去掉可编译要求? kmgCmd.CmdSlice([]string{"kmg", "go", "install", importPath}).MustRun() kmgCmd.CmdSlice([]string{"kmg", "go", "test", "-i", importPath}).MustRun() //TODO 解决需要预先创建pkg的问题. astPkg, fset := MustNewMainAstPackageFromImportPath(importPath) astFileList := []*ast.File{} for _, file := range astPkg.Files { astFileList = append(astFileList, file) } //os.Chdir(kmgConfig.DefaultEnv().ProjectPath) conf := &types.Config{ IgnoreFuncBodies: true, } pkg, err := conf.Check(importPath, fset, astFileList, nil) if err != nil { panic(err) } return pkg }
// 这个返回自己这个commit的名称,也返回所有父级commit的名称 func (repo *Repository) MustGetAllParentCommitId(commitId string) []string { output := kmgCmd.CmdSlice([]string{"git", "log", "--format=%H", commitId}).SetDir(repo.gitPath).MustCombinedOutput() outputSlice := []string{} for _, s := range strings.Split(string(output), "\n") { s = strings.TrimSpace(s) if s == "" { continue } outputSlice = append(outputSlice, s) } return outputSlice }
func RunCmdWithPassword(cmd, password string) { cmdTpl := `#!/usr/bin/expect -f spawn %s expect "assword:" send "%s\r" interact` cmd = fmt.Sprintf(cmdTpl, cmd, password) tmpName := kmgRand.MustCryptoRandToReadableAlphaNum(5) tmpPath := "/tmp/" + tmpName kmgFile.MustAppendFile(tmpPath, []byte(cmd)) defer kmgFile.MustDelete(tmpPath) os.Setenv("HOME", kmgSys.GetCurrentUserHomeDir()) kmgCmd.CmdSlice([]string{tmpPath}).MustStdioRun() }
//是否这个路径指向的东西在index里面存在(确切的文件) func (repo *Repository) MustIsFileInIndex(path string) bool { output := kmgCmd.CmdSlice([]string{"git", "ls-files", path}).SetDir(repo.gitPath).MustCombinedOutput() if len(output) == 0 { return false } for _, s := range strings.Split(string(output), "\n") { s = strings.TrimSpace(s) if s == "" { continue } if s == path { return true } } return false }
func (command *GoTest) gotest(path string) error { fmt.Printf("[gotest] path[%s]\n", path) args := []string{"test"} if command.v { args = append(args, "-v") } if command.bench != "" { args = append(args, "-bench", command.bench) } if command.runArg != "" { args = append(args, "-run", command.runArg) } return kmgCmd.CmdSlice(append([]string{"go"}, args...)). MustSetEnv("GOPATH", command.gopath). SetDir(path). StdioRun() }
func httpsCertCsrCLI() { domain := "" outDir := "" flag.StringVar(&domain, "domain", "", "the domain need to generate csr(google.com)") flag.StringVar(&outDir, "outDir", "", "the output dir(default to ./doc/cert/{domain})") flag.Parse() if domain == "" { flag.Usage() os.Exit(1) } if outDir == "" { outDir = "doc/cert/" + domain } kmgFile.Mkdir(outDir) kmgCmd.CmdSlice([]string{"openssl", "req", "-out", "domain.csr", "-new", "-newkey", "rsa:4096", "-nodes", "-keyout", "domain.key", "-subj", "/C=US/ST=US/L=US/O=US/OU=US/CN=" + domain + "/"}).SetDir(outDir).ProxyRun() }
/* GoCrossComplie [gofile] the output file will put into $project_root/bin/name_GOOS_GOARCH[.exe] */ func runGoCrossCompile() { command := GoCrossCompile{} flag.StringVar(&command.outputPath, "o", "", "output file dir(file name come from source file name),default to $project_root/bin") flag.StringVar(&command.version, "v", "", "version string in output file name") flag.StringVar(&command.platform, "platform", "", "platform(default use .kmg.yml config)") flag.Parse() if len(os.Args) <= 1 { kmgConsole.ExitOnErr(fmt.Errorf("need gofile parameter")) return } targetFile := flag.Arg(0) kmgc, err := kmgConfig.LoadEnvFromWd() kmgConsole.ExitOnErr(err) targetName := kmgFile.GetFileBaseWithoutExt(targetFile) if command.outputPath == "" { command.outputPath = filepath.Join(kmgc.ProjectPath, "bin") } targetList := []kmgConfig.CompileTarget{} if command.platform == "" { targetList = kmgc.CrossCompileTarget } else { targetList = []kmgConfig.CompileTarget{kmgConfig.CompileTarget(command.platform)} } for _, target := range targetList { fileName := "" if command.version == "" { fileName = targetName + "_" + target.GetGOOS() + "_" + target.GetGOARCH() } else { fileName = targetName + "_" + command.version + "_" + target.GetGOOS() + "_" + target.GetGOARCH() } if target.GetGOOS() == "windows" { fileName = fileName + ".exe" } outputFilePath := filepath.Join(command.outputPath, fileName) err := kmgCmd.CmdSlice([]string{"go", "build", "-i", "-o", outputFilePath, targetFile}). MustSetEnv("GOOS", target.GetGOOS()). MustSetEnv("GOARCH", target.GetGOARCH()). MustSetEnv("GOPATH", kmgc.GOPATHToString()). Run() kmgConsole.ExitOnErr(err) } return }
func MustSymlink(fromPath string, toPath string) { kmgCmd.CmdSlice([]string{"ln", "-sf", fromPath, toPath}).MustStdioRun() }
func (repo *Repository) MustSetRemoteUrl(branch string, url string) { kmgCmd.CmdSlice([]string{"git", "remote", "add", branch, url}).SetDir(repo.gitPath).MustStdioRun() }
func (repo *Repository) MustGetRemoteUrl(branch string) string { output := kmgCmd.CmdSlice([]string{"git", "ls-remote", "--get-url", branch}).SetDir(repo.gitPath).MustCombinedOutput() return strings.TrimSpace(string(output)) }
func (repo *Repository) MustIsFileIgnore(path string) bool { return kmgCmd.CmdSlice([]string{"git", "check-ignore", path}).SetDir(repo.gitPath). MustHiddenRunAndIsSuccess() }
func ProxyCommand(args ...string) func() { return func() { kmgCmd.CmdSlice(append(args, os.Args...)).ProxyRun() } }
func goRunInstall(goPath string, pathOrPkg string) { //只能更新本GOPATH里面的pkg,不能更多多个GOPATH里面其他GOPATH的pkg缓存. // go install 已知bug1 删除某个package里面的部分文件,然后由于引用到了旧的实现的代码,不会报错.删除pkg解决问题. // go install 已知bug2 如果一个package先是main,然后build了一个东西,然后又改成了非main,再gorun会使用旧的缓存/bin/里面的缓存. // TODO 已知bug3 当同一个项目的多个编译目标使用了同一个pkg,然后这个pkg变化了,缓存会出现A/B 问题,导致缓存完全无用. ctx := &goRunInstallContext{ platform: kmgPlatform.GetCompiledPlatform().String(), targetPkgMapCache: map[string]bool{}, pkgMapCache: map[string]*gorunCachePkgInfo{}, } ctx.targetCachePath = filepath.Join(goPath, "tmp", "gorun", kmgCrypto.Md5HexFromString("target_"+pathOrPkg+"_"+ctx.platform)) ctx.pkgCachePath = filepath.Join(goPath, "tmp", "gorun", "allPkgCache") ok := ctx.goRunInstallIsValidAndInvalidCache(goPath, pathOrPkg) if ok { //fmt.Println("use cache") return } //fmt.Println("not use cache") runCmdSliceWithGoPath(goPath, []string{"go", "install", pathOrPkg}) // 填充缓存 platform := ctx.platform ctx.targetPkgMapCache = map[string]bool{} outputJson := kmgCmd.CmdSlice([]string{"go", "list", "-json", pathOrPkg}). MustSetEnv("GOPATH", goPath).MustCombinedOutput() listObj := &struct { Deps []string Name string }{} kmgJson.MustUnmarshal(outputJson, &listObj) if listObj.Name != "main" { fmt.Printf("run non main package %s\n", pathOrPkg) return } listObj.Deps = append(listObj.Deps, pathOrPkg) for _, pkgName := range listObj.Deps { srcpkgPath := filepath.Join(goPath, "src", pkgName) fileList, err := kmgFile.ReadDirFileOneLevel(srcpkgPath) if err != nil { if !os.IsNotExist(err) { panic(err) } // 没有找到pkg,可能是这个pkg在GOROOT出现过,此处暂时不管. continue } ctx.targetPkgMapCache[pkgName] = true pkgInfo := &gorunCachePkgInfo{ GoFileMap: map[string]uint64{}, } for _, file := range fileList { ext := filepath.Ext(file) if ext == ".go" { pkgInfo.GoFileMap[file] = mustCheckSumFile(filepath.Join(srcpkgPath, file)) } } pkgInfo.IsMain = pkgName == pathOrPkg pkgInfo.Name = pkgName pkgBinPath := pkgInfo.getPkgBinPath(goPath, platform) pkgInfo.PkgMd5 = mustCheckSumFile(pkgBinPath) ctx.pkgMapCache[pkgName] = pkgInfo } kmgGob.MustWriteFile(ctx.targetCachePath, ctx.targetPkgMapCache) kmgGob.MustWriteFile(ctx.pkgCachePath, ctx.pkgMapCache) }
func NetworkConnection() (connectionCount int) { return networkConnection(string(kmgCmd.CmdSlice([]string{"bash", "-c", "netstat -na | grep ESTABLISHED | wc -l"}).MustCombinedOutput())) }
func (repo *Repository) MustIndexAddFile(path string) { kmgCmd.CmdSlice([]string{"git", "add", path}).SetDir(repo.gitPath).MustStdioRun() }
func (repo *Repository) MustIndexRemoveByPath(path string) { kmgCmd.CmdSlice([]string{"git", "rm", "--cached", "-rf", path}).SetDir(repo.gitPath).MustStdioRun() }
func (repo *Repository) MustResetToCommitId(commitId string) { kmgCmd.CmdSlice([]string{"git", "reset", commitId}).SetDir(repo.gitPath).MustStdioRun() }
func MustGitClone(url string, path string) { kmgCmd.CmdSlice([]string{"git", "clone", url, path}).MustRun() }