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:
parent
6951e5cd0c
commit
f19c520f23
@ -19,7 +19,7 @@ const (
|
|||||||
CodeTaskfileCacheNotFound
|
CodeTaskfileCacheNotFound
|
||||||
CodeTaskfileVersionCheckError
|
CodeTaskfileVersionCheckError
|
||||||
CodeTaskfileNetworkTimeout
|
CodeTaskfileNetworkTimeout
|
||||||
CodeTaskfileDuplicateInclude
|
_ // CodeTaskfileDuplicateInclude
|
||||||
CodeTaskfileCycle
|
CodeTaskfileCycle
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -79,17 +79,19 @@ 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
|
||||||
if err := vertex.Taskfile.Merge(
|
for _, include := range includes {
|
||||||
includedVertex.Taskfile,
|
if err := vertex.Taskfile.Merge(
|
||||||
include,
|
includedVertex.Taskfile,
|
||||||
); err != nil {
|
include,
|
||||||
return err
|
); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -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))
|
edge, err := r.graph.Edge(node.Location(), includeNode.Location())
|
||||||
if errors.Is(err, graph.ErrEdgeAlreadyExists) {
|
if err == graph.ErrEdgeNotFound {
|
||||||
edge, err := r.graph.Edge(node.Location(), includeNode.Location())
|
// If the edge doesn't exist, create it
|
||||||
if err != nil {
|
err = r.graph.AddEdge(
|
||||||
return err
|
node.Location(),
|
||||||
}
|
includeNode.Location(),
|
||||||
return &errors.TaskfileDuplicateIncludeError{
|
graph.EdgeData([]*ast.Include{include}),
|
||||||
URI: node.Location(),
|
)
|
||||||
IncludedURI: includeNode.Location(),
|
} else {
|
||||||
Namespaces: []string{namespace, edge.Properties.Data.(*ast.Include).Namespace},
|
// 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{
|
||||||
|
10
testdata/includes/Taskfile.yml
vendored
10
testdata/includes/Taskfile.yml
vendored
@ -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:
|
||||||
|
4
testdata/includes/module1/Taskfile.yml
vendored
4
testdata/includes/module1/Taskfile.yml
vendored
@ -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
|
||||||
|
6
testdata/includes/module2/Taskfile.yml
vendored
6
testdata/includes/module2/Taskfile.yml
vendored
@ -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
|
||||||
|
6
testdata/includes/module3/Taskfile.yml
vendored
6
testdata/includes/module3/Taskfile.yml
vendored
@ -1,6 +0,0 @@
|
|||||||
version: '3'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
gen_file:
|
|
||||||
cmds:
|
|
||||||
- echo included_taskfile_with_dir > included_taskfile_with_dir.txt
|
|
6
testdata/includes/module4/Taskfile.yml
vendored
6
testdata/includes/module4/Taskfile.yml
vendored
@ -1,6 +0,0 @@
|
|||||||
version: '3'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
gen_dir:
|
|
||||||
cmds:
|
|
||||||
- echo included_directory_with_dir > included_directory_with_dir.txt
|
|
Loading…
x
Reference in New Issue
Block a user