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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user