diff --git a/docs/src/css/custom.scss b/docs/src/css/custom.scss index 6b0bb7e31..80a807cf6 100644 --- a/docs/src/css/custom.scss +++ b/docs/src/css/custom.scss @@ -129,6 +129,21 @@ html[data-theme='dark'] { margin: 8px 0 0 0; padding: 4px 0 4px 20px; } + + .required { + margin-left: 8px; + margin-right: 0; + position: relative; + padding: 0 6px; + border-width: 1px; + border-radius: 3px; + border-color: #fa5035; + border-style: solid; + color: #fa5035; + display: inline-block; + letter-spacing: .02rem; + font-size: 0.8rem; + } } hr { diff --git a/src/cli/backup/exchange.go b/src/cli/backup/exchange.go index 52aee358d..137e1b493 100644 --- a/src/cli/backup/exchange.go +++ b/src/cli/backup/exchange.go @@ -56,7 +56,12 @@ const ( dataEvents = "events" ) -const exchangeServiceCommand = "exchange" +const ( + exchangeServiceCommand = "exchange" + exchangeServiceCommandCreateUseSuffix = " --all | --user " + exchangeServiceCommandDeleteUseSuffix = " --backup " + exchangeServiceCommandDetailsUseSuffix = " --backup " +) // called by backup.go to map parent subcommands to provider-specific handling. func addExchangeCommands(parent *cobra.Command) *cobra.Command { @@ -69,6 +74,8 @@ func addExchangeCommands(parent *cobra.Command) *cobra.Command { case createCommand: c, fs = utils.AddCommand(parent, exchangeCreateCmd()) + c.Use = c.Use + exchangeServiceCommandCreateUseSuffix + // Flags addition ordering should follow the order we want them to appear in help and docs: // More generic (ex: --all) and more frequently used flags take precedence. fs.BoolVar(&exchangeAll, @@ -90,91 +97,96 @@ func addExchangeCommands(parent *cobra.Command) *cobra.Command { case detailsCommand: c, fs = utils.AddCommand(parent, exchangeDetailsCmd()) + c.Use = c.Use + exchangeServiceCommandDetailsUseSuffix + // Flags addition ordering should follow the order we want them to appear in help and docs: // More generic (ex: --all) and more frequently used flags take precedence. fs.StringVar(&backupID, "backup", "", - "ID of the backup containing the details to be shown") + "ID of the backup to explore. (required)") cobra.CheckErr(c.MarkFlagRequired("backup")) fs.StringSliceVar( &user, "user", nil, - "Select backup details by user ID; accepts "+utils.Wildcard+" to select all users") + "Select backup details by user ID; accepts "+utils.Wildcard+" to select all users.") // email flags fs.StringSliceVar( &email, "email", nil, - "Select backup details by emails ID; accepts "+utils.Wildcard+" to select all emails") + "Select backup details for emails by email ID; accepts "+utils.Wildcard+" to select all emails.") fs.StringSliceVar( &emailFolder, "email-folder", nil, - "Select backup details by email folder ID; accepts "+utils.Wildcard+" to select all email folders") + "Select backup details for emails within a folder; accepts "+utils.Wildcard+" to select all email folders.") fs.StringVar( &emailSubject, "email-subject", "", - "Restore mail where the email subject lines contain this value") + "Select backup details for emails with a subject containing this value.") fs.StringVar( &emailSender, "email-sender", "", - "Restore mail where the email sender matches this user id") + "Select backup details for emails from a specific sender.") fs.StringVar( &emailReceivedAfter, "email-received-after", "", - "Restore mail where the email was received after this datetime") + "Select backup details for emails received after this datetime.") fs.StringVar( &emailReceivedBefore, "email-received-before", "", - "Restore mail where the email was received before this datetime") + "Select backup details for emails received before this datetime.") // event flags fs.StringSliceVar( &event, "event", nil, - "Select backup details by event ID; accepts "+utils.Wildcard+" to select all events") + "Select backup details for events by event ID; accepts "+utils.Wildcard+" to select all events.") fs.StringSliceVar( &eventCalendar, "event-calendar", nil, - "Select backup details by event calendar ID; accepts "+utils.Wildcard+" to select all events") + "Select backup details for events under a calendar; accepts "+utils.Wildcard+" to select all events.") fs.StringVar( &eventSubject, "event-subject", "", - "Select backup details where the event subject contains this value") + "Select backup details for events with a subject containing this value.") fs.StringVar( &eventOrganizer, "event-organizer", "", - "Select backup details where the event organizer user id contains this value") + "Select backup details for events from a specific organizer.") fs.StringVar( &eventRecurs, "event-recurs", "", - "Select backup details if the event recurs. Use `--event-recurs` false to select non-recurring events") + "Select backup details for recurring events. Use `--event-recurs false` to select non-recurring events.") fs.StringVar( &eventStartsAfter, "event-starts-after", "", - "Select backup details where the event starts after this datetime") + "Select backup details for events starting after this datetime.") fs.StringVar( &eventStartsBefore, "event-starts-before", "", - "Select backup details where the event starts before this datetime") + "Select backup details for events starting before this datetime.") + // contact flags fs.StringSliceVar( &contact, "contact", nil, - "Select backup details by contact ID; accepts "+utils.Wildcard+" to select all contacts") + "Select backup details for contacts by contact ID; accepts "+utils.Wildcard+" to select all contacts.") fs.StringSliceVar( &contactFolder, "contact-folder", nil, - "Select backup details by contact folder ID; accepts "+utils.Wildcard+" to select all contact folders") + "Select backup details for contacts within a folder; accepts "+utils.Wildcard+" to select all contact folders.") - // exchange-info flags fs.StringVar( &contactName, "contact-name", "", - "Select backup details where the contact name contains this value") + "Select backup details for contacts whose contact name contains this value.") case deleteCommand: c, fs = utils.AddCommand(parent, exchangeDeleteCmd()) - fs.StringVar(&backupID, "backup", "", "ID of the backup containing the details to be shown") + + c.Use = c.Use + exchangeServiceCommandDeleteUseSuffix + + fs.StringVar(&backupID, "backup", "", "ID of the backup to delete. (required)") cobra.CheckErr(c.MarkFlagRequired("backup")) } diff --git a/src/cli/backup/exchange_test.go b/src/cli/backup/exchange_test.go index 9ac1bad5f..da3164812 100644 --- a/src/cli/backup/exchange_test.go +++ b/src/cli/backup/exchange_test.go @@ -32,10 +32,22 @@ func (suite *ExchangeSuite) TestAddExchangeCommands() { expectShort string expectRunE func(*cobra.Command, []string) error }{ - {"create exchange", createCommand, expectUse, exchangeCreateCmd().Short, createExchangeCmd}, - {"list exchange", listCommand, expectUse, exchangeListCmd().Short, listExchangeCmd}, - {"details exchange", detailsCommand, expectUse, exchangeDetailsCmd().Short, detailsExchangeCmd}, - {"delete exchange", deleteCommand, expectUse, exchangeDeleteCmd().Short, deleteExchangeCmd}, + { + "create exchange", createCommand, expectUse + exchangeServiceCommandCreateUseSuffix, + exchangeCreateCmd().Short, createExchangeCmd, + }, + { + "list exchange", listCommand, expectUse, + exchangeListCmd().Short, listExchangeCmd, + }, + { + "details exchange", detailsCommand, expectUse + exchangeServiceCommandDetailsUseSuffix, + exchangeDetailsCmd().Short, detailsExchangeCmd, + }, + { + "delete exchange", deleteCommand, expectUse + exchangeServiceCommandDeleteUseSuffix, + exchangeDeleteCmd().Short, deleteExchangeCmd, + }, } for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { diff --git a/src/cli/backup/onedrive.go b/src/cli/backup/onedrive.go index cac4cc302..a047f4817 100644 --- a/src/cli/backup/onedrive.go +++ b/src/cli/backup/onedrive.go @@ -22,7 +22,12 @@ import ( // setup and globals // ------------------------------------------------------------------------------------------------ -const oneDriveServiceCommand = "onedrive" +const ( + oneDriveServiceCommand = "onedrive" + oneDriveServiceCommandCreateUseSuffix = " --user | " + utils.Wildcard + oneDriveServiceCommandDeleteUseSuffix = " --backup " + oneDriveServiceCommandDetailsUseSuffix = " --backup " +) var ( folderPaths []string @@ -45,8 +50,10 @@ func addOneDriveCommands(parent *cobra.Command) *cobra.Command { case createCommand: c, fs = utils.AddCommand(parent, oneDriveCreateCmd()) + c.Use = c.Use + oneDriveServiceCommandCreateUseSuffix + fs.StringArrayVar(&user, "user", nil, - "Backup OneDrive data by user ID; accepts "+utils.Wildcard+" to select all users") + "Backup OneDrive data by user ID; accepts "+utils.Wildcard+" to select all users. (required)") options.AddOperationFlags(c) case listCommand: @@ -54,7 +61,10 @@ func addOneDriveCommands(parent *cobra.Command) *cobra.Command { case detailsCommand: c, fs = utils.AddCommand(parent, oneDriveDetailsCmd()) - fs.StringVar(&backupID, "backup", "", "ID of the backup containing the details to be shown") + + c.Use = c.Use + oneDriveServiceCommandDetailsUseSuffix + + fs.StringVar(&backupID, "backup", "", "ID of the backup to explore. (required)") cobra.CheckErr(c.MarkFlagRequired("backup")) // onedrive hierarchy flags @@ -91,7 +101,10 @@ func addOneDriveCommands(parent *cobra.Command) *cobra.Command { case deleteCommand: c, fs = utils.AddCommand(parent, oneDriveDeleteCmd()) - fs.StringVar(&backupID, "backup", "", "ID of the backup containing the details to be shown") + + c.Use = c.Use + oneDriveServiceCommandDeleteUseSuffix + + fs.StringVar(&backupID, "backup", "", "ID of the backup to delete. (required)") cobra.CheckErr(c.MarkFlagRequired("backup")) } diff --git a/src/cli/backup/onedrive_test.go b/src/cli/backup/onedrive_test.go index b9cba6339..9eb71a8dd 100644 --- a/src/cli/backup/onedrive_test.go +++ b/src/cli/backup/onedrive_test.go @@ -29,10 +29,22 @@ func (suite *OneDriveSuite) TestAddOneDriveCommands() { expectShort string expectRunE func(*cobra.Command, []string) error }{ - {"create onedrive", createCommand, expectUse, oneDriveCreateCmd().Short, createOneDriveCmd}, - {"list onedrive", listCommand, expectUse, oneDriveListCmd().Short, listOneDriveCmd}, - {"details onedrive", detailsCommand, expectUse, oneDriveDetailsCmd().Short, detailsOneDriveCmd}, - {"delete onedrive", deleteCommand, expectUse, oneDriveDeleteCmd().Short, deleteOneDriveCmd}, + { + "create onedrive", createCommand, expectUse + oneDriveServiceCommandCreateUseSuffix, + oneDriveCreateCmd().Short, createOneDriveCmd, + }, + { + "list onedrive", listCommand, expectUse, + oneDriveListCmd().Short, listOneDriveCmd, + }, + { + "details onedrive", detailsCommand, expectUse + oneDriveServiceCommandDetailsUseSuffix, + oneDriveDetailsCmd().Short, detailsOneDriveCmd, + }, + { + "delete onedrive", deleteCommand, expectUse + oneDriveServiceCommandDeleteUseSuffix, + oneDriveDeleteCmd().Short, deleteOneDriveCmd, + }, } for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { diff --git a/src/cli/repo/s3.go b/src/cli/repo/s3.go index c5c16e95a..628da3fc9 100644 --- a/src/cli/repo/s3.go +++ b/src/cli/repo/s3.go @@ -37,12 +37,14 @@ func addS3Commands(parent *cobra.Command) *cobra.Command { c, fs = utils.AddCommand(parent, s3ConnectCmd()) } + c.Use = c.Use + s3ProviderCommandUseSuffix + // Flags addition ordering should follow the order we want them to appear in help and docs: // More generic (ex: --all) and more frequently used flags take precedence. - fs.StringVar(&bucket, "bucket", "", "Name of the S3 bucket (required).") + fs.StringVar(&bucket, "bucket", "", "Name of S3 bucket for repo. (required)") cobra.CheckErr(c.MarkFlagRequired("bucket")) - fs.StringVar(&prefix, "prefix", "", "Prefix applied to objects in the bucket.") - fs.StringVar(&endpoint, "endpoint", "s3.amazonaws.com", "Server endpoint for S3 communication.") + fs.StringVar(&prefix, "prefix", "", "Repo prefix within bucket.") + fs.StringVar(&endpoint, "endpoint", "s3.amazonaws.com", "S3 service endpoint.") fs.BoolVar(&succeedIfExists, "succeed-if-exists", false, "Exit with success if the repo has already been initialized.") // In general, we don't want to expose this flag to users and have them mistake it // for a broad-scale idempotency solution. We can un-hide it later the need arises. @@ -51,7 +53,10 @@ func addS3Commands(parent *cobra.Command) *cobra.Command { return c } -const s3ProviderCommand = "s3" +const ( + s3ProviderCommand = "s3" + s3ProviderCommandUseSuffix = " --bucket " +) // --------------------------------------------------------------------------------------------------------- // Init diff --git a/src/cli/repo/s3_test.go b/src/cli/repo/s3_test.go index 7f49b640a..ad8edcb98 100644 --- a/src/cli/repo/s3_test.go +++ b/src/cli/repo/s3_test.go @@ -20,7 +20,7 @@ func TestS3Suite(t *testing.T) { } func (suite *S3Suite) TestAddS3Commands() { - expectUse := s3ProviderCommand + expectUse := s3ProviderCommand + s3ProviderCommandUseSuffix table := []struct { name string diff --git a/src/cli/restore/exchange.go b/src/cli/restore/exchange.go index c41ec4f5b..a676c0525 100644 --- a/src/cli/restore/exchange.go +++ b/src/cli/restore/exchange.go @@ -51,83 +51,85 @@ func addExchangeCommands(parent *cobra.Command) *cobra.Command { case restoreCommand: c, fs = utils.AddCommand(parent, exchangeRestoreCmd()) + c.Use = c.Use + exchangeServiceCommandUseSuffix + // Flags addition ordering should follow the order we want them to appear in help and docs: // More generic (ex: --all) and more frequently used flags take precedence. // general flags - fs.StringVar(&backupID, "backup", "", "ID of the backup to restore") + fs.StringVar(&backupID, "backup", "", "ID of the backup to restore. (required)") cobra.CheckErr(c.MarkFlagRequired("backup")) fs.StringSliceVar(&user, "user", nil, - "Restore all data by user ID; accepts "+utils.Wildcard+" to select all users") + "Restore data by user ID; accepts "+utils.Wildcard+" to select all users.") // email flags fs.StringSliceVar(&email, "email", nil, - "Restore emails by ID; accepts "+utils.Wildcard+" to select all emails") + "Restore emails by ID; accepts "+utils.Wildcard+" to select all emails.") fs.StringSliceVar( &emailFolder, "email-folder", nil, - "Restore all emails by folder ID; accepts "+utils.Wildcard+" to select all email folders") + "Restore emails within a folder; accepts "+utils.Wildcard+" to select all email folders.") fs.StringVar( &emailSubject, "email-subject", "", - "Restore mail where the email subject lines contain this value") + "Restore emails with a subject containing this value.") fs.StringVar( &emailSender, "email-sender", "", - "Restore mail where the email sender matches this user id") + "Restore emails from a specific sender.") fs.StringVar( &emailReceivedAfter, "email-received-after", "", - "Restore mail where the email was received after this datetime") + "Restore emails received after this datetime.") fs.StringVar( &emailReceivedBefore, "email-received-before", "", - "Restore mail where the email was received before this datetime") + "Restore emails received before this datetime.") // event flags fs.StringSliceVar(&event, "event", nil, - "Restore events by ID; accepts "+utils.Wildcard+" to select all events") + "Restore events by event ID; accepts "+utils.Wildcard+" to select all events.") fs.StringSliceVar( &eventCalendar, "event-calendar", nil, - "Restore events by calendar ID; accepts "+utils.Wildcard+" to select all event calendars") + "Restore events under a calendar; accepts "+utils.Wildcard+" to select all event calendars.") fs.StringVar( &eventSubject, "event-subject", "", - "Restore events where the event subject contains this value") + "Restore events with a subject containing this value.") fs.StringVar( &eventOrganizer, "event-organizer", "", - "Restore events where the event organizer user id contains this value") + "Restore events from a specific organizer.") fs.StringVar( &eventRecurs, "event-recurs", "", - "Restore events if the event recurs. Use `--event-recurs false` to select non-recurring events") + "Restore recurring events. Use `--event-recurs false` to restore non-recurring events.") fs.StringVar( &eventStartsAfter, "event-starts-after", "", - "Restore events where the event starts after this datetime") + "Restore events starting after this datetime.") fs.StringVar( &eventStartsBefore, "event-starts-before", "", - "Restore events where the event starts before this datetime") + "Restore events starting before this datetime.") // contacts flags fs.StringSliceVar( &contact, "contact", nil, - "Restore contacts by ID; accepts "+utils.Wildcard+" to select all contacts") + "Restore contacts by contact ID; accepts "+utils.Wildcard+" to select all contacts.") fs.StringSliceVar( &contactFolder, "contact-folder", nil, - "Restore all contacts within the folder ID; accepts "+utils.Wildcard+" to select all contact folders") + "Restore contacts within a folder; accepts "+utils.Wildcard+" to select all contact folders.") fs.StringVar( &contactName, "contact-name", "", - "Restore contacts where the contact name contains this value") + "Restore contacts whose contact name contains this value.") // others options.AddOperationFlags(c) @@ -136,7 +138,10 @@ func addExchangeCommands(parent *cobra.Command) *cobra.Command { return c } -const exchangeServiceCommand = "exchange" +const ( + exchangeServiceCommand = "exchange" + exchangeServiceCommandUseSuffix = " --backup " +) // `corso restore exchange [...]` func exchangeRestoreCmd() *cobra.Command { diff --git a/src/cli/restore/exchange_test.go b/src/cli/restore/exchange_test.go index 17f5cb09e..e53cb8062 100644 --- a/src/cli/restore/exchange_test.go +++ b/src/cli/restore/exchange_test.go @@ -20,7 +20,7 @@ func TestExchangeSuite(t *testing.T) { } func (suite *ExchangeSuite) TestAddExchangeCommands() { - expectUse := exchangeServiceCommand + expectUse := exchangeServiceCommand + exchangeServiceCommandUseSuffix table := []struct { name string diff --git a/src/cli/restore/onedrive.go b/src/cli/restore/onedrive.go index 8430ae7f7..745b66d35 100644 --- a/src/cli/restore/onedrive.go +++ b/src/cli/restore/onedrive.go @@ -36,16 +36,18 @@ func addOneDriveCommands(parent *cobra.Command) *cobra.Command { case restoreCommand: c, fs = utils.AddCommand(parent, oneDriveRestoreCmd()) + c.Use = c.Use + oneDriveServiceCommandUseSuffix + // Flags addition ordering should follow the order we want them to appear in help and docs: // More generic (ex: --all) and more frequently used flags take precedence. fs.SortFlags = false - fs.StringVar(&backupID, "backup", "", "ID of the backup to restore") + fs.StringVar(&backupID, "backup", "", "ID of the backup to restore. (required)") cobra.CheckErr(c.MarkFlagRequired("backup")) fs.StringSliceVar(&user, "user", nil, - "Restore all data by user ID; accepts "+utils.Wildcard+" to select all users") + "Restore data by user ID; accepts "+utils.Wildcard+" to select all users.") // onedrive hierarchy (path/name) flags @@ -86,7 +88,10 @@ func addOneDriveCommands(parent *cobra.Command) *cobra.Command { return c } -const oneDriveServiceCommand = "onedrive" +const ( + oneDriveServiceCommand = "onedrive" + oneDriveServiceCommandUseSuffix = " --backup " +) // `corso restore onedrive [...]` func oneDriveRestoreCmd() *cobra.Command { diff --git a/src/cli/restore/onedrive_test.go b/src/cli/restore/onedrive_test.go index fd184c4d4..70a1d9c6d 100644 --- a/src/cli/restore/onedrive_test.go +++ b/src/cli/restore/onedrive_test.go @@ -20,7 +20,7 @@ func TestOneDriveSuite(t *testing.T) { } func (suite *OneDriveSuite) TestAddOneDriveCommands() { - expectUse := oneDriveServiceCommand + expectUse := oneDriveServiceCommand + oneDriveServiceCommandUseSuffix table := []struct { name string diff --git a/src/cmd/mdgen/mdgen.go b/src/cmd/mdgen/mdgen.go index 77139d7ac..0b04c3389 100644 --- a/src/cmd/mdgen/mdgen.go +++ b/src/cmd/mdgen/mdgen.go @@ -189,11 +189,16 @@ func printFlags(buf *bytes.Buffer, flags *pflag.FlagSet) { buf.WriteString("|") if flag.DefValue != "" { - buf.WriteString(fmt.Sprintf("`%s`", flag.DefValue)) + defValue := flag.DefValue + if defValue == "[]" { + defValue = "" + } + + buf.WriteString(fmt.Sprintf("`%s`", defValue)) } buf.WriteString("|") - buf.WriteString(flag.Usage) + buf.WriteString(strings.ReplaceAll(flag.Usage, "(required)", "
Required
")) buf.WriteString("|\n") }) }