github.com/octohelm/wagon@v0.0.0-20240308040401-88662650dc0b/pkg/engine/plan/task/fs_entries.go (about)

     1  package task
     2  
     3  import (
     4  	"context"
     5  	"dagger.io/dagger"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	"github.com/octohelm/wagon/pkg/engine/daggerutil"
    10  	"github.com/octohelm/wagon/pkg/engine/plan/task/core"
    11  )
    12  
    13  func init() {
    14  	core.DefaultFactory.Register(&Entries{})
    15  }
    16  
    17  type Entries struct {
    18  	core.Task
    19  
    20  	Input core.FS `json:"input"`
    21  
    22  	Depth int `json:"depth" default:"-1"`
    23  
    24  	// list of files and directories (ends with /) at the given path.
    25  	Output []string `json:"-" wagon:"generated,name=output"`
    26  }
    27  
    28  func (e *Entries) Do(ctx context.Context) error {
    29  	return daggerutil.Do(ctx, func(c *dagger.Client) error {
    30  		fw := &entriesWalker{
    31  			d:        e.Input.LoadDirectory(c),
    32  			maxDepth: e.Depth,
    33  		}
    34  
    35  		if err := fw.walk(ctx, "/", func(path string) error {
    36  			e.Output = append(e.Output, path)
    37  			return nil
    38  		}); err != nil {
    39  			return err
    40  		}
    41  
    42  		return nil
    43  	})
    44  }
    45  
    46  type entriesWalker struct {
    47  	d        *dagger.Directory
    48  	maxDepth int
    49  }
    50  
    51  func (w *entriesWalker) walk(ctx context.Context, path string, walkFunc func(path string) error) error {
    52  	if path == "" {
    53  		path = "/"
    54  	}
    55  
    56  	entries, err := w.d.Entries(ctx, dagger.DirectoryEntriesOpts{
    57  		Path: path,
    58  	})
    59  	if err != nil {
    60  		// entries failed means path is not directory
    61  		if err := walkFunc(path); err != nil {
    62  			return err
    63  		}
    64  		return nil
    65  	}
    66  
    67  	if w.maxDepth > 0 && strings.Count(path, "/") >= w.maxDepth {
    68  		return walkFunc(path + "/")
    69  	}
    70  
    71  	if len(entries) == 0 {
    72  		return walkFunc(path + "/")
    73  	}
    74  
    75  	for _, entry := range entries {
    76  		p := filepath.Join(path, entry)
    77  
    78  		if err := w.walk(ctx, p, walkFunc); err != nil {
    79  			return err
    80  		}
    81  	}
    82  
    83  	return nil
    84  }