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

mongodb / mongodb-atlas-cli / 28581285639

02 Jul 2026 09:53AM UTC coverage: 63.044% (-1.3%) from 64.305%
28581285639

push

github

web-flow
build(deps): bump the cloud-providers group with 3 updates (#4631)

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

21128 of 33513 relevant lines covered (63.04%)

0.66 hits per line

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

89.11
/internal/cli/plugin/plugin.go
1
// Copyright 2024 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 plugin
16

17
import (
18
        "errors"
19
        "fmt"
20
        "strings"
21

22
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli"
23
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/plugin"
24
        "github.com/mongodb/mongodb-atlas-cli/atlascli/internal/set"
25
        "github.com/spf13/cobra"
26
)
27

28
const (
29
        sourcePluginName = "sourcePluginName"
30
)
31

32
type Opts struct {
33
        plugins          *plugin.ValidatedPlugins
34
        existingCommands []*cobra.Command
35
}
36

37
func (opts *Opts) getValidPlugins() []*plugin.Plugin {
1✔
38
        return opts.plugins.GetValidPlugins()
1✔
39
}
1✔
40

41
func (opts *Opts) getValidAndInvalidPlugins() []*plugin.Plugin {
1✔
42
        return opts.plugins.GetValidAndInvalidPlugins()
1✔
43
}
1✔
44

45
// find a plugin given the input argument of a plugin command
46
// the input arg can be the plugin name, the github values (<repo-owner>/<repo-name>) or the entire github URL of the plugin.
47
func (opts *Opts) findPluginWithArg(arg string) (*plugin.Plugin, error) {
1✔
48
        // try to parse input to github values
1✔
49
        // if parsing fails it will be assumed that the input is the plugin name
1✔
50
        githubValues, err := parseGithubReleaseValues(arg)
1✔
51
        var pluginToUninstall *plugin.Plugin
1✔
52

1✔
53
        if err == nil {
2✔
54
                pluginToUninstall, err = opts.findPluginWithGithubValues(githubValues.owner, githubValues.name)
1✔
55
        } else {
2✔
56
                pluginToUninstall, err = opts.findPluginWithName(arg)
1✔
57
        }
1✔
58

59
        if err != nil {
2✔
60
                return nil, err
1✔
61
        }
1✔
62

63
        return pluginToUninstall, nil
1✔
64
}
65

66
func createExistingCommandsSet(existingCommands []*cobra.Command) set.Set[string] {
1✔
67
        existingCommandsSet := set.NewSet[string]()
1✔
68
        for _, cmd := range existingCommands {
2✔
69
                existingCommandsSet.Add(cmd.Name())
1✔
70
                for _, alias := range cmd.Aliases {
2✔
71
                        existingCommandsSet.Add(alias)
1✔
72
                }
1✔
73
        }
74

75
        return existingCommandsSet
1✔
76
}
77

78
// find a plugin given a github owner and repository name
79
//
80
// also searches through invalid plugins, because this function is also used for uninstall command
81
// throws an error when:
82
// - multiple plugins are found with the same github values
83
// - no plugin is found with the given github values
84
func (opts *Opts) findPluginWithGithubValues(owner string, name string) (*plugin.Plugin, error) {
1✔
85
        var foundPlugin *plugin.Plugin
1✔
86

1✔
87
        for _, p := range opts.getValidAndInvalidPlugins() {
2✔
88
                if p.Github != nil && p.Github.Equals(owner, name) {
2✔
89
                        if foundPlugin != nil {
1✔
90
                                return nil, fmt.Errorf(`found multiple plugins with github values %s/%s`, owner, name)
×
91
                        }
×
92

93
                        foundPlugin = p
1✔
94
                }
95
        }
96

97
        if foundPlugin == nil {
2✔
98
                return nil, fmt.Errorf(`could not find plugin with github values %s/%s`, owner, name)
1✔
99
        }
1✔
100

101
        return foundPlugin, nil
1✔
102
}
103

104
// find a plugin given a plugin name
105
//
106
// also searches through invalid plugins, because this function is also used for uninstall command
107
// throws an error when:
108
// - multiple plugins are found with the same name
109
// - no plugin is found with the given name
110
func (opts *Opts) findPluginWithName(name string) (*plugin.Plugin, error) {
1✔
111
        var foundPlugin *plugin.Plugin
1✔
112

1✔
113
        for _, p := range opts.getValidAndInvalidPlugins() {
2✔
114
                if p.Name == name {
2✔
115
                        if foundPlugin != nil {
1✔
116
                                return nil, fmt.Errorf(`found multiple plugins with name %s`, name)
×
117
                        }
×
118

119
                        foundPlugin = p
1✔
120
                }
121
        }
122

123
        if foundPlugin == nil {
2✔
124
                return nil, fmt.Errorf(`could not find plugin with name %s`, name)
1✔
125
        }
1✔
126

127
        return foundPlugin, nil
1✔
128
}
129

130
func RegisterCommands(rootCmd *cobra.Command) {
1✔
131
        plugins := plugin.GetAllPluginsValidated(createExistingCommandsSet(rootCmd.Commands()))
1✔
132

1✔
133
        // Get set of first-class plugins that need updating
1✔
134
        firstClassPluginsNeedingUpdate := getFirstClassPluginsNeedingUpdate(plugins)
1✔
135

1✔
136
        for _, p := range plugins.GetValidPlugins() {
2✔
137
                // Skip installed plugins that are first-class plugins needing update
1✔
138
                // Their commands will be handled by the first-class plugin mechanism
1✔
139
                if _, needsUpdate := firstClassPluginsNeedingUpdate[p.Name]; needsUpdate {
1✔
140
                        continue
×
141
                }
142
                rootCmd.AddCommand(p.GetCobraCommands()...)
1✔
143
        }
144

145
        rootCmd.AddCommand(getFirstClassPluginCommands(plugins)...)
1✔
146

1✔
147
        rootCmd.AddCommand(Builder(plugins, rootCmd.Commands()))
1✔
148
}
149

150
func validateManifest(manifest *plugin.Manifest) error {
1✔
151
        if valid, errorList := manifest.IsValid(); !valid {
1✔
152
                var manifestErrorLog strings.Builder
×
153
                fmt.Fprintf(&manifestErrorLog, "plugin in directory %q could not be loaded due to the following error(s) in the manifest.yaml:\n", manifest.PluginDirectoryPath)
×
154
                for _, err := range errorList {
×
155
                        fmt.Fprintf(&manifestErrorLog, "\t- %s\n", err.Error())
×
156
                }
×
157

158
                return errors.New(manifestErrorLog.String())
×
159
        }
160
        return nil
1✔
161
}
162

163
func Builder(plugins *plugin.ValidatedPlugins, existingCommands []*cobra.Command) *cobra.Command {
1✔
164
        const use = "plugin"
1✔
165
        cmd := &cobra.Command{
1✔
166
                Use:     use,
1✔
167
                Aliases: cli.GenerateAliases(use),
1✔
168
                Short:   "Manage plugins for the AtlasCLI.",
1✔
169
        }
1✔
170

1✔
171
        pluginOpts := &Opts{
1✔
172
                plugins:          plugins,
1✔
173
                existingCommands: existingCommands,
1✔
174
        }
1✔
175

1✔
176
        cmd.AddCommand(
1✔
177
                ListBuilder(pluginOpts),
1✔
178
                InstallBuilder(pluginOpts),
1✔
179
                UninstallBuilder(pluginOpts),
1✔
180
                UpdateBuilder(pluginOpts),
1✔
181
        )
1✔
182

1✔
183
        return cmd
1✔
184
}
1✔
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