init
This commit is contained in:
commit
9298fc4e4c
12 changed files with 599 additions and 0 deletions
72
internal/build/builder.go
Normal file
72
internal/build/builder.go
Normal file
|
@ -0,0 +1,72 @@
|
|||
package build
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"code.vulpine.solutions/sam/vlp/internal/packages"
|
||||
)
|
||||
|
||||
type Builder struct {
|
||||
Name string
|
||||
Version string
|
||||
Dependencies []packages.Dependency
|
||||
|
||||
SourceFetcher Fetcher
|
||||
Commands []BuildCommand
|
||||
Binaries []string
|
||||
|
||||
TempDir string
|
||||
}
|
||||
|
||||
type BuildCommand struct {
|
||||
Command string
|
||||
Args []string
|
||||
}
|
||||
|
||||
func New(name, version string) (*Builder, error) {
|
||||
b := &Builder{
|
||||
Name: name,
|
||||
Version: version,
|
||||
}
|
||||
|
||||
tmp, err := tmpDir(name, version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b.TempDir = tmp
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (b *Builder) Build() error {
|
||||
for i, cmd := range b.Commands {
|
||||
exitCode, out := execCommand(cmd.Command, cmd.Args...)
|
||||
if exitCode != 0 {
|
||||
return fmt.Errorf("command %d returned exit code %d: %v", i, exitCode, string(out))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func tmpDir(name, version string) (string, error) {
|
||||
tmp, err := os.MkdirTemp(os.TempDir(), "vlp-build-"+name+"-"+version+"_")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("creating temp dir: %w", err)
|
||||
}
|
||||
return tmp, nil
|
||||
}
|
||||
|
||||
func execCommand(bin string, args ...string) (int, []byte) {
|
||||
err := exec.Command(bin, args...).Run()
|
||||
if err != nil {
|
||||
eErr, ok := err.(*exec.ExitError)
|
||||
if ok {
|
||||
return eErr.ExitCode(), eErr.Stderr
|
||||
}
|
||||
|
||||
return 1, nil
|
||||
}
|
||||
return 0, nil
|
||||
}
|
51
internal/build/fetcher.go
Normal file
51
internal/build/fetcher.go
Normal file
|
@ -0,0 +1,51 @@
|
|||
package build
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type Fetcher interface {
|
||||
Fetch(tempDir string) error
|
||||
}
|
||||
|
||||
type BlankFetcher struct{}
|
||||
|
||||
func (BlankFetcher) Fetch(tempDir string) error {
|
||||
return fmt.Errorf("no sources were configured")
|
||||
}
|
||||
|
||||
var _ Fetcher = (*GitFetcher)(nil)
|
||||
|
||||
type GitFetcher struct {
|
||||
Repository, Ref string
|
||||
}
|
||||
|
||||
func (g GitFetcher) Fetch(tempDir string) error {
|
||||
|
||||
repoDir := filepath.Join(tempDir, "repo")
|
||||
exitCode, out := execCommand("git", "clone", "--depth=1", g.Repository, repoDir)
|
||||
if exitCode != 0 {
|
||||
return fmt.Errorf("git clone returned %d, output: %v", exitCode, string(out))
|
||||
}
|
||||
|
||||
err := os.Chdir(repoDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("changing to repository directory: %w", err)
|
||||
}
|
||||
|
||||
if g.Ref != "" {
|
||||
exitCode, out = execCommand("git", "fetch", "--depth=1", "origin", g.Ref)
|
||||
if exitCode != 0 {
|
||||
return fmt.Errorf("fetch clone returned %d, output: %v", exitCode, string(out))
|
||||
}
|
||||
|
||||
exitCode, out = execCommand("git", "checkout", g.Ref)
|
||||
if exitCode != 0 {
|
||||
return fmt.Errorf("git checkout returned %d, output: %v", exitCode, string(out))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
68
internal/build/tarball.go
Normal file
68
internal/build/tarball.go
Normal file
|
@ -0,0 +1,68 @@
|
|||
package build
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func (b *Builder) GenerateTarball() error {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
tarW := tar.NewWriter(buf)
|
||||
|
||||
err := tarW.WriteHeader(&tar.Header{
|
||||
Name: "bin/",
|
||||
Mode: int64(os.ModeDir) | 0o755,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("writing bin directory: %w", err)
|
||||
}
|
||||
|
||||
for _, bin := range b.Binaries {
|
||||
base := filepath.Base(bin)
|
||||
|
||||
binB, err := os.ReadFile(bin)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading binary %v: %w", bin, err)
|
||||
}
|
||||
|
||||
err = tarW.WriteHeader(&tar.Header{
|
||||
Name: filepath.Join("bin", base),
|
||||
Size: int64(len(binB)),
|
||||
Mode: 0o755,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("writing header for binary %v: %w", bin, err)
|
||||
}
|
||||
|
||||
_, err = tarW.Write(binB)
|
||||
if err != nil {
|
||||
return fmt.Errorf("writing binary %v: %w", bin, err)
|
||||
}
|
||||
}
|
||||
|
||||
err = tarW.Close()
|
||||
if err != nil {
|
||||
return fmt.Errorf("writing tar footer: %w", err)
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Join(b.TempDir, fmt.Sprintf("%v-%v-%v.tar", b.Name, b.Version, runtime.GOARCH)))
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating tarball: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = io.Copy(f, buf)
|
||||
if err != nil {
|
||||
return fmt.Errorf("writing to tarball: %w", err)
|
||||
}
|
||||
|
||||
fmt.Println("wrote tarball at", f.Name())
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue