mirror of
				https://github.com/therootcompany/pathman.git
				synced 2024-11-16 17:09:01 +00:00 
			
		
		
		
	Compare commits
	
		
			15 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2c283a2864 | |||
| 472d7bda0f | |||
| 12f8b86bbe | |||
| ca0a7fecb8 | |||
| 5f6e47244e | |||
| 74f81f519c | |||
| db19301520 | |||
| 571d639092 | |||
| 1ef3680b72 | |||
| 520c4a3b22 | |||
| c067c820cd | |||
| 3478e86919 | |||
| fcc35e88f6 | |||
| aa3bc63d25 | |||
| 964972846a | 
							
								
								
									
										158
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										158
									
								
								README.md
									
									
									
									
									
								
							| @ -1,126 +1,106 @@ | |||||||
| # [pathman](https://git.rootprojects.org/root/pathman) | # [pathman](https://git.rootprojects.org/root/pathman) | ||||||
| 
 | 
 | ||||||
| Manage PATH on Windows, Mac, and Linux with various Shells | Manage PATH on **Windows 10**, **Mac**, and **Linux** with various Shells | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
| pathman list | pathman list | ||||||
| pathman add ~/.local/bin | pathman add ~/.local/bin | ||||||
| pathman remove ~/.local/bin | pathman remove ~/.local/bin | ||||||
|  | pathman version | ||||||
|  | pathman help | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| Windows: stores PATH in the registry. | Where is the PATH managed? | ||||||
| 
 | 
 | ||||||
| Mac & Linux: stores PATH in `~/.config/envman/PATH.sh` | -   **Windows 10**: stores `PATH` in the registry. | ||||||
|  | -   **Mac** & **Linux**: stores `PATH` in `~/.config/envman/PATH.env` | ||||||
| 
 | 
 | ||||||
| ## Downloads | Note for **Windows 10** users: due to differences in how `cmd.exe`, PowerShell, and `pathman` use and interpret strings, spaces, paths, and variables, you'll get more consistent results if you: | ||||||
| 
 | 
 | ||||||
| ### MacOS | -   Use `~` rather than `%USERPROFILE%` or `$Env:USERPROFILE` | ||||||
|  | -   Use `/` rather than `\` for delimiting paths | ||||||
| 
 | 
 | ||||||
| MacOS (darwin): [64-bit Download ](https://rootprojects.org/pathman/dist/darwin/amd64/pathman) | ## Install | ||||||
| 
 | 
 | ||||||
| ``` | **Mac**, **Linux**: | ||||||
| curl https://rootprojects.org/pathman/dist/darwin/amd64/pathman -o pathman | 
 | ||||||
