1
0
mirror of https://github.com/go-task/task.git synced 2025-05-15 22:26:28 +02:00

feat: add support for multiple includes on a graph edge

This commit is contained in:
Pete Davison 2024-04-21 15:28:02 +00:00
parent 6951e5cd0c
commit f19c520f23
10 changed files with 41 additions and 56 deletions

View File

@ -19,7 +19,7 @@ const (
CodeTaskfileCacheNotFound CodeTaskfileCacheNotFound
CodeTaskfileVersionCheckError CodeTaskfileVersionCheckError
CodeTaskfileNetworkTimeout CodeTaskfileNetworkTimeout
CodeTaskfileDuplicateInclude _ // CodeTaskfileDuplicateInclude
CodeTaskfileCycle CodeTaskfileCycle
) )

View File

@ -3,7 +3,6 @@ package errors
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"strings"
"time" "time"
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
@ -176,22 +175,6 @@ func (err *TaskfileNetworkTimeoutError) Code() int {
return CodeTaskfileNetworkTimeout return CodeTaskfileNetworkTimeout
} }
type TaskfileDuplicateIncludeError struct {
URI string
IncludedURI string
Namespaces []string
}
func (err *TaskfileDuplicateIncludeError) Error() string {
return fmt.Sprintf(
`task: Taskfile %q attempted to include %q multiple times with namespaces: %s`, err.URI, err.IncludedURI, strings.Join(err.Namespaces, ", "),
)
}
func (err *TaskfileDuplicateIncludeError) Code() int {
return CodeTaskfileDuplicateInclude
}
// TaskfileCycleError is returned when we detect that a Taskfile includes a // TaskfileCycleError is returned when we detect that a Taskfile includes a
// set of Taskfiles that include each other in a cycle. // set of Taskfiles that include each other in a cycle.
type TaskfileCycleError struct { type TaskfileCycleError struct {

View File

@ -981,8 +981,8 @@ func TestIncludes(t *testing.T) {
"included_directory.txt": "included_directory", "included_directory.txt": "included_directory",
"included_directory_without_dir.txt": "included_directory_without_dir", "included_directory_without_dir.txt": "included_directory_without_dir",
"included_taskfile_without_dir.txt": "included_taskfile_without_dir", "included_taskfile_without_dir.txt": "included_taskfile_without_dir",
"./module3/included_taskfile_with_dir.txt": "included_taskfile_with_dir", "./module2/included_directory_with_dir.txt": "included_directory_with_dir",
"./module4/included_directory_with_dir.txt": "included_directory_with_dir", "./module2/included_taskfile_with_dir.txt": "included_taskfile_with_dir",
"os_include.txt": "os", "os_include.txt": "os",
}, },
} }

View File

@ -79,18 +79,20 @@ func (tfg *TaskfileGraph) Merge() (*Taskfile, error) {
} }
// Get the merge options // Get the merge options
include, ok := edge.Properties.Data.(*Include) includes, ok := edge.Properties.Data.([]*Include)
if !ok { if !ok {
return fmt.Errorf("task: Failed to get merge options") return fmt.Errorf("task: Failed to get merge options")
} }
// Merge the included Taskfile into the parent Taskfile // Merge the included Taskfiles into the parent Taskfile
for _, include := range includes {
if err := vertex.Taskfile.Merge( if err := vertex.Taskfile.Merge(
includedVertex.Taskfile, includedVertex.Taskfile,
include, include,
); err != nil { ); err != nil {
return err return err
} }
}
return nil return nil
}) })

View File

@ -140,17 +140,21 @@ func (r *Reader) include(node Node) error {
} }
// Create an edge between the Taskfiles // Create an edge between the Taskfiles
err = r.graph.AddEdge(node.Location(), includeNode.Location(), graph.EdgeData(include))
if errors.Is(err, graph.ErrEdgeAlreadyExists) {
edge, err := r.graph.Edge(node.Location(), includeNode.Location()) edge, err := r.graph.Edge(node.Location(), includeNode.Location())
if err != nil { if err == graph.ErrEdgeNotFound {
return err // If the edge doesn't exist, create it
} err = r.graph.AddEdge(
return &errors.TaskfileDuplicateIncludeError{ node.Location(),
URI: node.Location(), includeNode.Location(),
IncludedURI: includeNode.Location(), graph.EdgeData([]*ast.Include{include}),
Namespaces: []string{namespace, edge.Properties.Data.(*ast.Include).Namespace}, )
} } else {
// If the edge already exists
err = r.graph.UpdateEdge(
node.Location(),
includeNode.Location(),
graph.EdgeData(append(edge.Properties.Data.([]*ast.Include), include)),
)
} }
if errors.Is(err, graph.ErrEdgeCreatesCycle) { if errors.Is(err, graph.ErrEdgeCreatesCycle) {
return errors.TaskfileCycleError{ return errors.TaskfileCycleError{

View File

@ -6,13 +6,13 @@ includes:
included_without_dir: included_without_dir:
taskfile: ./module1 taskfile: ./module1
included_taskfile_without_dir: included_taskfile_without_dir:
taskfile: ./module2/Taskfile.yml taskfile: ./module1/Taskfile.yml
included_with_dir: included_with_dir:
taskfile: ./module3 taskfile: ./module2
dir: ./module3 dir: ./module2
included_taskfile_with_dir: included_taskfile_with_dir:
taskfile: ./module4/Taskfile.yml taskfile: ./module2/Taskfile.yml
dir: ./module4 dir: ./module2
included_os: ./Taskfile_{{OS}}.yml included_os: ./Taskfile_{{OS}}.yml
tasks: tasks:

View File

@ -1,6 +1,10 @@
version: '3' version: '3'
tasks: tasks:
gen_dir:
cmds:
- echo included_directory_without_dir > included_directory_without_dir.txt
gen_file: gen_file:
cmds: cmds:
- echo included_taskfile_without_dir > included_taskfile_without_dir.txt - echo included_taskfile_without_dir > included_taskfile_without_dir.txt

View File

@ -3,4 +3,8 @@ version: '3'
tasks: tasks:
gen_dir: gen_dir:
cmds: cmds:
- echo included_directory_without_dir > included_directory_without_dir.txt - echo included_directory_with_dir > included_directory_with_dir.txt
gen_file:
cmds:
- echo included_taskfile_with_dir > included_taskfile_with_dir.txt

View File

@ -1,6 +0,0 @@
version: '3'
tasks:
gen_file:
cmds:
- echo included_taskfile_with_dir > included_taskfile_with_dir.txt

View File

@ -1,6 +0,0 @@
version: '3'
tasks:
gen_dir:
cmds:
- echo included_directory_with_dir > included_directory_with_dir.txt