Compare commits

...

3 Commits

Author SHA1 Message Date
8225f41d0e Fix nil argument when -P flag is not given
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2022-12-28 18:44:48 -08:00
db060db4b1 Convert distro.ParseOSRelease() into a singleton 2022-12-28 18:40:20 -08:00
863b6e923a Split overrides into separate package with tests 2022-12-28 18:39:31 -08:00
5 changed files with 195 additions and 46 deletions

View File

@ -46,8 +46,16 @@ type OSRelease struct {
Logo string
}
// OSReleaseName returns the NAME field of the
var parsed *OSRelease
// OSReleaseName returns a struct parsed from the system's os-release
// file. It checks /etc/os-release as well as /usr/lib/os-release.
// The returned OSRelease struct is a singleton.
func ParseOSRelease(ctx context.Context) (*OSRelease, error) {
if parsed != nil {
return parsed, nil
}
fl, err := os.Open("/usr/lib/os-release")
if err != nil {
fl, err = os.Open("/etc/os-release")
@ -99,5 +107,6 @@ func ParseOSRelease(ctx context.Context) (*OSRelease, error) {
out.Like = strings.Split(runner.Vars["ID_LIKE"].Str, " ")
}
parsed = out
return out, nil
}

View File

@ -0,0 +1,92 @@
package overrides
import (
"runtime"
"strings"
"go.arsenm.dev/lure/distro"
"go.arsenm.dev/lure/internal/cpu"
)
type Opts struct {
Name string
Overrides bool
LikeDistros bool
}
var DefaultOpts = &Opts{
Overrides: true,
LikeDistros: true,
}
// Resolve generates a slice of possible override names in the order that they should be checked
func Resolve(info *distro.OSRelease, opts *Opts) []string {
if opts == nil {
opts = DefaultOpts
}
if !opts.Overrides {
return []string{opts.Name}
}
architectures := []string{runtime.GOARCH}
if runtime.GOARCH == "arm" {
// More specific goes first
architectures[0] = cpu.ARMVariant()
architectures = append(architectures, "arm")
}
distros := []string{info.ID}
if opts.LikeDistros {
distros = append(distros, info.Like...)
}
var out []string
for _, arch := range architectures {
for _, distro := range distros {
if opts.Name == "" {
out = append(
out,
arch+"_"+distro,
distro,
)
} else {
out = append(
out,
opts.Name+"_"+arch+"_"+distro,
opts.Name+"_"+distro,
)
}
}
if opts.Name == "" {
out = append(out, arch)
} else {
out = append(out, opts.Name+"_"+arch)
}
}
if opts.Name != "" {
out = append(out, opts.Name)
}
for index, item := range out {
out[index] = strings.ReplaceAll(item, "-", "_")
}
return out
}
func (o *Opts) WithName(name string) *Opts {
o.Name = name
return o
}
func (o *Opts) WithOverrides(v bool) *Opts {
o.Overrides = v
return o
}
func (o *Opts) WithLikeDistros(v bool) *Opts {
o.LikeDistros = v
return o
}

View File

@ -0,0 +1,86 @@
package overrides_test
import (
"reflect"
"testing"
"go.arsenm.dev/lure/distro"
"go.arsenm.dev/lure/internal/overrides"
)
var info = &distro.OSRelease{
ID: "centos",
Like: []string{"rhel", "fedora"},
}
func TestResolve(t *testing.T) {
names := overrides.Resolve(info, nil)
expected := []string{
"amd64_centos",
"centos",
"amd64_rhel",
"rhel",
"amd64_fedora",
"fedora",
"amd64",
}
if !reflect.DeepEqual(names, expected) {
t.Errorf("expected %v, got %v", expected, names)
}
}
func TestResolveName(t *testing.T) {
names := overrides.Resolve(info, &overrides.Opts{
Name: "deps",
Overrides: true,
LikeDistros: true,
})
expected := []string{
"deps_amd64_centos",
"deps_centos",
"deps_amd64_rhel",
"deps_rhel",
"deps_amd64_fedora",
"deps_fedora",
"deps_amd64",
"deps",
}
if !reflect.DeepEqual(names, expected) {
t.Errorf("expected %v, got %v", expected, names)
}
}
func TestResolveNoLikeDistros(t *testing.T) {
names := overrides.Resolve(info, &overrides.Opts{
Overrides: true,
LikeDistros: false,
})
expected := []string{
"amd64_centos",
"centos",
"amd64",
}
if !reflect.DeepEqual(names, expected) {
t.Errorf("expected %v, got %v", expected, names)
}
}
func TestResolveNoOverrides(t *testing.T) {
names := overrides.Resolve(info, &overrides.Opts{
Name: "deps",
Overrides: false,
LikeDistros: false,
})
expected := []string{"deps"}
if !reflect.DeepEqual(names, expected) {
t.Errorf("expected %v, got %v", expected, names)
}
}

View File

@ -21,14 +21,12 @@ package decoder
import (
"context"
"errors"
"fmt"
"reflect"
"runtime"
"strings"
"github.com/mitchellh/mapstructure"
"go.arsenm.dev/lure/distro"
"go.arsenm.dev/lure/internal/cpu"
"go.arsenm.dev/lure/internal/overrides"
"golang.org/x/exp/slices"
"mvdan.cc/sh/v3/expand"
"mvdan.cc/sh/v3/interp"
@ -169,7 +167,7 @@ func (d *Decoder) GetFunc(name string) (ScriptFunc, bool) {
}
func (d *Decoder) getFunc(name string) *syntax.Stmt {
names := d.genPossibleNames(name)
names := overrides.Resolve(d.info, overrides.DefaultOpts.WithName(name))
for _, fnName := range names {
fn, ok := d.runner.Funcs[fnName]
if ok {
@ -182,7 +180,7 @@ func (d *Decoder) getFunc(name string) *syntax.Stmt {
// getVar gets a variable based on its name, taking into account
// override variables and nameref variables.
func (d *Decoder) getVar(name string) *expand.Variable {
names := d.genPossibleNames(name)
names := overrides.Resolve(d.info, overrides.DefaultOpts.WithName(name))
for _, varName := range names {
val, ok := d.runner.Vars[varName]
if ok {
@ -200,43 +198,3 @@ func (d *Decoder) getVar(name string) *expand.Variable {
}
return nil
}
// genPossibleNames generates a slice of the possible names that
// could be used in the order that they should be checked
func (d *Decoder) genPossibleNames(name string) []string {
if !d.Overrides {
return []string{name}
}
architectures := []string{runtime.GOARCH}
if runtime.GOARCH == "arm" {
// More specific goes first
architectures[0] = cpu.ARMVariant()
architectures = append(architectures, "arm")
}
distros := []string{d.info.ID}
if d.LikeDistros {
distros = append(distros, d.info.Like...)
}
var out []string
for _, arch := range architectures {
for _, distro := range distros {
out = append(
out,
fmt.Sprintf("%s_%s_%s", name, arch, distro),
fmt.Sprintf("%s_%s", name, distro),
)
}
out = append(out, fmt.Sprintf("%s_%s", name, arch))
}
out = append(out, name)
for index, item := range out {
out[index] = strings.ReplaceAll(item, "-", "_")
}
return out
}

View File

@ -166,6 +166,10 @@ func main() {
},
Before: func(c *cli.Context) error {
args := strings.Split(c.String("pm-args"), " ")
if len(args) == 1 && args[0] == "" {
args = nil
}
manager.Args = append(manager.Args, args...)
return nil
},