@@ -31,6 +31,11 @@ type cmdRemote struct {
31
31
global * cmdGlobal
32
32
}
33
33
34
+ type remoteColumn struct {
35
+ Name string
36
+ Data func (string , config.Remote ) string
37
+ }
38
+
34
39
// Command returns a cobra.Command for use with (*cobra.Command).AddCommand.
35
40
func (c * cmdRemote ) Command () * cobra.Command {
36
41
cmd := & cobra.Command {}
@@ -706,7 +711,8 @@ type cmdRemoteList struct {
706
711
global * cmdGlobal
707
712
remote * cmdRemote
708
713
709
- flagFormat string
714
+ flagFormat string
715
+ flagColumns string
710
716
}
711
717
712
718
// Command returns a cobra.Command for use with (*cobra.Command).AddCommand.
@@ -716,14 +722,130 @@ func (c *cmdRemoteList) Command() *cobra.Command {
716
722
cmd .Aliases = []string {"ls" }
717
723
cmd .Short = i18n .G ("List the available remotes" )
718
724
cmd .Long = cli .FormatSection (i18n .G ("Description" ), i18n .G (
719
- `List the available remotes` ))
725
+ `List the available remotes
726
+
727
+ Default column layout: nupaPsg
728
+
729
+ == Columns ==
730
+ The -c option takes a comma separated list of arguments that control
731
+ which instance attributes to output when displaying in table or csv
732
+ format.
733
+
734
+ Column arguments are either pre-defined shorthand chars (see below),
735
+ or (extended) config keys.
736
+
737
+ Commas between consecutive shorthand chars are optional.
738
+
739
+ Pre-defined column shorthand chars:
740
+ n - Name
741
+ u - URL
742
+ p - Protocol
743
+ a - Auth Type
744
+ P - Public
745
+ s - Static
746
+ g - Global` ))
720
747
721
748
cmd .RunE = c .Run
722
749
cmd .Flags ().StringVarP (& c .flagFormat , "format" , "f" , "table" , i18n .G ("Format (csv|json|table|yaml|compact)" )+ "``" )
750
+ cmd .Flags ().StringVarP (& c .flagColumns , "columns" , "c" , defaultRemoteColumns , i18n .G ("Columns" )+ "``" )
723
751
724
752
return cmd
725
753
}
726
754
755
+ const defaultRemoteColumns = "nupaPsg"
756
+
757
+ func (c * cmdRemoteList ) parseColumns () ([]remoteColumn , error ) {
758
+ columnsShorthandMap := map [rune ]remoteColumn {
759
+ 'n' : {i18n .G ("NAME" ), c .remoteNameColumnData },
760
+ 'u' : {i18n .G ("URL" ), c .addrColumnData },
761
+ 'p' : {i18n .G ("PROTOCOL" ), c .protocolColumnData },
762
+ 'a' : {i18n .G ("AUTH TYPE" ), c .authTypeColumnData },
763
+ 'P' : {i18n .G ("PUBLIC" ), c .publicColumnData },
764
+ 's' : {i18n .G ("STATIC" ), c .staticColumnData },
765
+ 'g' : {i18n .G ("GLOBAL" ), c .globalColumnData },
766
+ }
767
+
768
+ columnList := strings .Split (c .flagColumns , "," )
769
+ columns := []remoteColumn {}
770
+
771
+ for _ , columnEntry := range columnList {
772
+ if columnEntry == "" {
773
+ return nil , fmt .Errorf (i18n .G ("Empty column entry (redundant, leading or trailing command) in '%s'" ), c .flagColumns )
774
+ }
775
+
776
+ for _ , columnRune := range columnEntry {
777
+ column , ok := columnsShorthandMap [columnRune ]
778
+ if ! ok {
779
+ return nil , fmt .Errorf (i18n .G ("Unknown column shorthand char '%c' in '%s'" ), columnRune , columnEntry )
780
+ }
781
+
782
+ columns = append (columns , column )
783
+ }
784
+ }
785
+
786
+ return columns , nil
787
+ }
788
+
789
+ func (c * cmdRemoteList ) remoteNameColumnData (name string , rc config.Remote ) string {
790
+ conf := c .global .conf
791
+
792
+ strName := name
793
+ if name == conf .DefaultRemote {
794
+ strName = fmt .Sprintf ("%s (%s)" , name , i18n .G ("current" ))
795
+ }
796
+
797
+ return strName
798
+ }
799
+
800
+ func (c * cmdRemoteList ) addrColumnData (name string , rc config.Remote ) string {
801
+ return rc .Addr
802
+ }
803
+
804
+ func (c * cmdRemoteList ) protocolColumnData (name string , rc config.Remote ) string {
805
+ return rc .Protocol
806
+ }
807
+
808
+ func (c * cmdRemoteList ) authTypeColumnData (name string , rc config.Remote ) string {
809
+ if rc .AuthType == "" {
810
+ if strings .HasPrefix (rc .Addr , "unix:" ) {
811
+ rc .AuthType = "file access"
812
+ } else if rc .Protocol != "incus" {
813
+ rc .AuthType = "none"
814
+ } else {
815
+ rc .AuthType = api .AuthenticationMethodTLS
816
+ }
817
+ }
818
+
819
+ return rc .AuthType
820
+ }
821
+
822
+ func (c * cmdRemoteList ) publicColumnData (name string , rc config.Remote ) string {
823
+ strPublic := i18n .G ("NO" )
824
+ if rc .Public {
825
+ strPublic = i18n .G ("YES" )
826
+ }
827
+
828
+ return strPublic
829
+ }
830
+
831
+ func (c * cmdRemoteList ) staticColumnData (name string , rc config.Remote ) string {
832
+ strStatic := i18n .G ("NO" )
833
+ if rc .Static {
834
+ strStatic = i18n .G ("YES" )
835
+ }
836
+
837
+ return strStatic
838
+ }
839
+
840
+ func (c * cmdRemoteList ) globalColumnData (name string , rc config.Remote ) string {
841
+ strGlobal := i18n .G ("NO" )
842
+ if rc .Global {
843
+ strGlobal = i18n .G ("YES" )
844
+ }
845
+
846
+ return strGlobal
847
+ }
848
+
727
849
// Run is used in the RunE field of the cobra.Command returned by Command.
728
850
func (c * cmdRemoteList ) Run (cmd * cobra.Command , args []string ) error {
729
851
conf := c .global .conf
@@ -734,56 +856,28 @@ func (c *cmdRemoteList) Run(cmd *cobra.Command, args []string) error {
734
856
return err
735
857
}
736
858
859
+ columns , err := c .parseColumns ()
860
+ if err != nil {
861
+ return err
862
+ }
863
+
737
864
// List the remotes
738
865
data := [][]string {}
739
866
for name , rc := range conf .Remotes {
740
- strPublic := i18n .G ("NO" )
741
- if rc .Public {
742
- strPublic = i18n .G ("YES" )
743
- }
744
-
745
- strStatic := i18n .G ("NO" )
746
- if rc .Static {
747
- strStatic = i18n .G ("YES" )
748
- }
749
-
750
- strGlobal := i18n .G ("NO" )
751
- if rc .Global {
752
- strGlobal = i18n .G ("YES" )
753
- }
754
-
755
- if rc .Protocol == "" {
756
- rc .Protocol = "incus"
757
- }
758
-
759
- if rc .AuthType == "" {
760
- if strings .HasPrefix (rc .Addr , "unix:" ) {
761
- rc .AuthType = "file access"
762
- } else if rc .Protocol != "incus" {
763
- rc .AuthType = "none"
764
- } else {
765
- rc .AuthType = api .AuthenticationMethodTLS
766
- }
767
- }
768
867
769
- strName := name
770
- if name == conf . DefaultRemote {
771
- strName = fmt . Sprintf ( "%s (%s)" , name , i18n . G ( "current" ))
868
+ line := [] string {}
869
+ for _ , column := range columns {
870
+ line = append ( line , column . Data ( name , rc ))
772
871
}
773
872
774
- data = append (data , [] string { strName , rc . Addr , rc . Protocol , rc . AuthType , strPublic , strStatic , strGlobal } )
873
+ data = append (data , line )
775
874
}
776
875
777
876
sort .Sort (cli .SortColumnsNaturally (data ))
778
877
779
- header := []string {
780
- i18n .G ("NAME" ),
781
- i18n .G ("URL" ),
782
- i18n .G ("PROTOCOL" ),
783
- i18n .G ("AUTH TYPE" ),
784
- i18n .G ("PUBLIC" ),
785
- i18n .G ("STATIC" ),
786
- i18n .G ("GLOBAL" ),
878
+ header := []string {}
879
+ for _ , column := range columns {
880
+ header = append (header , column .Name )
787
881
}
788
882
789
883
return cli .RenderTable (c .flagFormat , header , data , conf .Remotes )
0 commit comments