Skip to content

Commit

Permalink
Profiles WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
nielash committed Jan 12, 2024
1 parent 1045f54 commit 60b9568
Show file tree
Hide file tree
Showing 12 changed files with 1,530 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -18,3 +18,4 @@ __pycache__
/docs/static/img/logos/
resource_windows_*.syso
.devcontainer
.vscode/launch.json
1 change: 1 addition & 0 deletions cmd/all/all.go
Expand Up @@ -51,6 +51,7 @@ import (
_ "github.com/rclone/rclone/cmd/rmdirs"
_ "github.com/rclone/rclone/cmd/selfupdate"
_ "github.com/rclone/rclone/cmd/serve"
_ "github.com/rclone/rclone/cmd/setprofile"
_ "github.com/rclone/rclone/cmd/settier"
_ "github.com/rclone/rclone/cmd/sha1sum"
_ "github.com/rclone/rclone/cmd/size"
Expand Down
2 changes: 2 additions & 0 deletions cmd/cmd.go
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/rclone/rclone/fs/cache"
"github.com/rclone/rclone/fs/config/configfile"
"github.com/rclone/rclone/fs/config/configflags"
profiles "github.com/rclone/rclone/fs/config/configprofiles"
"github.com/rclone/rclone/fs/config/flags"
"github.com/rclone/rclone/fs/filter"
"github.com/rclone/rclone/fs/filter/filterflags"
Expand Down Expand Up @@ -567,6 +568,7 @@ func Main() {
}
setupRootCommand(Root)
AddBackendFlags()
profiles.AddProfiles(context.Background(), Root)
if err := Root.Execute(); err != nil {
if strings.HasPrefix(err.Error(), "unknown command") && selfupdateEnabled {
Root.PrintErrf("You could use '%s selfupdate' to get latest features.\n\n", Root.CommandPath())
Expand Down
16 changes: 16 additions & 0 deletions cmd/config/config.go
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/rclone/rclone/cmd"
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/config"
profiles "github.com/rclone/rclone/fs/config/configprofiles"
"github.com/rclone/rclone/fs/config/flags"
"github.com/rclone/rclone/fs/rc"
"github.com/spf13/cobra"
Expand All @@ -26,6 +27,7 @@ func init() {
configCommand.AddCommand(configTouchCommand)
configCommand.AddCommand(configPathsCommand)
configCommand.AddCommand(configShowCommand)
configCommand.AddCommand(configProfileCommand)
configCommand.AddCommand(configRedactedCommand)
configCommand.AddCommand(configDumpCommand)
configCommand.AddCommand(configProvidersCommand)
Expand Down Expand Up @@ -122,6 +124,20 @@ var configShowCommand = &cobra.Command{
},
}

var configProfileCommand = &cobra.Command{
Use: "profile",
Short: configCommand.Short,
Long: configCommand.Long,
Annotations: map[string]string{
"versionIntroduced": "v1.66",
},
Aliases: []string{"profiles"},
RunE: func(command *cobra.Command, args []string) error {
cmd.CheckArgs(0, 0, command, args)
return profiles.EditProfiles(context.Background())
},
}

var configRedactedCommand = &cobra.Command{
Use: "redacted [<remote>]",
Short: `Print redacted (decrypted) config file, or the redacted config for a single remote.`,
Expand Down
75 changes: 75 additions & 0 deletions cmd/setprofile/setprofile.go
@@ -0,0 +1,75 @@
// Package setprofile provides the setprofile command.
package setprofile

import (
"context"
"errors"
"os"

"github.com/rclone/rclone/cmd"
"github.com/rclone/rclone/fs"
profiles "github.com/rclone/rclone/fs/config/configprofiles"
"github.com/rclone/rclone/fs/config/flags"
"github.com/spf13/cobra"
)

var (
FlagsFrom fs.CommaSepList // FlagsFrom imports command-specific flags from these subcommands (note: will error if commands have conflicting flags.)
)

func init() {
cmd.Root.AddCommand(commandDefinition)
cmdFlags := commandDefinition.Flags()
flags.FVarP(cmdFlags, &FlagsFrom, "flags-from", "", "If set, import command-specific flags from these subcommands (note: will error if commands have conflicting flags.)", "")

commandDefinition.PersistentPreRunE = addFlagsFrom
commandDefinition.FParseErrWhitelist.UnknownFlags = true // allow unknown flags until we do our custom parsing
}

func addFlagsFrom(setprofilecmd *cobra.Command, args []string) error {
// prevent verbose getting double-counted (it's a CountVarP)
verbose := setprofilecmd.Flags().Lookup("verbose").Value.String()
defer func() {
err := setprofilecmd.Flags().Lookup("verbose").Value.Set(verbose)
if err != nil {
fs.Errorf(nil, "error trying to set verbose to %s: %v", verbose, err)
}
}()

if len(FlagsFrom) > 0 {
for _, subcommand := range FlagsFrom {
sc, _, err := cmd.Root.Find([]string{subcommand})
if err != nil {
return err
}
setprofilecmd.Flags().AddFlagSet(sc.Flags())
}
}
// now reenable validation and reparse the flags
commandDefinition.FParseErrWhitelist.UnknownFlags = false
return setprofilecmd.ParseFlags(os.Args)
}

var commandDefinition = &cobra.Command{
Use: "setprofile [args...] [flags...] --save-profile PROFILENAME",
Short: `Save a profile with the args and flags passed in.`,
Long: `
This command does nothing except set a profile.
For more detailed profile config options, see:
rclone config profile
`,
Annotations: map[string]string{
"groups": "Config",
},
Run: func(command *cobra.Command, args []string) {
cmd.CheckArgs(0, 100, command, args)
cmd.Run(false, false, command, func() error {
ctx, ci := fs.AddConfig(context.Background())
if ci.SaveProfile == "" {
return errors.New("must use --save-profile PROFILENAME with this command")
}
return profiles.HandleProfiles(ctx, command, args)
})
},
}
4 changes: 4 additions & 0 deletions fs/config.go
Expand Up @@ -150,6 +150,10 @@ type ConfigInfo struct {
Inplace bool // Download directly to destination file instead of atomic download to temp/rename
PartialSuffix string
MetadataMapper SpaceSepList
SaveProfile string
UseProfile CommaSepList
ProfileIncludeArgs bool
ProfileStrictFlags bool
}

// NewConfig creates a new config with everything set to the default
Expand Down
4 changes: 4 additions & 0 deletions fs/config/configflags/configflags.go
Expand Up @@ -151,6 +151,10 @@ func AddFlags(ci *fs.ConfigInfo, flagSet *pflag.FlagSet) {
flags.BoolVarP(flagSet, &ci.Inplace, "inplace", "", ci.Inplace, "Download directly to destination file instead of atomic download to temp/rename", "Copy")
flags.StringVarP(flagSet, &partialSuffix, "partial-suffix", "", ci.PartialSuffix, "Add partial-suffix to temporary file name when --inplace is not used", "Copy")
flags.FVarP(flagSet, &ci.MetadataMapper, "metadata-mapper", "", "Program to run to transforming metadata before upload", "Metadata")
flags.StringVarP(flagSet, &ci.SaveProfile, "save-profile", "", "", "Save this flag configuration as a reusable preset", "Config")
flags.FVarP(flagSet, &ci.UseProfile, "use-profile", "", "Use the flag configuration saved with this name. If more than one is provided, priority will be lowest to highest.", "Config")
flags.BoolVarP(flagSet, &ci.ProfileIncludeArgs, "profile-include-args", "", ci.ProfileIncludeArgs, "Include args (ex. the paths being synced) in addition to flags when saving/using a profile", "Config")
flags.BoolVarP(flagSet, &ci.ProfileStrictFlags, "profile-strict-flags", "", ci.ProfileStrictFlags, "If set, --use-profile will error if any flags are invalid for this command, instead of ignoring.", "Config")
}

// ParseHeaders converts the strings passed in via the header flags into HTTPOptions
Expand Down

0 comments on commit 60b9568

Please sign in to comment.