diff --git a/Formula/profilecli.rb b/Formula/profilecli.rb index ab3f1f1..18f45e2 100644 --- a/Formula/profilecli.rb +++ b/Formula/profilecli.rb @@ -1,3 +1,4 @@ +# Do not edit .rb file manually, edit .rb.tpl instead class Profilecli < Formula desc "Open source continuous profiling software" homepage "https://grafana.com/oss/pyroscope/" diff --git a/Formula/profilecli.rb.tpl b/Formula/profilecli.rb.tpl new file mode 100644 index 0000000..b8a0b9f --- /dev/null +++ b/Formula/profilecli.rb.tpl @@ -0,0 +1,59 @@ +# Do not edit .rb file manually, edit .rb.tpl instead +class Profilecli < Formula + desc "Open source continuous profiling software" + homepage "https://grafana.com/oss/pyroscope/" + version "{{.Version}}" + license "AGPL-3.0-only" + + on_macos do + if Hardware::CPU.intel? + url "https://github.com/grafana/pyroscope/releases/download/{{.Tag}}/profilecli_{{.Version}}_darwin_amd64.tar.gz" + sha256 "{{.DarwinAmd64}}" + + def install + bin.install "profilecli" + end + end + if Hardware::CPU.arm? + url "https://github.com/grafana/pyroscope/releases/download/{{.Tag}}/profilecli_{{.Version}}_darwin_arm64.tar.gz" + sha256 "{{.DarwinArm64}}" + + def install + bin.install "profilecli" + end + end + end + + on_linux do + if Hardware::CPU.intel? + url "https://github.com/grafana/pyroscope/releases/download/{{.Tag}}/profilecli_{{.Version}}_linux_amd64.tar.gz" + sha256 "{{.LinuxAmd64}}" + + def install + bin.install "profilecli" + end + end + if Hardware::CPU.arm? + if Hardware::CPU.is_64_bit? + url "https://github.com/grafana/pyroscope/releases/download/{{.Tag}}/profilecli_{{.Version}}_linux_arm64.tar.gz" + sha256 "{{.LinuxArm64}}" + + def install + bin.install "profilecli" + end + end + unless Hardware::CPU.is_64_bit? + url "https://github.com/grafana/pyroscope/releases/download/{{.Tag}}/profilecli_{{.Version}}_linux_armv7.tar.gz" + sha256 "{{.LinuxArmv7}}" + + def install + bin.install "profilecli" + end + end + end + end + + test do + system bin/"profilecli", "--version" + end +end diff --git a/Formula/pyroscope.rb b/Formula/pyroscope.rb index b406f6b..10c023e 100644 --- a/Formula/pyroscope.rb +++ b/Formula/pyroscope.rb @@ -1,3 +1,4 @@ +# Do not edit .rb file manually, edit .rb.tpl instead class Pyroscope < Formula desc "Open source continuous profiling software" homepage "https://grafana.com/oss/pyroscope/" diff --git a/Formula/pyroscope.rb.tpl b/Formula/pyroscope.rb.tpl new file mode 100644 index 0000000..0fa8303 --- /dev/null +++ b/Formula/pyroscope.rb.tpl @@ -0,0 +1,85 @@ +# Do not edit .rb file manually, edit .rb.tpl instead +class Pyroscope < Formula + desc "Open source continuous profiling software" + homepage "https://grafana.com/oss/pyroscope/" + version "{{.Version}}" + license "AGPL-3.0-only" + + def pyroscope_conf + <<~EOS + --- + pyroscopedb: + data_path: #{var}/lib/pyroscope + EOS + end + + on_macos do + if Hardware::CPU.intel? + url "https://github.com/grafana/pyroscope/releases/download/{{.Tag}}/pyroscope_{{.Version}}_darwin_amd64.tar.gz" + sha256 "{{.DarwinAmd64}}" + + def install + bin.install "pyroscope" + end + end + if Hardware::CPU.arm? + url "https://github.com/grafana/pyroscope/releases/download/{{.Tag}}/pyroscope_{{.Version}}_darwin_arm64.tar.gz" + sha256 "{{.DarwinArm64}}" + + def install + bin.install "pyroscope" + end + end + end + + on_linux do + if Hardware::CPU.intel? + url "https://github.com/grafana/pyroscope/releases/download/{{.Tag}}/pyroscope_{{.Version}}_linux_amd64.tar.gz" + sha256 "{{.LinuxAmd64}}" + + def install + bin.install "pyroscope" + end + end + if Hardware::CPU.arm? + if Hardware::CPU.is_64_bit? + url "https://github.com/grafana/pyroscope/releases/download/{{.Tag}}/pyroscope_{{.Version}}_linux_arm64.tar.gz" + sha256 "{{.LinuxArm64}}" + + def install + bin.install "pyroscope" + end + end + unless Hardware::CPU.is_64_bit? + url "https://github.com/grafana/pyroscope/releases/download/{{.Tag}}/pyroscope_{{.Version}}_linux_armv7.tar.gz" + sha256 "{{.LinuxArmv7}}" + + def install + bin.install "pyroscope" + end + end + end + end + + def post_install + (var/"log/pyroscope").mkpath + (var/"lib/pyroscope").mkpath + (etc/"pyroscope").mkpath + (etc/"pyroscope/config.yaml").write pyroscope_conf unless File.exist?((etc/"pyroscope/config.yaml")) + end + + service do + run [opt_bin/"pyroscope", "-config.file", "#{HOMEBREW_PREFIX}/etc/pyroscope/config.yaml"] + environment_variables PATH: std_service_path_env + keep_alive true + error_log_path "#{var}/log/pyroscope/server-stderr.log" + log_path "#{var}/log/pyroscope/server-stdout.log" + process_type :background + + working_dir "#{var}/lib/pyroscope" + end + + test do + system bin/"pyroscope", "--version" + end +end diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..39f404b --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +.PHONY: generate-formulas +generate-formulas: + @echo make sure to set PYROSCOPE_TAG environment variable, e.g PYROSCOPE_TAG=v1.0.0 + cd scripts/generate-formulas && go mod download && go run ./ ${PYROSCOPE_TAG} diff --git a/scripts/generate-formulas/go.mod b/scripts/generate-formulas/go.mod new file mode 100644 index 0000000..89a0248 --- /dev/null +++ b/scripts/generate-formulas/go.mod @@ -0,0 +1,5 @@ +module generate-formulas + +go 1.19 + +require github.com/jzelinskie/must v0.0.1 diff --git a/scripts/generate-formulas/go.sum b/scripts/generate-formulas/go.sum new file mode 100644 index 0000000..de62299 --- /dev/null +++ b/scripts/generate-formulas/go.sum @@ -0,0 +1,2 @@ +github.com/jzelinskie/must v0.0.1 h1:LT7fxrQCW9yWDkjnF75XFvODjKb6Su7qlx2LO8967Y8= +github.com/jzelinskie/must v0.0.1/go.mod h1:BTPQ0S/fIbENkk9zFU4JBtdtB+B4vibfTyeDC48z6zc= diff --git a/scripts/generate-formulas/main.go b/scripts/generate-formulas/main.go new file mode 100644 index 0000000..f7d7e25 --- /dev/null +++ b/scripts/generate-formulas/main.go @@ -0,0 +1,113 @@ +package main + +import ( + "bytes" + "fmt" + "io" + "net/http" + "os" + "path/filepath" + "strings" + "text/template" + + "github.com/jzelinskie/must" +) + +type Shas struct { + Tag string + Version string + DarwinAmd64 string + DarwinArm64 string + LinuxAmd64 string + LinuxArm64 string + LinuxArmv7 string +} + +func main() { + if len(os.Args) < 2 { + fmt.Println("Please specify pyroscope version (e.g. 1.0.0)") + return + } + + tag := os.Args[1] + url := fmt.Sprintf("https://github.com/grafana/pyroscope/releases/download/%s/checksums.txt", tag) + + res := must.NotError(http.Get(url)) + if res.StatusCode != 200 { + panic(fmt.Errorf("got status code %d", res.StatusCode)) + } + checksums := parseChecksums(must.NotError(io.ReadAll(res.Body)), tag) + + files := must.NotError(filepath.Glob("../../Formula/*.rb.tpl")) + + for _, f := range files { + base := filepath.Base(f) + arr := strings.Split(base, ".") + name := arr[0] + b := &bytes.Buffer{} + + txtTemplate := must.NotError(os.ReadFile(f)) + err := must.NotError(template.New(name).Parse(string(txtTemplate))).Execute(b, checksums[name]) + if err != nil { + panic(err) + } + os.WriteFile(fmt.Sprintf("../../Formula/%s.rb", name), b.Bytes(), 0644) + } +} + +// Example checksum file +// 01069268238c512931381d840cc5da9a77fb35594bf65416777be83830839a83 profilecli_1.0.0_windows_amd64.zip +// 0fea948d10091a8442c97d872eff7c81ae73d522415118d6ce81bcb2c0f35fa5 pyroscope_1.0.0_darwin_arm64.tar.gz +// 2203faf901ff538833b159ed03d6e0006ba8618e0d6230a0a2d88e2677f54913 profilecli_1.0.0_linux_amd64.tar.gz +// 438ff2a21c1117275f0e2940b9acb6985cae30892634849ff9720de1074115a1 profilecli_1.0.0_linux_arm64.tar.gz +// 45d2f8167f88ee58be57ddbf80184aeeabce3f48964287ec14572f4cbfc78827 profilecli_1.0.0_linux_armv7.tar.gz +// 4ea53282e35a65aa0dee6706bbfb4bb213dd74a7c9fab2e34c8ca9efe891f3b4 profilecli_1.0.0_darwin_arm64.tar.gz +// 5048e31b6aa912e284b72d6087af88204102d814c066af63f210a1f48504beff pyroscope_1.0.0_darwin_amd64.tar.gz +// 70fe31047f62188cbb8106920f0050da5dc21135d804bcbcf92cfb82837e7cd0 profilecli_1.0.0_darwin_amd64.tar.gz +// 7360b4c12ffe789e8b12030b164c45299d4514f063d4c7b87498d2aa89c5b0af pyroscope_1.0.0_linux_arm64.tar.gz +// a3967d0bff51ac2e943c812a6b3db27206c818ea126dd4b809bfa9527609d4b2 profilecli_1.0.0_windows_arm64.zip +// b6147f9d3aa8b009135cb8100669c5bada32f98fd618daf699a617300d313de2 pyroscope_1.0.0_linux_armv6.tar.gz +// d50cb09357dcaff20c814aee70a578fd6f1f079315fdc85c907d6d9b0881fb65 profilecli_1.0.0_linux_armv6.tar.gz +// e08b5c83558efc8e2e3a273f6166c93e3f7d0f8daa98557f2eb05c691480cf66 pyroscope_1.0.0_linux_amd64.tar.gz +// eaa32afde7306a4de06bd7a770a677edff733a7c9dbd21fa935c0f3f07850250 pyroscope_1.0.0_linux_armv7.tar.gz + +func parseChecksums(checksums []byte, tag string) map[string]*Shas { + shasMapping := make(map[string]*Shas) + + lines := bytes.Split(checksums, []byte("\n")) + for _, line := range lines { + arr := bytes.Split(line, []byte(" ")) + if len(arr) != 2 { + continue + } + + sha := string(arr[0]) + filename := arr[1] + filenameArr := bytes.Split(filename, []byte("_")) + name := string(filenameArr[0]) + version := string(filenameArr[1]) + os := string(filenameArr[2]) + archAndExtension := filenameArr[3] + archArr := bytes.Split(archAndExtension, []byte(".")) + arch := string(archArr[0]) + if _, ok := shasMapping[name]; !ok { + shasMapping[name] = &Shas{ + Tag: tag, + Version: version, + } + } + + if os == "darwin" && arch == "amd64" { + shasMapping[name].DarwinAmd64 = sha + } else if os == "darwin" && arch == "arm64" { + shasMapping[name].DarwinArm64 = sha + } else if os == "linux" && arch == "amd64" { + shasMapping[name].LinuxAmd64 = sha + } else if os == "linux" && arch == "arm64" { + shasMapping[name].LinuxArm64 = sha + } else if os == "linux" && arch == "armv7" { + shasMapping[name].LinuxArmv7 = sha + } + } + return shasMapping +}