vlp/internal/state/state.go
2024-09-19 02:12:57 +02:00

121 lines
2.4 KiB
Go

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
}