Skip to content

Commit bd33e5e

Browse files
CLOUDP-292660: add a new 'foascli sunset list' command to foascli to list all endpoints with theirs sunset date (#339)
1 parent 2323449 commit bd33e5e

File tree

17 files changed

+558
-17
lines changed

17 files changed

+558
-17
lines changed

tools/cli/internal/cli/breakingchanges/breakingchanges.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@ func Builder() *cobra.Command {
2323
cmd := &cobra.Command{
2424
Use: "breaking-changes",
2525
Short: "Manage API Breaking changes related commands.",
26-
Annotations: map[string]string{
27-
"toc": "true",
28-
},
2926
}
3027

3128
cmd.AddCommand(

tools/cli/internal/cli/breakingchanges/exemptions/exemptions.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@ func Builder() *cobra.Command {
2222
cmd := &cobra.Command{
2323
Use: "exemptions",
2424
Short: "Manage exemptions.",
25-
Annotations: map[string]string{
26-
"toc": "true",
27-
},
2825
}
2926

3027
cmd.AddCommand(ParseBuilder())

tools/cli/internal/cli/changelog/changelog.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ func Builder() *cobra.Command {
2424
cmd := &cobra.Command{
2525
Use: "changelog",
2626
Short: "Manage the API Changelog for the OpenAPI spec.",
27-
Annotations: map[string]string{
28-
"toc": "true",
29-
},
3027
}
3128

3229
cmd.AddCommand(

tools/cli/internal/cli/changelog/convert/convert.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@ func Builder() *cobra.Command {
2222
cmd := &cobra.Command{
2323
Use: "convert",
2424
Short: "Convert API Changelog entries into another format.",
25-
Annotations: map[string]string{
26-
"toc": "true",
27-
},
2825
}
2926

3027
cmd.AddCommand(SlackBuilder())

tools/cli/internal/cli/changelog/create.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ func (o *Opts) newOutputFilePath(fileName string) string {
116116
return fileName
117117
}
118118

119-
// Builder builds the merge command with the following signature:
119+
// CreateBuilder builds the merge command with the following signature:
120120
// changelog create -b path_folder -r path_folder --dry-run
121121
func CreateBuilder() *cobra.Command {
122122
opts := &Opts{

tools/cli/internal/cli/changelog/metadata/metadata.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@ func Builder() *cobra.Command {
2222
cmd := &cobra.Command{
2323
Use: "metadata",
2424
Short: "Manage the API Changelog Metadata.",
25-
Annotations: map[string]string{
26-
"toc": "true",
27-
},
2825
}
2926

3027
cmd.AddCommand(CreateBuilder())

tools/cli/internal/cli/flag/flag.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,6 @@ const (
4545
MessageID = "msg-id"
4646
ChannelID = "channel-id"
4747
ChannelIDShort = "c"
48+
From = "from"
49+
To = "to"
4850
)

tools/cli/internal/cli/root/openapi/builder.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/mongodb/openapi/tools/cli/internal/cli/changelog"
2323
"github.com/mongodb/openapi/tools/cli/internal/cli/merge"
2424
"github.com/mongodb/openapi/tools/cli/internal/cli/split"
25+
"github.com/mongodb/openapi/tools/cli/internal/cli/sunset"
2526
"github.com/mongodb/openapi/tools/cli/internal/cli/versions"
2627
"github.com/mongodb/openapi/tools/cli/internal/version"
2728
"github.com/spf13/cobra"
@@ -59,6 +60,7 @@ func Builder() *cobra.Command {
5960
versions.Builder(),
6061
changelog.Builder(),
6162
breakingchanges.Builder(),
63+
sunset.Builder(),
6264
)
6365
return rootCmd
6466
}

tools/cli/internal/cli/split/split.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func (o *Opts) Run() error {
6868
}
6969

7070
func (o *Opts) filter(oas *openapi3.T, version string) (result *openapi3.T, err error) {
71-
log.Printf("Filtering OpenAPI document by version %s", version)
71+
log.Printf("Filtering OpenAPI document by version %q", version)
7272
apiVersion, err := apiversion.New(apiversion.WithVersion(version))
7373
if err != nil {
7474
return nil, err
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
// Copyright 2025 MongoDB Inc
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package sunset
16+
17+
import (
18+
"encoding/json"
19+
"fmt"
20+
"strings"
21+
"time"
22+
23+
"github.com/mongodb/openapi/tools/cli/internal/openapi"
24+
25+
"github.com/mongodb/openapi/tools/cli/internal/cli/flag"
26+
"github.com/mongodb/openapi/tools/cli/internal/cli/usage"
27+
"github.com/mongodb/openapi/tools/cli/internal/openapi/sunset"
28+
"github.com/spf13/afero"
29+
"github.com/spf13/cobra"
30+
"gopkg.in/yaml.v3"
31+
)
32+
33+
type ListOpts struct {
34+
fs afero.Fs
35+
basePath string
36+
outputPath string
37+
format string
38+
from string
39+
to string
40+
toDate *time.Time
41+
fromDate *time.Time
42+
}
43+
44+
func (o *ListOpts) Run() error {
45+
loader := openapi.NewOpenAPI3()
46+
specInfo, err := loader.CreateOpenAPISpecFromPath(o.basePath)
47+
if err != nil {
48+
return err
49+
}
50+
51+
sunsets, err := o.newSunsetInRange(sunset.NewListFromSpec(specInfo))
52+
if err != nil {
53+
return err
54+
}
55+
56+
bytes, err := o.newSunsetListBytes(sunsets)
57+
if err != nil {
58+
return err
59+
}
60+
if o.outputPath != "" {
61+
return afero.WriteFile(o.fs, o.outputPath, bytes, 0o600)
62+
}
63+
64+
fmt.Println(string(bytes))
65+
return nil
66+
}
67+
68+
func (o *ListOpts) newSunsetInRange(sunsets []*sunset.Sunset) ([]*sunset.Sunset, error) {
69+
var out []*sunset.Sunset
70+
if o.from == "" && o.to == "" {
71+
return sunsets, nil
72+
}
73+
74+
for _, s := range sunsets {
75+
sunsetDate, err := time.Parse("2006-01-02", s.SunsetDate)
76+
if err != nil {
77+
return nil, err
78+
}
79+
80+
if isDateInRange(&sunsetDate, o.fromDate, o.toDate) {
81+
out = append(out, s)
82+
}
83+
}
84+
85+
return out, nil
86+
}
87+
88+
func isDateInRange(date, from, to *time.Time) bool {
89+
if date == nil {
90+
return false
91+
}
92+
93+
if from != nil && date.Before(*from) {
94+
return false
95+
}
96+
97+
if to != nil && date.After(*to) {
98+
return false
99+
}
100+
101+
return true
102+
}
103+
104+
func (o *ListOpts) newSunsetListBytes(versions []*sunset.Sunset) ([]byte, error) {
105+
data, err := json.MarshalIndent(versions, "", " ")
106+
if err != nil {
107+
return nil, err
108+
}
109+
110+
if format := strings.ToLower(o.format); format == "json" {
111+
return data, nil
112+
}
113+
114+
var jsonData any
115+
if mErr := json.Unmarshal(data, &jsonData); mErr != nil {
116+
return nil, mErr
117+
}
118+
119+
yamlData, err := yaml.Marshal(jsonData)
120+
if err != nil {
121+
return nil, err
122+
}
123+
124+
return yamlData, nil
125+
}
126+
127+
func (o *ListOpts) validate() error {
128+
if o.from != "" {
129+
value, err := time.Parse("2006-01-02", o.from)
130+
if err != nil {
131+
return err
132+
}
133+
o.fromDate = &value
134+
}
135+
136+
if o.to != "" {
137+
value, err := time.Parse("2006-01-02", o.to)
138+
if err != nil {
139+
return err
140+
}
141+
o.toDate = &value
142+
}
143+
144+
return nil
145+
}
146+
147+
// ListBuilder builds the merge command with the following signature:
148+
// sunset ls -s spec.json -f 2024-01-01 -t 2024-09-22
149+
func ListBuilder() *cobra.Command {
150+
opts := &ListOpts{
151+
fs: afero.NewOsFs(),
152+
}
153+
154+
cmd := &cobra.Command{
155+
Use: "list -s spec.json -o json",
156+
Short: "List API endpoints with a Sunset date for a given OpenAPI spec.",
157+
Aliases: []string{"ls"},
158+
Args: cobra.NoArgs,
159+
PreRunE: func(_ *cobra.Command, _ []string) error {
160+
return opts.validate()
161+
},
162+
RunE: func(_ *cobra.Command, _ []string) error {
163+
return opts.Run()
164+
},
165+
}
166+
167+
cmd.Flags().StringVarP(&opts.basePath, flag.Spec, flag.SpecShort, "", usage.Spec)
168+
cmd.Flags().StringVarP(&opts.outputPath, flag.Output, flag.OutputShort, "", usage.Output)
169+
cmd.Flags().StringVar(&opts.from, flag.From, "", usage.From)
170+
cmd.Flags().StringVar(&opts.to, flag.To, "", usage.To)
171+
cmd.Flags().StringVarP(&opts.format, flag.Format, flag.FormatShort, "json", usage.Format)
172+
173+
_ = cmd.MarkFlagRequired(flag.Spec)
174+
175+
return cmd
176+
}

0 commit comments

Comments
 (0)