@@ -3,14 +3,20 @@ package olmv1
33import (
44 "cmp"
55 "fmt"
6+ "io"
67 "os"
78 "slices"
9+ "sort"
10+ "strings"
811 "text/tabwriter"
912 "time"
1013
1114 "github.com/blang/semver/v4"
15+ "github.com/operator-framework/operator-registry/alpha/declcfg"
16+ "github.com/operator-framework/operator-registry/alpha/property"
1217 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1318 "k8s.io/apimachinery/pkg/util/duration"
19+ "k8s.io/apimachinery/pkg/util/json"
1420
1521 olmv1 "github.com/operator-framework/operator-controller/api/v1"
1622)
@@ -63,6 +69,107 @@ func printFormattedCatalogs(catalogs ...olmv1.ClusterCatalog) {
6369 _ = tw .Flush ()
6470}
6571
72+ func printFormattedDeclCfg (w io.Writer , catalogDcfg map [string ]* declcfg.DeclarativeConfig , listVersions bool ) {
73+ tw := tabwriter .NewWriter (w , 3 , 4 , 2 , ' ' , 0 )
74+ if listVersions {
75+ _ , _ = fmt .Fprint (tw , "PACKAGE\t CATALOG\t PROVIDER\t VERSION\n " )
76+ } else {
77+ _ , _ = fmt .Fprint (tw , "PACKAGE\t CATALOG\t PROVIDER\t CHANNELS\n " )
78+ }
79+ sortedCatalogs := []string {}
80+ for catalogName := range catalogDcfg {
81+ sortedCatalogs = append (sortedCatalogs , catalogName )
82+ }
83+ sort .Strings (sortedCatalogs )
84+ for _ , catalogName := range sortedCatalogs {
85+ dcfg := catalogDcfg [catalogName ]
86+ type dcfgPrintMeta struct {
87+ provider string
88+ channels []string
89+ versions []semver.Version
90+ }
91+ pkgProviders := map [string ]* dcfgPrintMeta {}
92+ sort .SliceStable (dcfg .Packages , func (i , j int ) bool {
93+ return dcfg .Packages [i ].Name < dcfg .Packages [j ].Name
94+ })
95+
96+ if listVersions {
97+ for _ , b := range dcfg .Bundles {
98+ if pkgProviders [b .Package ] == nil {
99+ pkgProviders [b .Package ] = & dcfgPrintMeta {}
100+ }
101+ if pkgProviders [b .Package ].versions == nil {
102+ pkgProviders [b .Package ].versions = []semver.Version {}
103+ }
104+ for _ , versionProp := range b .Properties {
105+ if versionProp .Type == property .TypePackage {
106+ var pkgProp property.Package
107+ if err := json .Unmarshal (versionProp .Value , & pkgProp ); err == nil && len (pkgProp .Version ) > 0 {
108+ if parsedVersion , err := semver .Parse (pkgProp .Version ); err == nil {
109+ pkgProviders [b .Package ].versions = append (pkgProviders [b .Package ].versions , parsedVersion )
110+ }
111+ }
112+ continue
113+ }
114+ if versionProp .Type == property .TypeCSVMetadata {
115+ var pkgProp property.CSVMetadata
116+ if err := json .Unmarshal (versionProp .Value , & pkgProp ); err == nil && len (pkgProp .Provider .Name ) > 0 {
117+ pkgProviders [b .Package ].provider = pkgProp .Provider .Name
118+ }
119+ continue
120+ }
121+ }
122+ }
123+ } else {
124+ for _ , c := range dcfg .Channels {
125+ if pkgProviders [c .Package ] == nil {
126+ pkgProviders [c .Package ] = & dcfgPrintMeta {}
127+ }
128+ if pkgProviders [c .Package ].channels == nil {
129+ pkgProviders [c .Package ].channels = []string {}
130+ }
131+ pkgProviders [c .Package ].channels = append (pkgProviders [c .Package ].channels , c .Name )
132+ }
133+ }
134+
135+ for _ , p := range dcfg .Packages {
136+ if listVersions {
137+ sort .SliceStable (pkgProviders [p .Name ].versions , func (i , j int ) bool {
138+ return pkgProviders [p .Name ].versions [i ].GT (pkgProviders [p .Name ].versions [j ])
139+ })
140+ for _ , v := range pkgProviders [p .Name ].versions {
141+ _ , _ = fmt .Fprintf (tw , "%s\t %s\t %s\t %s\n " ,
142+ p .Name ,
143+ catalogName ,
144+ pkgProviders [p .Name ].provider ,
145+ v )
146+ }
147+ } else {
148+ sort .Strings (pkgProviders [p .Name ].channels )
149+ _ , _ = fmt .Fprintf (tw , "%s\t %s\t %s\t %s\n " ,
150+ p .Name ,
151+ catalogName ,
152+ pkgProviders [p .Name ].provider ,
153+ strings .Join (pkgProviders [p .Name ].channels , "," ))
154+ }
155+ }
156+ }
157+ _ = tw .Flush ()
158+ }
159+
160+ func printDeclCfgJSON (w io.Writer , catalogDcfg map [string ]* declcfg.DeclarativeConfig ) {
161+ for _ , dcfg := range catalogDcfg {
162+ _ = declcfg .WriteJSON (* dcfg , w )
163+ }
164+ }
165+
166+ func printDeclCfgYAML (w io.Writer , catalogDcfg map [string ]* declcfg.DeclarativeConfig ) {
167+ for _ , dcfg := range catalogDcfg {
168+ _ = declcfg .WriteYAML (* dcfg , w )
169+ _ , _ = w .Write ([]byte ("---\n " ))
170+ }
171+ }
172+
66173// sortExtensions sorts extensions in place and uses the following sorting order:
67174// name (asc), version (desc)
68175func sortExtensions (extensions []olmv1.ClusterExtension ) {
0 commit comments