mirror of
https://github.com/jimeh/build-emacs-for-macos.git
synced 2026-02-19 13:06:38 +00:00
feat(plan): add plan command to create build plans
This commit is contained in:
125
pkg/plan/create.go
Normal file
125
pkg/plan/create.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package plan
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/jimeh/build-emacs-for-macos/pkg/commit"
|
||||
"github.com/jimeh/build-emacs-for-macos/pkg/gh"
|
||||
"github.com/jimeh/build-emacs-for-macos/pkg/osinfo"
|
||||
"github.com/jimeh/build-emacs-for-macos/pkg/repository"
|
||||
)
|
||||
|
||||
var nonAlphaNum = regexp.MustCompile(`[^\w_-]+`)
|
||||
|
||||
type TestBuildType string
|
||||
|
||||
//nolint:golint
|
||||
const (
|
||||
Draft TestBuildType = "draft"
|
||||
Prerelease TestBuildType = "prerelease"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
GithubToken string
|
||||
EmacsRepo string
|
||||
Ref string
|
||||
SHAOverride string
|
||||
OutputDir string
|
||||
TestBuild string
|
||||
TestBuildType TestBuildType
|
||||
Output io.Writer
|
||||
}
|
||||
|
||||
func Create(ctx context.Context, opts *Options) (*Plan, error) {
|
||||
logger := hclog.FromContext(ctx).Named("plan")
|
||||
|
||||
repo, err := repository.NewGitHub(opts.EmacsRepo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
gh := gh.New(ctx, opts.GithubToken)
|
||||
|
||||
lookupRef := opts.Ref
|
||||
if opts.SHAOverride != "" {
|
||||
lookupRef = opts.SHAOverride
|
||||
}
|
||||
logger.Info("fetching commit info", "ref", lookupRef)
|
||||
|
||||
repoCommit, _, err := gh.Repositories.GetCommit(
|
||||
ctx, repo.Owner(), repo.Name(), lookupRef,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
commitInfo := commit.New(repoCommit)
|
||||
osInfo, err := osinfo.New()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
releaseName := fmt.Sprintf(
|
||||
"Emacs.%s.%s.%s",
|
||||
commitInfo.DateString(),
|
||||
commitInfo.ShortSHA(),
|
||||
sanitizeString(opts.Ref),
|
||||
)
|
||||
buildName := fmt.Sprintf(
|
||||
"%s.%s.%s",
|
||||
releaseName,
|
||||
sanitizeString(osInfo.Name+"-"+osInfo.MajorMinor()),
|
||||
sanitizeString(osInfo.Arch),
|
||||
)
|
||||
diskImage := buildName + ".dmg"
|
||||
|
||||
plan := &Plan{
|
||||
Build: &Build{
|
||||
Name: buildName,
|
||||
},
|
||||
Source: &Source{
|
||||
Ref: opts.Ref,
|
||||
Repository: repo,
|
||||
Commit: commitInfo,
|
||||
Tarball: &Tarball{
|
||||
URL: repo.TarballURL(commitInfo.SHA),
|
||||
},
|
||||
},
|
||||
OS: osInfo,
|
||||
Release: &Release{
|
||||
Name: releaseName,
|
||||
},
|
||||
Output: &Output{
|
||||
Directory: opts.OutputDir,
|
||||
DiskImage: diskImage,
|
||||
},
|
||||
}
|
||||
|
||||
if opts.TestBuild != "" {
|
||||
testName := sanitizeString(opts.TestBuild)
|
||||
|
||||
plan.Build.Name += ".test." + testName
|
||||
plan.Release.Title = "Test Builds"
|
||||
plan.Release.Name = "test-builds"
|
||||
if opts.TestBuildType == Draft {
|
||||
plan.Release.Draft = true
|
||||
} else {
|
||||
plan.Release.Prerelease = true
|
||||
}
|
||||
|
||||
index := strings.LastIndex(diskImage, ".")
|
||||
plan.Output.DiskImage = diskImage[:index] + ".test." +
|
||||
testName + diskImage[index:]
|
||||
}
|
||||
|
||||
return plan, nil
|
||||
}
|
||||
|
||||
func sanitizeString(s string) string {
|
||||
return nonAlphaNum.ReplaceAllString(s, "-")
|
||||
}
|
||||
82
pkg/plan/plan.go
Normal file
82
pkg/plan/plan.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package plan
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/jimeh/build-emacs-for-macos/pkg/commit"
|
||||
"github.com/jimeh/build-emacs-for-macos/pkg/osinfo"
|
||||
"github.com/jimeh/build-emacs-for-macos/pkg/repository"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type Plan struct {
|
||||
Build *Build `yaml:"build,omitempty"`
|
||||
Source *Source `yaml:"source,omitempty"`
|
||||
OS *osinfo.OSInfo `yaml:"os,omitempty"`
|
||||
Release *Release `yaml:"release,omitempty"`
|
||||
Output *Output `yaml:"output,omitempty"`
|
||||
}
|
||||
|
||||
// Load attempts to loads a plan YAML from given filename.
|
||||
func Load(filename string) (*Plan, error) {
|
||||
b, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p := &Plan{}
|
||||
err = yaml.Unmarshal(b, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// WriteYAML writes plan in YAML format to given io.Writer.
|
||||
func (s *Plan) WriteYAML(w io.Writer) error {
|
||||
enc := yaml.NewEncoder(w)
|
||||
enc.SetIndent(2)
|
||||
|
||||
return enc.Encode(s)
|
||||
}
|
||||
|
||||
// YAML returns plan in YAML format.
|
||||
func (s *Plan) YAML() (string, error) {
|
||||
var buf bytes.Buffer
|
||||
err := s.WriteYAML(&buf)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
type Build struct {
|
||||
Name string `yaml:"name,omitempty"`
|
||||
}
|
||||
|
||||
type Source struct {
|
||||
Ref string `yaml:"ref,omitempty"`
|
||||
Repository *repository.Repository `yaml:"repository,omitempty"`
|
||||
Commit *commit.Commit `yaml:"commit,omitempty"`
|
||||
Tarball *Tarball `yaml:"tarball,omitempty"`
|
||||
}
|
||||
|
||||
type Tarball struct {
|
||||
URL string `yaml:"url,omitempty"`
|
||||
}
|
||||
|
||||
type Release struct {
|
||||
Name string `yaml:"name"`
|
||||
Title string `yaml:"title,omitempty"`
|
||||
Draft bool `yaml:"draft,omitempty"`
|
||||
Prerelease bool `yaml:"prerelease,omitempty"`
|
||||
}
|
||||
|
||||
type Output struct {
|
||||
Directory string `yaml:"directory,omitempty"`
|
||||
DiskImage string `yaml:"disk_image,omitempty"`
|
||||
}
|
||||
Reference in New Issue
Block a user