func GitTestCb(f func()) { oldwd, err := os.Getwd() if err != nil { panic(err) } defer func() { os.Chdir(oldwd) kmgFile.MustDelete("testFile") }() kmgFile.MustDelete("testFile") kmgFile.MustMkdir("testFile") os.Chdir("testFile") f() }
func TestFileTtlCache(t *testing.T) { kmgFile.MustDelete(getFileTtlCachePath("test_file_ttl_cache")) _, err := FileTtlCache("test_file_ttl_cache", func() (b []byte, ttl time.Duration, err error) { return []byte("1"), time.Millisecond, fmt.Errorf("error") }) kmgTest.Equal(err.Error(), "error") b, err := FileTtlCache("test_file_ttl_cache", func() (b []byte, ttl time.Duration, err error) { return []byte("1"), time.Millisecond, nil }) kmgTest.Equal(b, []byte("1")) kmgTest.Equal(err, nil) b, err = FileTtlCache("test_file_ttl_cache", func() (b []byte, ttl time.Duration, err error) { return []byte("2"), time.Millisecond, nil }) kmgTest.Equal(b, []byte("1")) kmgTest.Equal(err, nil) time.Sleep(time.Millisecond) b, err = FileTtlCache("test_file_ttl_cache", func() (b []byte, ttl time.Duration, err error) { return []byte("2"), time.Millisecond, nil }) kmgTest.Equal(b, []byte("2")) kmgTest.Equal(err, nil) }
func (fm *FileMutex) UnLock() { if !fm.isOwner { return } fm.isOwner = false kmgFile.MustDelete(fm.filePath) }
//从 .gitFakeSubmodule 中还原旧的fakeSubmoudle,并且将所有子项目都切换到该文件里面写的分支(使用reset切分支,保证不掉数据) func (repo *Repository) MustFakeSubmoduleUpdate() { rootPath := repo.gitPath SubmoduleList := map[string]SubRepositoryInfo{} kmgJson.MustReadFile(filepath.Join(rootPath, ".gitFakeSubmodule"), &SubmoduleList) for repoPath, SubmoduleInfo := range SubmoduleList { repoRealPath := filepath.Join(rootPath, repoPath) //子项目存在? if !MustIsRepositoryAtPath(repoRealPath) { tmpPath := filepath.Join(repoRealPath, kmgRand.MustCryptoRandToHex(8)) kmgFile.MustMkdir(tmpPath) MustGitClone(SubmoduleInfo.RemoteUrl, tmpPath) kmgFile.MustRename(filepath.Join(tmpPath, ".git"), filepath.Join(repoRealPath, ".git")) kmgFile.MustDelete(tmpPath) } //子项目的远程路径正确? subRepo := MustGetRepositoryFromPath(repoRealPath) if subRepo.MustGetRemoteUrl("origin") != SubmoduleInfo.RemoteUrl { subRepo.MustSetRemoteUrl("origin", SubmoduleInfo.RemoteUrl) } //子项目的版本号正确? if subRepo.MustGetHeadCommitId() != SubmoduleInfo.CommitId { subRepo.MustResetToCommitId(SubmoduleInfo.CommitId) } } }
func installGolangWithUrlMap(urlMap map[string]string) { p := kmgPlatform.GetCompiledPlatform() if p.Compatible(kmgPlatform.WindowsAmd64) { contentB, err := kmgHttp.UrlGetContent(urlMap["windows_amd64"]) kmgConsole.ExitOnErr(err) kmgFile.MustDelete(`c:\go`) err = kmgCompress.ZipUncompressFromBytesToDir(contentB, `c:\go`, "go") kmgConsole.ExitOnErr(err) err = kmgFile.CopyFile(`c:\go\bin\go.exe`, `c:\windows\system32\go.exe`) kmgConsole.ExitOnErr(err) err = kmgFile.CopyFile(`c:\go\bin\godoc.exe`, `c:\windows\system32\godoc.exe`) kmgConsole.ExitOnErr(err) err = kmgFile.CopyFile(`c:\go\bin\gofmt.exe`, `c:\windows\system32\gofmt.exe`) kmgConsole.ExitOnErr(err) return } tmpPath := kmgFile.MustChangeToTmpPath() defer kmgFile.MustDelete(tmpPath) if !kmgSys.MustIsRoot() { fmt.Println("you need to be root to install golang") return } url, ok := urlMap[p.String()] if !ok { kmgConsole.ExitOnErr(fmt.Errorf("not support platform [%s]", p)) } packageName := path.Base(url) contentB := kmgHttp.MustUrlGetContentProcess(url) kmgFile.MustWriteFile(packageName, contentB) kmgCmd.ProxyRun("tar -xf " + packageName) if kmgFile.MustFileExist("/usr/local/go") { kmgCmd.ProxyRun("mv /usr/local/go /usr/local/go.bak." + time.Now().Format(kmgTime.FormatFileNameV2)) } kmgCmd.ProxyRun("cp -rf go /usr/local") kmgFile.MustDeleteFile("/bin/go") kmgCmd.ProxyRun("ln -s /usr/local/go/bin/go /bin/go") kmgFile.MustDeleteFile("/bin/godoc") kmgCmd.ProxyRun("ln -s /usr/local/go/bin/godoc /bin/godoc") kmgFile.MustDeleteFile("/bin/gofmt") kmgCmd.ProxyRun("ln -s /usr/local/go/bin/gofmt /bin/gofmt") kmgFile.MustEnsureBinPath("/bin/go") kmgFile.MustEnsureBinPath("/bin/godoc") kmgFile.MustEnsureBinPath("/bin/gofmt") }
func TestMustMd5File(t *testing.T) { kmgFile.MustDelete("testFile") kmgFile.MustWriteFile("testFile", []byte("1")) md5name := MustMd5File("testFile") kmgTest.Equal(md5name, "c4ca4238a0b923820dcc509a6f75849b") kmgFile.MustWriteFile("testFile", []byte(md5name)) }
func TestMustGenerateCode(t *testing.T) { kmgGoTpl.MustBuildTplInDirWithCache("src/github.com/bronze1man/kmg/kmgRpc") // 模板变化需要运行两次,才能看到结果. kmgFile.MustDelete("testPackage/generated.go") MustGenerateCode(&GenerateRequest{ ObjectPkgPath: "github.com/bronze1man/kmg/kmgRpc/testPackage", ObjectName: "Demo", ObjectIsPointer: true, OutFilePath: "testPackage/generated.go", OutPackageImportPath: "github.com/bronze1man/kmg/kmgRpc/testPackage", }) kmgCmd.CmdString("kmg go test").SetDir("testPackage").Run() }
func ResourceBuild(req *ResourceUploadRequest) { if req.Name == "" { panic(`[ResourceBuild] req.Name == ""`) } tmpDirPath := kmgConfig.DefaultEnv().PathInTmp("kmgViewResource_build/" + req.Name) kmgFile.MustDelete(tmpDirPath) response := resourceBuildToDir(req.ImportPathList, tmpDirPath) req.Qiniu.MustUploadFromFile(tmpDirPath, req.QiniuPrefix) packageName := filepath.Base(filepath.Dir(req.OutGoFilePath)) urlPrefix := req.Qiniu.GetSchemeAndDomain() + "/" + req.QiniuPrefix //jsUrl:=urlPrefix+"/"+response.JsFileName //cssUrl:=urlPrefix+"/"+response.CssFileName // 不可以使用 fmt.Sprintf("%#v",generated) 会导出私有变量. //generated:=&Generated{ // Name: req.Name, // GeneratedJsFileUrl: jsUrl, // GeneratedCssFileUrl: cssUrl, // GeneratedUrlPrefix: urlPrefix, // RequestImportList: req.ImportPathList, //} outGoContent := []byte(`package ` + packageName + ` import ( "github.com/bronze1man/kmg/kmgView/kmgViewResource" "sync" ) var ` + req.Name + `Once sync.Once var ` + req.Name + `generated *kmgViewResource.Generated func get` + req.Name + `ViewResource() *kmgViewResource.Generated{ ` + req.Name + `Once.Do(func(){ ` + req.Name + `generated = &kmgViewResource.Generated{ Name: ` + fmt.Sprintf("%#v", req.Name) + `, GeneratedJsFileName: ` + fmt.Sprintf("%#v", response.JsFileName) + `, GeneratedCssFileName: ` + fmt.Sprintf("%#v", response.CssFileName) + `, GeneratedUrlPrefix: ` + fmt.Sprintf("%#v", urlPrefix) + `, RequestImportList: ` + fmt.Sprintf("%#v", req.ImportPathList) + `, } ` + req.Name + `generated.Init() }) return ` + req.Name + `generated } `) outGoContent, err := kmgFormat.Source(outGoContent) if err != nil { panic(err) } kmgFile.MustWriteFile(req.OutGoFilePath, outGoContent) }
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() }
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 TestGitFixNameCaseWithDirectory(ot *testing.T) { oldWd, err := os.Getwd() kmgTest.Equal(err, nil) kmgFile.MustDelete("testfile") kmgFile.MustWriteFileWithMkdir("testfile/a/a.txt", []byte("abc")) os.Chdir("testfile") defer os.Chdir(oldWd) kmgCmd.MustRun("git init") kmgCmd.MustRun("git add -A") kmgCmd.MustRun("git commit -am'save'") err = os.Rename("a", "A") kmgTest.Equal(err, nil) err = GitFixNameCase(filepath.Join(oldWd, "testfile")) kmgTest.Equal(err, nil) kmgCmd.MustRun("git status") kmgCmd.MustRun("git add -A") kmgCmd.MustRun("git commit -am'save'") }
func TestFileMd5ChangeCacheSymlink(t *testing.T) { callLog := make([]string, 32) //递归可用 kmgFile.MustDeleteFile(getFileChangeCachePath("test_file_change_cache")) kmgFile.MustDelete("testFile") kmgFile.MustWriteFileWithMkdir("testFile/d1/d2", []byte("1")) kmgCmd.MustRun("ln -s d1 testFile/d3") MustMd5FileChangeCache("test_file_change_cache", []string{ "testFile", }, func() { callLog[0] = "f3" }) kmgTest.Equal(callLog[0], "f3") MustMd5FileChangeCache("test_file_change_cache", []string{ "testFile", }, func() { callLog[1] = "f3" }) kmgTest.Equal(callLog[1], "") }
func (ctx *goRunInstallContext) goRunInstallIsValidAndInvalidCache(goPath string, pathOrPkg string) bool { err := kmgGob.ReadFile(ctx.targetCachePath, &ctx.targetPkgMapCache) if err != nil { //此处故意忽略错误 没有缓存文件 TODO 此处需要折腾其他东西吗? return false } err = kmgGob.ReadFile(ctx.pkgCachePath, &ctx.pkgMapCache) if err != nil { //此处故意忽略错误 没有缓存文件 return false } //kmgDebug.Println(info) isValid := true task := kmgTask.NewLimitThreadTaskManager(runtime.NumCPU()) for pkgName := range ctx.targetPkgMapCache { pkgName := pkgName task.AddFunc(func() { pkgInfo, ok := ctx.pkgMapCache[pkgName] if !ok { // 缓存不一致,删文件? pkgPath := filepath.Join("pkg", ctx.platform, pkgName+".a") if debug { fmt.Println("pkgname not found in pkgMapCache delete ", pkgPath) } kmgFile.MustDelete(pkgPath) isValid = false return } pkgPath := pkgInfo.getPkgBinPath(goPath, ctx.platform) if !checkFileWithMd5(pkgPath, pkgInfo.PkgMd5) { if debug { oldMd5 := uint64(0) if kmgFile.MustFileExist(pkgPath) { oldMd5 = mustCheckSumFile(pkgPath) } fmt.Println("pkgBinFile md5 not equal delete ", pkgPath, pkgInfo.PkgMd5, oldMd5) } kmgFile.MustDelete(pkgPath) isValid = false return } srcpkgPath := filepath.Join(goPath, "src", pkgName) fileList, err := kmgFile.ReadDirFileOneLevel(srcpkgPath) if err != nil { if !os.IsNotExist(err) { panic(err) } kmgFile.MustDelete(pkgPath) if debug { fmt.Println("dir not exist File delete ", pkgPath, srcpkgPath) } isValid = false return } isThisPkgValid := true for _, file := range fileList { ext := filepath.Ext(file) if ext == ".go" { // 多了一个文件 _, ok := pkgInfo.GoFileMap[file] if !ok { kmgFile.MustDelete(pkgPath) if debug { fmt.Println("more file ", file, " delete ", pkgPath) } isValid = false isThisPkgValid = false break } } } if !isThisPkgValid { return } for name, md5 := range pkgInfo.GoFileMap { goFilePath := filepath.Join(srcpkgPath, name) if !checkFileWithMd5(goFilePath, md5) { kmgFile.MustDelete(pkgPath) if debug { fmt.Println("gofile not match ", name, " delete ", pkgPath) } isValid = false break } } }) } task.Close() return isValid }
func TestFileMd5ChangeCacheOneDir(t *testing.T) { callLog := make([]string, 32) //递归可用 kmgFile.MustDeleteFile(getFileChangeCachePath("test_file_change_cache")) kmgFile.MustDelete("testFile/d1") kmgFile.MustMkdirAll("testFile/d1/d2") kmgFile.MustWriteFile("testFile/d1/d2/f3", []byte("1")) MustMd5FileChangeCache("test_file_change_cache", []string{ "testFile/d1", }, func() { callLog[3] = "f3" }) kmgTest.Equal(callLog[3], "f3") //没有碰过任何东西,缓存有效 MustMd5FileChangeCache("test_file_change_cache", []string{ "testFile/d1", }, func() { callLog[4] = "f3" }) kmgTest.Equal(callLog[4], "") //修改文件内容,缓存应该无效 kmgFile.MustWriteFile("testFile/d1/d2/f3", []byte("2")) MustMd5FileChangeCache("test_file_change_cache", []string{ "testFile/d1", }, func() { callLog[5] = "f3" }) kmgTest.Equal(callLog[5], "f3") //删除文件,缓存应该无效 kmgFile.MustDelete("testFile/d1/d2/f3") MustMd5FileChangeCache("test_file_change_cache", []string{ "testFile/d1", }, func() { callLog[6] = "f4" }) kmgTest.Equal(callLog[6], "f4") //添加文件,缓存应该无效 kmgFile.MustWriteFile("testFile/d1/d2/f4", []byte("3")) MustMd5FileChangeCache("test_file_change_cache", []string{ "testFile/d1", }, func() { callLog[7] = "f4" }) kmgTest.Equal(callLog[7], "f4") //读取文件,缓存有效 kmgFile.MustReadFile("testFile/d1/d2/f4") MustMd5FileChangeCache("test_file_change_cache", []string{ "testFile/d1", }, func() { callLog[8] = "f4" }) kmgTest.Equal(callLog[8], "") //创建目录,缓存有效 kmgFile.MustMkdir("testFile/d1/d2/f5") MustMd5FileChangeCache("test_file_change_cache", []string{ "testFile/d1", }, func() { callLog[9] = "f4" }) kmgTest.Equal(callLog[9], "") }
func TestGoRunFile(ot *testing.T) { wd, err := os.Getwd() if err != nil { panic(err) } defer os.Chdir(wd) root := kmgConfig.DefaultEnv().ProjectPath os.Chdir(root) kmgPath := filepath.Join(root, "bin/kmg") kmgFile.MustDelete(kmgPath) //kmgCmd.MustRun("kmg go install github.com/bronze1man/kmg/kmg") gopath := filepath.Join(wd, "testWorkspace") os.Chdir(gopath) kmgFile.MustDelete(filepath.Join(gopath, "bin")) kmgFile.MustDelete(filepath.Join(gopath, "pkg")) kmgFile.MustDelete(filepath.Join(gopath, "tmp")) kmgFile.MustDelete(filepath.Join(gopath, "src", "kmgTestMain", "other.go")) goRunInstall(gopath, "kmgTestMain") output := kmgCmd.MustRunAndReturnOutput(filepath.Join(gopath, "bin", "kmgTestMain")) kmgTest.Equal(string(output), "1\n") kmgFile.MustWriteFile(filepath.Join(wd, "testWorkspace", "src", "kmgTestMain", "other.go"), []byte(` package main func init(){ a=2 } `)) goRunInstall(gopath, "kmgTestMain") output = kmgCmd.MustRunAndReturnOutput(filepath.Join(gopath, "bin", "kmgTestMain")) kmgTest.Equal(string(output), "2\n") kmgFile.MustDelete(filepath.Join(wd, "testWorkspace", "src", "kmgTestMain", "other.go")) goRunInstall(gopath, "kmgTestMain") output = kmgCmd.MustRunAndReturnOutput(filepath.Join(gopath, "bin", "kmgTestMain")) kmgTest.Equal(string(output), "1\n") goRunInstall(gopath, "kmgTestMain/l2Main") output = kmgCmd.MustRunAndReturnOutput(filepath.Join(gopath, "bin", "l2Main")) kmgTest.Equal(string(output), "l2Main\n") kmgFile.MustWriteFile(filepath.Join(gopath, "src", "replaceBin", "replaceBin.go"), []byte(` package main import "fmt" func main(){ fmt.Println("replaceBin") } `)) goRunInstall(gopath, "replaceBin") output = kmgCmd.MustRunAndReturnOutput(filepath.Join(gopath, "bin", "replaceBin")) kmgTest.Equal(string(output), "replaceBin\n") kmgFile.MustWriteFile(filepath.Join(gopath, "src", "replaceBin", "replaceBin.go"), []byte(` package replaceBin var A = "1" `)) goRunInstall(gopath, "replaceBin") // 应该会说这个不是main的package }