Example #1
0
func runCommand(kmgc *kmgConfig.Env, args []string) {
	os.Chdir(kmgc.ProjectPath)
	logDir := filepath.Join(kmgc.LogPath, "run")
	kmgFile.MustMkdirAll(logDir)
	thisLogFilePath := filepath.Join(logDir, time.Now().Format(kmgTime.FormatFileName)+".log")
	kmgFile.MustWriteFile(thisLogFilePath, []byte{})
	if !kmgPlatform.GetCompiledPlatform().Compatible(kmgPlatform.WindowsAmd64) {
		lastLogPath := filepath.Join(logDir, "last.log")
		if kmgFile.MustFileExist(lastLogPath) {
			kmgFile.MustSymlink(kmgFile.MustReadSymbolLink(lastLogPath), filepath.Join(logDir, "last2.log"))
		}
		kmgFile.MustSymlink(filepath.Base(thisLogFilePath), lastLogPath)
	}
	//TODO 大部分命令是 kmg gorun xxx 在这个地方可以直接调用gorun解决问题,这样可以少开一个进程加快了一些速度
	// 问题: 上述做法不靠谱,会导致last.log没有用处.
	//if len(args) >= 2 && args[0] == "kmg" && strings.EqualFold(args[1], "gorun") {
	//	os.Args = append(args[1:], os.Args[1:]...)
	//	goCmd.GoRunCmd()
	//	return
	//}
	// 下面的做法不靠谱,会让signle无法传递
	//err := kmgCmd.CmdSlice(append(args, os.Args[1:]...)).
	//	SetDir(kmgc.ProjectPath).
	//	RunAndTeeOutputToFile(thisLogFilePath)
	// TODO bash转义
	bashCmd := strings.Join(append(args, os.Args[1:]...), " ")
	bashCmdStr := bashCmd + " 2>&1 | tee -i " + thisLogFilePath + " ; test ${PIPESTATUS[0]} -eq 0"
	if kmgPlatform.IsWindows() {
		err := kmgCmd.CmdString(bashCmdStr).SetDir(kmgc.ProjectPath).StdioRun()
		if err != nil {
			err = fmt.Errorf("kmg make: %s", err)
			kmgConsole.ExitOnErr(err)
		}
		return
	} else {
		err := kmgCmd.CmdBash(bashCmdStr).SetDir(kmgc.ProjectPath).StdioRun()
		if err != nil {
			err = fmt.Errorf("kmg make: %s", err)
			kmgConsole.ExitOnErr(err)
		}
		return
	}
}
Example #2
0
// key 表示一组缓存,pathList 即这组缓存相关的文件
// 比较容易用错的情况:
// key := 1
// pathList := []string{"/a.txt","/b.txt"}
// a.txt 或者 b.txt 中任意有文件发生变化,这个 key 对应的缓存都会被更新
// 如果要对单个文件进行缓存控制,那么应该一个文件一个 key
func MustMd5FileChangeCache(key string, pathList []string, f func()) {
	// 此处需要考虑,
	//   用户新添加了一个文件
	//   用户删除了一个文件
	//   用户编辑了一个文件
	//   用户在目录里面添加了一个文件
	//   用在在目录里面删除了一个文件
	//读取文件修改时间缓存信息
	toChange := false
	cacheInfo := map[string]string{}
	cacheFilePath := getFileChangeCachePath(key)
	err := kmgGob.ReadFile(cacheFilePath, &cacheInfo)
	if err != nil {
		//忽略缓存读取的任何错误
		cacheInfo = map[string]string{}
	}
	hasReadFileMap := map[string]bool{}
	for _, path := range pathList {
		statList, err := kmgFile.GetAllFileAndDirectoryStat(path)
		if err != nil {
			if os.IsNotExist(err) {
				toChange = true
				//fmt.Printf("[MustFileChangeCache] path:[%s] not exist\n", path)
				break
			}
			panic(err)
		}

		for _, stat := range statList {
			if stat.Fi.IsDir() {
				continue
			}
			hasReadFileMap[stat.FullPath] = true
			if stat.Fi.Mode()&os.ModeSymlink == os.ModeSymlink {
				if "symlink_"+kmgFile.MustReadSymbolLink(stat.FullPath) != cacheInfo[stat.FullPath] {
					toChange = true
					break
				}
				continue
			}
			if kmgCrypto.MustMd5File(stat.FullPath) != cacheInfo[stat.FullPath] {
				toChange = true
				//fmt.Printf("[MustMd5FileChangeCache] path:[%s] mod md5 not match save[%s] file[%s]\n", stat.FullPath,
				//	cacheMd5, kmgCrypto.MustMd5File(stat.FullPath))
				break
			}
		}
		if toChange {
			break
		}
	}
	//删除一个已经存储在缓存列表里面的文件,是一个修改.
	for fullPath := range cacheInfo {
		if !hasReadFileMap[fullPath] {
			toChange = true
			break
		}
	}
	if !toChange {
		return
	}
	f()
	cacheInfo = map[string]string{}
	for _, path := range pathList {
		statList, err := kmgFile.GetAllFileAndDirectoryStat(path)
		if err != nil {
			panic(err)
		}
		for _, stat := range statList {
			if stat.Fi.IsDir() {
				continue
			}
			if stat.Fi.Mode()&os.ModeSymlink == os.ModeSymlink {
				linkToPath := kmgFile.MustReadSymbolLink(stat.FullPath)
				cacheInfo[stat.FullPath] = "symlink_" + linkToPath
				continue
			}
			cacheInfo[stat.FullPath] = kmgCrypto.MustMd5File(stat.FullPath)
		}
	}
	kmgFile.MustMkdirForFile(cacheFilePath)
	kmgGob.MustWriteFile(cacheFilePath, cacheInfo)
	//保存文件缓存信息
	return
}