Files
truecharts/clustertool/pkg/helper/helper.go
T
2024-10-19 15:18:05 +02:00

118 lines
3.2 KiB
Go

package helper
import (
"fmt"
"io/fs"
"os"
"path/filepath"
"slices"
"sync"
"github.com/rs/zerolog/log"
)
var ExcludedDirs = []string{
"templates", ".github", "docs",
".vscode", "tools", ".devcontainer",
"testdata",
}
// WalkMode specifies the mode for walking charts
type WalkMode int
const (
// SyncMode processes charts sequentially
SyncMode WalkMode = iota
// AsyncMode processes charts concurrently
AsyncMode
)
type ActionFunc func(string, string) error
func getWalkDirFunc(action ActionFunc, bump string, mode WalkMode, wg *sync.WaitGroup) fs.WalkDirFunc {
return func(path string, info os.DirEntry, err error) error {
if err != nil {
return err
}
if info.IsDir() && slices.Contains(ExcludedDirs, info.Name()) {
return filepath.SkipDir
}
// Check if the current file is Chart.yaml
if info.Name() == "Chart.yaml" {
switch mode {
case SyncMode:
// Process charts sequentially
if err := action(path, bump); err != nil {
log.Fatal().Err(err).Msgf("Error executing action on Chart.yaml at [%s]", path)
}
case AsyncMode:
// Process charts concurrently
wg.Add(1)
go func(path string) {
defer wg.Done()
if err := action(path, bump); err != nil {
log.Fatal().Err(err).Msgf("Error executing action on Chart.yaml at [%s]", path)
}
}(path)
default:
return fmt.Errorf("invalid mode: %d", mode)
}
// Stop processing the current directory after finding Chart.yaml
return filepath.SkipDir
}
return nil
}
}
// TODO: Replace with WalkCharts2, first we have to refactor the "action" function
// Should be a valid fs.WalkDirFunc, if we need to add state to that function,
// we can use a closure to pass the state.
// UpdateChartFiles traverses Chart.yaml files based on the provided paths and executes the specified function.
// If paths is empty, process all charts.
// The mode parameter toggles between synchronous and asynchronous modes.
func WalkCharts(paths []string, action func(string, string) error, bump string, mode WalkMode) error {
var wg sync.WaitGroup
if len(paths) == 0 {
// If paths is empty, default to processing all charts in the charts directory
paths = []string{"./charts"}
}
for _, rootDir := range paths {
err := filepath.WalkDir(rootDir, getWalkDirFunc(action, bump, mode, &wg))
if err != nil {
return fmt.Errorf("error walking directory %s: %s", rootDir, err)
}
}
// Wait for all goroutines to finish in asynchronous mode
if mode == AsyncMode {
wg.Wait()
}
return nil
}
func UniqueNonEmptyElementsOf(s []string) []string {
unique := make(map[string]bool, len(s))
us := make([]string, len(unique))
for _, elem := range s {
if len(elem) != 0 {
if !unique[elem] {
us = append(us, elem)
unique[elem] = true
}
}
}
return us
}