Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
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)
}