Add CHANGELOG + improvements to #980

Closes #978
This commit is contained in:
Andrey Nering
2023-01-06 21:39:57 -03:00
parent aa6c7e4b94
commit 2efb3533ec
7 changed files with 171 additions and 70 deletions

View File

@@ -2,10 +2,11 @@ package taskfile
import (
"fmt"
"runtime"
"strings"
"gopkg.in/yaml.v3"
"github.com/go-task/task/v3/internal/goext"
)
// Platform represents GOOS and GOARCH values
@@ -14,67 +15,23 @@ type Platform struct {
Arch string
}
// ParsePlatform takes a string representing an OS/Arch combination (or either on their own)
// and parses it into the Platform struct. It returns an error if the input string is invalid.
// Valid combinations for input: OS, Arch, OS/Arch
func (p *Platform) ParsePlatform(input string) error {
// tidy up input
platformString := strings.ToLower(strings.TrimSpace(input))
splitValues := strings.Split(platformString, "/")
if len(splitValues) > 2 {
return fmt.Errorf("task: Invalid OS/Arch provided: %s", input)
}
err := p.parseOsOrArch(splitValues[0])
if err != nil {
return err
}
if len(splitValues) == 2 {
return p.parseArch(splitValues[1])
}
return nil
type ErrInvalidPlatform struct {
Platform string
}
// supportedOSes is a list of supported OSes
var supportedOSes = map[string]struct{}{
"windows": {},
"darwin": {},
"linux": {},
"freebsd": {},
}
func isSupportedOS(input string) bool {
_, exists := supportedOSes[input]
return exists
}
// supportedArchs is a list of supported architectures
var supportedArchs = map[string]struct{}{
"amd64": {},
"arm64": {},
"386": {},
}
func isSupportedArch(input string) bool {
_, exists := supportedArchs[input]
return exists
}
// MatchesCurrentPlatform returns true if the platform matches the current platform
func (p *Platform) MatchesCurrentPlatform() bool {
return (p.OS == "" || p.OS == runtime.GOOS) &&
(p.Arch == "" || p.Arch == runtime.GOARCH)
func (err *ErrInvalidPlatform) Error() string {
return fmt.Sprintf(`task: Invalid platform "%s"`, err.Platform)
}
// UnmarshalYAML implements yaml.Unmarshaler interface.
func (p *Platform) UnmarshalYAML(node *yaml.Node) error {
switch node.Kind {
case yaml.ScalarNode:
var platform string
if err := node.Decode(&platform); err != nil {
return err
}
if err := p.ParsePlatform(platform); err != nil {
if err := p.parsePlatform(platform); err != nil {
return err
}
return nil
@@ -82,22 +39,42 @@ func (p *Platform) UnmarshalYAML(node *yaml.Node) error {
return fmt.Errorf("yaml: line %d: cannot unmarshal %s into platform", node.Line, node.ShortTag())
}
// parsePlatform takes a string representing an OS/Arch combination (or either on their own)
// and parses it into the Platform struct. It returns an error if the input string is invalid.
// Valid combinations for input: OS, Arch, OS/Arch
func (p *Platform) parsePlatform(input string) error {
splitValues := strings.Split(input, "/")
if len(splitValues) > 2 {
return &ErrInvalidPlatform{Platform: input}
}
if err := p.parseOsOrArch(splitValues[0]); err != nil {
return &ErrInvalidPlatform{Platform: input}
}
if len(splitValues) == 2 {
if err := p.parseArch(splitValues[1]); err != nil {
return &ErrInvalidPlatform{Platform: input}
}
}
return nil
}
// parseOsOrArch will check if the given input is a valid OS or Arch value.
// If so, it will store it. If not, an error is returned
func (p *Platform) parseOsOrArch(osOrArch string) error {
if osOrArch == "" {
return fmt.Errorf("task: Blank OS/Arch value provided")
}
if isSupportedOS(osOrArch) {
if goext.IsKnownOS(osOrArch) {
p.OS = osOrArch
return nil
}
if isSupportedArch(osOrArch) {
if goext.IsKnownArch(osOrArch) {
p.Arch = osOrArch
return nil
}
return fmt.Errorf("task: Invalid OS/Arch value provided (%s)", osOrArch)
}
func (p *Platform) parseArch(arch string) error {
if arch == "" {
return fmt.Errorf("task: Blank Arch value provided")
@@ -105,7 +82,7 @@ func (p *Platform) parseArch(arch string) error {
if p.Arch != "" {
return fmt.Errorf("task: Multiple Arch values provided")
}
if isSupportedArch(arch) {
if goext.IsKnownArch(arch) {
p.Arch = arch
return nil
}

View File

@@ -0,0 +1,49 @@
package taskfile
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestPlatformParsing(t *testing.T) {
tests := []struct {
Input string
ExpectedOS string
ExpectedArch string
Error string
}{
{Input: "windows", ExpectedOS: "windows", ExpectedArch: ""},
{Input: "linux", ExpectedOS: "linux", ExpectedArch: ""},
{Input: "darwin", ExpectedOS: "darwin", ExpectedArch: ""},
{Input: "386", ExpectedOS: "", ExpectedArch: "386"},
{Input: "amd64", ExpectedOS: "", ExpectedArch: "amd64"},
{Input: "arm64", ExpectedOS: "", ExpectedArch: "arm64"},
{Input: "windows/386", ExpectedOS: "windows", ExpectedArch: "386"},
{Input: "windows/amd64", ExpectedOS: "windows", ExpectedArch: "amd64"},
{Input: "windows/arm64", ExpectedOS: "windows", ExpectedArch: "arm64"},
{Input: "invalid", Error: `task: Invalid platform "invalid"`},
{Input: "invalid/invalid", Error: `task: Invalid platform "invalid/invalid"`},
{Input: "windows/invalid", Error: `task: Invalid platform "windows/invalid"`},
{Input: "invalid/amd64", Error: `task: Invalid platform "invalid/amd64"`},
}
for _, test := range tests {
t.Run(test.Input, func(t *testing.T) {
var p Platform
err := p.parsePlatform(test.Input)
if test.Error != "" {
assert.Error(t, err)
assert.Equal(t, test.Error, err.Error())
} else {
assert.NoError(t, err)
assert.Equal(t, test.ExpectedOS, p.OS)
assert.Equal(t, test.ExpectedArch, p.Arch)
}
})
}
}