v symlink: use a .symlink/v.bat launcher to avoid global PATH polution
parent
7585483c69
commit
e79adc0ba1
|
@ -66,3 +66,4 @@ cachegrind.out.*
|
||||||
.DS_Store
|
.DS_Store
|
||||||
._*
|
._*
|
||||||
thumbs.db
|
thumbs.db
|
||||||
|
/.symlink/*
|
||||||
|
|
|
@ -2,17 +2,15 @@ import os
|
||||||
import v.pref
|
import v.pref
|
||||||
|
|
||||||
fn main(){
|
fn main(){
|
||||||
vexe := pref.vexe_path()
|
|
||||||
$if windows {
|
$if windows {
|
||||||
vdir := os.real_path(os.dir(vexe))
|
setup_symlink_on_windows()
|
||||||
res := os.system('setx /M PATH "$vdir;%PATH%"')
|
} $else {
|
||||||
if res == 0 {
|
setup_symlink_on_unix()
|
||||||
println('v has been prepended to the path')
|
|
||||||
exit(0)
|
|
||||||
}
|
}
|
||||||
exit(1)
|
|
||||||
}
|
}
|
||||||
//
|
|
||||||
|
fn setup_symlink_on_unix(){
|
||||||
|
vexe := pref.vexe_path()
|
||||||
mut link_path := '/usr/local/bin/v'
|
mut link_path := '/usr/local/bin/v'
|
||||||
mut ret := os.exec('ln -sf $vexe $link_path') or {
|
mut ret := os.exec('ln -sf $vexe $link_path') or {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -34,3 +32,58 @@ fn main(){
|
||||||
println('Failed to create symlink "$link_path". Try again with sudo.')
|
println('Failed to create symlink "$link_path". Try again with sudo.')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn setup_symlink_on_windows(){
|
||||||
|
vexe := pref.vexe_path()
|
||||||
|
// NB: Putting $vdir directly into PATH will also result in
|
||||||
|
// make.bat being global, which is NOT what we want.
|
||||||
|
//
|
||||||
|
// Instead, we create a small launcher v.bat, in a new local
|
||||||
|
// folder .symlink/ . That .symlink/ folder can then be put
|
||||||
|
// in PATH without poluting it with anything else - just a
|
||||||
|
// `v` command will be available, simillar to unix.
|
||||||
|
//
|
||||||
|
// Creating a real NTFS symlink to the real executable was also
|
||||||
|
// tried, but then os.real_path( os.executable() ) returns the
|
||||||
|
// path to the symlink, unfortunately, unlike on posix systems
|
||||||
|
// ¯\_(ツ)_/¯
|
||||||
|
vdir := os.real_path(os.dir(vexe))
|
||||||
|
vsymlinkdir := os.join_path(vdir, '.symlink')
|
||||||
|
vsymlinkbat := os.join_path(vsymlinkdir, 'v.bat')
|
||||||
|
os.rmdir_all(vsymlinkdir)
|
||||||
|
os.mkdir_all(vsymlinkdir)
|
||||||
|
os.write_file(vsymlinkbat, '$vexe %*')
|
||||||
|
if !os.exists( vsymlinkbat ) {
|
||||||
|
eprintln('Could not create $vsymlinkbat')
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
println('Created $vsymlinkbat .')
|
||||||
|
current_paths := os.getenv('PATH').split(';').map(it.trim('/\\'))
|
||||||
|
if vsymlinkdir in current_paths {
|
||||||
|
println('$vsymlinkdir is already on your PATH')
|
||||||
|
println('Try running `v version`')
|
||||||
|
exit(0)
|
||||||
|
}
|
||||||
|
// put vsymlinkdir first, prevent duplicates:
|
||||||
|
mut new_paths := [ vsymlinkdir ]
|
||||||
|
for p in current_paths {
|
||||||
|
if p !in new_paths {
|
||||||
|
new_paths << p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
change_path_cmd := 'setx /M PATH "' + new_paths.join(';') +'"'
|
||||||
|
println('Changing global PATH with:')
|
||||||
|
println(change_path_cmd)
|
||||||
|
res := os.system(change_path_cmd)
|
||||||
|
if res == 0 {
|
||||||
|
println('')
|
||||||
|
println('$vsymlinkdir has been prepended to PATH.')
|
||||||
|
println('Try running `v version`.')
|
||||||
|
exit(0)
|
||||||
|
} else {
|
||||||
|
println('Could not run `setx`, probably you are not an administrator.')
|
||||||
|
println('`v symlink` should be launched with admin privileges.')
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue