build/mage/release/formula.go (139 lines of code) (raw):

// Licensed to Elasticsearch B.V. under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Elasticsearch B.V. licenses this file to you under // the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package release import ( "bytes" "crypto/sha256" "fmt" "io" "os" "strings" "text/template" "github.com/elastic/harp/build/artifact" ) var formulaTemplate = strings.TrimSpace(`# typed: false # frozen_string_literal: true # Code generated by Harp build tool class {{ .Formula }} < Formula desc "{{ .Description }}" homepage "https://{{ .Repository }}" license "Apache-2.0" stable do on_macos do if Hardware::CPU.intel? url "https://{{ .Repository }}/releases/download/cmd%2F{{ .Bin }}%2F{{ .Release }}/{{ .Bin }}-darwin-amd64-{{ .Release }}.tar.gz" sha256 "{{ sha256file (printf "dist/%s-darwin-amd64-%s.tar.gz" .Bin .Release) }}" elsif Hardware::CPU.arm? url "https://{{ .Repository }}/releases/download/cmd%2F{{ .Bin }}%2F{{ .Release }}/{{ .Bin }}-darwin-arm64-{{ .Release }}.tar.gz" sha256 "{{ sha256file (printf "dist/%s-darwin-arm64-%s.tar.gz" .Bin .Release) }}" end end on_linux do if Hardware::CPU.intel? if Hardware::CPU.is_64_bit? url "https://{{ .Repository }}/releases/download/cmd%2F{{ .Bin }}%2F{{ .Release }}/{{ .Bin }}-linux-amd64-{{ .Release }}.tar.gz" sha256 "{{ sha256file (printf "dist/%s-linux-amd64-%s.tar.gz" .Bin .Release) }}" end elsif Hardware::CPU.arm? if Hardware::CPU.is_64_bit? url "https://{{ .Repository }}/releases/download/cmd%2F{{ .Bin }}%2F{{ .Release }}/{{ .Bin }}-linux-arm64-{{ .Release }}.tar.gz" sha256 "{{ sha256file (printf "dist/%s-linux-arm64-%s.tar.gz" .Bin .Release) }}" else url "https://{{ .Repository }}/releases/download/cmd%2F{{ .Bin }}%2F{{ .Release }}/{{ .Bin }}-linux-arm7-{{ .Release }}.tar.gz" sha256 "{{ sha256file (printf "dist/%s-linux-arm7-%s.tar.gz" .Bin .Release) }}" end end end end # Source definition head do url "https://{{ .Repository }}.git", :branch => "main" # build dependencies depends_on "go" => :build depends_on "mage" => :build end def install ENV.deparallelize if build.head? # Prepare build environment ENV["GOPATH"] = buildpath (buildpath/"src/{{ .Repository }}").install Dir["{*,.git,.gitignore}"] # Mage tools ENV.prepend_path "PATH", buildpath/"tools/bin" # In {{ .Repository }} command cd "src/{{ .Repository }}/cmd/{{ .Bin }}" do system "go", "mod", "vendor" system "mage", "compile" end # Install builded command cd "src/{{ .Repository }}/cmd/{{ .Bin }}/bin" do # Install binaries if OS.mac? && Hardware::CPU.arm? bin.install "{{ .Bin }}-darwin-arm64" => "{{ .Bin }}" elsif OS.mac? bin.install "{{ .Bin }}-darwin-amd64" => "{{ .Bin }}" elsif OS.linux? bin.install "{{ .Bin }}-linux-amd64" => "{{ .Bin }}" end end elsif OS.mac? && Hardware::CPU.arm? # Install binaries bin.install "{{ .Bin }}-darwin-arm64" => "{{ .Bin }}" elsif OS.mac? bin.install "{{ .Bin }}-darwin-amd64" => "{{ .Bin }}" elsif OS.linux? bin.install "{{ .Bin }}-linux-amd64" => "{{ .Bin }}" end # Final message ohai "Install success!" end def caveats <<~EOS If you have previously built {{ .Bin }} from source, make sure you're not using $GOPATH/bin/{{ .Bin }} instead of this one. If that's the case you can simply run rm -f $GOPATH/bin/{{ .Bin }} EOS end test do assert_match version.to_s, shell_output("#{bin}/{{ .Bin }} version") end end `) type formulaModel struct { Repository string Bin string Formula string Description string Release string } // HomebrewFormula generates HomeBrew formula for given command. func HomebrewFormula(cmd *artifact.Command) func() error { sha256sum := func(filename string) (string, error) { // Open file f, err := os.Open(filename) if err != nil { return "", err } // Prepare hasher h := sha256.New() if _, err := io.Copy(h, f); err != nil { return "", err } // No error return fmt.Sprintf("%x", h.Sum(nil)), nil } return func() error { // Compile template formulaTpl, err := template.New("Formula").Funcs(map[string]interface{}{ "sha256file": sha256sum, }).Parse(formulaTemplate) if err != nil { return err } // Merge data var buf bytes.Buffer if errTmpl := formulaTpl.Execute(&buf, &formulaModel{ Repository: cmd.Package, Bin: cmd.Kebab(), Formula: cmd.Camel(), Description: cmd.Description, Release: os.Getenv("RELEASE"), }); errTmpl != nil { return errTmpl } // Write output to Stdout _, errWrite := buf.WriteTo(os.Stdout) return errWrite } }