• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mongodb / mongodb-atlas-cli / 25848964073

14 May 2026 07:59AM UTC coverage: 22.479% (-41.3%) from 63.771%
25848964073

push

github

web-flow
build(deps): bump test-summary/action from 2.4 to 2.6 (#4576)

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

8987 of 39979 relevant lines covered (22.48%)

0.25 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

9.78
/internal/cli/root/builder.go
1
// Copyright 2022 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 root
16

17
import (
18
        "errors"
19
        "fmt"
20
        "io"
21
        "os"
22
        "runtime"
23
        "strings"
24
        "syscall"
25
        "time"
26

27
        "github.com/mongodb/atlas-cli-core/config"
28
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli"
29
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/accesslists"
30
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/accesslogs"
31
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/alerts"
32
        apiCmd "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/api"
33
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/auditing"
34
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/auth"
35
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/backup"
36
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/cloudproviders"
37
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/clusters"
38
        cliconfig "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/config"
39
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/customdbroles"
40
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/customdns"
41
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/datafederation"
42
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/datalake"
43
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/dbusers"
44
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/deployments"
45
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/events"
46
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/federatedauthentication"
47
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/integrations"
48
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/livemigrations"
49
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/logs"
50
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/maintenance"
51
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/metrics"
52
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/networking"
53
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/organizations"
54
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/performanceadvisor"
55
        pluginCmd "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/plugin"
56
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/privateendpoints"
57
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/processes"
58
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/projects"
59
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/security"
60
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/setup"
61
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/streams"
62
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/teams"
63
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/users"
64
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/flag"
65
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/homebrew"
66
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/latestrelease"
67
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/log"
68
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/prerun"
69
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/sighandle"
70
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/telemetry"
71
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/terminal"
72
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/usage"
73
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/version"
74
        "github.com/spf13/afero"
75
        "github.com/spf13/cobra"
76
)
77

78
const atlas = "atlas"
79

80
type Notifier struct {
81
        currentVersion string
82
        finder         latestrelease.VersionFinder
83
        filesystem     afero.Fs
84
        writer         io.Writer
85
}
86

87
func handleSignal() {
×
88
        sighandle.Notify(func(sig os.Signal) {
×
89
                telemetry.FinishTrackingCommand(telemetry.TrackOptions{
×
90
                        Err:    errors.New(sig.String()),
×
91
                        Signal: sig.String(),
×
92
                })
×
93
                os.Exit(1)
×
94
        }, os.Interrupt, syscall.SIGTERM)
×
95
}
96

97
// Builder conditionally adds children commands as needed.
98
func Builder() *cobra.Command {
×
99
        var (
×
100
                profile    string
×
101
                debugLevel bool
×
102
        )
×
103
        opts := &cli.RefresherOpts{}
×
104
        rootCmd := &cobra.Command{
×
105
                Version: version.Version,
×
106
                Use:     atlas,
×
107
                Short:   "CLI tool to manage MongoDB Atlas.",
×
108
                Long: `The Atlas CLI is a command line interface built specifically for MongoDB Atlas. You can manage your Atlas database deployments and Atlas Search from the terminal with short, intuitive commands.
×
109
                
×
110
Use the --help flag with any command for more info on that command.`,
×
111
                Example: `  # Display the help menu for the config command:
×
112
  atlas config --help
×
113
`,
×
114
                SilenceUsage:  true,
×
115
                SilenceErrors: true,
×
116
                Annotations: map[string]string{
×
117
                        "toc": "true",
×
118
                },
×
119
                PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
×
120
                        log.SetWriter(cmd.ErrOrStderr())
×
121
                        if debugLevel {
×
122
                                log.SetLevel(log.DebugLevel)
×
123
                        }
×
124

125
                        if err := config.InitProfile(profile); err != nil {
×
126
                                return err
×
127
                        }
×
128

129
                        telemetry.StartTrackingCommand(cmd, args)
×
130

×
131
                        handleSignal()
×
132

×
133
                        if shouldSetService(cmd) {
×
134
                                config.SetService(config.CloudService)
×
135
                        }
×
136

137
                        return prerun.ExecuteE(opts.InitFlow(config.Default()))
×
138
                },
139
                // PersistentPostRun only runs if the command is successful
140
                PersistentPostRun: func(cmd *cobra.Command, _ []string) {
×
141
                        // we don't run the release alert feature on the completion command
×
142
                        if strings.HasPrefix(cmd.CommandPath(), fmt.Sprintf("%s %s", atlas, "completion")) {
×
143
                                return
×
144
                        }
×
145

146
                        w := cmd.ErrOrStderr()
×
147
                        fs := afero.NewOsFs()
×
148
                        f, _ := latestrelease.NewVersionFinder(fs, version.NewReleaseVersionDescriber())
×
149

×
150
                        notifier := &Notifier{
×
151
                                currentVersion: latestrelease.VersionFromTag(version.Version),
×
152
                                finder:         f,
×
153
                                filesystem:     fs,
×
154
                                writer:         w,
×
155
                        }
×
156

×
157
                        if check, isHb := notifier.shouldCheck(); check {
×
158
                                _ = notifier.notifyIfApplicable(isHb)
×
159
                        }
×
160
                        telemetry.FinishTrackingCommand(telemetry.TrackOptions{})
×
161
                },
162
        }
163
        rootCmd.SetVersionTemplate(formattedVersion())
×
164
        rootCmd.SetHelpTemplate(cli.HelpTemplate)
×
165

×
166
        // hidden shortcuts
×
167
        loginCmd := auth.LoginBuilder()
×
168
        loginCmd.Hidden = true
×
169
        logoutCmd := auth.LogoutBuilder()
×
170
        logoutCmd.Hidden = true
×
171
        whoCmd := auth.WhoAmIBuilder()
×
172
        whoCmd.Hidden = true
×
173
        registerCmd := auth.RegisterBuilder()
×
174
        registerCmd.Hidden = true
×
175

×
176
        rootCmd.AddCommand(
×
177
                cliconfig.Builder(),
×
178
                auth.Builder(),
×
179
                setup.Builder(),
×
180
                projects.Builder(),
×
181
                organizations.Builder(),
×
182
                users.Builder(),
×
183
                teams.Builder(),
×
184
                clusters.Builder(),
×
185
                dbusers.Builder(),
×
186
                customdbroles.Builder(),
×
187
                accesslists.Builder(),
×
188
                datalake.Builder(),
×
189
                alerts.Builder(),
×
190
                backup.Builder(),
×
191
                events.Builder(),
×
192
                metrics.Builder(),
×
193
                performanceadvisor.Builder(),
×
194
                logs.Builder(),
×
195
                processes.Builder(),
×
196
                privateendpoints.Builder(),
×
197
                networking.Builder(),
×
198
                security.Builder(),
×
199
                integrations.Builder(),
×
200
                maintenance.Builder(),
×
201
                customdns.Builder(),
×
202
                cloudproviders.Builder(),
×
203
                streams.Builder(),
×
204
                livemigrations.Builder(),
×
205
                accesslogs.Builder(),
×
206
                loginCmd,
×
207
                logoutCmd,
×
208
                whoCmd,
×
209
                registerCmd,
×
210
                datafederation.Builder(),
×
211
                auditing.Builder(),
×
212
                deployments.Builder(),
×
213
                federatedauthentication.Builder(),
×
214
                apiCmd.Builder(),
×
215
        )
×
216

×
217
        pluginCmd.RegisterCommands(rootCmd)
×
218

×
219
        rootCmd.PersistentFlags().StringVarP(&profile, flag.Profile, flag.ProfileShort, "", usage.ProfileAtlasCLI)
×
220
        rootCmd.PersistentFlags().BoolVarP(&debugLevel, flag.Debug, flag.DebugShort, false, usage.Debug)
×
221
        _ = rootCmd.PersistentFlags().MarkHidden(flag.Debug)
×
222

×
223
        _ = rootCmd.RegisterFlagCompletionFunc(flag.Profile, func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
×
224
                return config.List(), cobra.ShellCompDirectiveDefault
×
225
        })
