Resolve include task paths relative to playbooks

This commit is contained in:
Virgil 2026-04-01 21:46:52 +00:00
parent ca6dc7912e
commit 5951f74f27
2 changed files with 59 additions and 0 deletions

View file

@ -619,6 +619,44 @@ func TestExecutorExtra_ParseTasksIter_Bad_InvalidFile(t *testing.T) {
assert.Error(t, err)
}
func TestExecutorExtra_RunIncludeTasks_Good_RelativePath(t *testing.T) {
dir := t.TempDir()
includedPath := joinPath(dir, "included.yml")
yaml := `- name: Included first task
debug:
msg: first
- name: Included second task
debug:
msg: second
`
require.NoError(t, writeTestFile(includedPath, []byte(yaml), 0644))
gatherFacts := false
play := &Play{
Name: "Include tasks",
Hosts: "localhost",
GatherFacts: &gatherFacts,
Tasks: []Task{
{
Name: "Load included tasks",
IncludeTasks: "included.yml",
},
},
}
e := NewExecutor(dir)
var started []string
e.OnTaskStart = func(host string, task *Task) {
started = append(started, host+":"+task.Name)
}
require.NoError(t, e.runPlay(context.Background(), play))
assert.Contains(t, started, "localhost:Included first task")
assert.Contains(t, started, "localhost:Included second task")
}
func TestExecutorExtra_GetHostsIter_Good(t *testing.T) {
inv := &Inventory{
All: &InventoryGroup{

View file

@ -126,6 +126,8 @@ func (p *Parser) ParseInventory(path string) (*Inventory, error) {
//
// tasks, err := parser.ParseTasks("/workspace/roles/web/tasks/main.yml")
func (p *Parser) ParseTasks(path string) ([]Task, error) {
path = p.resolvePath(path)
data, err := coreio.Local.Read(path)
if err != nil {
return nil, coreerr.E("Parser.ParseTasks", "read tasks", err)
@ -145,6 +147,25 @@ func (p *Parser) ParseTasks(path string) ([]Task, error) {
return tasks, nil
}
// resolvePath resolves a possibly relative path against the parser base path.
func (p *Parser) resolvePath(path string) string {
if path == "" || pathIsAbs(path) || p.basePath == "" {
return path
}
candidates := []string{
joinPath(p.basePath, path),
path,
}
for _, candidate := range candidates {
if coreio.Local.Exists(candidate) {
return candidate
}
}
return joinPath(p.basePath, path)
}
// ParseTasksIter returns an iterator for tasks in a tasks file.
//
// Example: