diff --git a/cmd/flag/common.go b/cmd/flag/common.go index b747b27..3b7a27f 100644 --- a/cmd/flag/common.go +++ b/cmd/flag/common.go @@ -31,18 +31,25 @@ var ( commonFlagValues CommonFlagValues ) -func SetCommonFlags(command *cobra.Command) { +func SetCommonFlags(command *cobra.Command, noResource bool) { command.Flags().StringVarP(&commonFlagValues.ConfigFilePath, "config", "c", "", "Set config file or dir (default \"$HOME/.irods\")") command.Flags().BoolVarP(&commonFlagValues.ShowVersion, "version", "v", false, "Print version") command.Flags().BoolVarP(&commonFlagValues.ShowHelp, "help", "h", false, "Print help") command.Flags().BoolVarP(&commonFlagValues.DebugMode, "debug", "d", false, "Enable debug mode") command.Flags().StringVar(&commonFlagValues.logLevelInput, "log_level", "", "Set log level") command.Flags().IntVarP(&commonFlagValues.SessionID, "session", "s", os.Getppid(), "Set session ID") - command.Flags().StringVarP(&commonFlagValues.Resource, "resource", "R", "", "Set resource server") + + if !noResource { + command.Flags().StringVarP(&commonFlagValues.Resource, "resource", "R", "", "Set resource server") + } command.MarkFlagsMutuallyExclusive("debug", "version") command.MarkFlagsMutuallyExclusive("log_level", "version") - command.MarkFlagsMutuallyExclusive("resource", "version") + + if !noResource { + command.MarkFlagsMutuallyExclusive("resource", "version") + } + command.MarkFlagsMutuallyExclusive("session", "version") } diff --git a/cmd/flag/target_object.go b/cmd/flag/target_object.go new file mode 100644 index 0000000..65833a0 --- /dev/null +++ b/cmd/flag/target_object.go @@ -0,0 +1,42 @@ +package flag + +import ( + "github.com/spf13/cobra" +) + +type TargetObjectFlagValues struct { + PathUpdated bool + Path string + ResourceUpdated bool + Resource string + UserUpdated bool + User string +} + +var ( + targetObjectFlagValues TargetObjectFlagValues +) + +func SetTargetObjectFlags(command *cobra.Command) { + command.Flags().StringVarP(&targetObjectFlagValues.Path, "path", "P", "", "Set a data object or collection as a target") + command.Flags().StringVarP(&targetObjectFlagValues.Resource, "resource", "R", "", "Set a resource as a target") + command.Flags().StringVarP(&targetObjectFlagValues.User, "user", "U", "", "Set a user as a target") + + command.MarkFlagsMutuallyExclusive("path", "resource", "user") +} + +func GetTargetObjectFlagValues(command *cobra.Command) *TargetObjectFlagValues { + if command.Flags().Changed("path") { + targetObjectFlagValues.PathUpdated = true + } + + if command.Flags().Changed("resource") { + targetObjectFlagValues.ResourceUpdated = true + } + + if command.Flags().Changed("user") { + targetObjectFlagValues.UserUpdated = true + } + + return &targetObjectFlagValues +} diff --git a/cmd/gocmd.go b/cmd/gocmd.go index 42767fd..48f9a68 100644 --- a/cmd/gocmd.go +++ b/cmd/gocmd.go @@ -67,7 +67,7 @@ func main() { }) // attach common flags - flag.SetCommonFlags(rootCmd) + flag.SetCommonFlags(rootCmd, true) // add sub commands subcmd.AddInitCommand(rootCmd) @@ -89,6 +89,8 @@ func main() { subcmd.AddBputCommand(rootCmd) subcmd.AddSvrinfoCommand(rootCmd) subcmd.AddPsCommand(rootCmd) + subcmd.AddLsmetaCommand(rootCmd) + subcmd.AddAddmetaCommand(rootCmd) subcmd.AddCopySftpIdCommand(rootCmd) subcmd.AddLsticketCommand(rootCmd) subcmd.AddRmticketCommand(rootCmd) diff --git a/cmd/subcmd/addmeta.go b/cmd/subcmd/addmeta.go new file mode 100644 index 0000000..f5c7e7c --- /dev/null +++ b/cmd/subcmd/addmeta.go @@ -0,0 +1,139 @@ +package subcmd + +import ( + irodsclient_fs "github.com/cyverse/go-irodsclient/fs" + "github.com/cyverse/gocommands/cmd/flag" + "github.com/cyverse/gocommands/commons" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "golang.org/x/xerrors" +) + +var addmetaCmd = &cobra.Command{ + Use: "addmeta [attribute name] [attribute value] [attribute unit (optional)]", + Aliases: []string{"add_meta", "add_metadata"}, + Short: "Add a metadata", + Long: `This adds a metadata to the given collection, data object, user, or a resource.`, + RunE: processAddmetaCommand, + Args: cobra.RangeArgs(2, 3), +} + +func AddAddmetaCommand(rootCmd *cobra.Command) { + // attach common flags + flag.SetCommonFlags(addmetaCmd, true) + + flag.SetTargetObjectFlags(addmetaCmd) + + rootCmd.AddCommand(addmetaCmd) +} + +func processAddmetaCommand(command *cobra.Command, args []string) error { + cont, err := flag.ProcessCommonFlags(command) + if err != nil { + return xerrors.Errorf("failed to process common flags: %w", err) + } + + if !cont { + return nil + } + + // handle local flags + _, err = commons.InputMissingFields() + if err != nil { + return xerrors.Errorf("failed to input missing fields: %w", err) + } + + targetObjectFlagValues := flag.GetTargetObjectFlagValues(command) + + // Create a connection + account := commons.GetAccount() + filesystem, err := commons.GetIRODSFSClient(account) + if err != nil { + return xerrors.Errorf("failed to get iRODS FS Client: %w", err) + } + + defer filesystem.Release() + + // get avu + attr := args[0] + value := args[1] + unit := "" + if len(args) >= 3 { + unit = args[2] + } + + if targetObjectFlagValues.PathUpdated { + err = addMetaToPath(filesystem, targetObjectFlagValues.Path, attr, value, unit) + if err != nil { + return err + } + } else if targetObjectFlagValues.UserUpdated { + err = addMetaToUser(filesystem, targetObjectFlagValues.User, attr, value, unit) + if err != nil { + return err + } + } else if targetObjectFlagValues.ResourceUpdated { + err = addMetaToResource(filesystem, targetObjectFlagValues.Resource, attr, value, unit) + if err != nil { + return err + } + } else { + // nothing updated + return xerrors.Errorf("path, user, or resource must be given") + } + + return nil +} + +func addMetaToPath(fs *irodsclient_fs.FileSystem, targetPath string, attribute string, value string, unit string) error { + logger := log.WithFields(log.Fields{ + "package": "subcmd", + "function": "addMetaToPath", + }) + + logger.Debugf("add metadata to path %s (attr %s, value %s, unit %s)", targetPath, attribute, value, unit) + + cwd := commons.GetCWD() + home := commons.GetHomeDir() + zone := commons.GetZone() + targetPath = commons.MakeIRODSPath(cwd, home, zone, targetPath) + + err := fs.AddMetadata(targetPath, attribute, value, unit) + if err != nil { + return xerrors.Errorf("failed to add metadata to path %s (attr %s, value %s, unit %s): %w", targetPath, attribute, value, unit, err) + } + + return nil +} + +func addMetaToUser(fs *irodsclient_fs.FileSystem, username string, attribute string, value string, unit string) error { + logger := log.WithFields(log.Fields{ + "package": "subcmd", + "function": "addMetaToUser", + }) + + logger.Debugf("add metadata to user %s (attr %s, value %s, unit %s)", username, attribute, value, unit) + + err := fs.AddUserMetadata(username, attribute, value, unit) + if err != nil { + return xerrors.Errorf("failed to add metadata to user %s (attr %s, value %s, unit %s): %w", username, attribute, value, unit, err) + } + + return nil +} + +func addMetaToResource(fs *irodsclient_fs.FileSystem, resource string, attribute string, value string, unit string) error { + logger := log.WithFields(log.Fields{ + "package": "subcmd", + "function": "addMetaToResource", + }) + + logger.Debugf("add metadata to resource %s (attr %s, value %s, unit %s)", resource, attribute, value, unit) + + err := fs.AddUserMetadata(resource, attribute, value, unit) + if err != nil { + return xerrors.Errorf("failed to add metadata to resource %s (attr %s, value %s, unit %s): %w", resource, attribute, value, unit, err) + } + + return nil +} diff --git a/cmd/subcmd/bclean.go b/cmd/subcmd/bclean.go index 76576ae..7ab4bf0 100644 --- a/cmd/subcmd/bclean.go +++ b/cmd/subcmd/bclean.go @@ -19,7 +19,7 @@ var bcleanCmd = &cobra.Command{ func AddBcleanCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(bcleanCmd) + flag.SetCommonFlags(bcleanCmd, false) // attach bundle temp flags flag.SetBundleTempFlags(bcleanCmd) @@ -30,7 +30,7 @@ func AddBcleanCommand(rootCmd *cobra.Command) { func processBcleanCommand(command *cobra.Command, args []string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "processBcleanCommand", }) @@ -82,7 +82,7 @@ func processBcleanCommand(command *cobra.Command, args []string) error { func bcleanOne(fs *irodsclient_fs.FileSystem, targetPath string, forceFlagValues *flag.ForceFlagValues) { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "bcleanOne", }) diff --git a/cmd/subcmd/bput.go b/cmd/subcmd/bput.go index b41408a..513c19a 100644 --- a/cmd/subcmd/bput.go +++ b/cmd/subcmd/bput.go @@ -24,7 +24,7 @@ var bputCmd = &cobra.Command{ func AddBputCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(bputCmd) + flag.SetCommonFlags(bputCmd, false) flag.SetBundleTempFlags(bputCmd) flag.SetBundleClearFlags(bputCmd) @@ -42,7 +42,7 @@ func AddBputCommand(rootCmd *cobra.Command) { func processBputCommand(command *cobra.Command, args []string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "processBputCommand", }) @@ -197,7 +197,7 @@ func processBputCommand(command *cobra.Command, args []string) error { func bputOne(bundleManager *commons.BundleTransferManager, sourcePath string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "bputOne", }) @@ -253,7 +253,7 @@ func bputDeleteExtra(bundleManager *commons.BundleTransferManager, targetPath st func bputDeleteExtraInternal(filesystem *irodsclient_fs.FileSystem, inputPathMap map[string]bool, targetPath string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "bputDeleteExtraInternal", }) diff --git a/cmd/subcmd/bun.go b/cmd/subcmd/bun.go index 107a419..79c73af 100644 --- a/cmd/subcmd/bun.go +++ b/cmd/subcmd/bun.go @@ -23,7 +23,7 @@ var bunCmd = &cobra.Command{ func AddBunCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(bunCmd) + flag.SetCommonFlags(bunCmd, false) flag.SetForceFlags(bunCmd, false) flag.SetBundleFlags(bunCmd) @@ -110,7 +110,7 @@ func getDataType(irodsPath string, dataType string) (irodsclient_types.DataType, func extractOne(filesystem *irodsclient_fs.FileSystem, sourcePath string, targetPath string, bundleFlagValues *flag.BundleFlagValues, forceFlagValues *flag.ForceFlagValues) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "extractOne", }) diff --git a/cmd/subcmd/cat.go b/cmd/subcmd/cat.go index e682486..faa503d 100644 --- a/cmd/subcmd/cat.go +++ b/cmd/subcmd/cat.go @@ -23,7 +23,7 @@ var catCmd = &cobra.Command{ func AddCatCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(catCmd) + flag.SetCommonFlags(catCmd, false) flag.SetTicketAccessFlags(catCmd) @@ -32,7 +32,7 @@ func AddCatCommand(rootCmd *cobra.Command) { func processCatCommand(command *cobra.Command, args []string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "processCatCommand", }) @@ -88,7 +88,7 @@ func processCatCommand(command *cobra.Command, args []string) error { func catOne(filesystem *irodsclient_fs.FileSystem, targetPath string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "catOne", }) diff --git a/cmd/subcmd/cd.go b/cmd/subcmd/cd.go index 7049f67..ee18e89 100644 --- a/cmd/subcmd/cd.go +++ b/cmd/subcmd/cd.go @@ -21,7 +21,7 @@ var cdCmd = &cobra.Command{ func AddCdCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(cdCmd) + flag.SetCommonFlags(cdCmd, true) rootCmd.AddCommand(cdCmd) } @@ -69,7 +69,7 @@ func processCdCommand(command *cobra.Command, args []string) error { func changeWorkingDir(fs *irodsclient_fs.FileSystem, collectionPath string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "changeWorkingDir", }) diff --git a/cmd/subcmd/copy-sftp-id.go b/cmd/subcmd/copy-sftp-id.go index 30df900..4a9627c 100644 --- a/cmd/subcmd/copy-sftp-id.go +++ b/cmd/subcmd/copy-sftp-id.go @@ -28,7 +28,7 @@ var copySftpIdCmd = &cobra.Command{ func AddCopySftpIdCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(copySftpIdCmd) + flag.SetCommonFlags(copySftpIdCmd, false) flag.SetForceFlags(copySftpIdCmd, false) flag.SetDryRunFlags(copySftpIdCmd) @@ -122,7 +122,7 @@ func scanSSHIdentityFiles() ([]string, error) { func copySftpId(filesystem *irodsclient_fs.FileSystem, forceFlagValues *flag.ForceFlagValues, dryRunFlagValues *flag.DryRunFlagValues, identityFiles []string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "copySftpId", }) diff --git a/cmd/subcmd/cp.go b/cmd/subcmd/cp.go index 2932c22..0c0a851 100644 --- a/cmd/subcmd/cp.go +++ b/cmd/subcmd/cp.go @@ -25,7 +25,7 @@ var cpCmd = &cobra.Command{ func AddCpCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(cpCmd) + flag.SetCommonFlags(cpCmd, false) flag.SetForceFlags(cpCmd, false) flag.SetRecursiveFlags(cpCmd) @@ -40,7 +40,7 @@ func AddCpCommand(rootCmd *cobra.Command) { func processCpCommand(command *cobra.Command, args []string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "processCpCommand", }) @@ -129,7 +129,7 @@ func processCpCommand(command *cobra.Command, args []string) error { func copyOne(parallelJobManager *commons.ParallelJobManager, inputPathMap map[string]bool, sourcePath string, targetPath string, recursiveFlagValues *flag.RecursiveFlagValues, forceFlagValues *flag.ForceFlagValues, differentialTransferFlagValues *flag.DifferentialTransferFlagValues) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "copyOne", }) @@ -301,7 +301,7 @@ func copyDeleteExtra(filesystem *irodsclient_fs.FileSystem, inputPathMap map[str func copyDeleteExtraInternal(filesystem *irodsclient_fs.FileSystem, inputPathMap map[string]bool, targetPath string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "copyDeleteExtraInternal", }) diff --git a/cmd/subcmd/env.go b/cmd/subcmd/env.go index 69bb163..1029147 100644 --- a/cmd/subcmd/env.go +++ b/cmd/subcmd/env.go @@ -18,7 +18,7 @@ var envCmd = &cobra.Command{ func AddEnvCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(envCmd) + flag.SetCommonFlags(envCmd, true) rootCmd.AddCommand(envCmd) } diff --git a/cmd/subcmd/get.go b/cmd/subcmd/get.go index 10e1fd8..b1aa8ca 100644 --- a/cmd/subcmd/get.go +++ b/cmd/subcmd/get.go @@ -29,7 +29,7 @@ var getCmd = &cobra.Command{ func AddGetCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(getCmd) + flag.SetCommonFlags(getCmd, false) flag.SetForceFlags(getCmd, false) flag.SetTicketAccessFlags(getCmd) @@ -47,7 +47,7 @@ func AddGetCommand(rootCmd *cobra.Command) { func processGetCommand(command *cobra.Command, args []string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "processGetCommand", }) @@ -166,7 +166,7 @@ func processGetCommand(command *cobra.Command, args []string) error { func getOne(parallelJobManager *commons.ParallelJobManager, inputPathMap map[string]bool, sourcePath string, targetPath string, forceFlagValues *flag.ForceFlagValues, parallelTransferFlagValues *flag.ParallelTransferFlagValues, differentialTransferFlagValues *flag.DifferentialTransferFlagValues, decryptionFlagValues *flag.DecryptionFlagValues, postTransferFlagValues *flag.PostTransferFlagValues) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "getOne", }) @@ -434,7 +434,7 @@ func getDeleteExtra(inputPathMap map[string]bool, targetPath string) error { func getDeleteExtraInternal(inputPathMap map[string]bool, targetPath string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "getDeleteExtraInternal", }) diff --git a/cmd/subcmd/init.go b/cmd/subcmd/init.go index 6e7d5c0..2e148f0 100644 --- a/cmd/subcmd/init.go +++ b/cmd/subcmd/init.go @@ -24,7 +24,7 @@ var initCmd = &cobra.Command{ func AddInitCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(initCmd) + flag.SetCommonFlags(initCmd, false) flag.SetInitFlags(initCmd) rootCmd.AddCommand(initCmd) diff --git a/cmd/subcmd/ls.go b/cmd/subcmd/ls.go index 3e8147f..f135501 100644 --- a/cmd/subcmd/ls.go +++ b/cmd/subcmd/ls.go @@ -35,7 +35,7 @@ var lsCmd = &cobra.Command{ func AddLsCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(lsCmd) + flag.SetCommonFlags(lsCmd, false) flag.SetListFlags(lsCmd) flag.SetTicketAccessFlags(lsCmd) @@ -46,7 +46,7 @@ func AddLsCommand(rootCmd *cobra.Command) { func processLsCommand(command *cobra.Command, args []string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "processLsCommand", }) diff --git a/cmd/subcmd/lsmeta.go b/cmd/subcmd/lsmeta.go new file mode 100644 index 0000000..bbb68a0 --- /dev/null +++ b/cmd/subcmd/lsmeta.go @@ -0,0 +1,235 @@ +package subcmd + +import ( + "fmt" + "sort" + + irodsclient_fs "github.com/cyverse/go-irodsclient/fs" + "github.com/cyverse/go-irodsclient/irods/types" + "github.com/cyverse/gocommands/cmd/flag" + "github.com/cyverse/gocommands/commons" + "github.com/spf13/cobra" + "golang.org/x/xerrors" +) + +var lsmetaCmd = &cobra.Command{ + Use: "lsmeta", + Aliases: []string{"ls_meta", "ls_metadata", "list_meta", "list_metadata"}, + Short: "List metadata", + Long: `This lists metadata for the given collection, data object, user, or a resource.`, + RunE: processLsmetaCommand, + Args: cobra.NoArgs, +} + +func AddLsmetaCommand(rootCmd *cobra.Command) { + // attach common flags + flag.SetCommonFlags(lsmetaCmd, true) + + flag.SetListFlags(lsmetaCmd) + flag.SetTargetObjectFlags(lsmetaCmd) + + rootCmd.AddCommand(lsmetaCmd) +} + +func processLsmetaCommand(command *cobra.Command, args []string) error { + cont, err := flag.ProcessCommonFlags(command) + if err != nil { + return xerrors.Errorf("failed to process common flags: %w", err) + } + + if !cont { + return nil + } + + // handle local flags + _, err = commons.InputMissingFields() + if err != nil { + return xerrors.Errorf("failed to input missing fields: %w", err) + } + + listFlagValues := flag.GetListFlagValues() + targetObjectFlagValues := flag.GetTargetObjectFlagValues(command) + + // Create a file system + account := commons.GetAccount() + filesystem, err := commons.GetIRODSFSClient(account) + if err != nil { + return xerrors.Errorf("failed to get iRODS FS Client: %w", err) + } + + defer filesystem.Release() + + if targetObjectFlagValues.PathUpdated { + err = listMetaForPath(filesystem, targetObjectFlagValues.Path, listFlagValues) + if err != nil { + return err + } + } else if targetObjectFlagValues.UserUpdated { + err = listMetaForUser(filesystem, targetObjectFlagValues.User, listFlagValues) + if err != nil { + return err + } + } else if targetObjectFlagValues.ResourceUpdated { + err = listMetaForResource(filesystem, targetObjectFlagValues.Resource, listFlagValues) + if err != nil { + return err + } + } else { + // nothing updated + return xerrors.Errorf("path, user, or resource must be given") + } + + return nil +} + +func listMetaForPath(fs *irodsclient_fs.FileSystem, targetPath string, listFlagValues *flag.ListFlagValues) error { + cwd := commons.GetCWD() + home := commons.GetHomeDir() + zone := commons.GetZone() + targetPath = commons.MakeIRODSPath(cwd, home, zone, targetPath) + + metas, err := fs.ListMetadata(targetPath) + if err != nil { + return xerrors.Errorf("failed to list meta for path %s: %w", targetPath, err) + } + + if len(metas) == 0 { + fmt.Printf("Found no metadata\n") + } else { + err = printMetas(metas, listFlagValues) + if err != nil { + return err + } + } + + return nil +} + +func listMetaForUser(fs *irodsclient_fs.FileSystem, username string, listFlagValues *flag.ListFlagValues) error { + metas, err := fs.ListUserMetadata(username) + if err != nil { + return xerrors.Errorf("failed to list meta for user %s: %w", username, err) + } + + if len(metas) == 0 { + fmt.Printf("Found no metadata\n") + } else { + err = printMetas(metas, listFlagValues) + if err != nil { + return err + } + } + + return nil +} + +func listMetaForResource(fs *irodsclient_fs.FileSystem, resource string, listFlagValues *flag.ListFlagValues) error { + metas, err := fs.ListResourceMetadata(resource) + if err != nil { + return xerrors.Errorf("failed to list meta for resource %s: %w", resource, err) + } + + if len(metas) == 0 { + fmt.Printf("Found no metadata\n") + } else { + err = printMetas(metas, listFlagValues) + if err != nil { + return err + } + } + + return nil +} + +func getMetaSortFunction(metas []*types.IRODSMeta, sortOrder commons.ListSortOrder, sortReverse bool) func(i int, j int) bool { + if sortReverse { + switch sortOrder { + case commons.ListSortOrderName: + return func(i int, j int) bool { + return metas[i].Name > metas[j].Name + } + case commons.ListSortOrderTime: + return func(i int, j int) bool { + return (metas[i].ModifyTime.After(metas[j].ModifyTime)) || + (metas[i].ModifyTime.Equal(metas[j].ModifyTime) && + metas[i].Name < metas[j].Name) + } + // Cannot sort meta by size or extension, so use default sort by avuid + default: + return func(i int, j int) bool { + return metas[i].AVUID < metas[j].AVUID + } + } + } + + switch sortOrder { + case commons.ListSortOrderName: + return func(i int, j int) bool { + return metas[i].Name < metas[j].Name + } + case commons.ListSortOrderTime: + return func(i int, j int) bool { + return (metas[i].ModifyTime.Before(metas[j].ModifyTime)) || + (metas[i].ModifyTime.Equal(metas[j].ModifyTime) && + metas[i].Name < metas[j].Name) + + } + // Cannot sort meta by size or extension, so use default sort by avuid + default: + return func(i int, j int) bool { + return metas[i].AVUID < metas[j].AVUID + } + } +} + +func printMetas(metas []*types.IRODSMeta, listFlagValues *flag.ListFlagValues) error { + sort.SliceStable(metas, getMetaSortFunction(metas, listFlagValues.SortOrder, listFlagValues.SortReverse)) + + for _, meta := range metas { + printMetaInternal(meta, listFlagValues) + } + + return nil +} + +func printMetaInternal(meta *types.IRODSMeta, listFlagValues *flag.ListFlagValues) { + createTime := commons.MakeDateTimeString(meta.CreateTime) + modTime := commons.MakeDateTimeString(meta.ModifyTime) + + name := meta.Name + if len(name) == 0 { + name = "" + } else { + name = fmt.Sprintf("\"%s\"", name) + } + + value := meta.Value + if len(value) == 0 { + value = "" + } else { + value = fmt.Sprintf("\"%s\"", value) + } + + units := meta.Units + if len(units) == 0 { + units = "" + } else { + units = fmt.Sprintf("\"%s\"", units) + } + + switch listFlagValues.Format { + case commons.ListFormatLong, commons.ListFormatVeryLong: + fmt.Printf("[%s]\n", meta.Name) + fmt.Printf("[%s]\n", meta.Name) + fmt.Printf(" id: %d\n", meta.AVUID) + fmt.Printf(" attribute: %s\n", name) + fmt.Printf(" value: %s\n", value) + fmt.Printf(" unit: %s\n", units) + fmt.Printf(" create time: %s\n", createTime) + fmt.Printf(" modify time: %s\n", modTime) + case commons.ListFormatNormal: + fallthrough + default: + fmt.Printf("%d\t%s\t%s\t%s\n", meta.AVUID, name, value, units) + } +} diff --git a/cmd/subcmd/lsticket.go b/cmd/subcmd/lsticket.go index 1f1200a..161bb1b 100644 --- a/cmd/subcmd/lsticket.go +++ b/cmd/subcmd/lsticket.go @@ -24,7 +24,7 @@ var lsticketCmd = &cobra.Command{ func AddLsticketCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(lsticketCmd) + flag.SetCommonFlags(lsticketCmd, true) flag.SetListFlags(lsticketCmd) @@ -136,7 +136,7 @@ func listTicket(fs *irodsclient_fs.FileSystem, listFlagValues *flag.ListFlagValu func getTicket(fs *irodsclient_fs.FileSystem, ticketName string, listFlagValues *flag.ListFlagValues) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "getTicket", }) diff --git a/cmd/subcmd/mkdir.go b/cmd/subcmd/mkdir.go index 40fd456..b451710 100644 --- a/cmd/subcmd/mkdir.go +++ b/cmd/subcmd/mkdir.go @@ -21,7 +21,7 @@ var mkdirCmd = &cobra.Command{ func AddMkdirCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(mkdirCmd) + flag.SetCommonFlags(mkdirCmd, false) flag.SetParentsFlags(mkdirCmd) @@ -66,7 +66,7 @@ func processMkdirCommand(command *cobra.Command, args []string) error { func makeOne(fs *irodsclient_fs.FileSystem, targetPath string, parentsFlagValues *flag.ParentsFlagValues) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "makeOne", }) diff --git a/cmd/subcmd/mkticket.go b/cmd/subcmd/mkticket.go index 06007b4..d21ba72 100644 --- a/cmd/subcmd/mkticket.go +++ b/cmd/subcmd/mkticket.go @@ -21,7 +21,7 @@ var mkticketCmd = &cobra.Command{ func AddMkticketCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(mkticketCmd) + flag.SetCommonFlags(mkticketCmd, true) flag.SetTicketFlags(mkticketCmd) @@ -64,7 +64,7 @@ func processMkticketCommand(command *cobra.Command, args []string) error { func makeTicket(fs *irodsclient_fs.FileSystem, ticketName string, ticketType types.TicketType, targetPath string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "makeTicket", }) diff --git a/cmd/subcmd/modticket.go b/cmd/subcmd/modticket.go index 5f4fe92..5995d93 100644 --- a/cmd/subcmd/modticket.go +++ b/cmd/subcmd/modticket.go @@ -21,7 +21,7 @@ var modticketCmd = &cobra.Command{ func AddModticketCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(modticketCmd) + flag.SetCommonFlags(modticketCmd, true) flag.SetTicketFlags(modticketCmd) diff --git a/cmd/subcmd/mv.go b/cmd/subcmd/mv.go index cd9d2ef..ab26e8a 100644 --- a/cmd/subcmd/mv.go +++ b/cmd/subcmd/mv.go @@ -20,7 +20,7 @@ var mvCmd = &cobra.Command{ func AddMvCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(mvCmd) + flag.SetCommonFlags(mvCmd, false) rootCmd.AddCommand(mvCmd) } @@ -66,7 +66,7 @@ func processMvCommand(command *cobra.Command, args []string) error { func moveOne(filesystem *irodsclient_fs.FileSystem, sourcePath string, targetPath string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "moveOne", }) diff --git a/cmd/subcmd/passwd.go b/cmd/subcmd/passwd.go index 723c998..689dddf 100644 --- a/cmd/subcmd/passwd.go +++ b/cmd/subcmd/passwd.go @@ -25,7 +25,7 @@ var passwdCmd = &cobra.Command{ func AddPasswdCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(passwdCmd) + flag.SetCommonFlags(passwdCmd, true) rootCmd.AddCommand(passwdCmd) } @@ -62,7 +62,7 @@ func processPasswdCommand(command *cobra.Command, args []string) error { func changePassword(fs *irodsclient_fs.FileSystem) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "changePassword", }) diff --git a/cmd/subcmd/ps.go b/cmd/subcmd/ps.go index f79d6fa..9c73610 100644 --- a/cmd/subcmd/ps.go +++ b/cmd/subcmd/ps.go @@ -25,7 +25,7 @@ var psCmd = &cobra.Command{ func AddPsCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(psCmd) + flag.SetCommonFlags(psCmd, true) flag.SetProcessFilterFlags(psCmd) @@ -69,7 +69,7 @@ func processPsCommand(command *cobra.Command, args []string) error { func listProcesses(fs *irodsclient_fs.FileSystem, processFilterFlagValues *flag.ProcessFilterFlagValues) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "listProcesses", }) diff --git a/cmd/subcmd/put.go b/cmd/subcmd/put.go index 25a3710..e804d8e 100644 --- a/cmd/subcmd/put.go +++ b/cmd/subcmd/put.go @@ -28,7 +28,7 @@ var putCmd = &cobra.Command{ func AddPutCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(putCmd) + flag.SetCommonFlags(putCmd, false) flag.SetForceFlags(putCmd, false) flag.SetTicketAccessFlags(putCmd) @@ -46,7 +46,7 @@ func AddPutCommand(rootCmd *cobra.Command) { func processPutCommand(command *cobra.Command, args []string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "processPutCommand", }) @@ -165,7 +165,7 @@ func processPutCommand(command *cobra.Command, args []string) error { func putOne(parallelJobManager *commons.ParallelJobManager, inputPathMap map[string]bool, sourcePath string, targetPath string, forceFlagValues *flag.ForceFlagValues, parallelTransferFlagValues *flag.ParallelTransferFlagValues, differentialTransferFlagValues *flag.DifferentialTransferFlagValues, encryptionFlagValues *flag.EncryptionFlagValues, postTransferFlagValues *flag.PostTransferFlagValues) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "putOne", }) @@ -431,7 +431,7 @@ func putDeleteExtra(filesystem *irodsclient_fs.FileSystem, inputPathMap map[stri func putDeleteExtraInternal(filesystem *irodsclient_fs.FileSystem, inputPathMap map[string]bool, targetPath string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "putDeleteExtraInternal", }) diff --git a/cmd/subcmd/pwd.go b/cmd/subcmd/pwd.go index ee144a7..91cd828 100644 --- a/cmd/subcmd/pwd.go +++ b/cmd/subcmd/pwd.go @@ -20,7 +20,7 @@ var pwdCmd = &cobra.Command{ func AddPwdCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(pwdCmd) + flag.SetCommonFlags(pwdCmd, true) rootCmd.AddCommand(pwdCmd) } diff --git a/cmd/subcmd/rm.go b/cmd/subcmd/rm.go index f587b96..fee5cc2 100644 --- a/cmd/subcmd/rm.go +++ b/cmd/subcmd/rm.go @@ -20,7 +20,7 @@ var rmCmd = &cobra.Command{ func AddRmCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(rmCmd) + flag.SetCommonFlags(rmCmd, false) flag.SetForceFlags(rmCmd, false) flag.SetRecursiveFlags(rmCmd) @@ -67,7 +67,7 @@ func processRmCommand(command *cobra.Command, args []string) error { func removeOne(filesystem *irodsclient_fs.FileSystem, targetPath string, forceFlagValues *flag.ForceFlagValues, recursiveFlagValues *flag.RecursiveFlagValues) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "removeOne", }) diff --git a/cmd/subcmd/rmdir.go b/cmd/subcmd/rmdir.go index 5cfcf77..d14c371 100644 --- a/cmd/subcmd/rmdir.go +++ b/cmd/subcmd/rmdir.go @@ -20,7 +20,7 @@ var rmdirCmd = &cobra.Command{ func AddRmdirCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(rmdirCmd) + flag.SetCommonFlags(rmdirCmd, false) rootCmd.AddCommand(rmdirCmd) } @@ -61,7 +61,7 @@ func processRmdirCommand(command *cobra.Command, args []string) error { func removeDirOne(filesystem *irodsclient_fs.FileSystem, targetPath string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "removeDirOne", }) diff --git a/cmd/subcmd/rmticket.go b/cmd/subcmd/rmticket.go index a5ff613..cb403d9 100644 --- a/cmd/subcmd/rmticket.go +++ b/cmd/subcmd/rmticket.go @@ -20,7 +20,7 @@ var rmticketCmd = &cobra.Command{ func AddRmticketCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(rmticketCmd) + flag.SetCommonFlags(rmticketCmd, true) rootCmd.AddCommand(rmticketCmd) } @@ -61,7 +61,7 @@ func processRmticketCommand(command *cobra.Command, args []string) error { func removeTicket(fs *irodsclient_fs.FileSystem, ticketName string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "removeTicket", }) diff --git a/cmd/subcmd/svrinfo.go b/cmd/subcmd/svrinfo.go index 2e5109f..6fa88da 100644 --- a/cmd/subcmd/svrinfo.go +++ b/cmd/subcmd/svrinfo.go @@ -24,7 +24,7 @@ var svrinfoCmd = &cobra.Command{ func AddSvrinfoCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(svrinfoCmd) + flag.SetCommonFlags(svrinfoCmd, true) rootCmd.AddCommand(svrinfoCmd) } @@ -64,7 +64,7 @@ func processSvrinfoCommand(command *cobra.Command, args []string) error { func displayVersion(account *types.IRODSAccount, fs *irodsclient_fs.FileSystem) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "displayVersion", }) diff --git a/cmd/subcmd/sync.go b/cmd/subcmd/sync.go index b923911..53c82ed 100644 --- a/cmd/subcmd/sync.go +++ b/cmd/subcmd/sync.go @@ -22,7 +22,7 @@ var syncCmd = &cobra.Command{ func AddSyncCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(syncCmd) + flag.SetCommonFlags(syncCmd, false) flag.SetBundleTempFlags(syncCmd) flag.SetBundleClearFlags(syncCmd) @@ -115,7 +115,7 @@ func processSyncCommand(command *cobra.Command, args []string) error { func syncFromLocalToIRODS(command *cobra.Command) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "syncFromLocalToIRODS", }) @@ -157,7 +157,7 @@ func syncFromLocalToIRODS(command *cobra.Command) error { func syncFromIRODSToIRODS(command *cobra.Command, sourcePaths []string, targetPath string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "syncFromIRODSToIRODS", }) @@ -199,7 +199,7 @@ func syncFromIRODSToIRODS(command *cobra.Command, sourcePaths []string, targetPa func syncFromIRODSToLocal(command *cobra.Command, sourcePaths []string, targetPath string) error { logger := log.WithFields(log.Fields{ - "package": "main", + "package": "subcmd", "function": "syncFromIRODSToLocal", }) diff --git a/cmd/subcmd/upgrade.go b/cmd/subcmd/upgrade.go index ff373cb..16ffc24 100644 --- a/cmd/subcmd/upgrade.go +++ b/cmd/subcmd/upgrade.go @@ -20,7 +20,7 @@ var upgradeCmd = &cobra.Command{ func AddUpgradeCommand(rootCmd *cobra.Command) { // attach common flags - flag.SetCommonFlags(upgradeCmd) + flag.SetCommonFlags(upgradeCmd, true) flag.SetCheckVersionFlags(upgradeCmd) diff --git a/go.mod b/go.mod index 59c9cf7..96dd750 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( github.com/creativeprojects/go-selfupdate v1.0.1 - github.com/cyverse/go-irodsclient v0.14.3 + github.com/cyverse/go-irodsclient v0.14.4 github.com/dustin/go-humanize v1.0.1 github.com/gliderlabs/ssh v0.3.5 github.com/jedib0t/go-pretty/v6 v6.3.1 diff --git a/go.sum b/go.sum index e91762b..b20c30c 100644 --- a/go.sum +++ b/go.sum @@ -9,8 +9,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creativeprojects/go-selfupdate v1.0.1 h1:5Un4MTv4puCR5GBgkDLC14J72fljGuMC60E63cFGq1o= github.com/creativeprojects/go-selfupdate v1.0.1/go.mod h1:nm7AWUJfrfYt/SB97NAcMhR0KEpPqlrVHXkWFti+ezw= -github.com/cyverse/go-irodsclient v0.14.3 h1:B6BI3H2nUoh6pu76EB0eKBPdFY9lq1qppuHfDbz9UB0= -github.com/cyverse/go-irodsclient v0.14.3/go.mod h1:eBXha3cwfrM0p1ijYVqsrLJQHpRwTfpA4c5dKCQsQFc= +github.com/cyverse/go-irodsclient v0.14.4 h1:x7u/5W8gUBdF0QOGV5r0ZeiIkW52HAHEIa9j74CgOx0= +github.com/cyverse/go-irodsclient v0.14.4/go.mod h1:eBXha3cwfrM0p1ijYVqsrLJQHpRwTfpA4c5dKCQsQFc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=