add remove
This commit is contained in:
parent
a48617eaa8
commit
0a5f44eca7
@ -3,12 +3,10 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/rand"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ppsep is used as the replacement for slashes in path
|
// ppsep is used as the replacement for slashes in path
|
||||||
@ -25,7 +23,8 @@ import (
|
|||||||
const ppsep = "-"
|
const ppsep = "-"
|
||||||
|
|
||||||
func usage() {
|
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() {
|
func main() {
|
||||||
@ -38,11 +37,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
action := os.Args[1]
|
action := os.Args[1]
|
||||||
|
|
||||||
paths, err := Paths()
|
paths := Paths()
|
||||||
if nil != err {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
if "show" == action {
|
if "show" == action {
|
||||||
if len(os.Args) > 2 {
|
if len(os.Args) > 2 {
|
||||||
@ -79,16 +74,18 @@ func main() {
|
|||||||
default:
|
default:
|
||||||
usage()
|
usage()
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
case "append":
|
/*
|
||||||
newpath, _, err := addPath(pathentry, appendOrder)
|
case "append":
|
||||||
if nil != err {
|
newpath, _, err := addPath(pathentry, appendOrder)
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
if nil != err {
|
||||||
return
|
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("New sessions will have " + pathentry + " in their PATH.")
|
||||||
//fmt.Println("\tsource", pathfile)
|
fmt.Println("To update this session run\n")
|
||||||
fmt.Printf(`%sexport PATH="$PATH:%s"%s`, "\t", newpath, "\n")
|
//fmt.Println("\tsource", pathfile)
|
||||||
|
fmt.Printf(`%sexport PATH="$PATH:%s"%s`, "\t", newpath, "\n")
|
||||||
|
*/
|
||||||
case "add":
|
case "add":
|
||||||
_, pathfile, err := addPath(pathentry, prependOrder)
|
_, pathfile, err := addPath(pathentry, prependOrder)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
@ -99,27 +96,19 @@ func main() {
|
|||||||
fmt.Printf("\tsource %s\n\n", pathfile)
|
fmt.Printf("\tsource %s\n\n", pathfile)
|
||||||
//fmt.Printf(`%sexport PATH="%s:$PATH"%s`, "\t", newpath, "\n\n")
|
//fmt.Printf(`%sexport PATH="%s:$PATH"%s`, "\t", newpath, "\n\n")
|
||||||
case "remove":
|
case "remove":
|
||||||
_, err := removePath(pathentry)
|
msg, err := removePath(pathentry)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err)
|
fmt.Fprintf(os.Stderr, "%s\n", err)
|
||||||
return
|
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
|
// Paths returns the slice of PATHs from the Environment
|
||||||
func Paths() ([]string, error) {
|
func Paths() []string {
|
||||||
// ":" on *nix
|
// ":" on *nix
|
||||||
return strings.Split(os.Getenv("PATH"), string(os.PathListSeparator)), nil
|
return strings.Split(os.Getenv("PATH"), string(os.PathListSeparator))
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type setOrder bool
|
type setOrder bool
|
||||||
@ -168,8 +157,12 @@ func addPath(oldpathentry string, order setOrder) (string, string, error) {
|
|||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ensureNotInPath(home, pathentry); nil != err {
|
if index, ok := isInPath(home, pathentry); ok {
|
||||||
return "", "", err
|
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
|
// ex: 100-opt»foo»bin.sh
|
||||||
@ -189,12 +182,76 @@ func addPath(oldpathentry string, order setOrder) (string, string, error) {
|
|||||||
return pathentry, fullname, nil
|
return pathentry, fullname, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO don't check in parser before add/append functions actually run
|
func removePath(oldpathentry string) (string, error) {
|
||||||
func ensureNotInPath(home, pathentry string) error {
|
home, err := os.UserHomeDir()
|
||||||
paths, err := Paths()
|
|
||||||
if nil != err {
|
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
|
index := -1
|
||||||
for i := range paths {
|
for i := range paths {
|
||||||
@ -205,15 +262,9 @@ func ensureNotInPath(home, pathentry string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if index >= 0 {
|
if index >= 0 {
|
||||||
fmt.Fprintf(
|
return index, true
|
||||||
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 nil
|
return -1, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalizeEntryAndFile(home, pathentry string) (string, string, error) {
|
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
|
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…
x
Reference in New Issue
Block a user