|  | ```bash | ||||||
|  | curl -s https://webinstall.dev/pathman | bash | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ### Windows | **Windows 10**: | ||||||
| 
 | 
 | ||||||
| <details> | This can be run from `cmd.exe` or PowerShell (`curl.exe` is a native part of Windows 10). | ||||||
| <summary>See download options</summary> |  | ||||||
| Windows 10: [64-bit Download](https://rootprojects.org/pathman/dist/windows/amd64/pathman.exe) |  | ||||||
| 
 | 
 | ||||||
| ``` | ```bash | ||||||
| powershell.exe $ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest https://rootprojects.org/pathman/dist/windows/amd64/pathman.exe -OutFile pathman.exe | curl.exe -sA "MS" https://webinstall.dev/pathman | powershell | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| **Debug version**: | ### Manual Install | ||||||
| 
 | 
 | ||||||
| ``` | 1. [Download](#downloads) | ||||||
| powershell.exe $ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest https://rootprojects.org/pathman/dist/windows/amd64/pathman.debug.exe -OutFile pathman.debug.exe | 2. Add to `PATH` | ||||||
|  | 
 | ||||||
|  | Or install via `npm`: | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | npm install -g pathman | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| Windows 7: [32-bit Download](https://rootprojects.org/pathman/dist/windows/386/pathman.exe) | #### Windows | ||||||
| 
 | 
 | ||||||
| ``` | ```cmd | ||||||
| powershell.exe "(New-Object Net.WebClient).DownloadFile('https://rootprojects.org/pathman/dist/windows/386/pathman.exe', 'pathman.exe')" |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| **Debug version**: |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| powershell.exe "(New-Object Net.WebClient).DownloadFile('https://rootprojects.org/pathman/dist/windows/386/pathman.debug.exe', 'pathman.debug.exe')" |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| </details> |  | ||||||
| 
 |  | ||||||
| ### Linux |  | ||||||
| 
 |  | ||||||
| <details> |  | ||||||
| <summary>See download options</summary> |  | ||||||
| 
 |  | ||||||
| Linux (64-bit): [Download](https://rootprojects.org/pathman/dist/linux/amd64/pathman) |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| curl https://rootprojects.org/pathman/dist/linux/amd64/pathman -o pathman |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| Linux (32-bit): [Download](https://rootprojects.org/pathman/dist/linux/386/pathman) |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| curl https://rootprojects.org/pathman/dist/linux/386/pathman -o pathman |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| </details> |  | ||||||
| 
 |  | ||||||
| ### Raspberry Pi (Linux ARM) |  | ||||||
| 
 |  | ||||||
| <details> |  | ||||||
| <summary>See download options</summary> |  | ||||||
| 
 |  | ||||||
| RPi 4 (64-bit armv8): [Download](https://rootprojects.org/pathman/dist/linux/armv8/pathman) |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| curl https://rootprojects.org/pathman/dist/linux/armv8/pathman -o pathman` |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| RPi 3 (armv7): [Download](https://rootprojects.org/pathman/dist/linux/armv7/pathman) |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| curl https://rootprojects.org/pathman/dist/linux/armv7/pathman -o pathman |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ARMv6: [Download](https://rootprojects.org/pathman/dist/linux/armv6/pathman) |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| curl https://rootprojects.org/pathman/dist/linux/armv6/pathman -o pathman |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| RPi Zero (armv5): [Download](https://rootprojects.org/pathman/dist/linux/armv5/pathman) |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| curl https://rootprojects.org/pathman/dist/linux/armv5/pathman -o pathman |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| </details> |  | ||||||
| 
 |  | ||||||
| ### Add to PATH |  | ||||||
| 
 |  | ||||||
| **Windows** |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| mkdir %userprofile%\bin | mkdir %userprofile%\bin | ||||||
| move pathman.exe %userprofile%\bin\pathman.exe | move pathman.exe %userprofile%\bin\pathman.exe | ||||||
| %userprofile%\bin\pathman.exe ~\bin | %userprofile%\bin\pathman.exe add ~/bin | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| **All Others** | #### Mac, Linux, etc | ||||||
| 
 | 
 | ||||||
| ``` | ```bash | ||||||
| chmod a+x ./pathman |  | ||||||
| mkdir -p ~/.local/bin | mkdir -p ~/.local/bin | ||||||
| mv ./pathman ~/.local/bin | mv ./pathman ~/.local/bin | ||||||
| pathman add ~/.local/bin | pathman add ~/.local/bin | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | ## Downloads | ||||||
|  | 
 | ||||||
|  | [Webi](https://webinstall.dev/pathman) (<https://webinstall.dev/pathman>) is the preferred install method, | ||||||
|  | but you can also download from [Git Releases](https://git.rootprojects.org/root/pathman/releases): | ||||||
|  | <https://git.rootprojects.org/root/pathman/releases>. | ||||||
|  | 
 | ||||||
|  | MacOS (including Apple Silicon M1), Linux, Raspberry Pi: | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | tar xvf pathman-v*.tar.gz | ||||||
|  | chmod a+x ./pathman | ||||||
|  | ./pathman --help | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Windows 10: | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | tar.exe xvf pathman-v*.zip | ||||||
|  | .\pathman.exe --help | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Supported Platforms | ||||||
|  | 
 | ||||||
|  | -   MacOS | ||||||
|  |     -   Apple Silicon M1 | ||||||
|  |     -   Intel x86_64 | ||||||
|  | -   Windows 10, 8, 7 | ||||||
|  | -   Linux | ||||||
|  |     -   amd64 / x86_64 | ||||||
|  |     -   386 | ||||||
|  | -   Raspberry Pi (Linux ARM) | ||||||
|  |     -   RPi 4 (64-bit armv8) | ||||||
|  |     -   RPi 3 (armv7) | ||||||
|  |     -   ARMv6 | ||||||
|  |     -   RPi Zero (armv5) | ||||||
|  | 
 | ||||||
|  | # CLI Help (API) | ||||||
|  | 
 | ||||||
| # add | # add | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
|  | |||||||
| @ -14,10 +14,9 @@ echo "" | |||||||
| echo "Windows amd64" | echo "Windows amd64" | ||||||
| #GOOS=windows GOARCH=amd64 go build -mod=vendor -o dist/windows/amd64/${exe}.exe -ldflags "-s -w -H=windowsgui" $gocmd | #GOOS=windows GOARCH=amd64 go build -mod=vendor -o dist/windows/amd64/${exe}.exe -ldflags "-s -w -H=windowsgui" $gocmd | ||||||
| GOOS=windows GOARCH=amd64 go build -mod=vendor -o dist/windows/amd64/${exe}.exe -ldflags "-s -w" $gocmd | GOOS=windows GOARCH=amd64 go build -mod=vendor -o dist/windows/amd64/${exe}.exe -ldflags "-s -w" $gocmd | ||||||
| GOOS=windows GOARCH=amd64 go build -mod=vendor -o dist/windows/amd64/${exe}.debug.exe | #GOOS=windows GOARCH=amd64 go build -mod=vendor -o dist/windows/amd64/${exe}.debug.exe | ||||||
| echo "Windows 386" | echo "Windows 386" | ||||||
| GOOS=windows GOARCH=386 go build -mod=vendor -o dist/windows/386/${exe}.exe -ldflags "-s -w" $gocmd | GOOS=windows GOARCH=386 go build -mod=vendor -o dist/windows/386/${exe}.exe -ldflags "-s -w" $gocmd | ||||||
| GOOS=windows GOARCH=386 go build -mod=vendor -o dist/windows/386/${exe}.debug.exe |  | ||||||
| 
 | 
 | ||||||
| echo "" | echo "" | ||||||
| echo "Darwin (macOS) amd64" | echo "Darwin (macOS) amd64" | ||||||
|  | |||||||
| @ -69,10 +69,11 @@ func initializeShells(home string) error { | |||||||
| 
 | 
 | ||||||
| 	var hasRC bool | 	var hasRC bool | ||||||
| 	var nativeMatch *envConfig | 	var nativeMatch *envConfig | ||||||
|  | 	shell := strings.TrimSuffix(filepath.Base(os.Getenv("SHELL")), ".exe") | ||||||
| 	for i := range confs { | 	for i := range confs { | ||||||
| 		c := confs[i] | 		c := confs[i] | ||||||
| 
 | 
 | ||||||
| 		if filepath.Base(os.Getenv("SHELL")) == c.shell { | 		if shell == c.shell { | ||||||
| 			nativeMatch = c | 			nativeMatch = c | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @ -103,7 +104,7 @@ func initializeShells(home string) error { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// MacOS is special. It *requires* .bash_profile in order to read .bashrc | 	// MacOS is special. It *requires* .bash_profile in order to read .bashrc | ||||||
| 	if "darwin" == runtime.GOOS && "bash" == os.Getenv("SHELL") { | 	if "darwin" == runtime.GOOS && "bash" == shell { | ||||||
| 		if err := ensureBashProfile(home); nil != err { | 		if err := ensureBashProfile(home); nil != err { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								npm/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								npm/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | node_modules | ||||||
							
								
								
									
										41
									
								
								npm/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								npm/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | |||||||
|  | # pathman | ||||||
|  | 
 | ||||||
|  | A cross-platform PATH manager | ||||||
|  | 
 | ||||||
|  | Manage PATH on Windows, Mac, and Linux with various Shells | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | pathman list | ||||||
|  | pathman add ~/.local/bin | ||||||
|  | pathman remove ~/.local/bin | ||||||
|  | pathman version | ||||||
|  | pathman help | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Windows: stores PATH in the registry. | ||||||
|  | 
 | ||||||
|  | Mac & Linux: stores PATH in `~/.config/envman/PATH.sh` | ||||||
|  | 
 | ||||||
|  | ## Meta Package | ||||||
|  | 
 | ||||||
|  | This is a meta-package to fetch and install the correction version of | ||||||
|  | [go-pathman](https://git.rootprojects.org/root/pathman) | ||||||
|  | for your architecture and platform. | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | npm install -g @root/pathman | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | # Supported Shells | ||||||
|  | 
 | ||||||
|  | In theory, anything with bourne-compatible exports. Specifically: | ||||||
|  | 
 | ||||||
|  | -   bash | ||||||
|  | -   zsh | ||||||
|  | -   fish | ||||||
|  | 
 | ||||||
|  | On Windows, all shells inherit from the registry. | ||||||
|  | 
 | ||||||
|  | -   cmd.exe | ||||||
|  | -   PowerShell | ||||||
|  | -   Git Bash | ||||||
							
								
								
									
										1
									
								
								npm/bin/pathman
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								npm/bin/pathman
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | # this will be replaced by the postinstall script | ||||||
							
								
								
									
										12
									
								
								npm/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								npm/index.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var spawner = require('./lib/exec.js'); | ||||||
|  | module.exports = spawner; | ||||||
|  | module.exports.install = require('./lib/install.js'); | ||||||
|  | 
 | ||||||
|  | if (require.main === module) { | ||||||
|  | 	// node index.js --foo bar => [ '--foo', 'bar' ]
 | ||||||
|  | 	spawner(process.argv.slice(2)).catch(function(err) { | ||||||
|  | 		console.error(err.message); | ||||||
|  | 	}); | ||||||
|  | } | ||||||
							
								
								
									
										36
									
								
								npm/lib/exec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								npm/lib/exec.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var pkg = require('../package.json'); | ||||||
|  | var spawn = require('child_process').spawn; | ||||||
|  | var os = require('os'); | ||||||
|  | var path = require('path'); | ||||||
|  | var ext = /^win/i.test(os.platform()) ? '.exe' : ''; | ||||||
|  | 
 | ||||||
|  | // @scope/packagename => packagename
 | ||||||
|  | // { bin: { "packagename": "bin/runner" } } => "bin/runner"
 | ||||||
|  | var bin = path.resolve(__dirname, '..', pkg.bin[pkg.name.replace(/.*\//, '')]); | ||||||
|  | 
 | ||||||
|  | function spawner(args) { | ||||||
|  | 	return new Promise(function(resolve, reject) { | ||||||
|  | 		var runner = spawn(path.join(bin + ext), args, { | ||||||
|  | 			windowsHide: true | ||||||
|  | 		}); | ||||||
|  | 		runner.stdout.on('data', function(chunk) { | ||||||
|  | 			console.info(chunk.toString('utf8')); | ||||||
|  | 		}); | ||||||
|  | 		runner.stderr.on('data', function(chunk) { | ||||||
|  | 			console.error(chunk.toString('utf8')); | ||||||
|  | 		}); | ||||||
|  | 		runner.on('exit', function(code) { | ||||||
|  | 			if (0 !== code) { | ||||||
|  | 				reject( | ||||||
|  | 					new Error("exited with non-zero status code '" + code + "'") | ||||||
|  | 				); | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  | 			resolve({ code: code }); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | module.exports = spawner; | ||||||
							
								
								
									
										219
									
								
								npm/lib/install.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										219
									
								
								npm/lib/install.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,219 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var pkg = require('../package.json'); | ||||||
|  | var path = require('path'); | ||||||
|  | var os = require('os'); | ||||||
|  | 
 | ||||||
|  | // https://nodejs.org/api/os.html#os_os_arch
 | ||||||
|  | // 'arm', 'arm64', 'ia32', 'mips', 'mipsel', 'ppc', 'ppc64', 's390', 's390x', 'x32', and 'x64'
 | ||||||
|  | var arch = os.arch(); // process.arch
 | ||||||
|  | 
 | ||||||
|  | // https://nodejs.org/api/os.html#os_os_platform
 | ||||||
|  | // 'aix', 'darwin', 'freebsd', 'linux', 'openbsd', 'sunos', 'win32'
 | ||||||
|  | var platform = os.platform(); // process.platform
 | ||||||
|  | var ext = /^win/i.test(platform) ? '.exe' : ''; | ||||||
|  | 
 | ||||||
|  | // This is _probably_ right. It's good enough for us
 | ||||||
|  | // https://github.com/nodejs/node/issues/13629
 | ||||||
|  | if ('arm' === arch) { | ||||||
|  | 	arch += 'v' + process.config.variables.arm_version; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var map = { | ||||||
|  | 	// arches
 | ||||||
|  | 	armv6: 'armv6', | ||||||
|  | 	armv7: 'armv7', | ||||||
|  | 	arm64: 'armv8', | ||||||
|  | 	ia32: '386', | ||||||
|  | 	x32: '386', | ||||||
|  | 	x64: 'amd64', | ||||||
|  | 	// platforms
 | ||||||
|  | 	darwin: 'darwin', | ||||||
|  | 	linux: 'linux', | ||||||
|  | 	win32: 'windows' | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | arch = map[arch]; | ||||||
|  | platform = map[platform]; | ||||||
|  | 
 | ||||||
|  | var pkg = require('../package.json'); | ||||||
|  | var newVer = pkg.version; | ||||||
|  | var fs = require('fs'); | ||||||
|  | var request = require('@root/request'); | ||||||
|  | var mkdirp = require('@root/mkdirp'); | ||||||
|  | 
 | ||||||
|  | function install(name, bindirs, getVersion, parseVersion, urlTpl) { | ||||||
|  | 	if (!arch || !platform) { | ||||||
|  | 		console.error( | ||||||
|  | 			"'" + | ||||||
|  | 				os.platform() + | ||||||
|  | 				"' on '" + | ||||||
|  | 				os.arch() + | ||||||
|  | 				"' isn't supported yet." | ||||||
|  | 		); | ||||||
|  | 		console.error( | ||||||
|  | 			'Please open an issue at https://git.rootprojects.org/root/pathman/issues' | ||||||
|  | 		); | ||||||
|  | 		process.exit(1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var url = urlTpl | ||||||
|  | 		.replace(/{{ .Version }}/g, newVer) | ||||||
|  | 		.replace(/{{ .Platform }}/g, platform) | ||||||
|  | 		.replace(/{{ .Arch }}/g, arch) | ||||||
|  | 		.replace(/{{ .Ext }}/g, ext); | ||||||
|  | 
 | ||||||
|  | 	console.info('Installing from', url); | ||||||
|  | 	return request({ uri: url, encoding: null }, function(err, resp) { | ||||||
|  | 		if (err) { | ||||||
|  | 			console.error(err); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		//console.log(resp.body.byteLength);
 | ||||||
|  | 		//console.log(typeof resp.body);
 | ||||||
|  | 		var bin = name + ext; | ||||||
|  | 		function next() { | ||||||
|  | 			if (!bindirs.length) { | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  | 			var bindir = bindirs.pop(); | ||||||
|  | 			return mkdirp(bindir, function(err) { | ||||||
|  | 				if (err) { | ||||||
|  | 					console.error(err); | ||||||
|  | 					return; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				var localbin = path.join(bindir, bin); | ||||||
|  | 				return fs.writeFile(localbin, resp.body, function(err) { | ||||||
|  | 					next(); | ||||||
|  | 					if (err) { | ||||||
|  | 						console.error(err); | ||||||
|  | 						return; | ||||||
|  | 					} | ||||||
|  | 					fs.chmodSync(localbin, parseInt('0755', 8)); | ||||||
|  | 					console.info('Wrote', bin, 'to', bindir); | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 		} | ||||||
|  | 		next(); | ||||||
|  | 	}); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function shouldUpdate(oldVer, newVer) { | ||||||
|  | 	// "v1.0.0-pre" is BEHIND "v1.0.0"
 | ||||||
|  | 	newVer = newVer | ||||||
|  | 		.replace(/^v/, '') | ||||||
|  | 		.split(/[\.\-\+]/) | ||||||
|  | 		.filter(Boolean); | ||||||
|  | 	oldVer = oldVer | ||||||
|  | 		.replace(/^v/, '') | ||||||
|  | 		.split(/[\.\-\+]/) | ||||||
|  | 		.filter(Boolean); | ||||||
|  | 
 | ||||||
|  | 	if (!oldVer.length) { | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// ex: v1.0.0-pre vs v1.0.0
 | ||||||
|  | 	if (newVer[3] && !oldVer[3]) { | ||||||
|  | 		// don't install beta over stable
 | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// ex: old is v1.0.0-pre
 | ||||||
|  | 	if (oldVer[3]) { | ||||||
|  | 		if (oldVer[2] > 0) { | ||||||
|  | 			oldVer[2] -= 1; | ||||||
|  | 		} else if (oldVer[1] > 0) { | ||||||
|  | 			oldVer[2] = 999; | ||||||
|  | 			oldVer[1] -= 1; | ||||||
|  | 		} else if (oldVer[0] > 0) { | ||||||
|  | 			oldVer[2] = 999; | ||||||
|  | 			oldVer[1] = 999; | ||||||
|  | 			oldVer[0] -= 1; | ||||||
|  | 		} else { | ||||||
|  | 			// v0.0.0
 | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// ex: v1.0.1 vs v1.0.0-pre
 | ||||||
|  | 	if (newVer[3]) { | ||||||
|  | 		if (newVer[2] > 0) { | ||||||
|  | 			newVer[2] -= 1; | ||||||
|  | 		} else if (newVer[1] > 0) { | ||||||
|  | 			newVer[2] = 999; | ||||||
|  | 			newVer[1] -= 1; | ||||||
|  | 		} else if (newVer[0] > 0) { | ||||||
|  | 			newVer[2] = 999; | ||||||
|  | 			newVer[1] = 999; | ||||||
|  | 			newVer[0] -= 1; | ||||||
|  | 		} else { | ||||||
|  | 			// v0.0.0
 | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// ex: v1.0.1 vs v1.0.0
 | ||||||
|  | 	if (oldVer[0] > newVer[0]) { | ||||||
|  | 		return false; | ||||||
|  | 	} else if (oldVer[0] < newVer[0]) { | ||||||
|  | 		return true; | ||||||
|  | 	} else if (oldVer[1] > newVer[1]) { | ||||||
|  | 		return false; | ||||||
|  | 	} else if (oldVer[1] < newVer[1]) { | ||||||
|  | 		return true; | ||||||
|  | 	} else if (oldVer[2] > newVer[2]) { | ||||||
|  | 		return false; | ||||||
|  | 	} else if (oldVer[2] < newVer[2]) { | ||||||
|  | 		return true; | ||||||
|  | 	} else if (!oldVer[3] && newVer[3]) { | ||||||
|  | 		return false; | ||||||
|  | 	} else if (oldVer[3] && !newVer[3]) { | ||||||
|  | 		return true; | ||||||
|  | 	} else { | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  | // Same version
 | ||||||
|  | console.log(false === shouldUpdate('0.5.0', '0.5.0')); | ||||||
|  | // No previous version
 | ||||||
|  | console.log(true === shouldUpdate('', '0.5.1')); | ||||||
|  | // The new version is slightly newer
 | ||||||
|  | console.log(true === shouldUpdate('0.5.0', '0.5.1')); | ||||||
|  | console.log(true === shouldUpdate('0.4.999-pre1', '0.5.0-pre1')); | ||||||
|  | // The new version is slightly older
 | ||||||
|  | console.log(false === shouldUpdate('0.5.0', '0.5.0-pre1')); | ||||||
|  | console.log(false === shouldUpdate('0.5.1', '0.5.0')); | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | function checkVersion(getVersion, parseVersion) { | ||||||
|  | 	var exec = require('child_process').exec; | ||||||
|  | 
 | ||||||
|  | 	return new Promise(function(resolve) { | ||||||
|  | 		exec(getVersion, { windowsHide: true }, function(err, stdout) { | ||||||
|  | 			var oldVer = parseVersion(stdout); | ||||||
|  | 			resolve(oldVer); | ||||||
|  | 			/* | ||||||
|  | 			//console.log('old:', oldVer, 'new:', newVer);
 | ||||||
|  | 			if (!shouldUpdate(oldVer, newVer)) { | ||||||
|  | 				console.info( | ||||||
|  | 					'Current ' + name + ' version is new enough:', | ||||||
|  | 					oldVer, | ||||||
|  | 					newVer | ||||||
|  | 				); | ||||||
|  | 				return; | ||||||
|  | 				//} else {
 | ||||||
|  | 				//	console.info('Current version is older:', oldVer, newVer);
 | ||||||
|  | 			} | ||||||
|  |       */ | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | module.exports = install; | ||||||
|  | module.exports._shouldUpdate = shouldUpdate; | ||||||
|  | module.exports._checkVersion = checkVersion; | ||||||
							
								
								
									
										18
									
								
								npm/package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								npm/package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | { | ||||||
|  | 	"name": "@root/pathman", | ||||||
|  | 	"version": "0.5.2-alpha.5", | ||||||
|  | 	"lockfileVersion": 1, | ||||||
|  | 	"requires": true, | ||||||
|  | 	"dependencies": { | ||||||
|  | 		"@root/mkdirp": { | ||||||
|  | 			"version": "1.0.0", | ||||||
|  | 			"resolved": "https://registry.npmjs.org/@root/mkdirp/-/mkdirp-1.0.0.tgz", | ||||||
|  | 			"integrity": "sha512-hxGAYUx5029VggfG+U9naAhQkoMSXtOeXtbql97m3Hi6/sQSRL/4khKZPyOF6w11glyCOU38WCNLu9nUcSjOfA==" | ||||||
|  | 		}, | ||||||
|  | 		"@root/request": { | ||||||
|  | 			"version": "1.3.11", | ||||||
|  | 			"resolved": "https://registry.npmjs.org/@root/request/-/request-1.3.11.tgz", | ||||||
|  | 			"integrity": "sha512-3a4Eeghcjsfe6zh7EJ+ni1l8OK9Fz2wL1OjP4UCa0YdvtH39kdXB9RGWuzyNv7dZi0+Ffkc83KfH0WbPMiuJFw==" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										40
									
								
								npm/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								npm/package.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | |||||||
|  | { | ||||||
|  | 	"name": "@root/pathman", | ||||||
|  | 	"version": "0.5.3-pre.3", | ||||||
|  | 	"description": "A cross-platform PATH manager", | ||||||
|  | 	"main": "index.js", | ||||||
|  | 	"homepage": "https://git.rootprojects.org/root/pathman/src/branch/master/npm", | ||||||
|  | 	"files": [ | ||||||
|  | 		"bin/", | ||||||
|  | 		"lib/", | ||||||
|  | 		"scripts/" | ||||||
|  | 	], | ||||||
|  | 	"bin": { | ||||||
|  | 		"pathman": "bin/pathman" | ||||||
|  | 	}, | ||||||
|  | 	"scripts": { | ||||||
|  | 		"pathman": "pathman", | ||||||
|  | 		"postinstall": "node scripts/fetch-prebuilt.js", | ||||||
|  | 		"test": "echo \"Error: no test specified\" && exit 1" | ||||||
|  | 	}, | ||||||
|  | 	"repository": { | ||||||
|  | 		"type": "git", | ||||||
|  | 		"url": "https://git.rootprojects.org/root/pathman.git" | ||||||
|  | 	}, | ||||||
|  | 	"keywords": [ | ||||||
|  | 		"launchd", | ||||||
|  | 		"systemd", | ||||||
|  | 		"winsvc", | ||||||
|  | 		"launchctl", | ||||||
|  | 		"systemctl", | ||||||
|  | 		"HKEY_CURRENT_USER", | ||||||
|  | 		"HKCU", | ||||||
|  | 		"Run" | ||||||
|  | 	], | ||||||
|  | 	"author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)", | ||||||
|  | 	"license": "MPL-2.0", | ||||||
|  | 	"dependencies": { | ||||||
|  | 		"@root/mkdirp": "^1.0.0", | ||||||
|  | 		"@root/request": "^1.3.11" | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										88
									
								
								npm/scripts/fetch-prebuilt.js
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										88
									
								
								npm/scripts/fetch-prebuilt.js
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,88 @@ | |||||||
|  | #!/usr/bin/env node
 | ||||||
|  | 
 | ||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var pkg = require('../package.json'); | ||||||
|  | var os = require('os'); | ||||||
|  | var path = require('path'); | ||||||
|  | var fs = require('fs'); | ||||||
|  | var manager = require('../index.js'); | ||||||
|  | 
 | ||||||
|  | if (require.main === module) { | ||||||
|  | 	run(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function run() { | ||||||
|  | 	var ext = /^win/i.test(os.platform()) ? '.exe' : ''; | ||||||
|  | 	//var homedir = require('os').homedir();
 | ||||||
|  | 	//var bindir = path.join(homedir, '.local', 'bin');
 | ||||||
|  | 	var bindir = path.resolve(__dirname, '..', 'bin'); | ||||||
|  | 	var name = pkg.name.replace(/.*\//, ''); | ||||||
|  | 	if ('.exe' === ext) { | ||||||
|  | 		winpmstall(pkg.name, name, bindir); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return manager.install( | ||||||
|  | 		name, | ||||||
|  | 		[bindir], | ||||||
|  | 		'pathman version', | ||||||
|  | 		function parseVersion(stdout) { | ||||||
|  | 			return (stdout || '').split(' ')[0]; | ||||||
|  | 		}, | ||||||
|  | 		'https://rootprojects.org/pathman/dist/{{ .Platform }}/{{ .Arch }}/pathman{{ .Ext }}' | ||||||
|  | 	); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function winpmstall(pkgname, name, bindir) { | ||||||
|  | 	var dd = /\//.test(pkgname) ? '../' : ''; | ||||||
|  | 	var pkgpath = pkgname.replace(/@/g, '\\@'); | ||||||
|  | 
 | ||||||
|  | 	try { | ||||||
|  | 		fs.writeFileSync( | ||||||
|  | 			path.join(bindir, name), | ||||||
|  | 			[ | ||||||
|  | 				'#!/usr/bin/env bash', | ||||||
|  | 				'"$(dirname "$0")/' + name + '.exe" "$@"', | ||||||
|  | 				'exit $?' | ||||||
|  | 			].join('\n') | ||||||
|  | 		); | ||||||
|  | 	} catch (e) { | ||||||
|  | 		// ignore
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// because bugs in npm + git bash oddities, of course
 | ||||||
|  | 	// https://npm.community/t/globally-installed-package-does-not-execute-in-git-bash-on-windows/9394
 | ||||||
|  | 	try { | ||||||
|  | 		fs.writeFileSync( | ||||||
|  | 			path.join(__dirname, dd + '../../.bin', name), | ||||||
|  | 			[ | ||||||
|  | 				'#!/bin/sh', | ||||||
|  | 				'# manual bugfix patch for npm on windows', | ||||||
|  | 				'basedir=$(dirname "$(echo "$0" | sed -e \'s,\\\\,/,g\')")', | ||||||
|  | 				'"$basedir/../' + pkgpath + '/bin/' + name + '"   "$@"', | ||||||
|  | 				'exit $?' | ||||||
|  | 			].join('\n') | ||||||
|  | 		); | ||||||
|  | 	} catch (e) { | ||||||
|  | 		// ignore
 | ||||||
|  | 	} | ||||||
|  | 	try { | ||||||
|  | 		fs.writeFileSync( | ||||||
|  | 			path.join(__dirname, dd + '../../..', name), | ||||||
|  | 			[ | ||||||
|  | 				'#!/bin/sh', | ||||||
|  | 				'# manual bugfix patch for npm on windows', | ||||||
|  | 				'basedir=$(dirname "$(echo "$0" | sed -e \'s,\\\\,/,g\')")', | ||||||
|  | 				'"$basedir/node_modules/' + | ||||||
|  | 					pkgname + | ||||||
|  | 					'/bin/' + | ||||||
|  | 					name + | ||||||
|  | 					'"   "$@"', | ||||||
|  | 				'exit $?' | ||||||
|  | 			].join('\n') | ||||||
|  | 		); | ||||||
|  | 	} catch (e) { | ||||||
|  | 		// ignore
 | ||||||
|  | 	} | ||||||
|  | 	// end bugfix
 | ||||||
|  | } | ||||||
							
								
								
									
										68
									
								
								pathman.go
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								pathman.go
									
									
									
									
									
								
							| @ -46,36 +46,10 @@ func main() { | |||||||
| 		entry = os.Args[2] | 		entry = os.Args[2] | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// https://superuser.com/a/69190/73857 |  | ||||||
| 	// https://github.com/rust-lang-nursery/rustup.rs/issues/686#issuecomment-253982841 |  | ||||||
| 	// exec source $HOME/.profile |  | ||||||
| 	shell := os.Getenv("SHELL") |  | ||||||
| 	shell = filepath.Base(shell) |  | ||||||
| 	switch shell { |  | ||||||
| 	case "": |  | ||||||
| 		if strings.HasSuffix(os.Getenv("COMSPEC"), "/cmd.exe") { |  | ||||||
| 			shell = "cmd" |  | ||||||
| 		} |  | ||||||
| 	case "fish": |  | ||||||
| 		// ignore |  | ||||||
| 	case "zsh": |  | ||||||
| 		// ignore |  | ||||||
| 	case "bash": |  | ||||||
| 		// ignore |  | ||||||
| 	default: |  | ||||||
| 		// warn and try anyway |  | ||||||
| 		fmt.Fprintf( |  | ||||||
| 			os.Stderr, |  | ||||||
| 			"%q isn't a recognized shell. Please open an issue at https://git.rootprojects.org/root/pathman/issues?q=%s", |  | ||||||
| 			shell, |  | ||||||
| 			shell, |  | ||||||
| 		) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	home, _ := os.UserHomeDir() | 	home, _ := os.UserHomeDir() | ||||||
| 	if "" != entry && '~' == entry[0] { | 	if "" != entry && '~' == entry[0] { | ||||||
| 		// Let windows users not to have to type %USERPROFILE% or \Users\me every time | 		// Let windows users not to have to type %USERPROFILE% or \Users\me every time | ||||||
| 		entry = strings.Replace(entry, "~", home, 0) | 		entry = strings.Replace(entry, "~", home, 1) | ||||||
| 	} | 	} | ||||||
| 	switch action { | 	switch action { | ||||||
| 	default: | 	default: | ||||||
| @ -92,8 +66,10 @@ func main() { | |||||||
| 		} | 		} | ||||||
| 		list() | 		list() | ||||||
| 	case "add": | 	case "add": | ||||||
|  | 		checkShell() | ||||||
| 		add(entry) | 		add(entry) | ||||||
| 	case "remove": | 	case "remove": | ||||||
|  | 		checkShell() | ||||||
| 		remove(entry) | 		remove(entry) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @ -157,7 +133,7 @@ func add(entry string) { | |||||||
| 
 | 
 | ||||||
| 	modified, err := addPath(entry) | 	modified, err := addPath(entry) | ||||||
| 	if nil != err { | 	if nil != err { | ||||||
| 		fmt.Fprintf(os.Stderr, "failed to add %q to PATH: %s", entry, err) | 		fmt.Fprintf(os.Stderr, "%sfailed to add %q to PATH: %s", pathstore, entry, err) | ||||||
| 		os.Exit(1) | 		os.Exit(1) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -223,6 +199,38 @@ func remove(entry string) { | |||||||
| 	fmt.Println(msg + "\n") | 	fmt.Println(msg + "\n") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // warns if this is an unknown / untested shell | ||||||
|  | func checkShell() { | ||||||
|  | 	// https://superuser.com/a/69190/73857 | ||||||
|  | 	// https://github.com/rust-lang-nursery/rustup.rs/issues/686#issuecomment-253982841 | ||||||
|  | 	// exec source $HOME/.profile | ||||||
|  | 	shellexe := filepath.Base(os.Getenv("SHELL")) | ||||||
|  | 	shell := strings.TrimSuffix(shellexe, ".exe") | ||||||
|  | 	switch shell { | ||||||
|  | 	case ".": | ||||||
|  | 		shell = "" | ||||||
|  | 		fallthrough | ||||||
|  | 	case "": | ||||||
|  | 		if strings.HasSuffix(os.Getenv("COMSPEC"), "\\cmd.exe") { | ||||||
|  | 			shell = "cmd" | ||||||
|  | 		} | ||||||
|  | 	case "fish": | ||||||
|  | 		// ignore | ||||||
|  | 	case "zsh": | ||||||
|  | 		// ignore | ||||||
|  | 	case "bash": | ||||||
|  | 		// ignore | ||||||
|  | 	default: | ||||||
|  | 		// warn and try anyway | ||||||
|  | 		fmt.Fprintf( | ||||||
|  | 			os.Stderr, | ||||||
|  | 			"%q isn't a recognized shell. Please open an issue at https://git.rootprojects.org/root/pathman/issues?q=%s\n", | ||||||
|  | 			shellexe, | ||||||
|  | 			shellexe, | ||||||
|  | 		) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Paths returns path entries in the current environment | // Paths returns path entries in the current environment | ||||||
| func Paths() []string { | func Paths() []string { | ||||||
| 	cur := os.Getenv("PATH") | 	cur := os.Getenv("PATH") | ||||||
| @ -242,7 +250,7 @@ func Paths() []string { | |||||||
| // path entry to the current shell session | // path entry to the current shell session | ||||||
| func Add(p string) string { | func Add(p string) string { | ||||||
| 	if isCmdExe() { | 	if isCmdExe() { | ||||||
| 		return fmt.Sprintf(`PATH %s;%PATH%`, p) | 		return fmt.Sprintf(`PATH %s;%%PATH%%`, strings.Replace(p, "%", "%%", -1)) | ||||||
| 	} | 	} | ||||||
| 	return fmt.Sprintf(`export PATH="%s:$PATH"`, p) | 	return fmt.Sprintf(`export PATH="%s:$PATH"`, p) | ||||||
| } | } | ||||||
| @ -257,5 +265,5 @@ func Remove(entries []string) string { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func isCmdExe() bool { | func isCmdExe() bool { | ||||||
| 	return "" == os.Getenv("SHELL") && strings.Contains(strings.ToLower(os.Getenv("COMSPEC")), "/cmd.exe") | 	return "" == os.Getenv("SHELL") && strings.HasSuffix(strings.ToLower(os.Getenv("COMSPEC")), "\\cmd.exe") | ||||||
| } | } | ||||||
|  | |||||||
| @ -6,6 +6,8 @@ import ( | |||||||
| 	"git.rootprojects.org/root/pathman/envpath" | 	"git.rootprojects.org/root/pathman/envpath" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | var pathstore = "" | ||||||
|  | 
 | ||||||
| func addPath(p string) (bool, error) { | func addPath(p string) (bool, error) { | ||||||
| 	return envpath.Add(p) | 	return envpath.Add(p) | ||||||
| } | } | ||||||
|  | |||||||
| @ -6,6 +6,8 @@ import ( | |||||||
| 	"git.rootprojects.org/root/pathman/winpath" | 	"git.rootprojects.org/root/pathman/winpath" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | var pathstore = "[winpath] " | ||||||
|  | 
 | ||||||
| func addPath(p string) (bool, error) { | func addPath(p string) (bool, error) { | ||||||
| 	return winpath.Add(p) | 	return winpath.Add(p) | ||||||
| } | } | ||||||
|  | |||||||
| @ -56,7 +56,7 @@ func NormalizePathEntry(pathentry string) (string, string) { | |||||||
| 	if strings.HasPrefix(strings.ToLower(absentry)+sep, strings.ToLower(home)+sep) { | 	if strings.HasPrefix(strings.ToLower(absentry)+sep, strings.ToLower(home)+sep) { | ||||||
| 		// %USERPROFILE% is allowed, but only for user PATH | 		// %USERPROFILE% is allowed, but only for user PATH | ||||||
| 		// https://superuser.com/a/442163/73857 | 		// https://superuser.com/a/442163/73857 | ||||||
| 		homeentry = `%USERPROFILE%` + pathentry[len(home):] | 		homeentry = `%USERPROFILE%` + absentry[len(home):] | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if absentry == pathentry { | 	if absentry == pathentry { | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| // +build windows,unsafe | // +build windows,!nounsafe | ||||||
| 
 | 
 | ||||||
| package winpath | package winpath | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -29,12 +29,6 @@ func add(p string) (bool, error) { | |||||||
| 		return false, nil | 		return false, nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	k, err := registry.OpenKey(registry.CURRENT_USER, `Environment`, registry.SET_VALUE) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return false, err |  | ||||||
| 	} |  | ||||||
| 	defer k.Close() |  | ||||||
| 
 |  | ||||||
| 	cur = append([]string{p}, cur...) | 	cur = append([]string{p}, cur...) | ||||||
| 	err = write(cur) | 	err = write(cur) | ||||||
| 	if nil != err { | 	if nil != err { | ||||||
| @ -63,7 +57,7 @@ func remove(p string) (bool, error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = write(cur) | 	err = write(newpaths) | ||||||
| 	if nil != err { | 	if nil != err { | ||||||
| 		return false, err | 		return false, err | ||||||
| 	} | 	} | ||||||
| @ -74,15 +68,15 @@ func remove(p string) (bool, error) { | |||||||
| func write(cur []string) error { | func write(cur []string) error { | ||||||
| 	// TODO --system to add to the system PATH rather than the user PATH | 	// TODO --system to add to the system PATH rather than the user PATH | ||||||
| 
 | 
 | ||||||
| 	k, err := registry.OpenKey(registry.CURRENT_USER, `Environment`, registry.QUERY_VALUE) | 	k, err := registry.OpenKey(registry.CURRENT_USER, `Environment`, registry.SET_VALUE) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return fmt.Errorf("Can't open HKCU Environment for writes: %s", err) | ||||||
| 	} | 	} | ||||||
| 	defer k.Close() | 	defer k.Close() | ||||||
| 
 | 
 | ||||||
| 	err = k.SetStringValue(`Path`, strings.Join(cur, string(os.PathListSeparator))) | 	err = k.SetStringValue(`Path`, strings.Join(cur, string(os.PathListSeparator))) | ||||||
| 	if nil != err { | 	if nil != err { | ||||||
| 		return err | 		return fmt.Errorf("Can't set HKCU Environment[Path]: %s", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = k.Close() | 	err = k.Close() | ||||||
| @ -104,7 +98,7 @@ func paths() ([]string, error) { | |||||||
| 	// TBH, it's a mess to do this on *nix systems. | 	// TBH, it's a mess to do this on *nix systems. | ||||||
| 	k, err := registry.OpenKey(registry.CURRENT_USER, `Environment`, registry.QUERY_VALUE) | 	k, err := registry.OpenKey(registry.CURRENT_USER, `Environment`, registry.QUERY_VALUE) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, fmt.Errorf("Can't open HKCU Environment for reads: %s", err) | ||||||
| 	} | 	} | ||||||
| 	defer k.Close() | 	defer k.Close() | ||||||
| 
 | 
 | ||||||
| @ -112,7 +106,7 @@ func paths() ([]string, error) { | |||||||
| 	// PATH, Path, path will all work. | 	// PATH, Path, path will all work. | ||||||
| 	s, _, err := k.GetStringValue("Path") | 	s, _, err := k.GetStringValue("Path") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, fmt.Errorf("Can't query HKCU Environment[Path]: %s", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// ";" on Windows | 	// ";" on Windows | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user