//go:build mage // +build mage package main import ( "bufio" "fmt" "io" "os" "os/exec" "path" "path/filepath" "strings" "text/template" "github.com/magefile/mage/mg" "github.com/magefile/mage/sh" ) // Default mage target var Default = Build var ( chocoPath = path.Join("chocolatey") binPath = path.Join("bin") chocoBinPath = path.Join("bin", "choco") chocoLegalPath = path.Join(chocoBinPath, "legal") chocoToolsPath = path.Join(chocoBinPath, "tools") chocoNuspec = path.Join(chocoBinPath, "windowsspyblocker.nuspec") wsbPath = path.Join(binPath, "WindowsSpyBlocker.exe") wsbEnv = map[string]string{ "GO111MODULE": "on", "GOOS": "windows", "GOARCH": "386", "CGO_ENABLED": "0", } ) // Build Run go build func Build() error { mg.Deps(Clean) mg.Deps(Generate) var args []string args = append(args, "build", "-o", wsbPath, "-v") args = append(args, "-ldflags", flags()) fmt.Println("⚙️ Go build...") if err := sh.RunWith(wsbEnv, mg.GoCmd(), args...); err != nil { return err } return nil } // Clean Remove files generated at build-time func Clean() error { if err := createDir(binPath); err != nil { return err } if err := cleanDir(binPath); err != nil { return err } return nil } // Download Run go mod download func Download() error { fmt.Println("⚙️ Go mod download...") if err := sh.RunWith(wsbEnv, mg.GoCmd(), "mod", "download"); err != nil { return err } return nil } // Generate Run go generate func Generate() error { mg.Deps(Download) mg.Deps(appConf) mg.Deps(manifest) mg.Deps(versionInfo) fmt.Println("⚙️ Go generate...") if err := sh.RunV(mg.GoCmd(), "generate", "-v"); err != nil { return err } return nil } // ChocoPack Run choco pack func ChocoPack() error { mg.Deps(ChocoPrepare) fmt.Println("⚙️ Chocolatey package...") choco, err := exec.LookPath("choco") if err != nil { return err } var args []string args = append(args, "pack", "--out", binPath) args = append(args, "--version", tag()) args = append(args, "--acceptlicense", "--yes") args = append(args, chocoNuspec) if err := sh.RunV(choco, args...); err != nil { return err } return nil } // ChocoPush Run choco push func ChocoPush() error { fmt.Println("⚙️ Chocolatey push...") choco, err := exec.LookPath("choco") if err != nil { return err } nupkg := fmt.Sprintf("windowsspyblocker.%s.nupkg", tag()) var args []string args = append(args, "push", path.Join(binPath, nupkg)) args = append(args, "--source", "https://package.chocolatey.org") args = append(args, "--apikey", os.Getenv("CHOCO_API_KEY")) args = append(args, "--acceptlicense", "--yes") if err := sh.RunV(choco, args...); err != nil { return err } return nil } // ChocoPrepare Generate chocolatey files func ChocoPrepare() error { fmt.Println("🔨 Generating Chocolatey files...") if err := createDir(chocoBinPath); err != nil { return err } if err := cleanDir(chocoBinPath); err != nil { return err } if err := copyDir(chocoPath, chocoBinPath); err != nil { return err } if err := createDir(chocoLegalPath); err != nil { return err } if err := copyFile("LICENSE", path.Join(chocoLegalPath, "LICENSE.txt")); err != nil { return err } if err := copyFile(wsbPath, path.Join(chocoToolsPath, "WindowsSpyBlocker.exe")); err != nil { return err } nuspec, err := os.ReadFile(chocoNuspec) if err != nil { return err } nuspecContent := strings.Replace(string(nuspec), "0.0.0", fmt.Sprintf("%s", tag()), -1) err = os.WriteFile(chocoNuspec, []byte(nuspecContent), 0) if err != nil { return err } return nil } // flags returns ldflags func flags() string { mod := mod() tag := tag() return fmt.Sprintf(`-s -w -X "%s/app/utils/config.AppVersion=%s"`, mod, tag) } // mod returns module name func mod() string { f, err := os.Open("go.mod") if err == nil { reader := bufio.NewReader(f) line, _, _ := reader.ReadLine() return strings.Replace(string(line), "module ", "", 1) } return "" } // tag returns the git tag for the current branch or "" if none. func tag() string { s, _ := sh.Output("bash", "-c", "git describe --abbrev=0 --tags 2> /dev/null") if s == "" { return "0.0.0" } return s } // hash returns the git hash for the current repo or "" if none. func hash() string { hash, _ := sh.Output("git", "rev-parse", "--short", "HEAD") return hash } // appConf generates app.conf file func appConf() error { fmt.Println("🔨 Generating app.conf...") var tpl = template.Must(template.New("").Parse(`{ "version": "{{ .Version }}", "debug": false, "useEmbeddedData": true, "proxifier": { "logPath": "C:/Users/[username]/Documents/Proxifier/Log.txt" }, "sysmon": { "evtxPath": "C:/WINDOWS/system32/winevt/Logs/Microsoft-Windows-Sysmon%4Operational.evtx" }, "wireshark": { "pcapngPath": "C:/Users/[username]/Documents/Wireshark/cap.pcapng", "capture": { "interface": 1, "filter": "not arp and port not 53 and not icmp and not icmp6 and not broadcast" } }, "exclude": { "ips": [ "0.0.0.0", "127.0.0.1", "192.168.0.0-192.168.0.255", "8.8.8.8", "8.8.4.4", "255.255.255.255" ], "hosts": [ "MyComputer", "localhost", "localhost.localdomain", "*.local", "yourISP.com", "*.yourISP.com", "wireshark.org", "*.wireshark.org" ], "orgs": [ "*facebook*" ] } } `)) f, err := os.Create("app.conf") if err != nil { return err } defer f.Close() return tpl.Execute(f, struct { Version string }{ Version: tag(), }) } // manifest generates manifest for versioninfo func manifest() error { fmt.Println("🔨 Generating app.manifest...") file, err := os.Create("app.manifest") if err != nil { return err } defer file.Close() _, err = io.WriteString(file, ` `) if err != nil { return err } return nil } // versionInfo generates versioninfo.json func versionInfo() error { fmt.Println("🔨 Generating versioninfo.json...") var tpl = template.Must(template.New("").Parse(`{ "FixedFileInfo": { "FileFlagsMask": "3f", "FileFlags ": "00", "FileOS": "040004", "FileType": "01", "FileSubType": "00" }, "StringFileInfo": { "Comments": "", "CompanyName": "", "FileDescription": "Block spying and tracking on Windows", "FileVersion": "{{ .Version }}.0", "InternalName": "", "LegalCopyright": "https://{{ .Package }}", "LegalTrademarks": "", "OriginalFilename": "WindowsSpyBlocker.exe", "PrivateBuild": "", "ProductName": "WindowsSpyBlocker", "ProductVersion": "{{ .Version }}.0", "SpecialBuild": "" }, "VarFileInfo": { "Translation": { "LangID": "0409", "CharsetID": "04B0" } } }`)) f, err := os.Create("versioninfo.json") if err != nil { return err } defer f.Close() return tpl.Execute(f, struct { Package string Version string }{ Package: mod(), Version: tag(), }) } func createDir(path string) error { if _, err := os.Stat(path); os.IsNotExist(err) { return os.MkdirAll(path, 777) } return nil } func cleanDir(dir string) error { d, err := os.Open(dir) if err != nil { return err } defer d.Close() names, err := d.Readdirnames(-1) if err != nil { return err } for _, name := range names { err = os.RemoveAll(filepath.Join(dir, name)) if err != nil { return err } } return nil } func copyDir(src string, dst string) error { var err error var srcinfo os.FileInfo if srcinfo, err = os.Stat(src); err != nil { return err } if err = os.MkdirAll(dst, srcinfo.Mode()); err != nil { return err } fds, err := os.ReadDir(src) if err != nil { return err } for _, fd := range fds { srcfp := path.Join(src, fd.Name()) dstfp := path.Join(dst, fd.Name()) if fd.IsDir() { if err = copyDir(srcfp, dstfp); err != nil { fmt.Println(err) } } else { if err = copyFile(srcfp, dstfp); err != nil { fmt.Println(err) } } } return nil } func copyFile(src string, dest string) error { srcFile, err := os.Open(src) if err != nil { return err } defer srcFile.Close() destFile, err := os.Create(dest) if err != nil { return err } defer destFile.Close() _, err = io.Copy(destFile, srcFile) if err != nil { return err } err = destFile.Sync() if err != nil { return err } return nil }