@@ -107,6 +107,16 @@ func Compile(logger *Logger, bitfile *parser.Bitfile) (*Engine, error) {
107107 return engine , nil
108108}
109109
110+ // Files lists all files that are referenced by the engine.
111+ func (e * Engine ) Files () []string {
112+ return e .globber .Files ()
113+ }
114+
115+ // Ignored returns all files that are ignored by the engine.
116+ func (e * Engine ) Ignored () []string {
117+ return e .globber .Ignored ()
118+ }
119+
110120func (e * Engine ) analyse (bitfile * parser.Bitfile ) error {
111121 for _ , entry := range bitfile .Entries {
112122 switch entry := entry .(type ) {
@@ -124,6 +134,7 @@ func (e *Engine) analyse(bitfile *parser.Bitfile) error {
124134 target .inputs = & parser.RefList {Pos : entry .Pos }
125135 }
126136 if entry .Outputs == nil {
137+ fmt .Println (entry .Pos )
127138 target .outputs = & parser.RefList {Pos : entry .Pos }
128139 }
129140 logger := e .targetLogger (target )
@@ -141,7 +152,7 @@ func (e *Engine) analyse(bitfile *parser.Bitfile) error {
141152 target .build = directive
142153
143154 case "inputs" , "outputs" :
144- refs , err := parser .ParseRefList (directive .Value .Body )
155+ refs , err := parser .ParseRefList (directive .Pos , directive . Value .Body )
145156 if err != nil {
146157 return participle .Errorf (directive .Value .Pos , "failed to parse %s: %s" , directive .Command , err )
147158 }
@@ -367,15 +378,23 @@ func (e *Engine) Close() error {
367378}
368379
369380func (e * Engine ) Build (outputs []string ) error {
381+ return e .build (outputs , map [string ]bool {})
382+ }
383+
384+ func (e * Engine ) build (outputs []string , seen map [string ]bool ) error {
370385 if len (outputs ) == 0 {
371386 outputs = e .Outputs ()
372387 }
373388 for _ , name := range outputs {
374- var err error
375- name , err = e .normalisePath (name )
389+ name , err := e .normalisePath (name ) //nolint:govet
376390 if err != nil {
377391 return err
378392 }
393+ if seen [name ] {
394+ continue
395+ }
396+ seen [name ] = true
397+
379398 log := e .log .Scope (name )
380399
381400 target , err := e .getTarget (name )
@@ -389,15 +408,16 @@ func (e *Engine) Build(outputs []string) error {
389408 }
390409 continue
391410 }
392- log .Tracef ("Building." )
393411
394412 // Build dependencies.
395413 for _ , input := range target .inputs .Refs {
396- if err := e .Build ([]string {input .Text }); err != nil {
414+ if err := e .build ([]string {input .Text }, seen ); err != nil {
397415 return participle .Wrapf (input .Pos , err , "build failed" )
398416 }
399417 }
400418
419+ log .Tracef ("Building." )
420+
401421 // Build target.
402422 err = target .buildFunc (log , target )
403423 if err != nil {
@@ -437,12 +457,13 @@ func (e *Engine) defaultBuildFunc(log *Logger, target *Target) error {
437457// A function used to compute a hash of an output.
438458type outputRefHasher func (target * Target , ref * parser.Ref ) (hasher , error )
439459
440- func (e * Engine ) recursivelyComputeHash (target * Target , refHasher outputRefHasher , seen map [string ]* parser. Ref , forEach func (* Target , hasher )) (hasher , error ) {
460+ func (e * Engine ) recursivelyComputeHash (target * Target , refHasher outputRefHasher , seen map [string ]bool , forEach func (* Target , hasher )) (hasher , error ) {
441461 h := newHasher ()
442462 for _ , input := range target .inputs .Refs {
443- // if orig, ok := seen[input.Text]; ok {
444- // return 0, participle.Errorf(input.Pos, "circular dependency %s", orig.Pos)
445- // }
463+ if _ , ok := seen [input .Text ]; ok {
464+ continue
465+ }
466+ seen [input .Text ] = true
446467 inputTarget , err := e .getTarget (input .Text )
447468 if err != nil {
448469 return 0 , participle .Wrapf (input .Pos , err , "couldn't find matching input" )
@@ -454,7 +475,6 @@ func (e *Engine) recursivelyComputeHash(target *Target, refHasher outputRefHashe
454475 h .update (subh )
455476 }
456477 for _ , output := range target .outputs .Refs {
457- seen [output .Text ] = output
458478 rh , err := refHasher (target , output )
459479 if err != nil {
460480 return 0 , participle .Wrapf (output .Pos , err , "hash failed" )
@@ -534,12 +554,11 @@ func (e *Engine) evaluate() error {
534554 return err
535555 }
536556
537- subRefs , err := parser .ParseRefList (evaluated )
557+ subRefs , err := parser .ParseRefList (ref . Pos , evaluated )
538558 if err != nil {
539559 return participle .Errorf (ref .Pos , "failed to parse output %q: %s" , evaluated , err )
540560 }
541561 for _ , subRef := range subRefs .Refs {
542- subRef .Pos = ref .Pos
543562 subRef .Text , err = e .normalisePath (subRef .Text )
544563 if err != nil {
545564 return participle .Errorf (subRef .Pos , "%s" , err )
@@ -581,7 +600,7 @@ func (e *Engine) evaluate() error {
581600 if err != nil {
582601 return err
583602 }
584- innerRefs , err := parser .ParseRefList (evaluated )
603+ innerRefs , err := parser .ParseRefList (ref . Pos , evaluated )
585604 if err != nil {
586605 return participle .Errorf (ref .Pos , "failed to parse input %q: %s" , evaluated , err )
587606 }
@@ -615,13 +634,13 @@ func (e *Engine) evaluate() error {
615634 // Second pass - restore hashes from the DB.
616635 for _ , target := range e .targets {
617636 logger := e .targetLogger (target )
618- _ , err := e .recursivelyComputeHash (target , e .dbRefHasher , map [string ]* parser. Ref {}, func (target * Target , h hasher ) {
637+ _ , err := e .recursivelyComputeHash (target , e .dbRefHasher , map [string ]bool {}, func (target * Target , h hasher ) {
619638 target .storedHash = h
620639 })
621640 if err != nil && ! errors .Is (err , os .ErrNotExist ) {
622641 return err
623642 }
624- _ , err = e .recursivelyComputeHash (target , e .realRefHasher , map [string ]* parser. Ref {}, func (target * Target , h hasher ) {
643+ _ , err = e .recursivelyComputeHash (target , e .realRefHasher , map [string ]bool {}, func (target * Target , h hasher ) {
625644 target .realHash = h
626645 })
627646 if err != nil && ! errors .Is (err , os .ErrNotExist ) {
0 commit comments