From eefbac34079bb4001fb7bba60368652c2d19cdd3 Mon Sep 17 00:00:00 2001 From: Hedzr Yeh Date: Wed, 30 Oct 2024 12:00:21 +0800 Subject: [PATCH] cmdr: add LoadedSources --- cli/config.go | 7 ++++--- cli/for_test.go | 1 + cli/types.go | 26 ++++++++++++++++++++++++++ cli/worker/pre.go | 27 +++++++++++++++++++++------ cmdr.go | 2 ++ 5 files changed, 54 insertions(+), 9 deletions(-) diff --git a/cli/config.go b/cli/config.go index 9dfc43d..8163842 100644 --- a/cli/config.go +++ b/cli/config.go @@ -66,9 +66,10 @@ type Runner interface { Root() *RootCommand // root command Args() []string // command-line - SuggestRetCode() int // os process return code - SetSuggestRetCode(ret int) // update ret code (0-255) from onAction, onTask, ... - ParsedState() ParsedState // the parsed states + SuggestRetCode() int // os process return code + SetSuggestRetCode(ret int) // update ret code (0-255) from onAction, onTask, ... + ParsedState() ParsedState // the parsed states + LoadedSources() (results []LoadedSources) // the loaded sources // Actions return a state map. // The states can be: diff --git a/cli/for_test.go b/cli/for_test.go index f39f9b2..d561cf0 100644 --- a/cli/for_test.go +++ b/cli/for_test.go @@ -950,6 +950,7 @@ func (*workerS) Root() *RootCommand { return nil func (*workerS) Args() []string { return nil } // func (w *workerS) SuggestRetCode() int { return w.retCode } // func (w *workerS) ParsedState() ParsedState { return nil } +func (w *workerS) LoadedSources() (results []LoadedSources) { return } // diff --git a/cli/types.go b/cli/types.go index f641b9e..4ea7b21 100644 --- a/cli/types.go +++ b/cli/types.go @@ -46,6 +46,32 @@ type Loader interface { Load(app App) (err error) } +// SingleFileLoadable finds out a loader if it supports loading single file +type SingleFileLoadable interface { + LoadFile(ctx context.Context, filename string, app App) (err error) +} + +// WriteBackHandler is same with [store.Writable]. +type WriteBackHandler interface { + Save(ctx context.Context) error +} + +// LoadedSource is a package which contains all loaded +// files/sources. +type LoadedSource struct { + Main []string // such as main config file(s) + Children []string // the config files in conf.d/ subdirectory +} + +// LoadedSources collect the assorted sources. +type LoadedSources map[string]*LoadedSource + +// QueryLoadedSources will be available if a loader allows +// which loaded sources are queried. +type QueryLoadedSources interface { + LoadedSources() LoadedSources +} + type RootCommand struct { AppName string Version string diff --git a/cli/worker/pre.go b/cli/worker/pre.go index 7e846a0..fd3977c 100644 --- a/cli/worker/pre.go +++ b/cli/worker/pre.go @@ -210,10 +210,15 @@ func (w *workerS) commandsToStoreR(ctx context.Context, root *cli.RootCommand, c func (w *workerS) loadLoaders(ctx context.Context) (err error) { w.precheckLoaders(ctx) - // By default, we try loading `$(pwd)/.appName.json'. - // The main reason is the feature doesn't take new dependence to another 3rd-party lib. - // For cmdr/v2, we restrict to go builtins, google, and ours libraries. - // And, ours libraries will not import any others except go builtins and google's. + // By default, we try loading `$(pwd)/.appName.json' if there + // is no any loaders specified. + // + // The main reason is the feature doesn't take new dependence + // to another 3rd-party lib. + // + // For cmdr/v2, we restrict to go builtins, google, and ours + // libraries. And, ours libraries will not import any others + // except go builtins and google's. if len(w.Config.Loaders) == 0 { appDir := dir.GetCurrentDir() appName := w.Name() @@ -221,12 +226,11 @@ func (w *workerS) loadLoaders(ctx context.Context) (err error) { jsonLoader.filename = path.Join(appDir, "."+appName+".json") logz.DebugContext(ctx, "use internal tiny json loader", "filename", jsonLoader.filename) w.Config.Loaders = append(w.Config.Loaders, jsonLoader) - return } for _, loader := range w.Config.Loaders { if loader != nil { - if err = loader.Load(w.root.App()); err != nil { + if err = loader.Load(ctx, w.root.App()); err != nil { break } } @@ -234,6 +238,17 @@ func (w *workerS) loadLoaders(ctx context.Context) (err error) { return } +func (w *workerS) LoadedSources() (results []cli.LoadedSources) { + for _, loader := range w.Config.Loaders { + if loader != nil { + if q, ok := loader.(cli.QueryLoadedSources); ok { + results = append(results, q.LoadedSources()) + } + } + } + return +} + func (w *workerS) precheckLoaders(ctx context.Context) { if w.configFile != "" { found := false diff --git a/cmdr.go b/cmdr.go index 585a49a..7905368 100644 --- a/cmdr.go +++ b/cmdr.go @@ -99,6 +99,8 @@ func ParsedLastCmd() cli.Cmd { return App().ParsedState().LastCmd() } func ParsedCommands() []cli.Cmd { return App().ParsedState().MatchedCommands() } // the parsed commands func ParsedPositionalArgs() []string { return App().ParsedState().PositionalArgs() } // the rest positional args +func LoadedSources() []cli.LoadedSources { return App().LoadedSources() } // the loaded config files or other sources + // Store returns the KVStore associated with current App(). func Store() store.Store { return App().Store() }