44 "errors"
55 "fmt"
66
7- "github.com/jahvon/tuikit/types"
87 "github.com/spf13/cobra"
98
109 "github.com/jahvon/flow/cmd/internal/flags"
@@ -16,31 +15,67 @@ import (
1615 "github.com/jahvon/flow/types/executable"
1716)
1817
19- func RegisterLibraryCmd (ctx * context.Context , rootCmd * cobra.Command ) {
20- libraryCmd := & cobra.Command {
21- Use : "library" ,
22- Short : "View and manage your library of workspaces and executables." ,
23- Aliases : []string {"lib" },
24- Args : cobra .NoArgs ,
18+ func RegisterBrowseCmd (ctx * context.Context , rootCmd * cobra.Command ) {
19+ browseCmd := & cobra.Command {
20+ Use : "browse [EXECUTABLE-REFERENCE]" ,
21+ Short : "Discover and explore available executables." ,
22+ Aliases : []string {"ls" , "library" },
23+ Long : "Browse executables across workspaces.\n \n " +
24+ " flow browse # Interactive multi-pane executable browser\n " +
25+ " flow browse --list # Simple list view of executables\n " +
26+ " flow browse VERB [ID] # Detailed view of specific executable\n \n " +
27+ fmt .Sprintf (
28+ "See %s for more information on executable verbs and " +
29+ "%s for more information on executable references." ,
30+ io .TypesDocsURL ("flowfile" , "executableverb" ),
31+ io .TypesDocsURL ("flowfile" , "executableref" ),
32+ ),
33+ Args : cobra .MaximumNArgs (2 ),
34+ ValidArgsFunction : func (cmd * cobra.Command , args []string , toComplete string ) ([]string , cobra.ShellCompDirective ) {
35+ execList , err := ctx .ExecutableCache .GetExecutableList (ctx .Logger )
36+ if err != nil {
37+ return nil , cobra .ShellCompDirectiveError
38+ }
39+ execIDs := make ([]string , 0 , len (execList ))
40+ for _ , e := range execList {
41+ execIDs = append (execIDs , e .ID ())
42+ }
43+ return execIDs , cobra .ShellCompDirectiveNoFileComp
44+ },
2545 PreRun : func (cmd * cobra.Command , args []string ) { StartTUI (ctx , cmd ) },
2646 PostRun : func (cmd * cobra.Command , args []string ) { WaitForTUI (ctx , cmd ) },
27- Run : func (cmd * cobra.Command , args []string ) { libraryFunc (ctx , cmd , args ) },
28- }
29- RegisterFlag (ctx , libraryCmd , * flags .FilterWorkspaceFlag )
30- RegisterFlag (ctx , libraryCmd , * flags .FilterNamespaceFlag )
31- RegisterFlag (ctx , libraryCmd , * flags .FilterVerbFlag )
32- RegisterFlag (ctx , libraryCmd , * flags .FilterTagFlag )
33- RegisterFlag (ctx , libraryCmd , * flags .FilterExecSubstringFlag )
34- RegisterFlag (ctx , libraryCmd , * flags .AllNamespacesFlag )
35- registerGlanceLibraryCmd (ctx , libraryCmd )
36- registerViewLibraryCmd (ctx , libraryCmd )
37- rootCmd .AddCommand (libraryCmd )
47+ Run : func (cmd * cobra.Command , args []string ) { browseFunc (ctx , cmd , args ) },
48+ }
49+ RegisterFlag (ctx , browseCmd , * flags .ListFlag )
50+ RegisterFlag (ctx , browseCmd , * flags .OutputFormatFlag )
51+ RegisterFlag (ctx , browseCmd , * flags .FilterWorkspaceFlag )
52+ RegisterFlag (ctx , browseCmd , * flags .FilterNamespaceFlag )
53+ RegisterFlag (ctx , browseCmd , * flags .FilterVerbFlag )
54+ RegisterFlag (ctx , browseCmd , * flags .FilterTagFlag )
55+ RegisterFlag (ctx , browseCmd , * flags . FilterExecSubstringFlag )
56+ RegisterFlag (ctx , browseCmd , * flags . AllNamespacesFlag )
57+ rootCmd .AddCommand (browseCmd )
3858}
3959
40- func libraryFunc (ctx * context.Context , cmd * cobra.Command , _ []string ) {
60+ func browseFunc (ctx * context.Context , cmd * cobra.Command , args []string ) {
61+ if len (args ) >= 1 {
62+ viewExecutable (ctx , cmd , args )
63+ return
64+ }
65+
66+ listMode := flags .ValueFor [bool ](ctx , cmd , * flags .ListFlag , false )
67+ if listMode || ! TUIEnabled (ctx , cmd ) {
68+ listExecutables (ctx , cmd , args )
69+ return
70+ }
71+
72+ executableLibrary (ctx , cmd , args )
73+ }
74+
75+ func executableLibrary (ctx * context.Context , cmd * cobra.Command , _ []string ) {
4176 logger := ctx .Logger
4277 if ! TUIEnabled (ctx , cmd ) {
43- logger .FatalErr (errors .New ("library command requires an interactive terminal" ))
78+ logger .FatalErr (errors .New ("interactive discovery requires an interactive terminal" ))
4479 }
4580
4681 wsFilter := flags .ValueFor [string ](ctx , cmd , * flags .FilterWorkspaceFlag , false )
@@ -92,26 +127,7 @@ func libraryFunc(ctx *context.Context, cmd *cobra.Command, _ []string) {
92127 SetView (ctx , cmd , libraryModel )
93128}
94129
95- func registerGlanceLibraryCmd (ctx * context.Context , libraryCmd * cobra.Command ) {
96- glanceCmd := & cobra.Command {
97- Use : "glance" ,
98- Short : "View a list of just executables." ,
99- Args : cobra .NoArgs ,
100- PreRun : func (cmd * cobra.Command , args []string ) { StartTUI (ctx , cmd ) },
101- PostRun : func (cmd * cobra.Command , args []string ) { WaitForTUI (ctx , cmd ) },
102- Run : func (cmd * cobra.Command , args []string ) { glanceLibraryCmd (ctx , cmd , args ) },
103- }
104- RegisterFlag (ctx , glanceCmd , * flags .OutputFormatFlag )
105- RegisterFlag (ctx , glanceCmd , * flags .FilterWorkspaceFlag )
106- RegisterFlag (ctx , glanceCmd , * flags .FilterNamespaceFlag )
107- RegisterFlag (ctx , glanceCmd , * flags .FilterVerbFlag )
108- RegisterFlag (ctx , glanceCmd , * flags .FilterTagFlag )
109- RegisterFlag (ctx , glanceCmd , * flags .FilterExecSubstringFlag )
110- RegisterFlag (ctx , glanceCmd , * flags .AllNamespacesFlag )
111- libraryCmd .AddCommand (glanceCmd )
112- }
113-
114- func glanceLibraryCmd (ctx * context.Context , cmd * cobra.Command , _ []string ) {
130+ func listExecutables (ctx * context.Context , cmd * cobra.Command , _ []string ) {
115131 logger := ctx .Logger
116132 wsFilter := flags .ValueFor [string ](ctx , cmd , * flags .FilterWorkspaceFlag , false )
117133 if wsFilter == "." {
@@ -149,57 +165,35 @@ func glanceLibraryCmd(ctx *context.Context, cmd *cobra.Command, _ []string) {
149165
150166 if TUIEnabled (ctx , cmd ) {
151167 runFunc := func (ref string ) error { return runByRef (ctx , cmd , ref ) }
152- view := execIO .NewExecutableListView (
153- ctx ,
154- filteredExec ,
155- types .Format (outputFormat ),
156- runFunc ,
157- )
168+ view := execIO .NewExecutableListView (ctx , filteredExec , runFunc )
158169 SetView (ctx , cmd , view )
159170 } else {
160171 execIO .PrintExecutableList (logger , outputFormat , filteredExec )
161172 }
162173}
163174
164- func registerViewLibraryCmd (ctx * context.Context , libraryCmd * cobra.Command ) {
165- viewCmd := & cobra.Command {
166- Use : "view VERB ID" ,
167- Aliases : []string {"show" , "find" },
168- Short : "View an executable's documentation. The executable is found by reference." ,
169- Long : "View an executable by the executable's verb and ID.\n The target executable's ID should be in the " +
170- "form of 'ws/ns:name' and the verb should match the target executable's verb or one of its aliases.\n \n " +
171- fmt .Sprintf (
172- "See %s for more information on executable verbs.\n " +
173- "See %s for more information on executable IDs." ,
174- io .TypesDocsURL ("flowfile" , "ExecutableVerb" ),
175- io .TypesDocsURL ("flowfile" , "ExecutableRef" ),
176- ),
177- Args : cobra .ExactArgs (2 ),
178- PreRun : func (cmd * cobra.Command , args []string ) { StartTUI (ctx , cmd ) },
179- PostRun : func (cmd * cobra.Command , args []string ) { WaitForTUI (ctx , cmd ) },
180- Run : func (cmd * cobra.Command , args []string ) { viewLibraryFunc (ctx , cmd , args ) },
181- }
182- RegisterFlag (ctx , viewCmd , * flags .OutputFormatFlag )
183- libraryCmd .AddCommand (viewCmd )
184- }
185-
186- func viewLibraryFunc (ctx * context.Context , cmd * cobra.Command , args []string ) {
175+ func viewExecutable (ctx * context.Context , cmd * cobra.Command , args []string ) {
187176 logger := ctx .Logger
177+
188178 verbStr := args [0 ]
189179 verb := executable .Verb (verbStr )
190180 if err := verb .Validate (); err != nil {
191181 logger .FatalErr (err )
192182 }
193- id := args [1 ]
194- ws , ns , name := executable .MustParseExecutableID (id )
195- if ws == "" {
196- ws = ctx .CurrentWorkspace .AssignedName ()
197- }
198- if ns == "" && ctx .Config .CurrentNamespace != "" {
199- ns = ctx .Config .CurrentNamespace
183+
184+ var execID string
185+ if len (args ) > 1 {
186+ id := args [1 ]
187+ ws , ns , name := executable .MustParseExecutableID (id )
188+ if ws == executable .WildcardWorkspace {
189+ ws = ctx .CurrentWorkspace .AssignedName ()
190+ }
191+ if ns == executable .WildcardNamespace && ctx .Config .CurrentNamespace != "" {
192+ ns = ctx .Config .CurrentNamespace
193+ }
194+ execID = executable .NewExecutableID (ws , ns , name )
200195 }
201- id = executable .NewExecutableID (ws , ns , name )
202- ref := executable .NewRef (id , verb )
196+ ref := executable .NewRef (execID , verb )
203197
204198 exec , err := ctx .ExecutableCache .GetExecutableByRef (logger , ref )
205199 if err != nil && errors .Is (cache .NewExecutableNotFoundError (ref .String ()), err ) {
@@ -218,7 +212,7 @@ func viewLibraryFunc(ctx *context.Context, cmd *cobra.Command, args []string) {
218212 outputFormat := flags .ValueFor [string ](ctx , cmd , * flags .OutputFormatFlag , false )
219213 if TUIEnabled (ctx , cmd ) {
220214 runFunc := func (ref string ) error { return runByRef (ctx , cmd , ref ) }
221- view := execIO .NewExecutableView (ctx , exec , types . Format ( outputFormat ), runFunc )
215+ view := execIO .NewExecutableView (ctx , exec , runFunc )
222216 SetView (ctx , cmd , view )
223217 } else {
224218 execIO .PrintExecutable (logger , outputFormat , exec )
0 commit comments