init
This commit is contained in:
commit
9298fc4e4c
12 changed files with 599 additions and 0 deletions
28
LICENSE
Normal file
28
LICENSE
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
BSD 3-Clause License
|
||||||
|
|
||||||
|
Copyright (c) 2024, sam
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
26
cmd/vlp/main.go
Normal file
26
cmd/vlp/main.go
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"code.vulpine.solutions/sam/vlp/internal/commands/build"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var App = &cli.App{
|
||||||
|
Name: "vlp",
|
||||||
|
Usage: "Package manager for foxes",
|
||||||
|
UseShortOptionHandling: true,
|
||||||
|
Commands: []*cli.Command{
|
||||||
|
build.Command,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
err := App.Run(os.Args)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error running vlp:", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
14
go.mod
Normal file
14
go.mod
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
module code.vulpine.solutions/sam/vlp
|
||||||
|
|
||||||
|
go 1.23.1
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/urfave/cli/v2 v2.27.4
|
||||||
|
github.com/yuin/gopher-lua v1.1.1
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
|
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
|
||||||
|
)
|
10
go.sum
Normal file
10
go.sum
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8=
|
||||||
|
github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ=
|
||||||
|
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
|
||||||
|
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
|
||||||
|
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
|
||||||
|
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
|
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
|
||||||
|
}
|
45
internal/commands/build/command.go
Normal file
45
internal/commands/build/command.go
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package build
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"code.vulpine.solutions/sam/vlp/internal/packages"
|
||||||
|
"code.vulpine.solutions/sam/vlp/internal/state"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Command = &cli.Command{
|
||||||
|
Name: "build",
|
||||||
|
Aliases: []string{"b"},
|
||||||
|
Usage: "Build a package from source",
|
||||||
|
Args: true,
|
||||||
|
ArgsUsage: "<name>",
|
||||||
|
Action: action,
|
||||||
|
}
|
||||||
|
|
||||||
|
func action(ctx *cli.Context) error {
|
||||||
|
if ctx.NArg() < 1 {
|
||||||
|
return cli.Exit("Not enough arguments", 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
name := ctx.Args().Get(0)
|
||||||
|
|
||||||
|
script, err := packages.LookupPackageFile(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
s := state.New(name)
|
||||||
|
err = s.Eval(script)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.Build()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(s.Builder.Name, s.Builder.Dependencies)
|
||||||
|
return nil
|
||||||
|
}
|
38
internal/packages/packages.go
Normal file
38
internal/packages/packages.go
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package packages
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Package struct {
|
||||||
|
Name string
|
||||||
|
Dependencies []Dependency
|
||||||
|
}
|
||||||
|
|
||||||
|
type Dependency struct {
|
||||||
|
Name string
|
||||||
|
Version string
|
||||||
|
}
|
||||||
|
|
||||||
|
func LookupPackageFile(name string) (io.Reader, error) {
|
||||||
|
path := filepath.Join("./packages", name+".lua")
|
||||||
|
|
||||||
|
f, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("opening package file: %w", err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
|
_, err = io.Copy(buf, f)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("reading package file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf, nil
|
||||||
|
}
|
111
internal/state/builtins.go
Normal file
111
internal/state/builtins.go
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
package state
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.vulpine.solutions/sam/vlp/internal/build"
|
||||||
|
"code.vulpine.solutions/sam/vlp/internal/packages"
|
||||||
|
lua "github.com/yuin/gopher-lua"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *State) depends(ls *lua.LState) int {
|
||||||
|
t := ls.GetTop()
|
||||||
|
if t == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 1; i <= t; i++ {
|
||||||
|
table, ok := ls.Get(i).(*lua.LTable)
|
||||||
|
if !ok {
|
||||||
|
ls.RaiseError("Argument %v was not a table", i)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
name string
|
||||||
|
version = "*"
|
||||||
|
)
|
||||||
|
|
||||||
|
switch table.Len() {
|
||||||
|
default:
|
||||||
|
fallthrough
|
||||||
|
case 2:
|
||||||
|
version = table.RawGetInt(2).String()
|
||||||
|
fallthrough
|
||||||
|
case 1:
|
||||||
|
name = table.RawGetInt(1).String()
|
||||||
|
case 0:
|
||||||
|
ls.RaiseError("Table %v is empty", i)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Builder.Dependencies = append(s.Builder.Dependencies, packages.Dependency{Name: name, Version: version})
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *State) git(ls *lua.LState) int {
|
||||||
|
t := ls.GetTop()
|
||||||
|
if t == 0 {
|
||||||
|
ls.RaiseError("`git` needs a repository URL")
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var repo, ref string
|
||||||
|
|
||||||
|
lrepo, ok := ls.Get(1).(lua.LString)
|
||||||
|
if !ok {
|
||||||
|
ls.RaiseError("Argument 1 is not a string")
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
repo = lrepo.String()
|
||||||
|
|
||||||
|
lref, ok := ls.Get(2).(lua.LString)
|
||||||
|
if ok {
|
||||||
|
ref = lref.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Builder.SourceFetcher = build.GitFetcher{Repository: repo, Ref: ref}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *State) cmd(ls *lua.LState) int {
|
||||||
|
t := ls.GetTop()
|
||||||
|
if t == 0 {
|
||||||
|
ls.RaiseError("`cmd` needs a command to run")
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
lcmd, ok := ls.Get(1).(lua.LString)
|
||||||
|
if !ok {
|
||||||
|
ls.RaiseError("Argument 1 is not a string")
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var args []string
|
||||||
|
for i := 2; i <= t; i++ {
|
||||||
|
larg := ls.Get(i)
|
||||||
|
if larg == lua.LNil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
args = append(args, larg.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Builder.Commands = append(s.Builder.Commands, build.BuildCommand{Command: lcmd.String(), Args: args})
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *State) bin(ls *lua.LState) int {
|
||||||
|
if ls.GetTop() != 1 {
|
||||||
|
ls.RaiseError("`bin` needs a single binary to install")
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
lbin, ok := ls.Get(1).(lua.LString)
|
||||||
|
if !ok {
|
||||||
|
ls.RaiseError("Argument 1 is not a string")
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Builder.Binaries = append(s.Builder.Binaries, lbin.String())
|
||||||
|
return 0
|
||||||
|
}
|
121
internal/state/state.go
Normal file
121
internal/state/state.go
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
package state
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"code.vulpine.solutions/sam/vlp/internal/build"
|
||||||
|
lua "github.com/yuin/gopher-lua"
|
||||||
|
)
|
||||||
|
|
||||||
|
type State struct {
|
||||||
|
Lua *lua.LState
|
||||||
|
Builder *build.Builder
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(packageName string) *State {
|
||||||
|
s := &State{
|
||||||
|
Lua: lua.NewState(lua.Options{
|
||||||
|
IncludeGoStackTrace: true,
|
||||||
|
}),
|
||||||
|
Builder: &build.Builder{Name: packageName},
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Lua.SetGlobal("depends", s.Lua.NewFunction(s.depends))
|
||||||
|
s.Lua.SetGlobal("git", s.Lua.NewFunction(s.git))
|
||||||
|
s.Lua.SetGlobal("cmd", s.Lua.NewFunction(s.cmd))
|
||||||
|
s.Lua.SetGlobal("bin", s.Lua.NewFunction(s.bin))
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// Eval evaluates a build script. It does not actually build the package yet.
|
||||||
|
func (s *State) Eval(r io.Reader) error {
|
||||||
|
script, err := io.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("reading script: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.Lua.DoString(string(script))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("executing script: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var name, version string
|
||||||
|
|
||||||
|
lname := s.Lua.GetGlobal("name")
|
||||||
|
if nameStr, ok := lname.(lua.LString); ok {
|
||||||
|
name = nameStr.String()
|
||||||
|
} else {
|
||||||
|
name = s.Builder.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
lversion := s.Lua.GetGlobal("version")
|
||||||
|
if versionStr, ok := lversion.(lua.LString); ok {
|
||||||
|
version = versionStr.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Builder, err = build.New(name, version)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("creating builder: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *State) Build() error {
|
||||||
|
fetchFn, ok := s.Lua.GetGlobal("fetch").(*lua.LFunction)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("`fetch` was not defined")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := s.Lua.CallByParam(lua.P{
|
||||||
|
Fn: fetchFn,
|
||||||
|
NRet: 0,
|
||||||
|
Protect: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("running fetch function: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.Builder.SourceFetcher.Fetch(s.Builder.TempDir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("fetching source: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
buildFn := s.Lua.GetGlobal("build")
|
||||||
|
if buildFn != lua.LNil {
|
||||||
|
err := s.Lua.CallByParam(lua.P{
|
||||||
|
Fn: buildFn,
|
||||||
|
NRet: 0,
|
||||||
|
Protect: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("running build function: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.Builder.Build()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("building source: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
installFn := s.Lua.GetGlobal("install")
|
||||||
|
if installFn != lua.LNil {
|
||||||
|
err := s.Lua.CallByParam(lua.P{
|
||||||
|
Fn: installFn,
|
||||||
|
NRet: 0,
|
||||||
|
Protect: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("running install function: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.Builder.GenerateTarball()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("generating zip: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
15
packages/vlp.lua
Normal file
15
packages/vlp.lua
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
depends({"go", "1.23"}, {"hello", "*"})
|
||||||
|
|
||||||
|
function fetch()
|
||||||
|
git("https://code.vulpine.solutions/sam/vlp.git")
|
||||||
|
end
|
||||||
|
|
||||||
|
function build()
|
||||||
|
cmd("go", "build", "./cmd/vlp")
|
||||||
|
end
|
||||||
|
|
||||||
|
function install()
|
||||||
|
bin("vlp")
|
||||||
|
end
|
Loading…
Reference in a new issue