×
226
        return rootCmd
×
227
}
228

229
const verTemplate = `atlascli version: %s
230
git version: %s
231
Go version: %s
232
   os: %s
233
   arch: %s
234
   compiler: %s
235
`
236

237
func shouldSetService(cmd *cobra.Command) bool {
×
238
        if config.Service() != "" {
×
239
                return false
×
240
        }
×
241

242
        if strings.HasPrefix(cmd.CommandPath(), fmt.Sprintf("%s %s", atlas, "config")) { // user wants to set credentials
×
243
                return false
×
244
        }
×
245

246
        if strings.HasPrefix(cmd.CommandPath(), fmt.Sprintf("%s %s", atlas, "completion")) {
×
247
                return false
×
248
        }
×
249

250
        return true
×
251
}
252

253
func formattedVersion() string {
×
254
        return fmt.Sprintf(verTemplate,
×
255
                version.Version,
×
256
                version.GitCommit,
×
257
                runtime.Version(),
×
258
                runtime.GOOS,
×
259
                runtime.GOARCH,
×
260
                runtime.Compiler)
×
261
}
×
262

263
func (n *Notifier) shouldCheck() (shouldCheck, isHb bool) {
×
264
        shouldCheck = !config.SkipUpdateCheck() && terminal.IsTerminal(n.writer)
×
265
        isHb = false
×
266

×
267
        if !shouldCheck {
×
268
                return shouldCheck, isHb
×
269
        }
×
270

271
        c, _ := homebrew.NewChecker(n.filesystem)
×
272
        isHb = c.IsHomebrew()
×
273

×
274
        return shouldCheck, isHb
×
275
}
276

277
func (n *Notifier) notifyIfApplicable(isHb bool) error {
1✔
278
        release, err := n.finder.Find()
1✔
279
        if err != nil || release == nil {
2✔
280
                return err
1✔
281
        }
1✔
282

283
        // homebrew is an external dependency we give them 24h to have the cli available there
284
        if isHb && !isAtLeast24HoursPast(release.PublishedAt) {
1✔
285
                return nil
×
286
        }
×
287

288
        var upgradeInstructions string
1✔
289
        if isHb {
1✔
290
                upgradeInstructions = `To upgrade, run "brew update && brew upgrade mongodb-atlas-cli"`
×
291
        } else {
1✔
292
                upgradeInstructions = "To upgrade, see: https://dochub.mongodb.org/core/install-atlas-cli"
1✔
293
        }
1✔
294
        _, err = fmt.Fprintf(n.writer, `
1✔
295
A new version of atlascli is available %q!
1✔
296
%s
1✔
297

1✔
298
To disable this alert, run "atlas config set skip_update_check true"
1✔
299
`, release.Version, upgradeInstructions)
1✔
300
        return err
1✔
301
}
302

303
func isAtLeast24HoursPast(t time.Time) bool {
×
304
        return !t.IsZero() && time.Since(t) >= time.Hour*24
×
305
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc