diff options
author | Jesús Espino <jespinog@gmail.com> | 2018-03-07 20:04:18 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-07 20:04:18 +0000 |
commit | b2dd00dd5b83fc7e8b311a55f5a2536e4f3d45a5 (patch) | |
tree | 00d2bbb524e27727dc111994082f5293e6d12b11 /cmd | |
parent | 03b6d1f652407fa9c3ec7e740e120a1c3e920de0 (diff) | |
download | chat-b2dd00dd5b83fc7e8b311a55f5a2536e4f3d45a5.tar.gz chat-b2dd00dd5b83fc7e8b311a55f5a2536e4f3d45a5.tar.bz2 chat-b2dd00dd5b83fc7e8b311a55f5a2536e4f3d45a5.zip |
Adding enterprise commands support (#8327)
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/cmd.go | 26 | ||||
-rw-r--r-- | cmd/cmdtestlib.go (renamed from cmd/platform/platform_test.go) | 14 | ||||
-rw-r--r-- | cmd/commands/channel.go (renamed from cmd/platform/channel.go) | 176 | ||||
-rw-r--r-- | cmd/commands/channel_test.go (renamed from cmd/platform/channel_test.go) | 33 | ||||
-rw-r--r-- | cmd/commands/channelargs.go (renamed from cmd/platform/channelargs.go) | 3 | ||||
-rw-r--r-- | cmd/commands/command.go (renamed from cmd/platform/command.go) | 25 | ||||
-rw-r--r-- | cmd/commands/commandargs.go (renamed from cmd/platform/commandargs.go) | 3 | ||||
-rw-r--r-- | cmd/commands/config.go (renamed from cmd/platform/config.go) | 19 | ||||
-rw-r--r-- | cmd/commands/config_flag_test.go (renamed from cmd/platform/mattermost_test.go) | 11 | ||||
-rw-r--r-- | cmd/commands/config_test.go (renamed from cmd/platform/config_test.go) | 7 | ||||
-rw-r--r-- | cmd/commands/exec_command_test.go | 21 | ||||
-rw-r--r-- | cmd/commands/import.go (renamed from cmd/platform/import.go) | 61 | ||||
-rw-r--r-- | cmd/commands/jobserver.go (renamed from cmd/platform/jobserver.go) | 20 | ||||
-rw-r--r-- | cmd/commands/ldap.go (renamed from cmd/platform/ldap.go) | 21 | ||||
-rw-r--r-- | cmd/commands/license.go (renamed from cmd/platform/license.go) | 17 | ||||
-rw-r--r-- | cmd/commands/message_export.go (renamed from cmd/platform/message_export.go) | 26 | ||||
-rw-r--r-- | cmd/commands/message_export_test.go (renamed from cmd/platform/message_export_test.go) | 11 | ||||
-rw-r--r-- | cmd/commands/reset.go | 53 | ||||
-rw-r--r-- | cmd/commands/roles.go (renamed from cmd/platform/roles.go) | 25 | ||||
-rw-r--r-- | cmd/commands/roles_test.go (renamed from cmd/platform/roles_test.go) | 5 | ||||
-rw-r--r-- | cmd/commands/sampledata.go (renamed from cmd/platform/sampledata.go) | 73 | ||||
-rw-r--r-- | cmd/commands/sampledata_test.go (renamed from cmd/platform/sampledata_test.go) | 9 | ||||
-rw-r--r-- | cmd/commands/server.go (renamed from cmd/platform/server.go) | 16 | ||||
-rw-r--r-- | cmd/commands/server_test.go (renamed from cmd/platform/server_test.go) | 4 | ||||
-rw-r--r-- | cmd/commands/team.go (renamed from cmd/platform/team.go) | 83 | ||||
-rw-r--r-- | cmd/commands/team_test.go (renamed from cmd/platform/team_test.go) | 9 | ||||
-rw-r--r-- | cmd/commands/teamargs.go (renamed from cmd/platform/teamargs.go) | 3 | ||||
-rw-r--r-- | cmd/commands/test.go (renamed from cmd/platform/test.go) | 38 | ||||
-rw-r--r-- | cmd/commands/user.go (renamed from cmd/platform/user.go) | 219 | ||||
-rw-r--r-- | cmd/commands/user_test.go (renamed from cmd/platform/user_test.go) | 15 | ||||
-rw-r--r-- | cmd/commands/userargs.go (renamed from cmd/platform/userargs.go) | 3 | ||||
-rw-r--r-- | cmd/commands/version.go (renamed from cmd/platform/version.go) | 26 | ||||
-rw-r--r-- | cmd/commands/version_test.go (renamed from cmd/platform/version_test.go) | 6 | ||||
-rw-r--r-- | cmd/init.go (renamed from cmd/platform/init.go) | 8 | ||||
-rw-r--r-- | cmd/output.go (renamed from cmd/platform/output.go) | 3 | ||||
-rw-r--r-- | cmd/platform/mattermost.go | 88 |
36 files changed, 625 insertions, 555 deletions
diff --git a/cmd/cmd.go b/cmd/cmd.go new file mode 100644 index 000000000..5a1a25bd9 --- /dev/null +++ b/cmd/cmd.go @@ -0,0 +1,26 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package cmd + +import ( + "github.com/spf13/cobra" +) + +type Command = cobra.Command + +func Run(args []string) error { + RootCmd.SetArgs(args) + return RootCmd.Execute() +} + +var RootCmd = &cobra.Command{ + Use: "platform", + Short: "Open source, self-hosted Slack-alternative", + Long: `Mattermost offers workplace messaging across web, PC and phones with archiving, search and integration with your existing systems. Documentation available at https://docs.mattermost.com`, +} + +func init() { + RootCmd.PersistentFlags().StringP("config", "c", "config.json", "Configuration file to use.") + RootCmd.PersistentFlags().Bool("disableconfigwatch", false, "When set config.json will not be loaded from disk when the file is changed.") +} diff --git a/cmd/platform/platform_test.go b/cmd/cmdtestlib.go index 792cabe38..db97b1a41 100644 --- a/cmd/platform/platform_test.go +++ b/cmd/cmdtestlib.go @@ -1,7 +1,7 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main +package cmd import ( "flag" @@ -30,7 +30,7 @@ func execArgs(t *testing.T, args []string) []string { return append(append(ret, "--", "--disableconfigwatch"), args...) } -func checkCommand(t *testing.T, args ...string) string { +func CheckCommand(t *testing.T, args ...string) string { path, err := os.Executable() require.NoError(t, err) output, err := exec.Command(path, execArgs(t, args)...).CombinedOutput() @@ -38,16 +38,8 @@ func checkCommand(t *testing.T, args ...string) string { return strings.TrimSpace(strings.TrimSuffix(strings.TrimSpace(string(output)), "PASS")) } -func runCommand(t *testing.T, args ...string) error { +func RunCommand(t *testing.T, args ...string) error { path, err := os.Executable() require.NoError(t, err) return exec.Command(path, execArgs(t, args)...).Run() } - -func TestExecCommand(t *testing.T) { - if filter := flag.Lookup("test.run").Value.String(); filter != "ExecCommand" { - t.Skip("use -run ExecCommand to execute a command via the test executable") - } - rootCmd.SetArgs(flag.Args()) - require.NoError(t, rootCmd.Execute()) -} diff --git a/cmd/platform/channel.go b/cmd/commands/channel.go index 5d86ad9da..597a22450 100644 --- a/cmd/platform/channel.go +++ b/cmd/commands/channel.go @@ -1,22 +1,24 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package commands import ( "errors" "fmt" "github.com/mattermost/mattermost-server/app" + "github.com/mattermost/mattermost-server/cmd" "github.com/mattermost/mattermost-server/model" "github.com/spf13/cobra" ) -var channelCmd = &cobra.Command{ +var ChannelCmd = &cobra.Command{ Use: "channel", Short: "Management of channels", } -var channelCreateCmd = &cobra.Command{ +var ChannelCreateCmd = &cobra.Command{ Use: "create", Short: "Create a channel", Long: `Create a channel.`, @@ -25,7 +27,7 @@ var channelCreateCmd = &cobra.Command{ RunE: createChannelCmdF, } -var removeChannelUsersCmd = &cobra.Command{ +var RemoveChannelUsersCmd = &cobra.Command{ Use: "remove [channel] [users]", Short: "Remove users from channel", Long: "Remove some users from channel", @@ -33,7 +35,7 @@ var removeChannelUsersCmd = &cobra.Command{ RunE: removeChannelUsersCmdF, } -var addChannelUsersCmd = &cobra.Command{ +var AddChannelUsersCmd = &cobra.Command{ Use: "add [channel] [users]", Short: "Add users to channel", Long: "Add some users to channel", @@ -41,7 +43,7 @@ var addChannelUsersCmd = &cobra.Command{ RunE: addChannelUsersCmdF, } -var archiveChannelsCmd = &cobra.Command{ +var ArchiveChannelsCmd = &cobra.Command{ Use: "archive [channels]", Short: "Archive channels", Long: `Archive some channels. @@ -51,7 +53,7 @@ Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channe RunE: archiveChannelsCmdF, } -var deleteChannelsCmd = &cobra.Command{ +var DeleteChannelsCmd = &cobra.Command{ Use: "delete [channels]", Short: "Delete channels", Long: `Permanently delete some channels. @@ -61,7 +63,7 @@ Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channe RunE: deleteChannelsCmdF, } -var listChannelsCmd = &cobra.Command{ +var ListChannelsCmd = &cobra.Command{ Use: "list [teams]", Short: "List all channels on specified teams.", Long: `List all channels on specified teams. @@ -70,7 +72,7 @@ Archived channels are appended with ' (archived)'.`, RunE: listChannelsCmdF, } -var moveChannelsCmd = &cobra.Command{ +var MoveChannelsCmd = &cobra.Command{ Use: "move [team] [channels]", Short: "Moves channels to the specified team", Long: `Moves the provided channels to the specified team. @@ -80,7 +82,7 @@ Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channe RunE: moveChannelsCmdF, } -var restoreChannelsCmd = &cobra.Command{ +var RestoreChannelsCmd = &cobra.Command{ Use: "restore [channels]", Short: "Restore some channels", Long: `Restore a previously deleted channel @@ -89,7 +91,7 @@ Channels can be specified by [team]:[channel]. ie. myteam:mychannel or by channe RunE: restoreChannelsCmdF, } -var modifyChannelCmd = &cobra.Command{ +var ModifyChannelCmd = &cobra.Command{ Use: "modify [channel]", Short: "Modify a channel's public/private type", Long: `Change the public/private type of a channel. @@ -99,55 +101,57 @@ Channel can be specified by [team]:[channel]. ie. myteam:mychannel or by channel } func init() { - channelCreateCmd.Flags().String("name", "", "Channel Name") - channelCreateCmd.Flags().String("display_name", "", "Channel Display Name") - channelCreateCmd.Flags().String("team", "", "Team name or ID") - channelCreateCmd.Flags().String("header", "", "Channel header") - channelCreateCmd.Flags().String("purpose", "", "Channel purpose") - channelCreateCmd.Flags().Bool("private", false, "Create a private channel.") - - moveChannelsCmd.Flags().String("username", "", "Required. Username who is moving the channel.") - - deleteChannelsCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the channels.") - - modifyChannelCmd.Flags().Bool("private", false, "Convert the channel to a private channel") - modifyChannelCmd.Flags().Bool("public", false, "Convert the channel to a public channel") - modifyChannelCmd.Flags().String("username", "", "Required. Username who changes the channel privacy.") - - channelCmd.AddCommand( - channelCreateCmd, - removeChannelUsersCmd, - addChannelUsersCmd, - archiveChannelsCmd, - deleteChannelsCmd, - listChannelsCmd, - moveChannelsCmd, - restoreChannelsCmd, - modifyChannelCmd, + ChannelCreateCmd.Flags().String("name", "", "Channel Name") + ChannelCreateCmd.Flags().String("display_name", "", "Channel Display Name") + ChannelCreateCmd.Flags().String("team", "", "Team name or ID") + ChannelCreateCmd.Flags().String("header", "", "Channel header") + ChannelCreateCmd.Flags().String("purpose", "", "Channel purpose") + ChannelCreateCmd.Flags().Bool("private", false, "Create a private channel.") + + MoveChannelsCmd.Flags().String("username", "", "Required. Username who is moving the channel.") + + DeleteChannelsCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the channels.") + + ModifyChannelCmd.Flags().Bool("private", false, "Convert the channel to a private channel") + ModifyChannelCmd.Flags().Bool("public", false, "Convert the channel to a public channel") + ModifyChannelCmd.Flags().String("username", "", "Required. Username who changes the channel privacy.") + + ChannelCmd.AddCommand( + ChannelCreateCmd, + RemoveChannelUsersCmd, + AddChannelUsersCmd, + ArchiveChannelsCmd, + DeleteChannelsCmd, + ListChannelsCmd, + MoveChannelsCmd, + RestoreChannelsCmd, + ModifyChannelCmd, ) + + cmd.RootCmd.AddCommand(ChannelCmd) } -func createChannelCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func createChannelCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } - name, errn := cmd.Flags().GetString("name") + name, errn := command.Flags().GetString("name") if errn != nil || name == "" { return errors.New("Name is required") } - displayname, errdn := cmd.Flags().GetString("display_name") + displayname, errdn := command.Flags().GetString("display_name") if errdn != nil || displayname == "" { return errors.New("Display Name is required") } - teamArg, errteam := cmd.Flags().GetString("team") + teamArg, errteam := command.Flags().GetString("team") if errteam != nil || teamArg == "" { return errors.New("Team is required") } - header, _ := cmd.Flags().GetString("header") - purpose, _ := cmd.Flags().GetString("purpose") - useprivate, _ := cmd.Flags().GetBool("private") + header, _ := command.Flags().GetString("header") + purpose, _ := command.Flags().GetString("purpose") + useprivate, _ := command.Flags().GetBool("private") channelType := model.CHANNEL_OPEN if useprivate { @@ -176,8 +180,8 @@ func createChannelCmdF(cmd *cobra.Command, args []string) error { return nil } -func removeChannelUsersCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func removeChannelUsersCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -201,16 +205,16 @@ func removeChannelUsersCmdF(cmd *cobra.Command, args []string) error { func removeUserFromChannel(a *app.App, channel *model.Channel, user *model.User, userArg string) { if user == nil { - CommandPrintErrorln("Can't find user '" + userArg + "'") + cmd.CommandPrintErrorln("Can't find user '" + userArg + "'") return } if err := a.RemoveUserFromChannel(user.Id, "", channel); err != nil { - CommandPrintErrorln("Unable to remove '" + userArg + "' from " + channel.Name + ". Error: " + err.Error()) + cmd.CommandPrintErrorln("Unable to remove '" + userArg + "' from " + channel.Name + ". Error: " + err.Error()) } } -func addChannelUsersCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func addChannelUsersCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -234,16 +238,16 @@ func addChannelUsersCmdF(cmd *cobra.Command, args []string) error { func addUserToChannel(a *app.App, channel *model.Channel, user *model.User, userArg string) { if user == nil { - CommandPrintErrorln("Can't find user '" + userArg + "'") + cmd.CommandPrintErrorln("Can't find user '" + userArg + "'") return } if _, err := a.AddUserToChannel(user, channel); err != nil { - CommandPrintErrorln("Unable to add '" + userArg + "' from " + channel.Name + ". Error: " + err.Error()) + cmd.CommandPrintErrorln("Unable to add '" + userArg + "' from " + channel.Name + ". Error: " + err.Error()) } } -func archiveChannelsCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func archiveChannelsCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -255,19 +259,19 @@ func archiveChannelsCmdF(cmd *cobra.Command, args []string) error { channels := getChannelsFromChannelArgs(a, args) for i, channel := range channels { if channel == nil { - CommandPrintErrorln("Unable to find channel '" + args[i] + "'") + cmd.CommandPrintErrorln("Unable to find channel '" + args[i] + "'") continue } if result := <-a.Srv.Store.Channel().Delete(channel.Id, model.GetMillis()); result.Err != nil { - CommandPrintErrorln("Unable to archive channel '" + channel.Name + "' error: " + result.Err.Error()) + cmd.CommandPrintErrorln("Unable to archive channel '" + channel.Name + "' error: " + result.Err.Error()) } } return nil } -func deleteChannelsCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func deleteChannelsCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -276,10 +280,10 @@ func deleteChannelsCmdF(cmd *cobra.Command, args []string) error { return errors.New("Enter at least one channel to delete.") } - confirmFlag, _ := cmd.Flags().GetBool("confirm") + confirmFlag, _ := command.Flags().GetBool("confirm") if !confirmFlag { var confirm string - CommandPrettyPrintln("Are you sure you want to delete the channels specified? All data will be permanently deleted? (YES/NO): ") + cmd.CommandPrettyPrintln("Are you sure you want to delete the channels specified? All data will be permanently deleted? (YES/NO): ") fmt.Scanln(&confirm) if confirm != "YES" { return errors.New("ABORTED: You did not answer YES exactly, in all capitals.") @@ -289,13 +293,13 @@ func deleteChannelsCmdF(cmd *cobra.Command, args []string) error { channels := getChannelsFromChannelArgs(a, args) for i, channel := range channels { if channel == nil { - CommandPrintErrorln("Unable to find channel '" + args[i] + "'") + cmd.CommandPrintErrorln("Unable to find channel '" + args[i] + "'") continue } if err := deleteChannel(a, channel); err != nil { - CommandPrintErrorln("Unable to delete channel '" + channel.Name + "' error: " + err.Error()) + cmd.CommandPrintErrorln("Unable to delete channel '" + channel.Name + "' error: " + err.Error()) } else { - CommandPrettyPrintln("Deleted channel '" + channel.Name + "'") + cmd.CommandPrettyPrintln("Deleted channel '" + channel.Name + "'") } } @@ -306,8 +310,8 @@ func deleteChannel(a *app.App, channel *model.Channel) *model.AppError { return a.PermanentDeleteChannel(channel) } -func moveChannelsCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func moveChannelsCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -321,7 +325,7 @@ func moveChannelsCmdF(cmd *cobra.Command, args []string) error { return errors.New("Unable to find destination team '" + args[0] + "'") } - username, erru := cmd.Flags().GetString("username") + username, erru := command.Flags().GetString("username") if erru != nil || username == "" { return errors.New("Username is required") } @@ -330,14 +334,14 @@ func moveChannelsCmdF(cmd *cobra.Command, args []string) error { channels := getChannelsFromChannelArgs(a, args[1:]) for i, channel := range channels { if channel == nil { - CommandPrintErrorln("Unable to find channel '" + args[i] + "'") + cmd.CommandPrintErrorln("Unable to find channel '" + args[i] + "'") continue } originTeamID := channel.TeamId if err := moveChannel(a, team, channel, user); err != nil { - CommandPrintErrorln("Unable to move channel '" + channel.Name + "' error: " + err.Error()) + cmd.CommandPrintErrorln("Unable to move channel '" + channel.Name + "' error: " + err.Error()) } else { - CommandPrettyPrintln("Moved channel '" + channel.Name + "' to " + team.Name + "(" + team.Id + ") from " + originTeamID + ".") + cmd.CommandPrettyPrintln("Moved channel '" + channel.Name + "' to " + team.Name + "(" + team.Id + ") from " + originTeamID + ".") } } @@ -358,7 +362,7 @@ func moveChannel(a *app.App, team *model.Team, channel *model.Channel, user *mod if webhook.ChannelId == channel.Id { webhook.TeamId = team.Id if result := <-a.Srv.Store.Webhook().UpdateIncoming(webhook); result.Err != nil { - CommandPrintErrorln("Failed to move incoming webhook '" + webhook.Id + "' to new team.") + cmd.CommandPrintErrorln("Failed to move incoming webhook '" + webhook.Id + "' to new team.") } } } @@ -371,7 +375,7 @@ func moveChannel(a *app.App, team *model.Team, channel *model.Channel, user *mod if webhook.ChannelId == channel.Id { webhook.TeamId = team.Id if result := <-a.Srv.Store.Webhook().UpdateOutgoing(webhook); result.Err != nil { - CommandPrintErrorln("Failed to move outgoing webhook '" + webhook.Id + "' to new team.") + cmd.CommandPrintErrorln("Failed to move outgoing webhook '" + webhook.Id + "' to new team.") } } } @@ -380,8 +384,8 @@ func moveChannel(a *app.App, team *model.Team, channel *model.Channel, user *mod return nil } -func listChannelsCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func listChannelsCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -393,19 +397,19 @@ func listChannelsCmdF(cmd *cobra.Command, args []string) error { teams := getTeamsFromTeamArgs(a, args) for i, team := range teams { if team == nil { - CommandPrintErrorln("Unable to find team '" + args[i] + "'") + cmd.CommandPrintErrorln("Unable to find team '" + args[i] + "'") continue } if result := <-a.Srv.Store.Channel().GetAll(team.Id); result.Err != nil { - CommandPrintErrorln("Unable to list channels for '" + args[i] + "'") + cmd.CommandPrintErrorln("Unable to list channels for '" + args[i] + "'") } else { channels := result.Data.([]*model.Channel) for _, channel := range channels { if channel.DeleteAt > 0 { - CommandPrettyPrintln(channel.Name + " (archived)") + cmd.CommandPrettyPrintln(channel.Name + " (archived)") } else { - CommandPrettyPrintln(channel.Name) + cmd.CommandPrettyPrintln(channel.Name) } } } @@ -414,8 +418,8 @@ func listChannelsCmdF(cmd *cobra.Command, args []string) error { return nil } -func restoreChannelsCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func restoreChannelsCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -427,19 +431,19 @@ func restoreChannelsCmdF(cmd *cobra.Command, args []string) error { channels := getChannelsFromChannelArgs(a, args) for i, channel := range channels { if channel == nil { - CommandPrintErrorln("Unable to find channel '" + args[i] + "'") + cmd.CommandPrintErrorln("Unable to find channel '" + args[i] + "'") continue } if result := <-a.Srv.Store.Channel().SetDeleteAt(channel.Id, 0, model.GetMillis()); result.Err != nil { - CommandPrintErrorln("Unable to restore channel '" + args[i] + "'") + cmd.CommandPrintErrorln("Unable to restore channel '" + args[i] + "'") } } return nil } -func modifyChannelCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func modifyChannelCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -448,13 +452,13 @@ func modifyChannelCmdF(cmd *cobra.Command, args []string) error { return errors.New("Enter at one channel to modify.") } - username, erru := cmd.Flags().GetString("username") + username, erru := command.Flags().GetString("username") if erru != nil || username == "" { return errors.New("Username is required") } - public, _ := cmd.Flags().GetBool("public") - private, _ := cmd.Flags().GetBool("private") + public, _ := command.Flags().GetBool("public") + private, _ := command.Flags().GetBool("private") if public == private { return errors.New("You must specify only one of --public or --private") diff --git a/cmd/platform/channel_test.go b/cmd/commands/channel_test.go index cf8603cf3..bd19b020a 100644 --- a/cmd/platform/channel_test.go +++ b/cmd/commands/channel_test.go @@ -1,13 +1,14 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main +package commands import ( "strings" "testing" "github.com/mattermost/mattermost-server/api" + "github.com/mattermost/mattermost-server/cmd" "github.com/mattermost/mattermost-server/model" "github.com/stretchr/testify/require" ) @@ -18,13 +19,13 @@ func TestJoinChannel(t *testing.T) { channel := th.CreateChannel(th.BasicClient, th.BasicTeam) - checkCommand(t, "channel", "add", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email) + cmd.CheckCommand(t, "channel", "add", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email) // Joining twice should succeed - checkCommand(t, "channel", "add", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email) + cmd.CheckCommand(t, "channel", "add", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email) // should fail because channel does not exist - require.Error(t, runCommand(t, "channel", "add", th.BasicTeam.Name+":"+channel.Name+"asdf", th.BasicUser2.Email)) + require.Error(t, cmd.RunCommand(t, "channel", "add", th.BasicTeam.Name+":"+channel.Name+"asdf", th.BasicUser2.Email)) } func TestRemoveChannel(t *testing.T) { @@ -33,15 +34,15 @@ func TestRemoveChannel(t *testing.T) { channel := th.CreateChannel(th.BasicClient, th.BasicTeam) - checkCommand(t, "channel", "add", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email) + cmd.CheckCommand(t, "channel", "add", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email) // should fail because channel does not exist - require.Error(t, runCommand(t, "channel", "remove", th.BasicTeam.Name+":doesnotexist", th.BasicUser2.Email)) + require.Error(t, cmd.RunCommand(t, "channel", "remove", th.BasicTeam.Name+":doesnotexist", th.BasicUser2.Email)) - checkCommand(t, "channel", "remove", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email) + cmd.CheckCommand(t, "channel", "remove", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email) // Leaving twice should succeed - checkCommand(t, "channel", "remove", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email) + cmd.CheckCommand(t, "channel", "remove", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email) } func TestMoveChannel(t *testing.T) { @@ -63,12 +64,12 @@ func TestMoveChannel(t *testing.T) { origin := team1.Name + ":" + channel.Name dest := team2.Name - checkCommand(t, "channel", "add", origin, adminEmail) + cmd.CheckCommand(t, "channel", "add", origin, adminEmail) // should fail with nill because errors are logged instead of returned when a channel does not exist - require.Nil(t, runCommand(t, "channel", "move", dest, team1.Name+":doesnotexist", "--username", adminUsername)) + require.Nil(t, cmd.RunCommand(t, "channel", "move", dest, team1.Name+":doesnotexist", "--username", adminUsername)) - checkCommand(t, "channel", "move", dest, origin, "--username", adminUsername) + cmd.CheckCommand(t, "channel", "move", dest, origin, "--username", adminUsername) } func TestListChannels(t *testing.T) { @@ -78,7 +79,7 @@ func TestListChannels(t *testing.T) { channel := th.CreateChannel(th.BasicClient, th.BasicTeam) th.BasicClient.Must(th.BasicClient.DeleteChannel(channel.Id)) - output := checkCommand(t, "channel", "list", th.BasicTeam.Name) + output := cmd.CheckCommand(t, "channel", "list", th.BasicTeam.Name) if !strings.Contains(string(output), "town-square") { t.Fatal("should have channels") @@ -96,10 +97,10 @@ func TestRestoreChannel(t *testing.T) { channel := th.CreateChannel(th.BasicClient, th.BasicTeam) th.BasicClient.Must(th.BasicClient.DeleteChannel(channel.Id)) - checkCommand(t, "channel", "restore", th.BasicTeam.Name+":"+channel.Name) + cmd.CheckCommand(t, "channel", "restore", th.BasicTeam.Name+":"+channel.Name) // restoring twice should succeed - checkCommand(t, "channel", "restore", th.BasicTeam.Name+":"+channel.Name) + cmd.CheckCommand(t, "channel", "restore", th.BasicTeam.Name+":"+channel.Name) } func TestCreateChannel(t *testing.T) { @@ -109,8 +110,8 @@ func TestCreateChannel(t *testing.T) { id := model.NewId() name := "name" + id - checkCommand(t, "channel", "create", "--display_name", name, "--team", th.BasicTeam.Name, "--name", name) + cmd.CheckCommand(t, "channel", "create", "--display_name", name, "--team", th.BasicTeam.Name, "--name", name) name = name + "-private" - checkCommand(t, "channel", "create", "--display_name", name, "--team", th.BasicTeam.Name, "--private", "--name", name) + cmd.CheckCommand(t, "channel", "create", "--display_name", name, "--team", th.BasicTeam.Name, "--private", "--name", name) } diff --git a/cmd/platform/channelargs.go b/cmd/commands/channelargs.go index c12a9cc9a..680fed34b 100644 --- a/cmd/platform/channelargs.go +++ b/cmd/commands/channelargs.go @@ -1,6 +1,7 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package commands import ( "fmt" diff --git a/cmd/platform/command.go b/cmd/commands/command.go index bbc5b47da..0202714b6 100644 --- a/cmd/platform/command.go +++ b/cmd/commands/command.go @@ -1,20 +1,22 @@ // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package commands import ( "errors" "github.com/mattermost/mattermost-server/app" + "github.com/mattermost/mattermost-server/cmd" "github.com/mattermost/mattermost-server/model" "github.com/spf13/cobra" ) -var commandCmd = &cobra.Command{ +var CommandCmd = &cobra.Command{ Use: "command", Short: "Management of slash commands", } -var commandMoveCmd = &cobra.Command{ +var CommandMoveCmd = &cobra.Command{ Use: "move", Short: "Move a slash command to a different team", Long: `Move a slash command to a different team. Commands can be specified by [team]:[command-trigger-word]. ie. myteam:trigger or by command ID.`, @@ -23,13 +25,14 @@ var commandMoveCmd = &cobra.Command{ } func init() { - commandCmd.AddCommand( - commandMoveCmd, + CommandCmd.AddCommand( + CommandMoveCmd, ) + cmd.RootCmd.AddCommand(CommandCmd) } -func moveCommandCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func moveCommandCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -44,16 +47,16 @@ func moveCommandCmdF(cmd *cobra.Command, args []string) error { } commands := getCommandsFromCommandArgs(a, args[1:]) - CommandPrintErrorln(commands) + cmd.CommandPrintErrorln(commands) for i, command := range commands { if command == nil { - CommandPrintErrorln("Unable to find command '" + args[i+1] + "'") + cmd.CommandPrintErrorln("Unable to find command '" + args[i+1] + "'") continue } if err := moveCommand(a, team, command); err != nil { - CommandPrintErrorln("Unable to move command '" + command.Trigger + "' error: " + err.Error()) + cmd.CommandPrintErrorln("Unable to move command '" + command.Trigger + "' error: " + err.Error()) } else { - CommandPrettyPrintln("Moved command '" + command.Trigger + "'") + cmd.CommandPrettyPrintln("Moved command '" + command.Trigger + "'") } } diff --git a/cmd/platform/commandargs.go b/cmd/commands/commandargs.go index 96e756815..702f01c9a 100644 --- a/cmd/platform/commandargs.go +++ b/cmd/commands/commandargs.go @@ -1,6 +1,7 @@ // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package commands import ( "fmt" diff --git a/cmd/platform/config.go b/cmd/commands/config.go index cd4356529..ef3b0f75e 100644 --- a/cmd/platform/config.go +++ b/cmd/commands/config.go @@ -1,23 +1,25 @@ // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package commands import ( "encoding/json" "errors" "os" + "github.com/mattermost/mattermost-server/cmd" "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/utils" "github.com/spf13/cobra" ) -var configCmd = &cobra.Command{ +var ConfigCmd = &cobra.Command{ Use: "config", Short: "Configuration", } -var validateConfigCmd = &cobra.Command{ +var ValidateConfigCmd = &cobra.Command{ Use: "validate", Short: "Validate config file", Long: "If the config file is valid, this command will output a success message and have a zero exit code. If it is invalid, this command will output an error and have a non-zero exit code.", @@ -25,15 +27,16 @@ var validateConfigCmd = &cobra.Command{ } func init() { - configCmd.AddCommand( - validateConfigCmd, + ConfigCmd.AddCommand( + ValidateConfigCmd, ) + cmd.RootCmd.AddCommand(ConfigCmd) } -func configValidateCmdF(cmd *cobra.Command, args []string) error { +func configValidateCmdF(command *cobra.Command, args []string) error { utils.TranslationsPreInit() model.AppErrorInit(utils.T) - filePath, err := cmd.Flags().GetString("config") + filePath, err := command.Flags().GetString("config") if err != nil { return err } @@ -60,6 +63,6 @@ func configValidateCmdF(cmd *cobra.Command, args []string) error { return errors.New(utils.T(err.Id)) } - CommandPrettyPrintln("The document is valid") + cmd.CommandPrettyPrintln("The document is valid") return nil } diff --git a/cmd/platform/mattermost_test.go b/cmd/commands/config_flag_test.go index 7246d620f..8d284ab73 100644 --- a/cmd/platform/mattermost_test.go +++ b/cmd/commands/config_flag_test.go @@ -1,7 +1,7 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main +package commands import ( "io/ioutil" @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/mattermost/mattermost-server/cmd" "github.com/mattermost/mattermost-server/utils" ) @@ -34,8 +35,8 @@ func TestConfigFlag(t *testing.T) { defer os.Chdir(prevDir) os.Chdir(dir) - require.Error(t, runCommand(t, "version")) - checkCommand(t, "--config", "foo.json", "version") - checkCommand(t, "--config", "./foo.json", "version") - checkCommand(t, "--config", configPath, "version") + require.Error(t, cmd.RunCommand(t, "version")) + cmd.CheckCommand(t, "--config", "foo.json", "version") + cmd.CheckCommand(t, "--config", "./foo.json", "version") + cmd.CheckCommand(t, "--config", configPath, "version") } diff --git a/cmd/platform/config_test.go b/cmd/commands/config_test.go index f1c09c6f5..54ddfcb61 100644 --- a/cmd/platform/config_test.go +++ b/cmd/commands/config_test.go @@ -1,7 +1,7 @@ // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main +package commands import ( "io/ioutil" @@ -9,6 +9,7 @@ import ( "path/filepath" "testing" + "github.com/mattermost/mattermost-server/cmd" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -25,6 +26,6 @@ func TestConfigValidate(t *testing.T) { config.SetDefaults() require.NoError(t, ioutil.WriteFile(path, []byte(config.ToJson()), 0600)) - assert.Error(t, runCommand(t, "--config", "foo.json", "config", "validate")) - assert.NoError(t, runCommand(t, "--config", path, "config", "validate")) + assert.Error(t, cmd.RunCommand(t, "--config", "foo.json", "config", "validate")) + assert.NoError(t, cmd.RunCommand(t, "--config", path, "config", "validate")) } diff --git a/cmd/commands/exec_command_test.go b/cmd/commands/exec_command_test.go new file mode 100644 index 000000000..79e65fe83 --- /dev/null +++ b/cmd/commands/exec_command_test.go @@ -0,0 +1,21 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package commands + +import ( + "flag" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/mattermost/mattermost-server/cmd" +) + +func TestExecCommand(t *testing.T) { + if filter := flag.Lookup("test.run").Value.String(); filter != "ExecCommand" { + t.Skip("use -run ExecCommand to execute a command via the test executable") + } + cmd.RootCmd.SetArgs(flag.Args()) + require.NoError(t, cmd.RootCmd.Execute()) +} diff --git a/cmd/platform/import.go b/cmd/commands/import.go index 44ada904f..4058d175a 100644 --- a/cmd/platform/import.go +++ b/cmd/commands/import.go @@ -1,6 +1,7 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package commands import ( "errors" @@ -8,15 +9,16 @@ import ( "fmt" + "github.com/mattermost/mattermost-server/cmd" "github.com/spf13/cobra" ) -var importCmd = &cobra.Command{ +var ImportCmd = &cobra.Command{ Use: "import", Short: "Import data.", } -var slackImportCmd = &cobra.Command{ +var SlackImportCmd = &cobra.Command{ Use: "slack [team] [file]", Short: "Import a team from Slack.", Long: "Import a team from a Slack export zip file.", @@ -24,7 +26,7 @@ var slackImportCmd = &cobra.Command{ RunE: slackImportCmdF, } -var bulkImportCmd = &cobra.Command{ +var BulkImportCmd = &cobra.Command{ Use: "bulk [file]", Short: "Import bulk data.", Long: "Import data from a Mattermost Bulk Import File.", @@ -33,18 +35,19 @@ var bulkImportCmd = &cobra.Command{ } func init() { - bulkImportCmd.Flags().Bool("apply", false, "Save the import data to the database. Use with caution - this cannot be reverted.") - bulkImportCmd.Flags().Bool("validate", false, "Validate the import data without making any changes to the system.") - bulkImportCmd.Flags().Int("workers", 2, "How many workers to run whilst doing the import.") + BulkImportCmd.Flags().Bool("apply", false, "Save the import data to the database. Use with caution - this cannot be reverted.") + BulkImportCmd.Flags().Bool("validate", false, "Validate the import data without making any changes to the system.") + BulkImportCmd.Flags().Int("workers", 2, "How many workers to run whilst doing the import.") - importCmd.AddCommand( - bulkImportCmd, - slackImportCmd, + ImportCmd.AddCommand( + BulkImportCmd, + SlackImportCmd, ) + cmd.RootCmd.AddCommand(ImportCmd) } -func slackImportCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func slackImportCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -69,32 +72,32 @@ func slackImportCmdF(cmd *cobra.Command, args []string) error { return err } - CommandPrettyPrintln("Running Slack Import. This may take a long time for large teams or teams with many messages.") + cmd.CommandPrettyPrintln("Running Slack Import. This may take a long time for large teams or teams with many messages.") a.SlackImport(fileReader, fileInfo.Size(), team.Id) - CommandPrettyPrintln("Finished Slack Import.") + cmd.CommandPrettyPrintln("Finished Slack Import.") return nil } -func bulkImportCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func bulkImportCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } - apply, err := cmd.Flags().GetBool("apply") + apply, err := command.Flags().GetBool("apply") if err != nil { return errors.New("Apply flag error") } - validate, err := cmd.Flags().GetBool("validate") + validate, err := command.Flags().GetBool("validate") if err != nil { return errors.New("Validate flag error") } - workers, err := cmd.Flags().GetInt("workers") + workers, err := command.Flags().GetInt("workers") if err != nil { return errors.New("Workers flag error") } @@ -110,28 +113,28 @@ func bulkImportCmdF(cmd *cobra.Command, args []string) error { defer fileReader.Close() if apply && validate { - CommandPrettyPrintln("Use only one of --apply or --validate.") + cmd.CommandPrettyPrintln("Use only one of --apply or --validate.") return nil } else if apply && !validate { - CommandPrettyPrintln("Running Bulk Import. This may take a long time.") + cmd.CommandPrettyPrintln("Running Bulk Import. This may take a long time.") } else { - CommandPrettyPrintln("Running Bulk Import Data Validation.") - CommandPrettyPrintln("** This checks the validity of the entities in the data file, but does not persist any changes **") - CommandPrettyPrintln("Use the --apply flag to perform the actual data import.") + cmd.CommandPrettyPrintln("Running Bulk Import Data Validation.") + cmd.CommandPrettyPrintln("** This checks the validity of the entities in the data file, but does not persist any changes **") + cmd.CommandPrettyPrintln("Use the --apply flag to perform the actual data import.") } - CommandPrettyPrintln("") + cmd.CommandPrettyPrintln("") if err, lineNumber := a.BulkImport(fileReader, !apply, workers); err != nil { - CommandPrettyPrintln(err.Error()) + cmd.CommandPrettyPrintln(err.Error()) if lineNumber != 0 { - CommandPrettyPrintln(fmt.Sprintf("Error occurred on data file line %v", lineNumber)) + cmd.CommandPrettyPrintln(fmt.Sprintf("Error occurred on data file line %v", lineNumber)) } } else { if apply { - CommandPrettyPrintln("Finished Bulk Import.") + cmd.CommandPrettyPrintln("Finished Bulk Import.") } else { - CommandPrettyPrintln("Validation complete. You can now perform the import by rerunning this command with the --apply flag.") + cmd.CommandPrettyPrintln("Validation complete. You can now perform the import by rerunning this command with the --apply flag.") } } diff --git a/cmd/platform/jobserver.go b/cmd/commands/jobserver.go index 044ee6b6a..b96984b41 100644 --- a/cmd/platform/jobserver.go +++ b/cmd/commands/jobserver.go @@ -1,6 +1,7 @@ // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package commands import ( "os" @@ -8,27 +9,30 @@ import ( "syscall" l4g "github.com/alecthomas/log4go" + "github.com/mattermost/mattermost-server/cmd" "github.com/spf13/cobra" ) -var jobserverCmd = &cobra.Command{ +var JobserverCmd = &cobra.Command{ Use: "jobserver", Short: "Start the Mattermost job server", Run: jobserverCmdF, } func init() { - jobserverCmd.Flags().Bool("nojobs", false, "Do not run jobs on this jobserver.") - jobserverCmd.Flags().Bool("noschedule", false, "Do not schedule jobs from this jobserver.") + JobserverCmd.Flags().Bool("nojobs", false, "Do not run jobs on this jobserver.") + JobserverCmd.Flags().Bool("noschedule", false, "Do not schedule jobs from this jobserver.") + + cmd.RootCmd.AddCommand(JobserverCmd) } -func jobserverCmdF(cmd *cobra.Command, args []string) { +func jobserverCmdF(command *cobra.Command, args []string) { // Options - noJobs, _ := cmd.Flags().GetBool("nojobs") - noSchedule, _ := cmd.Flags().GetBool("noschedule") + noJobs, _ := command.Flags().GetBool("nojobs") + noSchedule, _ := command.Flags().GetBool("noschedule") // Initialize - a, err := initDBCommandContext("config.json") + a, err := cmd.InitDBCommandContext("config.json") if err != nil { panic(err.Error()) } diff --git a/cmd/platform/ldap.go b/cmd/commands/ldap.go index 1bbcaa2f5..6938eae28 100644 --- a/cmd/platform/ldap.go +++ b/cmd/commands/ldap.go @@ -1,18 +1,20 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package commands import ( + "github.com/mattermost/mattermost-server/cmd" "github.com/mattermost/mattermost-server/model" "github.com/spf13/cobra" ) -var ldapCmd = &cobra.Command{ +var LdapCmd = &cobra.Command{ Use: "ldap", Short: "LDAP related utilities", } -var ldapSyncCmd = &cobra.Command{ +var LdapSyncCmd = &cobra.Command{ Use: "sync", Short: "Synchronize now", Long: "Synchronize all LDAP users now.", @@ -21,13 +23,14 @@ var ldapSyncCmd = &cobra.Command{ } func init() { - ldapCmd.AddCommand( - ldapSyncCmd, + LdapCmd.AddCommand( + LdapSyncCmd, ) + cmd.RootCmd.AddCommand(LdapCmd) } -func ldapSyncCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func ldapSyncCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -35,9 +38,9 @@ func ldapSyncCmdF(cmd *cobra.Command, args []string) error { if ldapI := a.Ldap; ldapI != nil { job, err := ldapI.StartSynchronizeJob(true) if err != nil || job.Status == model.JOB_STATUS_ERROR || job.Status == model.JOB_STATUS_CANCELED { - CommandPrintErrorln("ERROR: AD/LDAP Synchronization please check the server logs") + cmd.CommandPrintErrorln("ERROR: AD/LDAP Synchronization please check the server logs") } else { - CommandPrettyPrintln("SUCCESS: AD/LDAP Synchronization Complete") + cmd.CommandPrettyPrintln("SUCCESS: AD/LDAP Synchronization Complete") } } diff --git a/cmd/platform/license.go b/cmd/commands/license.go index 73efe9137..dce257a5d 100644 --- a/cmd/platform/license.go +++ b/cmd/commands/license.go @@ -1,20 +1,22 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package commands import ( "errors" "io/ioutil" + "github.com/mattermost/mattermost-server/cmd" "github.com/spf13/cobra" ) -var licenseCmd = &cobra.Command{ +var LicenseCmd = &cobra.Command{ Use: "license", Short: "Licensing commands", } -var uploadLicenseCmd = &cobra.Command{ +var UploadLicenseCmd = &cobra.Command{ Use: "upload [license]", Short: "Upload a license.", Long: "Upload a license. Replaces current license.", @@ -23,11 +25,12 @@ var uploadLicenseCmd = &cobra.Command{ } func init() { - licenseCmd.AddCommand(uploadLicenseCmd) + LicenseCmd.AddCommand(UploadLicenseCmd) + cmd.RootCmd.AddCommand(LicenseCmd) } -func uploadLicenseCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func uploadLicenseCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -45,7 +48,7 @@ func uploadLicenseCmdF(cmd *cobra.Command, args []string) error { return err } - CommandPrettyPrintln("Uploaded license file") + cmd.CommandPrettyPrintln("Uploaded license file") return nil } diff --git a/cmd/platform/message_export.go b/cmd/commands/message_export.go index fb1f4073b..7162d46c2 100644 --- a/cmd/platform/message_export.go +++ b/cmd/commands/message_export.go @@ -1,7 +1,7 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main +package commands import ( "errors" @@ -10,11 +10,12 @@ import ( "time" + "github.com/mattermost/mattermost-server/cmd" "github.com/mattermost/mattermost-server/model" "github.com/spf13/cobra" ) -var messageExportCmd = &cobra.Command{ +var MessageExportCmd = &cobra.Command{ Use: "export", Short: "Export data from Mattermost", Long: "Export data from Mattermost in a format suitable for import into a third-party application", @@ -23,13 +24,14 @@ var messageExportCmd = &cobra.Command{ } func init() { - messageExportCmd.Flags().String("format", "actiance", "The format to export data in") - messageExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.") - messageExportCmd.Flags().Int("timeoutSeconds", -1, "The maximum number of seconds to wait for the job to complete before timing out.") + MessageExportCmd.Flags().String("format", "actiance", "The format to export data in") + MessageExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.") + MessageExportCmd.Flags().Int("timeoutSeconds", -1, "The maximum number of seconds to wait for the job to complete before timing out.") + cmd.RootCmd.AddCommand(MessageExportCmd) } -func messageExportCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func messageExportCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -39,20 +41,20 @@ func messageExportCmdF(cmd *cobra.Command, args []string) error { } // for now, format is hard-coded to actiance. In time, we'll have to support other formats and inject them into job data - if format, err := cmd.Flags().GetString("format"); err != nil { + if format, err := command.Flags().GetString("format"); err != nil { return errors.New("format flag error") } else if format != "actiance" { return errors.New("unsupported export format") } - startTime, err := cmd.Flags().GetInt64("exportFrom") + startTime, err := command.Flags().GetInt64("exportFrom") if err != nil { return errors.New("exportFrom flag error") } else if startTime < 0 { return errors.New("exportFrom must be a positive integer") } - timeoutSeconds, err := cmd.Flags().GetInt("timeoutSeconds") + timeoutSeconds, err := command.Flags().GetInt("timeoutSeconds") if err != nil { return errors.New("timeoutSeconds error") } else if timeoutSeconds < 0 { @@ -69,9 +71,9 @@ func messageExportCmdF(cmd *cobra.Command, args []string) error { job, err := messageExportI.StartSynchronizeJob(ctx, startTime) if err != nil || job.Status == model.JOB_STATUS_ERROR || job.Status == model.JOB_STATUS_CANCELED { - CommandPrintErrorln("ERROR: Message export job failed. Please check the server logs") + cmd.CommandPrintErrorln("ERROR: Message export job failed. Please check the server logs") } else { - CommandPrettyPrintln("SUCCESS: Message export job complete") + cmd.CommandPrettyPrintln("SUCCESS: Message export job complete") } } diff --git a/cmd/platform/message_export_test.go b/cmd/commands/message_export_test.go index 386aa4268..5170b77af 100644 --- a/cmd/platform/message_export_test.go +++ b/cmd/commands/message_export_test.go @@ -1,7 +1,7 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main +package commands import ( "io/ioutil" @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/mattermost/mattermost-server/cmd" "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/utils" ) @@ -24,7 +25,7 @@ func TestMessageExportNotEnabled(t *testing.T) { defer os.RemoveAll(filepath.Dir(configPath)) // should fail fast because the feature isn't enabled - require.Error(t, runCommand(t, "--config", configPath, "export")) + require.Error(t, cmd.RunCommand(t, "--config", configPath, "export")) } func TestMessageExportInvalidFormat(t *testing.T) { @@ -32,7 +33,7 @@ func TestMessageExportInvalidFormat(t *testing.T) { defer os.RemoveAll(filepath.Dir(configPath)) // should fail fast because format isn't supported - require.Error(t, runCommand(t, "--config", configPath, "--format", "not_actiance", "export")) + require.Error(t, cmd.RunCommand(t, "--config", configPath, "--format", "not_actiance", "export")) } func TestMessageExportNegativeExportFrom(t *testing.T) { @@ -40,7 +41,7 @@ func TestMessageExportNegativeExportFrom(t *testing.T) { defer os.RemoveAll(filepath.Dir(configPath)) // should fail fast because export from must be a valid timestamp - require.Error(t, runCommand(t, "--config", configPath, "--format", "actiance", "--exportFrom", "-1", "export")) + require.Error(t, cmd.RunCommand(t, "--config", configPath, "--format", "actiance", "--exportFrom", "-1", "export")) } func TestMessageExportNegativeTimeoutSeconds(t *testing.T) { @@ -48,7 +49,7 @@ func TestMessageExportNegativeTimeoutSeconds(t *testing.T) { defer os.RemoveAll(filepath.Dir(configPath)) // should fail fast because timeout seconds must be a positive int - require.Error(t, runCommand(t, "--config", configPath, "--format", "actiance", "--exportFrom", "0", "--timeoutSeconds", "-1", "export")) + require.Error(t, cmd.RunCommand(t, "--config", configPath, "--format", "actiance", "--exportFrom", "0", "--timeoutSeconds", "-1", "export")) } func writeTempConfig(t *testing.T, isMessageExportEnabled bool) string { diff --git a/cmd/commands/reset.go b/cmd/commands/reset.go new file mode 100644 index 000000000..e479d0354 --- /dev/null +++ b/cmd/commands/reset.go @@ -0,0 +1,53 @@ +// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package commands + +import ( + "errors" + "fmt" + + "github.com/mattermost/mattermost-server/cmd" + "github.com/spf13/cobra" +) + +var ResetCmd = &cobra.Command{ + Use: "reset", + Short: "Reset the database to initial state", + Long: "Completely erases the database causing the loss of all data. This will reset Mattermost to its initial state.", + RunE: resetCmdF, +} + +func init() { + ResetCmd.Flags().Bool("confirm", false, "Confirm you really want to delete everything and a DB backup has been performed.") + + cmd.RootCmd.AddCommand(ResetCmd) +} + +func resetCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) + if err != nil { + return err + } + + confirmFlag, _ := command.Flags().GetBool("confirm") + if !confirmFlag { + var confirm string + cmd.CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ") + fmt.Scanln(&confirm) + + if confirm != "YES" { + return errors.New("ABORTED: You did not answer YES exactly, in all capitals.") + } + cmd.CommandPrettyPrintln("Are you sure you want to delete everything? All data will be permanently deleted? (YES/NO): ") + fmt.Scanln(&confirm) + if confirm != "YES" { + return errors.New("ABORTED: You did not answer YES exactly, in all capitals.") + } + } + + a.Srv.Store.DropAllTables() + cmd.CommandPrettyPrintln("Database sucessfully reset") + + return nil +} diff --git a/cmd/platform/roles.go b/cmd/commands/roles.go index e7a1c1a0e..bf7c39476 100644 --- a/cmd/platform/roles.go +++ b/cmd/commands/roles.go @@ -1,19 +1,21 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package commands import ( "errors" + "github.com/mattermost/mattermost-server/cmd" "github.com/spf13/cobra" ) -var rolesCmd = &cobra.Command{ +var RolesCmd = &cobra.Command{ Use: "roles", Short: "Management of user roles", } -var makeSystemAdminCmd = &cobra.Command{ +var MakeSystemAdminCmd = &cobra.Command{ Use: "system_admin [users]", Short: "Set a user as system admin", Long: "Make some users system admins", @@ -21,7 +23,7 @@ var makeSystemAdminCmd = &cobra.Command{ RunE: makeSystemAdminCmdF, } -var makeMemberCmd = &cobra.Command{ +var MakeMemberCmd = &cobra.Command{ Use: "member [users]", Short: "Remove system admin privileges", Long: "Remove system admin privileges from some users.", @@ -30,14 +32,15 @@ var makeMemberCmd = &cobra.Command{ } func init() { - rolesCmd.AddCommand( - makeSystemAdminCmd, - makeMemberCmd, + RolesCmd.AddCommand( + MakeSystemAdminCmd, + MakeMemberCmd, ) + cmd.RootCmd.AddCommand(RolesCmd) } -func makeSystemAdminCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func makeSystemAdminCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -60,8 +63,8 @@ func makeSystemAdminCmdF(cmd *cobra.Command, args []string) error { return nil } -func makeMemberCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func makeMemberCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } diff --git a/cmd/platform/roles_test.go b/cmd/commands/roles_test.go index 1a5ae5173..1e0a46a4e 100644 --- a/cmd/platform/roles_test.go +++ b/cmd/commands/roles_test.go @@ -1,12 +1,13 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main +package commands import ( "testing" "github.com/mattermost/mattermost-server/api" + "github.com/mattermost/mattermost-server/cmd" "github.com/mattermost/mattermost-server/model" ) @@ -14,7 +15,7 @@ func TestAssignRole(t *testing.T) { th := api.Setup().InitBasic() defer th.TearDown() - checkCommand(t, "roles", "system_admin", th.BasicUser.Email) + cmd.CheckCommand(t, "roles", "system_admin", th.BasicUser.Email) if result := <-th.App.Srv.Store.User().GetByEmail(th.BasicUser.Email); result.Err != nil { t.Fatal() diff --git a/cmd/platform/sampledata.go b/cmd/commands/sampledata.go index 97a73b021..5377f1153 100644 --- a/cmd/platform/sampledata.go +++ b/cmd/commands/sampledata.go @@ -1,6 +1,7 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package commands import ( "encoding/json" @@ -16,15 +17,34 @@ import ( "github.com/icrowley/fake" "github.com/mattermost/mattermost-server/app" + "github.com/mattermost/mattermost-server/cmd" "github.com/spf13/cobra" ) -var sampleDataCmd = &cobra.Command{ +var SampleDataCmd = &cobra.Command{ Use: "sampledata", Short: "Generate sample data", RunE: sampleDataCmdF, } +func init() { + SampleDataCmd.Flags().Int64P("seed", "s", 1, "Seed used for generating the random data (Different seeds generate different data).") + SampleDataCmd.Flags().IntP("teams", "t", 2, "The number of sample teams.") + SampleDataCmd.Flags().Int("channels-per-team", 10, "The number of sample channels per team.") + SampleDataCmd.Flags().IntP("users", "u", 15, "The number of sample users.") + SampleDataCmd.Flags().Int("team-memberships", 2, "The number of sample team memberships per user.") + SampleDataCmd.Flags().Int("channel-memberships", 5, "The number of sample channel memberships per user in a team.") + SampleDataCmd.Flags().Int("posts-per-channel", 100, "The number of sample post per channel.") + SampleDataCmd.Flags().Int("direct-channels", 30, "The number of sample direct message channels.") + SampleDataCmd.Flags().Int("posts-per-direct-channel", 15, "The number of sample posts per direct message channel.") + SampleDataCmd.Flags().Int("group-channels", 15, "The number of sample group message channels.") + SampleDataCmd.Flags().Int("posts-per-group-channel", 30, "The number of sample posts per group message channel.") + SampleDataCmd.Flags().IntP("workers", "w", 2, "How many workers to run during the import.") + SampleDataCmd.Flags().String("profile-images", "", "Optional. Path to folder with images to randomly pick as user profile image.") + SampleDataCmd.Flags().StringP("bulk", "b", "", "Optional. Path to write a JSONL bulk file instead of loading into the database.") + cmd.RootCmd.AddCommand(SampleDataCmd) +} + func sliceIncludes(vs []string, t string) bool { for _, v := range vs { if v == t { @@ -109,81 +129,64 @@ func randomMessage(users []string) string { return message } -func init() { - sampleDataCmd.Flags().Int64P("seed", "s", 1, "Seed used for generating the random data (Different seeds generate different data).") - sampleDataCmd.Flags().IntP("teams", "t", 2, "The number of sample teams.") - sampleDataCmd.Flags().Int("channels-per-team", 10, "The number of sample channels per team.") - sampleDataCmd.Flags().IntP("users", "u", 15, "The number of sample users.") - sampleDataCmd.Flags().Int("team-memberships", 2, "The number of sample team memberships per user.") - sampleDataCmd.Flags().Int("channel-memberships", 5, "The number of sample channel memberships per user in a team.") - sampleDataCmd.Flags().Int("posts-per-channel", 100, "The number of sample post per channel.") - sampleDataCmd.Flags().Int("direct-channels", 30, "The number of sample direct message channels.") - sampleDataCmd.Flags().Int("posts-per-direct-channel", 15, "The number of sample posts per direct message channel.") - sampleDataCmd.Flags().Int("group-channels", 15, "The number of sample group message channels.") - sampleDataCmd.Flags().Int("posts-per-group-channel", 30, "The number of sample posts per group message channel.") - sampleDataCmd.Flags().IntP("workers", "w", 2, "How many workers to run during the import.") - sampleDataCmd.Flags().String("profile-images", "", "Optional. Path to folder with images to randomly pick as user profile image.") - sampleDataCmd.Flags().StringP("bulk", "b", "", "Optional. Path to write a JSONL bulk file instead of loading into the database.") -} - -func sampleDataCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func sampleDataCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } - seed, err := cmd.Flags().GetInt64("seed") + seed, err := command.Flags().GetInt64("seed") if err != nil { return errors.New("Invalid seed parameter") } - bulk, err := cmd.Flags().GetString("bulk") + bulk, err := command.Flags().GetString("bulk") if err != nil { return errors.New("Invalid bulk parameter") } - teams, err := cmd.Flags().GetInt("teams") + teams, err := command.Flags().GetInt("teams") if err != nil || teams < 0 { return errors.New("Invalid teams parameter") } - channelsPerTeam, err := cmd.Flags().GetInt("channels-per-team") + channelsPerTeam, err := command.Flags().GetInt("channels-per-team") if err != nil || channelsPerTeam < 0 { return errors.New("Invalid channels-per-team parameter") } - users, err := cmd.Flags().GetInt("users") + users, err := command.Flags().GetInt("users") if err != nil || users < 0 { return errors.New("Invalid users parameter") } - teamMemberships, err := cmd.Flags().GetInt("team-memberships") + teamMemberships, err := command.Flags().GetInt("team-memberships") if err != nil || teamMemberships < 0 { return errors.New("Invalid team-memberships parameter") } - channelMemberships, err := cmd.Flags().GetInt("channel-memberships") + channelMemberships, err := command.Flags().GetInt("channel-memberships") if err != nil || channelMemberships < 0 { return errors.New("Invalid channel-memberships parameter") } - postsPerChannel, err := cmd.Flags().GetInt("posts-per-channel") + postsPerChannel, err := command.Flags().GetInt("posts-per-channel") if err != nil || postsPerChannel < 0 { return errors.New("Invalid posts-per-channel parameter") } - directChannels, err := cmd.Flags().GetInt("direct-channels") + directChannels, err := command.Flags().GetInt("direct-channels") if err != nil || directChannels < 0 { return errors.New("Invalid direct-channels parameter") } - postsPerDirectChannel, err := cmd.Flags().GetInt("posts-per-direct-channel") + postsPerDirectChannel, err := command.Flags().GetInt("posts-per-direct-channel") if err != nil || postsPerDirectChannel < 0 { return errors.New("Invalid posts-per-direct-channel parameter") } - groupChannels, err := cmd.Flags().GetInt("group-channels") + groupChannels, err := command.Flags().GetInt("group-channels") if err != nil || groupChannels < 0 { return errors.New("Invalid group-channels parameter") } - postsPerGroupChannel, err := cmd.Flags().GetInt("posts-per-group-channel") + postsPerGroupChannel, err := command.Flags().GetInt("posts-per-group-channel") if err != nil || postsPerGroupChannel < 0 { return errors.New("Invalid posts-per-group-channel parameter") } - workers, err := cmd.Flags().GetInt("workers") + workers, err := command.Flags().GetInt("workers") if err != nil { return errors.New("Invalid workers parameter") } - profileImagesPath, err := cmd.Flags().GetString("profile-images") + profileImagesPath, err := command.Flags().GetString("profile-images") if err != nil { return errors.New("Invalid profile-images parameter") } diff --git a/cmd/platform/sampledata_test.go b/cmd/commands/sampledata_test.go index de28c0856..d71ac0575 100644 --- a/cmd/platform/sampledata_test.go +++ b/cmd/commands/sampledata_test.go @@ -1,12 +1,13 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main +package commands import ( "testing" "github.com/mattermost/mattermost-server/api" + "github.com/mattermost/mattermost-server/cmd" "github.com/stretchr/testify/require" ) @@ -15,11 +16,11 @@ func TestSampledataBadParameters(t *testing.T) { defer th.TearDown() // should fail because you need at least 1 worker - require.Error(t, runCommand(t, "sampledata", "--workers", "0")) + require.Error(t, cmd.RunCommand(t, "sampledata", "--workers", "0")) // should fail because you have more team memberships than teams - require.Error(t, runCommand(t, "sampledata", "--teams", "10", "--teams-memberships", "11")) + require.Error(t, cmd.RunCommand(t, "sampledata", "--teams", "10", "--teams-memberships", "11")) // should fail because you have more channel memberships than channels per team - require.Error(t, runCommand(t, "sampledata", "--channels-per-team", "10", "--channel-memberships", "11")) + require.Error(t, cmd.RunCommand(t, "sampledata", "--channels-per-team", "10", "--channel-memberships", "11")) } diff --git a/cmd/platform/server.go b/cmd/commands/server.go index 31606e6eb..8358fe98f 100644 --- a/cmd/platform/server.go +++ b/cmd/commands/server.go @@ -1,7 +1,7 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main +package commands import ( "net" @@ -14,6 +14,7 @@ import ( "github.com/mattermost/mattermost-server/api" "github.com/mattermost/mattermost-server/api4" "github.com/mattermost/mattermost-server/app" + "github.com/mattermost/mattermost-server/cmd" "github.com/mattermost/mattermost-server/manualtesting" "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/utils" @@ -31,17 +32,22 @@ var MaxNotificationsPerChannelDefault int64 = 1000000 var serverCmd = &cobra.Command{ Use: "server", Short: "Run the Mattermost server", - RunE: runServerCmd, + RunE: serverCmdF, SilenceUsage: true, } -func runServerCmd(cmd *cobra.Command, args []string) error { - config, err := cmd.Flags().GetString("config") +func init() { + cmd.RootCmd.AddCommand(serverCmd) + cmd.RootCmd.RunE = serverCmdF +} + +func serverCmdF(command *cobra.Command, args []string) error { + config, err := command.Flags().GetString("config") if err != nil { return err } - disableConfigWatch, _ := cmd.Flags().GetBool("disableconfigwatch") + disableConfigWatch, _ := command.Flags().GetBool("disableconfigwatch") interruptChan := make(chan os.Signal, 1) return runServer(config, disableConfigWatch, interruptChan) diff --git a/cmd/platform/server_test.go b/cmd/commands/server_test.go index 2f04e7d15..fb7dfdef2 100644 --- a/cmd/platform/server_test.go +++ b/cmd/commands/server_test.go @@ -1,7 +1,7 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main +package commands import ( "io/ioutil" @@ -110,7 +110,7 @@ func TestRunServerSystemdNotification(t *testing.T) { panic(err) } data := buffer[0:count] - ch<- string(data) + ch <- string(data) }(socketReader) // Start and stop the server diff --git a/cmd/platform/team.go b/cmd/commands/team.go index 1cb5bd99e..9c07b7456 100644 --- a/cmd/platform/team.go +++ b/cmd/commands/team.go @@ -1,22 +1,24 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package commands import ( "errors" "fmt" "github.com/mattermost/mattermost-server/app" + "github.com/mattermost/mattermost-server/cmd" "github.com/mattermost/mattermost-server/model" "github.com/spf13/cobra" ) -var teamCmd = &cobra.Command{ +var TeamCmd = &cobra.Command{ Use: "team", Short: "Management of teams", } -var teamCreateCmd = &cobra.Command{ +var TeamCreateCmd = &cobra.Command{ Use: "create", Short: "Create a team", Long: `Create a team.`, @@ -25,7 +27,7 @@ var teamCreateCmd = &cobra.Command{ RunE: createTeamCmdF, } -var removeUsersCmd = &cobra.Command{ +var RemoveUsersCmd = &cobra.Command{ Use: "remove [team] [users]", Short: "Remove users from team", Long: "Remove some users from team", @@ -33,7 +35,7 @@ var removeUsersCmd = &cobra.Command{ RunE: removeUsersCmdF, } -var addUsersCmd = &cobra.Command{ +var AddUsersCmd = &cobra.Command{ Use: "add [team] [users]", Short: "Add users to team", Long: "Add some users to team", @@ -41,7 +43,7 @@ var addUsersCmd = &cobra.Command{ RunE: addUsersCmdF, } -var deleteTeamsCmd = &cobra.Command{ +var DeleteTeamsCmd = &cobra.Command{ Use: "delete [teams]", Short: "Delete teams", Long: `Permanently delete some teams. @@ -51,37 +53,38 @@ Permanently deletes a team along with all related information including posts fr } func init() { - teamCreateCmd.Flags().String("name", "", "Team Name") - teamCreateCmd.Flags().String("display_name", "", "Team Display Name") - teamCreateCmd.Flags().Bool("private", false, "Create a private team.") - teamCreateCmd.Flags().String("email", "", "Administrator Email (anyone with this email is automatically a team admin)") - - deleteTeamsCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the team and a DB backup has been performed.") - - teamCmd.AddCommand( - teamCreateCmd, - removeUsersCmd, - addUsersCmd, - deleteTeamsCmd, + TeamCreateCmd.Flags().String("name", "", "Team Name") + TeamCreateCmd.Flags().String("display_name", "", "Team Display Name") + TeamCreateCmd.Flags().Bool("private", false, "Create a private team.") + TeamCreateCmd.Flags().String("email", "", "Administrator Email (anyone with this email is automatically a team admin)") + + DeleteTeamsCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the team and a DB backup has been performed.") + + TeamCmd.AddCommand( + TeamCreateCmd, + RemoveUsersCmd, + AddUsersCmd, + DeleteTeamsCmd, ) + cmd.RootCmd.AddCommand(TeamCmd) } -func createTeamCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func createTeamCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } - name, errn := cmd.Flags().GetString("name") + name, errn := command.Flags().GetString("name") if errn != nil || name == "" { return errors.New("Name is required") } - displayname, errdn := cmd.Flags().GetString("display_name") + displayname, errdn := command.Flags().GetString("display_name") if errdn != nil || displayname == "" { return errors.New("Display Name is required") } - email, _ := cmd.Flags().GetString("email") - useprivate, _ := cmd.Flags().GetBool("private") + email, _ := command.Flags().GetString("email") + useprivate, _ := command.Flags().GetBool("private") teamType := model.TEAM_OPEN if useprivate { @@ -102,8 +105,8 @@ func createTeamCmdF(cmd *cobra.Command, args []string) error { return nil } -func removeUsersCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func removeUsersCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -127,16 +130,16 @@ func removeUsersCmdF(cmd *cobra.Command, args []string) error { func removeUserFromTeam(a *app.App, team *model.Team, user *model.User, userArg string) { if user == nil { - CommandPrintErrorln("Can't find user '" + userArg + "'") + cmd.CommandPrintErrorln("Can't find user '" + userArg + "'") return } if err := a.LeaveTeam(team, user, ""); err != nil { - CommandPrintErrorln("Unable to remove '" + userArg + "' from " + team.Name + ". Error: " + err.Error()) + cmd.CommandPrintErrorln("Unable to remove '" + userArg + "' from " + team.Name + ". Error: " + err.Error()) } } -func addUsersCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func addUsersCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -160,16 +163,16 @@ func addUsersCmdF(cmd *cobra.Command, args []string) error { func addUserToTeam(a *app.App, team *model.Team, user *model.User, userArg string) { if user == nil { - CommandPrintErrorln("Can't find user '" + userArg + "'") + cmd.CommandPrintErrorln("Can't find user '" + userArg + "'") return } if err := a.JoinUserToTeam(team, user, ""); err != nil { - CommandPrintErrorln("Unable to add '" + userArg + "' to " + team.Name) + cmd.CommandPrintErrorln("Unable to add '" + userArg + "' to " + team.Name) } } -func deleteTeamsCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func deleteTeamsCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -178,16 +181,16 @@ func deleteTeamsCmdF(cmd *cobra.Command, args []string) error { return errors.New("Not enough arguments.") } - confirmFlag, _ := cmd.Flags().GetBool("confirm") + confirmFlag, _ := command.Flags().GetBool("confirm") if !confirmFlag { var confirm string - CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ") + cmd.CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ") fmt.Scanln(&confirm) if confirm != "YES" { return errors.New("ABORTED: You did not answer YES exactly, in all capitals.") } - CommandPrettyPrintln("Are you sure you want to delete the teams specified? All data will be permanently deleted? (YES/NO): ") + cmd.CommandPrettyPrintln("Are you sure you want to delete the teams specified? All data will be permanently deleted? (YES/NO): ") fmt.Scanln(&confirm) if confirm != "YES" { return errors.New("ABORTED: You did not answer YES exactly, in all capitals.") @@ -197,13 +200,13 @@ func deleteTeamsCmdF(cmd *cobra.Command, args []string) error { teams := getTeamsFromTeamArgs(a, args) for i, team := range teams { if team == nil { - CommandPrintErrorln("Unable to find team '" + args[i] + "'") + cmd.CommandPrintErrorln("Unable to find team '" + args[i] + "'") continue } if err := deleteTeam(a, team); err != nil { - CommandPrintErrorln("Unable to delete team '" + team.Name + "' error: " + err.Error()) + cmd.CommandPrintErrorln("Unable to delete team '" + team.Name + "' error: " + err.Error()) } else { - CommandPrettyPrintln("Deleted team '" + team.Name + "'") + cmd.CommandPrettyPrintln("Deleted team '" + team.Name + "'") } } diff --git a/cmd/platform/team_test.go b/cmd/commands/team_test.go index 1e13d6cfa..1a91df4bc 100644 --- a/cmd/platform/team_test.go +++ b/cmd/commands/team_test.go @@ -1,12 +1,13 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main +package commands import ( "testing" "github.com/mattermost/mattermost-server/api" + "github.com/mattermost/mattermost-server/cmd" "github.com/mattermost/mattermost-server/model" ) @@ -18,7 +19,7 @@ func TestCreateTeam(t *testing.T) { name := "name" + id displayName := "Name " + id - checkCommand(t, "team", "create", "--name", name, "--display_name", displayName) + cmd.CheckCommand(t, "team", "create", "--name", name, "--display_name", displayName) found := th.SystemAdminClient.Must(th.SystemAdminClient.FindTeamByName(name)).Data.(bool) @@ -31,7 +32,7 @@ func TestJoinTeam(t *testing.T) { th := api.Setup().InitSystemAdmin().InitBasic() defer th.TearDown() - checkCommand(t, "team", "add", th.SystemAdminTeam.Name, th.BasicUser.Email) + cmd.CheckCommand(t, "team", "add", th.SystemAdminTeam.Name, th.BasicUser.Email) profiles := th.SystemAdminClient.Must(th.SystemAdminClient.GetProfilesInTeam(th.SystemAdminTeam.Id, 0, 1000, "")).Data.(map[string]*model.User) @@ -53,7 +54,7 @@ func TestLeaveTeam(t *testing.T) { th := api.Setup().InitBasic() defer th.TearDown() - checkCommand(t, "team", "remove", th.BasicTeam.Name, th.BasicUser.Email) + cmd.CheckCommand(t, "team", "remove", th.BasicTeam.Name, th.BasicUser.Email) profiles := th.BasicClient.Must(th.BasicClient.GetProfilesInTeam(th.BasicTeam.Id, 0, 1000, "")).Data.(map[string]*model.User) diff --git a/cmd/platform/teamargs.go b/cmd/commands/teamargs.go index 144db388b..aa62d52b8 100644 --- a/cmd/platform/teamargs.go +++ b/cmd/commands/teamargs.go @@ -1,6 +1,7 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package commands import ( "github.com/mattermost/mattermost-server/app" diff --git a/cmd/platform/test.go b/cmd/commands/test.go index 9ab3fbb36..62df16438 100644 --- a/cmd/platform/test.go +++ b/cmd/commands/test.go @@ -1,7 +1,7 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main +package commands import ( "bufio" @@ -14,39 +14,41 @@ import ( "github.com/mattermost/mattermost-server/api" "github.com/mattermost/mattermost-server/api4" + "github.com/mattermost/mattermost-server/cmd" "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/utils" "github.com/mattermost/mattermost-server/wsapi" "github.com/spf13/cobra" ) -var testCmd = &cobra.Command{ +var TestCmd = &cobra.Command{ Use: "test", Short: "Testing Commands", Hidden: true, } -var runWebClientTestsCmd = &cobra.Command{ +var RunWebClientTestsCmd = &cobra.Command{ Use: "web_client_tests", Short: "Run the web client tests", RunE: webClientTestsCmdF, } -var runServerForWebClientTestsCmd = &cobra.Command{ +var RunServerForWebClientTestsCmd = &cobra.Command{ Use: "web_client_tests_server", Short: "Run the server configured for running the web client tests against it", RunE: serverForWebClientTestsCmdF, } func init() { - testCmd.AddCommand( - runWebClientTestsCmd, - runServerForWebClientTestsCmd, + TestCmd.AddCommand( + RunWebClientTestsCmd, + RunServerForWebClientTestsCmd, ) + cmd.RootCmd.AddCommand(TestCmd) } -func webClientTestsCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func webClientTestsCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -67,8 +69,8 @@ func webClientTestsCmdF(cmd *cobra.Command, args []string) error { return nil } -func serverForWebClientTestsCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func serverForWebClientTestsCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -101,17 +103,17 @@ func setupClientTests(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = false } -func executeTestCommand(cmd *exec.Cmd) { - cmdOutPipe, err := cmd.StdoutPipe() +func executeTestCommand(command *exec.Cmd) { + cmdOutPipe, err := command.StdoutPipe() if err != nil { - CommandPrintErrorln("Failed to run tests") + cmd.CommandPrintErrorln("Failed to run tests") os.Exit(1) return } - cmdErrOutPipe, err := cmd.StderrPipe() + cmdErrOutPipe, err := command.StderrPipe() if err != nil { - CommandPrintErrorln("Failed to run tests") + cmd.CommandPrintErrorln("Failed to run tests") os.Exit(1) return } @@ -130,8 +132,8 @@ func executeTestCommand(cmd *exec.Cmd) { } }() - if err := cmd.Run(); err != nil { - CommandPrintErrorln("Client Tests failed") + if err := command.Run(); err != nil { + cmd.CommandPrintErrorln("Client Tests failed") os.Exit(1) return } diff --git a/cmd/platform/user.go b/cmd/commands/user.go index e2a8c9748..dda1c5bfe 100644 --- a/cmd/platform/user.go +++ b/cmd/commands/user.go @@ -1,6 +1,7 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package commands import ( "encoding/json" @@ -10,16 +11,17 @@ import ( l4g "github.com/alecthomas/log4go" "github.com/mattermost/mattermost-server/app" + "github.com/mattermost/mattermost-server/cmd" "github.com/mattermost/mattermost-server/model" "github.com/spf13/cobra" ) -var userCmd = &cobra.Command{ +var UserCmd = &cobra.Command{ Use: "user", Short: "Management of users", } -var userActivateCmd = &cobra.Command{ +var UserActivateCmd = &cobra.Command{ Use: "activate [emails, usernames, userIds]", Short: "Activate users", Long: "Activate users that have been deactivated.", @@ -28,7 +30,7 @@ var userActivateCmd = &cobra.Command{ RunE: userActivateCmdF, } -var userDeactivateCmd = &cobra.Command{ +var UserDeactivateCmd = &cobra.Command{ Use: "deactivate [emails, usernames, userIds]", Short: "Deactivate users", Long: "Deactivate users. Deactivated users are immediately logged out of all sessions and are unable to log back in.", @@ -37,7 +39,7 @@ var userDeactivateCmd = &cobra.Command{ RunE: userDeactivateCmdF, } -var userCreateCmd = &cobra.Command{ +var UserCreateCmd = &cobra.Command{ Use: "create", Short: "Create a user", Long: "Create a user", @@ -45,7 +47,7 @@ var userCreateCmd = &cobra.Command{ RunE: userCreateCmdF, } -var userInviteCmd = &cobra.Command{ +var UserInviteCmd = &cobra.Command{ Use: "invite [email] [teams]", Short: "Send user an email invite to a team.", Long: `Send user an email invite to a team. @@ -56,7 +58,7 @@ You can specify teams by name or ID.`, RunE: userInviteCmdF, } -var resetUserPasswordCmd = &cobra.Command{ +var ResetUserPasswordCmd = &cobra.Command{ Use: "password [user] [password]", Short: "Set a user's password", Long: "Set a user's password", @@ -64,7 +66,7 @@ var resetUserPasswordCmd = &cobra.Command{ RunE: resetUserPasswordCmdF, } -var resetUserMfaCmd = &cobra.Command{ +var ResetUserMfaCmd = &cobra.Command{ Use: "resetmfa [users]", Short: "Turn off MFA", Long: `Turn off multi-factor authentication for a user. @@ -73,7 +75,7 @@ If MFA enforcement is enabled, the user will be forced to re-enable MFA as soon RunE: resetUserMfaCmdF, } -var deleteUserCmd = &cobra.Command{ +var DeleteUserCmd = &cobra.Command{ Use: "delete [users]", Short: "Delete users and all posts", Long: "Permanently delete user and all related information including posts.", @@ -81,7 +83,7 @@ var deleteUserCmd = &cobra.Command{ RunE: deleteUserCmdF, } -var deleteAllUsersCmd = &cobra.Command{ +var DeleteAllUsersCmd = &cobra.Command{ Use: "deleteall", Short: "Delete all users and all posts", Long: "Permanently delete all users and all related information including posts.", @@ -89,7 +91,7 @@ var deleteAllUsersCmd = &cobra.Command{ RunE: deleteAllUsersCommandF, } -var migrateAuthCmd = &cobra.Command{ +var MigrateAuthCmd = &cobra.Command{ Use: "migrate_auth [from_auth] [to_auth] [migration-options]", Short: "Mass migrate user accounts authentication type", Long: `Migrates accounts from one authentication provider to another. For example, you can upgrade your authentication provider from email to ldap.`, @@ -127,7 +129,7 @@ var migrateAuthCmd = &cobra.Command{ RunE: migrateAuthCmdF, } -var verifyUserCmd = &cobra.Command{ +var VerifyUserCmd = &cobra.Command{ Use: "verify [users]", Short: "Verify email of users", Long: "Verify the emails of some users.", @@ -135,7 +137,7 @@ var verifyUserCmd = &cobra.Command{ RunE: verifyUserCmdF, } -var searchUserCmd = &cobra.Command{ +var SearchUserCmd = &cobra.Command{ Use: "search [users]", Short: "Search for users", Long: "Search for users based on username, email, or user ID.", @@ -144,23 +146,23 @@ var searchUserCmd = &cobra.Command{ } func init() { - userCreateCmd.Flags().String("username", "", "Required. Username for the new user account.") - userCreateCmd.Flags().String("email", "", "Required. The email address for the new user account.") - userCreateCmd.Flags().String("password", "", "Required. The password for the new user account.") - userCreateCmd.Flags().String("nickname", "", "Optional. The nickname for the new user account.") - userCreateCmd.Flags().String("firstname", "", "Optional. The first name for the new user account.") - userCreateCmd.Flags().String("lastname", "", "Optional. The last name for the new user account.") - userCreateCmd.Flags().String("locale", "", "Optional. The locale (ex: en, fr) for the new user account.") - userCreateCmd.Flags().Bool("system_admin", false, "Optional. If supplied, the new user will be a system administrator. Defaults to false.") - - deleteUserCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the user and a DB backup has been performed.") - - deleteAllUsersCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the user and a DB backup has been performed.") - - migrateAuthCmd.Flags().Bool("force", false, "Force the migration to occur even if there are duplicates on the LDAP server. Duplicates will not be migrated. (ldap only)") - migrateAuthCmd.Flags().Bool("auto", false, "Automatically migrate all users. Assumes the usernames and emails are identical between Mattermost and SAML services. (saml only)") - migrateAuthCmd.Flags().Bool("dryRun", false, "Run a simulation of the migration process without changing the database.") - migrateAuthCmd.SetUsageTemplate(`Usage: + UserCreateCmd.Flags().String("username", "", "Required. Username for the new user account.") + UserCreateCmd.Flags().String("email", "", "Required. The email address for the new user account.") + UserCreateCmd.Flags().String("password", "", "Required. The password for the new user account.") + UserCreateCmd.Flags().String("nickname", "", "Optional. The nickname for the new user account.") + UserCreateCmd.Flags().String("firstname", "", "Optional. The first name for the new user account.") + UserCreateCmd.Flags().String("lastname", "", "Optional. The last name for the new user account.") + UserCreateCmd.Flags().String("locale", "", "Optional. The locale (ex: en, fr) for the new user account.") + UserCreateCmd.Flags().Bool("system_admin", false, "Optional. If supplied, the new user will be a system administrator. Defaults to false.") + + DeleteUserCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the user and a DB backup has been performed.") + + DeleteAllUsersCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the user and a DB backup has been performed.") + + MigrateAuthCmd.Flags().Bool("force", false, "Force the migration to occur even if there are duplicates on the LDAP server. Duplicates will not be migrated. (ldap only)") + MigrateAuthCmd.Flags().Bool("auto", false, "Automatically migrate all users. Assumes the usernames and emails are identical between Mattermost and SAML services. (saml only)") + MigrateAuthCmd.Flags().Bool("dryRun", false, "Run a simulation of the migration process without changing the database.") + MigrateAuthCmd.SetUsageTemplate(`Usage: platform user migrate_auth [from_auth] [to_auth] [migration-options] [flags] Examples: @@ -184,7 +186,7 @@ Flags: Global Flags: {{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}} `) - migrateAuthCmd.SetHelpTemplate(`Usage: + MigrateAuthCmd.SetHelpTemplate(`Usage: platform user migrate_auth [from_auth] [to_auth] [migration-options] [flags] Examples: @@ -221,23 +223,24 @@ Global Flags: {{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}} `) - userCmd.AddCommand( - userActivateCmd, - userDeactivateCmd, - userCreateCmd, - userInviteCmd, - resetUserPasswordCmd, - resetUserMfaCmd, - deleteUserCmd, - deleteAllUsersCmd, - migrateAuthCmd, - verifyUserCmd, - searchUserCmd, + UserCmd.AddCommand( + UserActivateCmd, + UserDeactivateCmd, + UserCreateCmd, + UserInviteCmd, + ResetUserPasswordCmd, + ResetUserMfaCmd, + DeleteUserCmd, + DeleteAllUsersCmd, + MigrateAuthCmd, + VerifyUserCmd, + SearchUserCmd, ) + cmd.RootCmd.AddCommand(UserCmd) } -func userActivateCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func userActivateCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -256,7 +259,7 @@ func changeUsersActiveStatus(a *app.App, userArgs []string, active bool) { err := changeUserActiveStatus(a, user, userArgs[i], active) if err != nil { - CommandPrintErrorln(err.Error()) + cmd.CommandPrintErrorln(err.Error()) } } } @@ -275,8 +278,8 @@ func changeUserActiveStatus(a *app.App, user *model.User, userArg string, activa return nil } -func userDeactivateCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func userDeactivateCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -289,29 +292,29 @@ func userDeactivateCmdF(cmd *cobra.Command, args []string) error { return nil } -func userCreateCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func userCreateCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } - username, erru := cmd.Flags().GetString("username") + username, erru := command.Flags().GetString("username") if erru != nil || username == "" { return errors.New("Username is required") } - email, erre := cmd.Flags().GetString("email") + email, erre := command.Flags().GetString("email") if erre != nil || email == "" { return errors.New("Email is required") } - password, errp := cmd.Flags().GetString("password") + password, errp := command.Flags().GetString("password") if errp != nil || password == "" { return errors.New("Password is required") } - nickname, _ := cmd.Flags().GetString("nickname") - firstname, _ := cmd.Flags().GetString("firstname") - lastname, _ := cmd.Flags().GetString("lastname") - locale, _ := cmd.Flags().GetString("locale") - systemAdmin, _ := cmd.Flags().GetBool("system_admin") + nickname, _ := command.Flags().GetString("nickname") + firstname, _ := command.Flags().GetString("firstname") + lastname, _ := command.Flags().GetString("lastname") + locale, _ := command.Flags().GetString("locale") + systemAdmin, _ := command.Flags().GetBool("system_admin") user := &model.User{ Username: username, @@ -329,13 +332,13 @@ func userCreateCmdF(cmd *cobra.Command, args []string) error { a.UpdateUserRoles(ruser.Id, "system_user system_admin", false) } - CommandPrettyPrintln("Created User") + cmd.CommandPrettyPrintln("Created User") return nil } -func userInviteCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func userInviteCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -354,7 +357,7 @@ func userInviteCmdF(cmd *cobra.Command, args []string) error { err := inviteUser(a, email, team, args[i+1]) if err != nil { - CommandPrintErrorln(err.Error()) + cmd.CommandPrintErrorln(err.Error()) } } @@ -368,13 +371,13 @@ func inviteUser(a *app.App, email string, team *model.Team, teamArg string) erro } a.SendInviteEmails(team, "Administrator", invites, *a.Config().ServiceSettings.SiteURL) - CommandPrettyPrintln("Invites may or may not have been sent.") + cmd.CommandPrettyPrintln("Invites may or may not have been sent.") return nil } -func resetUserPasswordCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func resetUserPasswordCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -396,8 +399,8 @@ func resetUserPasswordCmdF(cmd *cobra.Command, args []string) error { return nil } -func resetUserMfaCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func resetUserMfaCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -421,8 +424,8 @@ func resetUserMfaCmdF(cmd *cobra.Command, args []string) error { return nil } -func deleteUserCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func deleteUserCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -431,16 +434,16 @@ func deleteUserCmdF(cmd *cobra.Command, args []string) error { return errors.New("Expected at least one argument. See help text for details.") } - confirmFlag, _ := cmd.Flags().GetBool("confirm") + confirmFlag, _ := command.Flags().GetBool("confirm") if !confirmFlag { var confirm string - CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ") + cmd.CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ") fmt.Scanln(&confirm) if confirm != "YES" { return errors.New("ABORTED: You did not answer YES exactly, in all capitals.") } - CommandPrettyPrintln("Are you sure you want to permanently delete the specified users? (YES/NO): ") + cmd.CommandPrettyPrintln("Are you sure you want to permanently delete the specified users? (YES/NO): ") fmt.Scanln(&confirm) if confirm != "YES" { return errors.New("ABORTED: You did not answer YES exactly, in all capitals.") @@ -462,8 +465,8 @@ func deleteUserCmdF(cmd *cobra.Command, args []string) error { return nil } -func deleteAllUsersCommandF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func deleteAllUsersCommandF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -472,16 +475,16 @@ func deleteAllUsersCommandF(cmd *cobra.Command, args []string) error { return errors.New("Expected zero arguments.") } - confirmFlag, _ := cmd.Flags().GetBool("confirm") + confirmFlag, _ := command.Flags().GetBool("confirm") if !confirmFlag { var confirm string - CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ") + cmd.CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ") fmt.Scanln(&confirm) if confirm != "YES" { return errors.New("ABORTED: You did not answer YES exactly, in all capitals.") } - CommandPrettyPrintln("Are you sure you want to permanently delete all user accounts? (YES/NO): ") + cmd.CommandPrettyPrintln("Are you sure you want to permanently delete all user accounts? (YES/NO): ") fmt.Scanln(&confirm) if confirm != "YES" { return errors.New("ABORTED: You did not answer YES exactly, in all capitals.") @@ -492,19 +495,19 @@ func deleteAllUsersCommandF(cmd *cobra.Command, args []string) error { return err } - CommandPrettyPrintln("All user accounts successfully deleted.") + cmd.CommandPrettyPrintln("All user accounts successfully deleted.") return nil } -func migrateAuthCmdF(cmd *cobra.Command, args []string) error { +func migrateAuthCmdF(command *cobra.Command, args []string) error { if args[1] == "saml" { - return migrateAuthToSamlCmdF(cmd, args) + return migrateAuthToSamlCmdF(command, args) } - return migrateAuthToLdapCmdF(cmd, args) + return migrateAuthToLdapCmdF(command, args) } -func migrateAuthToLdapCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func migrateAuthToLdapCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -525,28 +528,28 @@ func migrateAuthToLdapCmdF(cmd *cobra.Command, args []string) error { return errors.New("Invalid match_field argument") } - forceFlag, _ := cmd.Flags().GetBool("force") - dryRunFlag, _ := cmd.Flags().GetBool("dryRun") + forceFlag, _ := command.Flags().GetBool("force") + dryRunFlag, _ := command.Flags().GetBool("dryRun") if migrate := a.AccountMigration; migrate != nil { if err := migrate.MigrateToLdap(fromAuth, matchField, forceFlag, dryRunFlag); err != nil { return errors.New("Error while migrating users: " + err.Error()) } - CommandPrettyPrintln("Sucessfully migrated accounts.") + cmd.CommandPrettyPrintln("Sucessfully migrated accounts.") } return nil } -func migrateAuthToSamlCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func migrateAuthToSamlCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } - dryRunFlag, _ := cmd.Flags().GetBool("dryRun") - autoFlag, _ := cmd.Flags().GetBool("auto") + dryRunFlag, _ := command.Flags().GetBool("dryRun") + autoFlag, _ := command.Flags().GetBool("auto") matchesFile := "" matches := map[string]string{} @@ -570,7 +573,7 @@ func migrateAuthToSamlCmdF(cmd *cobra.Command, args []string) error { if autoFlag && !dryRunFlag { var confirm string - CommandPrettyPrintln("You are about to perform an automatic \"" + fromAuth + " to saml\" migration. This must only be done if your current Mattermost users with " + fromAuth + " auth have the same username and email in your SAML service. Otherwise, provide the usernames and emails from your SAML Service using the \"users file\" without the \"--auto\" option.\n\nDo you want to proceed with automatic migration anyway? (YES/NO):") + cmd.CommandPrettyPrintln("You are about to perform an automatic \"" + fromAuth + " to saml\" migration. This must only be done if your current Mattermost users with " + fromAuth + " auth have the same username and email in your SAML service. Otherwise, provide the usernames and emails from your SAML Service using the \"users file\" without the \"--auto\" option.\n\nDo you want to proceed with automatic migration anyway? (YES/NO):") fmt.Scanln(&confirm) if confirm != "YES" { @@ -588,14 +591,14 @@ func migrateAuthToSamlCmdF(cmd *cobra.Command, args []string) error { return errors.New("Error while migrating users: " + err.Error()) } l4g.Close() - CommandPrettyPrintln("Sucessfully migrated accounts.") + cmd.CommandPrettyPrintln("Sucessfully migrated accounts.") } return nil } -func verifyUserCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func verifyUserCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -608,19 +611,19 @@ func verifyUserCmdF(cmd *cobra.Command, args []string) error { for i, user := range users { if user == nil { - CommandPrintErrorln("Unable to find user '" + args[i] + "'") + cmd.CommandPrintErrorln("Unable to find user '" + args[i] + "'") continue } if cresult := <-a.Srv.Store.User().VerifyEmail(user.Id); cresult.Err != nil { - CommandPrintErrorln("Unable to verify '" + args[i] + "' email. Error: " + cresult.Err.Error()) + cmd.CommandPrintErrorln("Unable to verify '" + args[i] + "' email. Error: " + cresult.Err.Error()) } } return nil } -func searchUserCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func searchUserCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -633,21 +636,21 @@ func searchUserCmdF(cmd *cobra.Command, args []string) error { for i, user := range users { if i > 0 { - CommandPrettyPrintln("------------------------------") + cmd.CommandPrettyPrintln("------------------------------") } if user == nil { - CommandPrintErrorln("Unable to find user '" + args[i] + "'") + cmd.CommandPrintErrorln("Unable to find user '" + args[i] + "'") continue } - CommandPrettyPrintln("id: " + user.Id) - CommandPrettyPrintln("username: " + user.Username) - CommandPrettyPrintln("nickname: " + user.Nickname) - CommandPrettyPrintln("position: " + user.Position) - CommandPrettyPrintln("first_name: " + user.FirstName) - CommandPrettyPrintln("last_name: " + user.LastName) - CommandPrettyPrintln("email: " + user.Email) - CommandPrettyPrintln("auth_service: " + user.AuthService) + cmd.CommandPrettyPrintln("id: " + user.Id) + cmd.CommandPrettyPrintln("username: " + user.Username) + cmd.CommandPrettyPrintln("nickname: " + user.Nickname) + cmd.CommandPrettyPrintln("position: " + user.Position) + cmd.CommandPrettyPrintln("first_name: " + user.FirstName) + cmd.CommandPrettyPrintln("last_name: " + user.LastName) + cmd.CommandPrettyPrintln("email: " + user.Email) + cmd.CommandPrettyPrintln("auth_service: " + user.AuthService) } return nil diff --git a/cmd/platform/user_test.go b/cmd/commands/user_test.go index 5383ad914..960ac3878 100644 --- a/cmd/platform/user_test.go +++ b/cmd/commands/user_test.go @@ -1,12 +1,13 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main +package commands import ( "testing" "github.com/mattermost/mattermost-server/api" + "github.com/mattermost/mattermost-server/cmd" "github.com/mattermost/mattermost-server/model" ) @@ -18,9 +19,9 @@ func TestCreateUserWithTeam(t *testing.T) { email := "success+" + id + "@simulator.amazonses.com" username := "name" + id - checkCommand(t, "user", "create", "--email", email, "--password", "mypassword1", "--username", username) + cmd.CheckCommand(t, "user", "create", "--email", email, "--password", "mypassword1", "--username", username) - checkCommand(t, "team", "add", th.SystemAdminTeam.Id, email) + cmd.CheckCommand(t, "team", "add", th.SystemAdminTeam.Id, email) profiles := th.SystemAdminClient.Must(th.SystemAdminClient.GetProfilesInTeam(th.SystemAdminTeam.Id, 0, 1000, "")).Data.(map[string]*model.User) @@ -46,7 +47,7 @@ func TestCreateUserWithoutTeam(t *testing.T) { email := "success+" + id + "@simulator.amazonses.com" username := "name" + id - checkCommand(t, "user", "create", "--email", email, "--password", "mypassword1", "--username", username) + cmd.CheckCommand(t, "user", "create", "--email", email, "--password", "mypassword1", "--username", username) if result := <-th.App.Srv.Store.User().GetByEmail(email); result.Err != nil { t.Fatal() @@ -62,7 +63,7 @@ func TestResetPassword(t *testing.T) { th := api.Setup().InitBasic() defer th.TearDown() - checkCommand(t, "user", "password", th.BasicUser.Email, "password2") + cmd.CheckCommand(t, "user", "password", th.BasicUser.Email, "password2") th.BasicClient.Logout() th.BasicUser.Password = "password2" @@ -74,8 +75,8 @@ func TestMakeUserActiveAndInactive(t *testing.T) { defer th.TearDown() // first inactivate the user - checkCommand(t, "user", "deactivate", th.BasicUser.Email) + cmd.CheckCommand(t, "user", "deactivate", th.BasicUser.Email) // activate the inactive user - checkCommand(t, "user", "activate", th.BasicUser.Email) + cmd.CheckCommand(t, "user", "activate", th.BasicUser.Email) } diff --git a/cmd/platform/userargs.go b/cmd/commands/userargs.go index 0089cc4da..ddeed6460 100644 --- a/cmd/platform/userargs.go +++ b/cmd/commands/userargs.go @@ -1,6 +1,7 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package commands import ( "github.com/mattermost/mattermost-server/app" diff --git a/cmd/platform/version.go b/cmd/commands/version.go index 9616be1d7..eaf6a1a68 100644 --- a/cmd/platform/version.go +++ b/cmd/commands/version.go @@ -1,23 +1,29 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package commands import ( "github.com/mattermost/mattermost-server/app" + "github.com/mattermost/mattermost-server/cmd" "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/store" "github.com/mattermost/mattermost-server/store/sqlstore" "github.com/spf13/cobra" ) -var versionCmd = &cobra.Command{ +var VersionCmd = &cobra.Command{ Use: "version", Short: "Display version information", RunE: versionCmdF, } -func versionCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) +func init() { + cmd.RootCmd.AddCommand(VersionCmd) +} + +func versionCmdF(command *cobra.Command, args []string) error { + a, err := cmd.InitDBCommandContextCobra(command) if err != nil { return err } @@ -28,12 +34,12 @@ func versionCmdF(cmd *cobra.Command, args []string) error { } func printVersion(a *app.App) { - CommandPrintln("Version: " + model.CurrentVersion) - CommandPrintln("Build Number: " + model.BuildNumber) - CommandPrintln("Build Date: " + model.BuildDate) - CommandPrintln("Build Hash: " + model.BuildHash) - CommandPrintln("Build Enterprise Ready: " + model.BuildEnterpriseReady) + cmd.CommandPrintln("Version: " + model.CurrentVersion) + cmd.CommandPrintln("Build Number: " + model.BuildNumber) + cmd.CommandPrintln("Build Date: " + model.BuildDate) + cmd.CommandPrintln("Build Hash: " + model.BuildHash) + cmd.CommandPrintln("Build Enterprise Ready: " + model.BuildEnterpriseReady) if supplier, ok := a.Srv.Store.(*store.LayeredStore).DatabaseLayer.(*sqlstore.SqlSupplier); ok { - CommandPrintln("DB Version: " + supplier.GetCurrentSchemaVersion()) + cmd.CommandPrintln("DB Version: " + supplier.GetCurrentSchemaVersion()) } } diff --git a/cmd/platform/version_test.go b/cmd/commands/version_test.go index eea2549ee..24a1389b1 100644 --- a/cmd/platform/version_test.go +++ b/cmd/commands/version_test.go @@ -1,12 +1,14 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main +package commands import ( "testing" + + "github.com/mattermost/mattermost-server/cmd" ) func TestVersion(t *testing.T) { - checkCommand(t, "version") + cmd.CheckCommand(t, "version") } diff --git a/cmd/platform/init.go b/cmd/init.go index ef3d78692..b71d71d31 100644 --- a/cmd/platform/init.go +++ b/cmd/init.go @@ -1,7 +1,7 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main +package cmd import ( "github.com/mattermost/mattermost-server/app" @@ -10,13 +10,13 @@ import ( "github.com/spf13/cobra" ) -func initDBCommandContextCobra(cmd *cobra.Command) (*app.App, error) { +func InitDBCommandContextCobra(cmd *cobra.Command) (*app.App, error) { config, err := cmd.Flags().GetString("config") if err != nil { return nil, err } - a, err := initDBCommandContext(config) + a, err := InitDBCommandContext(config) if err != nil { // Returning an error just prints the usage message, so actually panic panic(err) @@ -25,7 +25,7 @@ func initDBCommandContextCobra(cmd *cobra.Command) (*app.App, error) { return a, nil } -func initDBCommandContext(configFileLocation string) (*app.App, error) { +func InitDBCommandContext(configFileLocation string) (*app.App, error) { if err := utils.TranslationsPreInit(); err != nil { return nil, err } diff --git a/cmd/platform/output.go b/cmd/output.go index edf6ccc71..630e831de 100644 --- a/cmd/platform/output.go +++ b/cmd/output.go @@ -1,6 +1,7 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -package main + +package cmd import ( "fmt" diff --git a/cmd/platform/mattermost.go b/cmd/platform/mattermost.go deleted file mode 100644 index e4a120e1e..000000000 --- a/cmd/platform/mattermost.go +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -package main - -import ( - "errors" - "fmt" - "os" - - "github.com/spf13/cobra" - - // Plugins - _ "github.com/mattermost/mattermost-server/model/gitlab" - - // Enterprise Imports - _ "github.com/mattermost/mattermost-server/imports" - - // Enterprise Deps - _ "github.com/dgryski/dgoogauth" - _ "github.com/go-ldap/ldap" - _ "github.com/hashicorp/memberlist" - _ "github.com/mattermost/rsc/qr" - _ "github.com/prometheus/client_golang/prometheus" - _ "github.com/prometheus/client_golang/prometheus/promhttp" - _ "github.com/tylerb/graceful" - _ "gopkg.in/olivere/elastic.v5" - - // Temp imports for new dependencies - _ "github.com/gorilla/schema" -) - -func main() { - if err := rootCmd.Execute(); err != nil { - os.Exit(1) - } -} - -func init() { - rootCmd.PersistentFlags().StringP("config", "c", "config.json", "Configuration file to use.") - rootCmd.PersistentFlags().Bool("disableconfigwatch", false, "When set config.json will not be loaded from disk when the file is changed.") - - resetCmd.Flags().Bool("confirm", false, "Confirm you really want to delete everything and a DB backup has been performed.") - - rootCmd.AddCommand(serverCmd, versionCmd, userCmd, teamCmd, licenseCmd, importCmd, resetCmd, channelCmd, rolesCmd, testCmd, ldapCmd, configCmd, jobserverCmd, commandCmd, messageExportCmd, sampleDataCmd) -} - -var rootCmd = &cobra.Command{ - Use: "platform", - Short: "Open source, self-hosted Slack-alternative", - Long: `Mattermost offers workplace messaging across web, PC and phones with archiving, search and integration with your existing systems. Documentation available at https://docs.mattermost.com`, - RunE: runServerCmd, -} - -var resetCmd = &cobra.Command{ - Use: "reset", - Short: "Reset the database to initial state", - Long: "Completely erases the database causing the loss of all data. This will reset Mattermost to its initial state.", - RunE: resetCmdF, -} - -func resetCmdF(cmd *cobra.Command, args []string) error { - a, err := initDBCommandContextCobra(cmd) - if err != nil { - return err - } - - confirmFlag, _ := cmd.Flags().GetBool("confirm") - if !confirmFlag { - var confirm string - CommandPrettyPrintln("Have you performed a database backup? (YES/NO): ") - fmt.Scanln(&confirm) - - if confirm != "YES" { - return errors.New("ABORTED: You did not answer YES exactly, in all capitals.") - } - CommandPrettyPrintln("Are you sure you want to delete everything? All data will be permanently deleted? (YES/NO): ") - fmt.Scanln(&confirm) - if confirm != "YES" { - return errors.New("ABORTED: You did not answer YES exactly, in all capitals.") - } - } - - a.Srv.Store.DropAllTables() - CommandPrettyPrintln("Database sucessfully reset") - - return nil -} |