@@ -23,56 +23,81 @@ func ParseProject(io io.IO, filename string) task.Project {
2323
2424 // Iterate over top-level nodes
2525 for _ , node := range doc .Nodes {
26- if node .Name != "task" {
27- panic (fmt .Sprintf ("unknown top-level node: %s" , node .Name ))
28- }
26+ if node .Name == "default" {
27+ // Parse default node with properties: task and args
28+ for _ , prop := range node .Properties {
29+ if prop .Key == "task" {
30+ config .DefaultTask = prop .Value .Value
31+ } else if prop .Key == "args" {
32+ // Split args by whitespace to get individual arguments
33+ argsStr := prop .Value .Value
34+ if argsStr != "" {
35+ // Simple split by space - could be enhanced to handle quoted strings
36+ config .DefaultArgs = splitArgs (argsStr )
37+ }
38+ }
39+ }
2940
30- if len (node .Arguments ) < 1 {
31- panic ("task node requires a name argument" )
32- }
41+ if config .DefaultTask == "" {
42+ panic ("default node requires a 'task' property" )
43+ }
44+ } else {
45+ // fmt.Printf("[DEBUG] Found task node: %+v\n", node.Name)
46+ // fmt.Printf("[DEBUG] Found task node: %+v\n", node)
47+ // fmt.Printf("[DEBUG] Arguments: %+v\n", node.Arguments)
48+ // fmt.Printf("[DEBUG] Children: %+v\n", node.Children)
3349
34- taskName := node .Arguments [0 ].Value
50+ if node .Name != "task" {
51+ panic (fmt .Sprintf ("unknown top-level node: %s" , node .Name ))
52+ }
3553
36- task := task.Task {
37- Name : taskName ,
38- DependsOn : []string {},
39- EnvVars : make (map [string ]string ),
40- }
54+ if len (node .Arguments ) < 1 {
55+ panic ("task node requires a name argument" )
56+ }
4157
42- if node .Children != nil {
43- for _ , child := range node .Children {
44- switch child .Name {
45- case "cmd" :
46- cmd , cmdTemplate := parseCmdNode (child )
47- if cmdTemplate != nil {
48- task .CommandTemplate = cmdTemplate
49- } else {
50- task .Command = cmd
51- }
52- case "description" :
53- if len (child .Arguments ) > 0 {
54- task .Description = child .Arguments [0 ].Value
55- }
56- case "depends" :
57- if child .Children != nil {
58- for _ , dep := range child .Children {
59- if dep .Name == "on" && len (dep .Arguments ) > 0 {
60- task .DependsOn = append (task .DependsOn , dep .Arguments [0 ].Value )
58+ taskName := node .Arguments [0 ].Value
59+
60+ task := task.Task {
61+ Name : taskName ,
62+ DependsOn : []string {},
63+ EnvVars : make (map [string ]string ),
64+ }
65+
66+ if node .Children != nil {
67+ for _ , child := range node .Children {
68+ switch child .Name {
69+ case "cmd" :
70+ cmd , cmdTemplate := parseCmdNode (child )
71+ if cmdTemplate != nil {
72+ task .CommandTemplate = cmdTemplate
73+ } else {
74+ task .Command = cmd
75+ }
76+ case "description" :
77+ if len (child .Arguments ) > 0 {
78+ task .Description = child .Arguments [0 ].Value
79+ }
80+ case "depends" :
81+ if child .Children != nil {
82+ for _ , dep := range child .Children {
83+ if dep .Name == "on" && len (dep .Arguments ) > 0 {
84+ task .DependsOn = append (task .DependsOn , dep .Arguments [0 ].Value )
85+ }
6186 }
6287 }
88+ case "env" :
89+ // env KEY="value" (property syntax)
90+ for _ , prop := range child .Properties {
91+ task .EnvVars [prop .Key ] = prop .Value .Value
92+ }
93+ default :
94+ panic (fmt .Sprintf ("unknown property in task '%s': %s" , taskName , child .Name ))
6395 }
64- case "env" :
65- // env KEY="value" (property syntax)
66- for _ , prop := range child .Properties {
67- task .EnvVars [prop .Key ] = prop .Value .Value
68- }
69- default :
70- panic (fmt .Sprintf ("unknown property in task '%s': %s" , taskName , child .Name ))
7196 }
7297 }
73- }
7498
75- config .Tasks .Set (taskName , task )
99+ config .Tasks .Set (taskName , task )
100+ }
76101 }
77102
78103 return config
@@ -180,3 +205,46 @@ func parseWhereVariable(node kdly.Node) task.WhereVariable {
180205 Children : children ,
181206 }
182207}
208+
209+ // splitArgs splits a string of arguments by whitespace
210+ // This is a simple implementation that doesn't handle quoted strings
211+ func splitArgs (argsStr string ) []string {
212+ if argsStr == "" {
213+ return nil
214+ }
215+
216+ var args []string
217+ var current string
218+ inQuote := false
219+ quoteChar := rune (0 )
220+
221+ for _ , ch := range argsStr {
222+ if ! inQuote {
223+ if ch == ' ' || ch == '\t' {
224+ if current != "" {
225+ args = append (args , current )
226+ current = ""
227+ }
228+ continue
229+ } else if ch == '"' || ch == '\'' {
230+ inQuote = true
231+ quoteChar = ch
232+ continue
233+ }
234+ } else {
235+ if ch == quoteChar {
236+ inQuote = false
237+ quoteChar = 0
238+ continue
239+ }
240+ }
241+
242+ current += string (ch )
243+ }
244+
245+ if current != "" {
246+ args = append (args , current )
247+ }
248+
249+ return args
250+ }
0 commit comments