add remove
This commit is contained in:
parent
a48617eaa8
commit
0a5f44eca7
|
@ -3,12 +3,10 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ppsep is used as the replacement for slashes in path
|
||||
|
@ -25,7 +23,8 @@ import (
|
|||
const ppsep = "-"
|
||||
|
||||
func usage() {
|
||||
fmt.Fprintf(os.Stderr, "Usage: envpath show|add|append|remove <path>\n")
|
||||
//fmt.Fprintf(os.Stderr, "Usage: envpath show|add|append|remove <path>\n")
|
||||
fmt.Fprintf(os.Stderr, "Usage: envpath show|add|remove <path>\n")
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -38,11 +37,7 @@ func main() {
|
|||
}
|
||||
action := os.Args[1]
|
||||
|
||||
paths, err := Paths()
|
||||
if nil != err {
|
||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
||||
os.Exit(2)
|
||||
}
|
||||
paths := Paths()
|
||||
|
||||
if "show" == action {
|
||||
if len(os.Args) > 2 {
|
||||
|
@ -79,16 +74,18 @@ func main() {
|
|||
default:
|
||||
usage()
|
||||
os.Exit(1)
|
||||
case "append":
|
||||
newpath, _, err := addPath(pathentry, appendOrder)
|
||||
if nil != err {
|
||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Println("New sessions will have " + pathentry + " in their PATH.")
|
||||
fmt.Println("To update this session run\n")
|
||||
//fmt.Println("\tsource", pathfile)
|
||||
fmt.Printf(`%sexport PATH="$PATH:%s"%s`, "\t", newpath, "\n")
|
||||
/*
|
||||
case "append":
|
||||
newpath, _, err := addPath(pathentry, appendOrder)
|
||||
if nil != err {
|
||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Println("New sessions will have " + pathentry + " in their PATH.")
|
||||
fmt.Println("To update this session run\n")
|
||||
//fmt.Println("\tsource", pathfile)
|
||||
fmt.Printf(`%sexport PATH="$PATH:%s"%s`, "\t", newpath, "\n")
|
||||
*/
|
||||
case "add":
|
||||
_, pathfile, err := addPath(pathentry, prependOrder)
|
||||
if nil != err {
|
||||
|
@ -99,27 +96,19 @@ func main() {
|
|||
fmt.Printf("\tsource %s\n\n", pathfile)
|
||||
//fmt.Printf(`%sexport PATH="%s:$PATH"%s`, "\t", newpath, "\n\n")
|
||||
case "remove":
|
||||
_, err := removePath(pathentry)
|
||||
msg, err := removePath(pathentry)
|
||||
if nil != err {
|
||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Println(msg)
|
||||
}
|
||||
|
||||
// TODO support both of these usages:
|
||||
// 1. export PATH="$(envpath append /opt/whatever/bin)"
|
||||
// 2. envpath append /opt/whatever/bin
|
||||
// export PATH="$PATH:/opt/whatever/bin"
|
||||
}
|
||||
|
||||
// Paths returns the slice of PATHs from the Environment
|
||||
func Paths() ([]string, error) {
|
||||
func Paths() []string {
|
||||
// ":" on *nix
|
||||
return strings.Split(os.Getenv("PATH"), string(os.PathListSeparator)), nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
return strings.Split(os.Getenv("PATH"), string(os.PathListSeparator))
|
||||
}
|
||||
|
||||
type setOrder bool
|
||||
|
@ -168,8 +157,12 @@ func addPath(oldpathentry string, order setOrder) (string, string, error) {
|
|||
return "", "", err
|
||||
}
|
||||
|
||||
if err := ensureNotInPath(home, pathentry); nil != err {
|
||||
return "", "", err
|
||||
if index, ok := isInPath(home, pathentry); ok {
|
||||
return "", "", fmt.Errorf(
|
||||
"%q is in your PATH at position %d and must be removed manually to re-order\n",
|
||||
pathentry,
|
||||
index,
|
||||
)
|
||||
}
|
||||
|
||||
// ex: 100-opt»foo»bin.sh
|
||||
|
@ -189,12 +182,76 @@ func addPath(oldpathentry string, order setOrder) (string, string, error) {
|
|||
return pathentry, fullname, nil
|
||||
}
|
||||
|
||||
// TODO don't check in parser before add/append functions actually run
|
||||
func ensureNotInPath(home, pathentry string) error {
|
||||
paths, err := Paths()
|
||||
func removePath(oldpathentry string) (string, error) {
|
||||
home, err := os.UserHomeDir()
|
||||
if nil != err {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
home = filepath.ToSlash(home)
|
||||
|
||||
pathentry, fname, err := normalizeEntryAndFile(home, oldpathentry)
|
||||
if nil != err {
|
||||
return "", err
|
||||
}
|
||||
|
||||
envpathd := filepath.Join(home, ".config/envpath/path.d")
|
||||
err = os.MkdirAll(envpathd, 0755)
|
||||
if nil != err {
|
||||
return "", err
|
||||
}
|
||||
|
||||
nodes, err := ioutil.ReadDir(envpathd)
|
||||
if nil != err {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var fullname string
|
||||
for i := range nodes {
|
||||
node := nodes[i]
|
||||
// 000-foo-bin.sh vs foo-bin.sh
|
||||
if strings.HasSuffix(node.Name(), "-"+fname) {
|
||||
if len(strings.Split(node.Name(), "-"))-1 == len(strings.Split(fname, "-")) {
|
||||
fullname = node.Name()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
paths := Paths()
|
||||
index, exists := isInPath(home, pathentry)
|
||||
|
||||
if "" == fullname {
|
||||
if exists {
|
||||
return "", fmt.Errorf("%q is in your PATH, but is NOT managed by envpath", pathentry)
|
||||
}
|
||||
return "", fmt.Errorf("%q is NOT in your PATH, and NOT managed by envpath", pathentry)
|
||||
}
|
||||
|
||||
err = os.Remove(filepath.Join(envpathd, fullname))
|
||||
if nil != err {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if !exists {
|
||||
return fmt.Sprintf("Removed %s", filepath.Join(envpathd, fullname)), nil
|
||||
}
|
||||
|
||||
newpaths := []string{}
|
||||
for i := range paths {
|
||||
if i == index {
|
||||
continue
|
||||
}
|
||||
newpaths = append(newpaths, paths[i])
|
||||
}
|
||||
return fmt.Sprintf(
|
||||
"Removed %s. To update the current shell re-export the new PATH:\n\n"+
|
||||
"\texport PATH=%q\n",
|
||||
fullname,
|
||||
strings.Join(newpaths, ":"),
|
||||
), nil
|
||||
}
|
||||
|
||||
func isInPath(home, pathentry string) (int, bool) {
|
||||
paths := Paths()
|
||||
|
||||
index := -1
|
||||
for i := range paths {
|
||||
|
@ -205,15 +262,9 @@ func ensureNotInPath(home, pathentry string) error {
|
|||
}
|
||||
}
|
||||
if index >= 0 {
|
||||
fmt.Fprintf(
|
||||
os.Stderr,
|
||||
"%q is in your PATH at position %d and must be removed manually to re-order\n",
|
||||
pathentry,
|
||||
index,
|
||||
)
|
||||
os.Exit(3)
|
||||
return index, true
|
||||
}
|
||||
return nil
|
||||
return -1, false
|
||||
}
|
||||
|
||||
func normalizeEntryAndFile(home, pathentry string) (string, string, error) {
|
||||
|
@ -321,59 +372,3 @@ func getOrder(nodes []os.FileInfo, pathentry, fname, envpathd string, fn sorter)
|
|||
|
||||
return priority, nil
|
||||
}
|
||||
|
||||
func removePath(oldpathentry string) (string, error) {
|
||||
// TODO Show current PATH sans this item
|
||||
/*
|
||||
oldpaths := paths
|
||||
paths = []string{}
|
||||
for i := range oldpaths {
|
||||
if i != index {
|
||||
paths = append(paths, oldpaths[i])
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
home, err := os.UserHomeDir()
|
||||
if nil != err {
|
||||
return "", err
|
||||
}
|
||||
home = filepath.ToSlash(home)
|
||||
|
||||
pathentry, fname, err := normalizeEntryAndFile(home, oldpathentry)
|
||||
if nil != err {
|
||||
return "", err
|
||||
}
|
||||
|
||||
envpathd := filepath.Join(home, ".config/envpath/path.d")
|
||||
err = os.MkdirAll(envpathd, 0755)
|
||||
if nil != err {
|
||||
return "", err
|
||||
}
|
||||
|
||||
/*
|
||||
err = ensureNotInPath(home, pathentry)
|
||||
if nil != err {
|
||||
return "", err
|
||||
}
|
||||
*/
|
||||
|
||||
nodes, err := ioutil.ReadDir(envpathd)
|
||||
if nil != err {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// TODO rename getOrder to getNext
|
||||
_, err = getOrder(nodes, pathentry, fname, envpathd, sortForward)
|
||||
if nil == err {
|
||||
fmt.Fprintf(os.Stderr, "%q is not managed by envpath.\n", pathentry)
|
||||
}
|
||||
|
||||
/*
|
||||
if index < 0 {
|
||||
fmt.Fprintf(os.Stderr, "%q is NOT in PATH.\n", pathentry)
|
||||
os.Exit(3)
|
||||
}
|
||||
*/
|
||||
return "", nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue