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
}
}