func resourceBuildToDir(ImportPackageList []string, tmpDirPath string) (response resourceBuildToDirResponse) { builder := &tBuilder{ pkgMap: map[string]*pkg{}, } for _, importPath := range ImportPackageList { builder.handlePkg(importPath) } for _, pkg := range builder.pkgDepOrder { builder.JsContent = append(builder.JsContent, pkg.JsContent...) builder.JsContent = append(builder.JsContent, byte('\n')) builder.CssContent = append(builder.CssContent, pkg.CssContent...) builder.CssContent = append(builder.CssContent, byte('\n')) } response.CssFileName = kmgCrypto.Md5Hex(builder.CssContent) + ".css" response.JsFileName = kmgCrypto.Md5Hex(builder.JsContent) + ".js" kmgFile.MustMkdir(tmpDirPath) kmgFile.MustWriteFile(filepath.Join(tmpDirPath, response.CssFileName), builder.CssContent) kmgFile.MustWriteFile(filepath.Join(tmpDirPath, response.JsFileName), builder.JsContent) for _, pkg := range builder.pkgDepOrder { for _, filePath := range pkg.ResourceFilePathList { kmgFile.MustWriteFile(filepath.Join(tmpDirPath, filepath.Base(filePath)), kmgFile.MustReadFile(filePath)) } } for _, pkg := range builder.pkgDepOrder { response.NeedCachePathList = append(response.NeedCachePathList, pkg.Dirpath) } response.ImportPackageList = ImportPackageList return response }
func tsetCompressor(compressor func(inb []byte) (outb []byte), decompressor func(inb []byte) (outb []byte)) { origin := []byte("123") ob := compressor([]byte("123")) output := decompressor(ob) kmgTest.Equal(origin, output) //for i:=1;i<20;i++ { // fmt.Println(kmgHex.UpperEncodeBytesToString(compressor(bytes.Repeat([]byte{'1'},i)))) //} //for i:=1;i<100;i++ { // fmt.Println(kmgHex.UpperEncodeBytesToString(compressor(kmgRand.MustCryptoRandBytes(i)))) //} for _, i := range []int{1, 10, 100, 1000, 1e4, 1e5} { ob = compressor(kmgRand.MustCryptoRandBytes(i)) fmt.Println(i, len(ob), len(ob)-i) } for _, path := range []string{ "/Users/bronze1man/tmp/vanke.sql", "/bin/kmg", } { c := kmgFile.MustReadFile(path) t := time.Now() ob = compressor(c) dur := time.Since(t) fmt.Println(path, kmgNet.SizeString(int64(len(c))), kmgNet.SizeString(int64(len(ob))), float64(len(ob))/float64(len(c)), dur) } fmt.Println() }
func TestGoTpl(ot *testing.T) { MustBuildTplInDir("testFile") files := kmgFile.MustGetAllFiles("testFile") AllCurrect := true ErrorMsg := "" for _, file := range files { if filepath.Ext(file) != ".gotplhtml" { continue } generated := kmgFile.MustReadFile(filepath.Join(filepath.Dir(file), kmgFile.GetFileBaseWithoutExt(file)+".go")) correct, err := kmgFile.ReadFile(filepath.Join(filepath.Dir(file), kmgFile.GetFileBaseWithoutExt(file)+".go.good")) if err != nil { ErrorMsg += fmt.Sprintf("%s read good file fail err [%s]\n", file, err) AllCurrect = false continue } if !bytes.Equal(generated, correct) { ErrorMsg += fmt.Sprintf("%s generated not equal correct\n", file) AllCurrect = false continue } } if !AllCurrect { panic(ErrorMsg) } }
func (b *tBuilder) parsePkg(packageName string) *pkg { thisPkg := &pkg{ PackageName: packageName, } thisPkg.Dirpath = path.Join(kmgConfig.DefaultEnv().GetFirstGOPATH(), "src", packageName) if !kmgFile.MustDirectoryExist(thisPkg.Dirpath) { panic("[kmgViewResource] can not found dir " + thisPkg.Dirpath) } fileList := kmgFile.MustGetAllFileOneLevel(thisPkg.Dirpath) for _, file := range fileList { ext := kmgFile.GetExt(file) if ext == ".js" { thisPkg.JsFilePathList = append(thisPkg.JsFilePathList, file) importPathList := parseImportPath(file, kmgFile.MustReadFile(file)) thisPkg.ImportPathList = kmgStrings.SliceNoRepeatMerge(thisPkg.ImportPathList, importPathList) } else if ext == ".css" { thisPkg.CssFilePathList = append(thisPkg.CssFilePathList, file) importPathList := parseImportPath(file, kmgFile.MustReadFile(file)) thisPkg.ImportPathList = kmgStrings.SliceNoRepeatMerge(thisPkg.ImportPathList, importPathList) } else if kmgStrings.IsInSlice(allowResourceExt, ext) { name := filepath.Base(file) if b.ResourceFileNameMap[name] { panic("[kmgViewResource] resource file name " + name + " repeat path " + file) } thisPkg.ResourceFilePathList = append(thisPkg.ResourceFilePathList, file) } } sort.Strings(thisPkg.JsFilePathList) sort.Strings(thisPkg.CssFilePathList) for _, file := range thisPkg.JsFilePathList { // 这个泄漏信息比较严重.暂时关掉吧. //thisPkg.JsContent = append(thisPkg.JsContent, []byte("\n/* "+file+" */\n\n")...) thisPkg.JsContent = append(thisPkg.JsContent, kmgFile.MustReadFile(file)...) thisPkg.JsContent = append(thisPkg.JsContent, byte('\n')) } for _, file := range thisPkg.CssFilePathList { //thisPkg.CssContent = append(thisPkg.CssContent, []byte("\n/* "+file+"*/\n\n")...) thisPkg.CssContent = append(thisPkg.CssContent, kmgFile.MustReadFile(file)...) thisPkg.CssContent = append(thisPkg.CssContent, byte('\n')) } return thisPkg }
func parseFile(pkgPath string, path string, pkg *Package) *File { gofile := &File{ PackagePath: pkgPath, ImportMap: map[string]bool{}, AliasImportMap: map[string]string{}, Pkg: pkg, } content := kmgFile.MustReadFile(path) posFile := kmgGoReader.NewPosFile(path, content) content = goSourceRemoveComment(content, posFile) r := kmgGoReader.NewReader(content, posFile) r.ReadAllSpace() r.MustReadMatch(tokenPackage) r.ReadUntilByte('\n') for { if r.IsEof() { return gofile //没有 import 正确情况 } r.ReadAllSpace() if r.IsMatchAfter(tokenImport) { gofile.readImport(r) continue } break } for { switch { case r.IsEof(): return gofile case r.IsMatchAfter(tokenFunc): funcDecl := gofile.readGoFunc(r) if funcDecl.GetKind() == Func { gofile.FuncList = append(gofile.FuncList, funcDecl) } else { gofile.MethodList = append(gofile.MethodList, funcDecl) } case r.IsMatchAfter(tokenType): //r.ReadUntilByte('\n') gofile.readGoType(r) case r.IsMatchAfter(tokenVar): gofile.readGoVar(r) case r.IsMatchAfter(tokenConst): gofile.readGoConst(r) // 有一些没有分析的代码,里面可能包含import,此处先简单绕过. case r.IsMatchAfter(tokenDoubleQuate) || r.IsMatchAfter(tokenGraveAccent): MustReadGoString(r) //fmt.Println(string(ret)) case r.IsMatchAfter(tokenSingleQuate): mustReadGoChar(r) default: r.ReadByte() } } }
func MustBuildTplInPathList(pathList []string) { for _, val := range pathList { ext := filepath.Ext(val) if ext == ".gotpl" { out, err := BuildTplOneFile(kmgFile.MustReadFile(val), false) if err != nil { panic(fmt.Sprintf("%s %s", val, err.Error())) } outFilePath := kmgFile.PathTrimExt(val) + ".go" kmgFile.MustWriteFile(outFilePath, out) } else if ext == ".gotplhtml" { out, err := BuildTplOneFile(kmgFile.MustReadFile(val), true) if err != nil { panic(fmt.Sprintf("%s %s", val, err.Error())) } outFilePath := kmgFile.PathTrimExt(val) + ".go" kmgFile.MustWriteFile(outFilePath, out) } } }
// 证实可用 func SetIpForwardOn() { if !kmgPlatform.IsLinux() { panic("[SetIpForwardOn] only support linux now") } kmgFile.MustWriteFile("/proc/sys/net/ipv4/ip_forward", []byte("1")) // 已经证实,多次写入不会出现任何问题. // TODO 正确解析/etc/sysctl.conf 如果后面又加一条 = 0 估计就挂了. if !bytes.Contains(kmgFile.MustReadFile("/etc/sysctl.conf"), []byte("\nnet.ipv4.ip_forward = 1")) { kmgFile.MustAppendFile("/etc/sysctl.conf", []byte("\nnet.ipv4.ip_forward = 1")) } }
func IsIpForwardOn() bool { if !kmgPlatform.IsLinux() { panic("[IsIpForwardOn] only support linux now") } b := kmgFile.MustReadFile("/proc/sys/net/ipv4/ip_forward") if bytes.Contains(b, []byte{'0'}) { return false } if bytes.Contains(b, []byte{'1'}) { return true } panic(fmt.Errorf("[IsIpForwardOn] unable to understand info in /proc/sys/net/ipv4/ip_forward %#v", b)) }
func MustBuildTplInDir(path string) { pathList, err := kmgFile.GetAllFiles(path) if err != nil { panic(err) } for _, val := range pathList { if filepath.Ext(val) != ".jst" { continue } out := MustBuildTplOneFile(kmgFile.MustReadFile(val)) outFilePath := kmgFile.PathTrimExt(val) + ".js" kmgFile.MustWriteFile(outFilePath, out) } }
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], "") }
//获得文件的MD5值 func MustMd5File(path string) string { content := kmgFile.MustReadFile(path) return Md5Hex(content) }
func runFileHttpServer() { listenAddr := "" path := "" key := "" flag.StringVar(&listenAddr, "l", ":80", "listen address") flag.StringVar(&path, "path", "", "root path of the file server") flag.StringVar(&key, "key", "", "crypto key use to encrypt all request of this server") flag.Parse() var err error if path == "" { path, err = os.Getwd() if err != nil { fmt.Printf("os.Getwd() fail %s", err) return } } else { kmgErr.PanicIfError(os.Chdir(path)) } if key == "" { http.Handle("/", http.FileServer(http.Dir(path))) } if key != "" { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { realPath := filepath.Join(path, r.URL.Path) if !kmgFile.MustFileExist(realPath) { w.Write([]byte("File Not Exist")) return } if !kmgStrings.IsInSlice(cacheFilePathSlice, realPath) { cacheFilePathSlice = append(cacheFilePathSlice, realPath) } updateCache := func() { cacheFilePathEncryptMap[realPath] = kmgCrypto.CompressAndEncryptBytesEncodeV2( kmgCrypto.Get32PskFromString(key), kmgFile.MustReadFile(realPath), ) } checkCache := func() { lock.Lock() defer lock.Unlock() kmgCache.MustMd5FileChangeCache(realPath, []string{realPath}, func() { updateCache() }) } checkCache() //进程重启后,内存中的缓存掉了,但是文件系统的缓存还在 _, exist := cacheFilePathEncryptMap[realPath] if !exist { updateCache() } w.Write(cacheFilePathEncryptMap[realPath]) }) } fmt.Println("start server at", listenAddr) err = http.ListenAndServe(listenAddr, nil) if err != nil { fmt.Printf("http.ListenAndServe() fail %s", err) return } return }