From 4bc6bb3871893096964d0847738f377d00438506 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Fri, 29 Dec 2023 04:27:03 +0100 Subject: [PATCH] don't use extra cmds, use a flag (#25) Introduced a `-D` flag to drop a path before re-adding it, preventing duplicates. Corrected typos in comments and method names for better clarity. Enhanced `DirList` test to cover new functionality and ensure the integrity of path manipulation. Updated usage message to include information about the new `-D` flag feature. --- cmd/pathctl/main.go | 61 ++++++++++++++++++------------------------- pathlist/list.go | 16 ++++++------ pathlist/list_test.go | 3 ++- 3 files changed, 36 insertions(+), 44 deletions(-) diff --git a/cmd/pathctl/main.go b/cmd/pathctl/main.go index 218e360..6ca8c15 100644 --- a/cmd/pathctl/main.go +++ b/cmd/pathctl/main.go @@ -20,6 +20,7 @@ var ( versionMode bool listMode bool noprefixMode bool + dropMode bool ) var ( @@ -31,42 +32,37 @@ var cmdHandlers map[string]func(d pathlist.List) func init() { flag.BoolVar(&helpMode, "help", false, "display this help and exit.") flag.BoolVar(&versionMode, "version", false, "output version information and exit.") + flag.BoolVar(&dropMode, "D", false, "drop the path before adding it again to the list.") flag.BoolVar(&noprefixMode, "noprefix", false, "output the variable contents only.") flag.BoolVar(&listMode, "L", false, "use a newline character as path list separator.") - flag.StringVar(&envVar, "E", "PATH", "input environment variable") + flag.StringVar(&envVar, "E", "PATH", "input environment variable.") flag.Usage = usage flag.CommandLine.SetOutput(os.Stderr) cmdHandlers = func() map[string]func(pathlist.List) { - hAppend := func(d pathlist.List) { d.Append(flag.Arg(1)) } - hMoveAppend := func(d pathlist.List) { - d.Drop(flag.Arg(1)) + hAppend := func(d pathlist.List) { + if dropMode { + d.Drop(flag.Arg(1)) + } d.Append(flag.Arg(1)) } hDrop := func(d pathlist.List) { d.Drop(flag.Arg(1)) } - hMovePrepend := func(d pathlist.List) { - d.Drop(flag.Arg(1)) - d.Prepend(flag.Arg(1)) - } hPrepend := func(d pathlist.List) { + if dropMode { + d.Drop(flag.Arg(1)) + } d.Prepend(flag.Arg(1)) } return map[string]func(pathlist.List){ - "append": hAppend, - "drop": hDrop, - "prepend": hPrepend, - "move-append": hMoveAppend, - "move-prepend": hMovePrepend, - //"appendPathctlDir": func() { appendPath(exePath()) }, - //"prependPathctlDir": func() { prependPath(exePath()) }, + "append": hAppend, + "drop": hDrop, + "prepend": hPrepend, // aliases - "a": hAppend, - "d": hDrop, - "p": hPrepend, - "mv": hMoveAppend, - "mp": hMovePrepend, + "a": hAppend, + "d": hDrop, + "p": hPrepend, } }() } @@ -115,10 +111,6 @@ func printPathList(d pathlist.List) { fmt.Println(sb.String()) } -func list(d pathlist.List) { - printPathList(d) -} - func handleHelpAndVersionModes() { if !helpMode && !versionMode { return @@ -135,21 +127,16 @@ func handleHelpAndVersionModes() { } func usage() { - s := fmt.Sprintf(`Usage: %s COMMAND [PATH] + s := fmt.Sprintf(`Usage: %s [COMMAND [PATH]] Make the management of the PATH environment variable simple, fast, and predictable. Commands: - append, a append a path to the end of the list - move-append, ma append a new path to the end of the list; - if the list contains the path already then - it will be moved to the end of the list - drop, d drop a path - prepend, p prepend a path to the list - move-prepend, mp prepend a new path to the top of the list; - if the list contains the path already then - it will be moved to the top of the list + append, a append a path to the end of the list. + drop, d drop a path. + prepend, p prepend a path to the list. + Options: `, programme) _, _ = fmt.Fprintln(os.Stderr, s) @@ -157,7 +144,11 @@ Options: flag.PrintDefaults() _, _ = fmt.Fprintln(os.Stderr, ` +When used with the -D flag, the commands append and prepend +drop PATH before adding it again to the list. This behaviour +guarantees that PATH is added as either the first or the last +element of the path list. + If COMMAND is not provided, it prints the contents of the PATH environment variable.`) } - diff --git a/pathlist/list.go b/pathlist/list.go index 9d0e3e5..0a5eeb4 100644 --- a/pathlist/list.go +++ b/pathlist/list.go @@ -1,4 +1,4 @@ -// Package pathlist implements functions to manipoulate PATH-like +// Package pathlist implements functions to manipulate PATH-like // environment variables. package pathlist @@ -42,8 +42,8 @@ type List interface { // Slice returns the path list as a slice of strings. Slice() []string - // Returns the path list as a string of path list separator-separated - // directories. + // String returns the path list as a string of path list + // separator-separated directories. String() string } @@ -168,18 +168,18 @@ func (d *dirList) clone(o *dirList) *dirList { } func removeDups[T comparable](col []T, applyFn func(T) (T, bool)) []T { - uniq := []T{} + var uniq = make([]T, 0) ks := make(map[T]interface{}) for _, el := range col { - newval, ok := applyFn(el) + vv, ok := applyFn(el) if !ok { continue } - if _, ok := ks[newval]; !ok { - uniq = append(uniq, newval) - ks[newval] = struct{}{} + if _, ok := ks[vv]; !ok { + uniq = append(uniq, vv) + ks[vv] = struct{}{} } } diff --git a/pathlist/list_test.go b/pathlist/list_test.go index e97a427..5b9e210 100644 --- a/pathlist/list_test.go +++ b/pathlist/list_test.go @@ -62,7 +62,8 @@ func Test_DirList_Prepend(t *testing.T) { func Test_DirList_Drop(t *testing.T) { d := New() - d.Load("/opt/local/bin:/usr/local/bin:/sbin:/bin:/var") + d.Load("/opt/local/bin:/usr/local/bin:/sbin:/bin:/var:/bin") + require.Equal(t, d.Slice(), []string{"/opt/local/bin", "/usr/local/bin", "/sbin", "/bin", "/var"}) d.Drop("/opt/local/bin") d.Drop("/opt/local/bin") d.Drop("/opt/local/bin")