Skip to content
This repository has been archived by the owner on Sep 1, 2022. It is now read-only.

Commit

Permalink
feat: add undo yvm effects on the shell commands (#400)
Browse files Browse the repository at this point in the history
* wip: placeholders for unuse and unload

* wip: get old and shim path internal commands

* wip: update tests

* test: new util path functions

* wip: fix get old and shim path commands

* wip: only echo shimming when manually called

* wip: remove yvm fish functions on unload

* wip: only echo deactivate when manually called

* wip: add bash commands to undo yvm

* docs: update api docs

* wip: unset regular PATH when in fish shell
  • Loading branch information
Emmanuel Ogbizi authored Jun 12, 2019
1 parent b67b638 commit 32a2ebc
Show file tree
Hide file tree
Showing 12 changed files with 340 additions and 82 deletions.
16 changes: 16 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ List the currently installed versions of Yarn.

List Yarn versions available to install.

## `deactivate`

Undo effects of `yvm` on current shell. This removes shimming and any used versions from the system path.

## `which [version]`

Display file path to a version of Yarn.
Expand All @@ -50,6 +54,18 @@ Show a list of registered version aliases. These can be used in place of `[versi

Register a new alias that can be used. Used internally to refer to `default`, `latest`, `stable` etc.

## `unalias <name>`

Deregisters an alias using the name specified.

### `--force|-F`

Removes an alias even while there are references to it from other aliases.

### `--recursive|-R`

Removes an alias, including all dependant aliases and their own dependants.

## `update-self`

Updates yvm to the latest version.
Expand Down
14 changes: 6 additions & 8 deletions src/commands/getNewPath.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@ import path from 'path'

import log from 'util/log'
import { versionRootPath } from 'util/utils'
import { getPathDelimiter, getPathEntries, yvmPath } from 'util/path'
import { getNonYvmVersionPathEntries, toPathString, yvmPath } from 'util/path'
import { getSplitVersionAndArgs } from 'util/version'
import { ensureVersionInstalled } from 'commands/install'

export const buildNewPath = ({ version, rootPath = yvmPath, shell }) => {
const pathDelimiter = getPathDelimiter(shell)
const destPath = versionRootPath(rootPath)
const newPathSegment = path.resolve(destPath, `v${version}`, 'bin')
const isNotYvmYarnPath = pathSegment => !pathSegment.startsWith(destPath)
const nonYvmPathEntries = getPathEntries(shell).filter(isNotYvmYarnPath)
const updatedPath = [newPathSegment, ...new Set(nonYvmPathEntries)]
return updatedPath.join(pathDelimiter).trim()
const updatedPath = [
path.resolve(versionRootPath(rootPath), `v${version}`, 'bin'),
...new Set(getNonYvmVersionPathEntries({ shell, rootPath })),
]
return toPathString({ shell, paths: updatedPath })
}

export const getNewPath = async (maybeVersion, shell) => {
Expand Down
16 changes: 16 additions & 0 deletions src/commands/getOldPath.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import log from 'util/log'
import { getNonYvmPathEntries, toPathString } from 'util/path'

export const buildOldPath = shell =>
toPathString({ shell, paths: [...new Set(getNonYvmPathEntries(shell))] })

export const getOldPath = async shell => {
try {
log.capturable(buildOldPath(shell))
return 0
} catch (e) {
log.error(e.message)
log.info(e.stack)
return 1
}
}
22 changes: 22 additions & 0 deletions src/commands/getShimPath.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import log from 'util/log'
import { shimRootPath } from 'util/utils'
import { getNonYvmShimPathEntries, toPathString, yvmPath } from 'util/path'

export const buildShimPath = shell => {
const updatedPath = [
shimRootPath(yvmPath),
...new Set(getNonYvmShimPathEntries(shell)),
]
return toPathString({ shell, paths: updatedPath })
}

export const getShimPath = async shell => {
try {
log.capturable(buildShimPath(shell))
return 0
} catch (e) {
log.error(e.message)
log.info(e.stack)
return 1
}
}
60 changes: 57 additions & 3 deletions src/shell/yvm.fish
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ set -q YVM_DIR; or set -gx YVM_DIR "$HOME/.yvm"
function yvm
set command $argv[1]

function yvm_set_fish_user_paths
set -gx PATH (yvm_call_node_script get-old-path)
set -gx fish_user_paths (string split ' ' -- $argv[1])
end

function yvm_use
if test (count $argv) -gt 0
set PROVIDED_VERSION $argv[1]
Expand All @@ -14,13 +19,54 @@ function yvm
end
if [ -z "$NEW_FISH_USER_PATHS" ]
yvm_err "Could not get new path from yvm"
exit 1
else
set -gx fish_user_paths (string split ' ' -- $NEW_FISH_USER_PATHS)
yvm_set_fish_user_paths $NEW_FISH_USER_PATHS
set -l new_version (yarn --version)
yvm_echo "Now using yarn version $new_version"
end
end

function yvm_shim
begin
set NEW_FISH_USER_PATHS (yvm_call_node_script get-shim-path --shell=fish)
end
if [ -z "$NEW_FISH_USER_PATHS" ]
yvm_err "Could not get shim path from yvm"
exit 1
else
yvm_set_fish_user_paths $NEW_FISH_USER_PATHS
end
end

function yvm_deactivate
begin
set NEW_FISH_USER_PATHS (yvm_call_node_script get-old-path --shell=fish)
end
if [ -z "$NEW_FISH_USER_PATHS" ]
yvm_err "Could not remove yvm from system path"
exit 1
else
yvm_set_fish_user_paths $NEW_FISH_USER_PATHS
end
end

function yvm_unload
yvm_deactivate
set -e YVM_DIR
functions -e yvm_set_fish_user_paths
functions -e yvm_use
functions -e yvm_shim
functions -e yvm_deactivate
functions -e yvm_unload
functions -e yvm_err
functions -e yvm_call_node_script
functions -e yvm_init_sh
functions -e yvm
yvm_echo "YVM configuration unloaded from shell"
functions -e yvm_echo
end

function yvm_echo
command printf "%s\n" $argv 2>/dev/null
end
Expand All @@ -40,7 +86,7 @@ function yvm
yvm_err "%s\n" "Please ensure your YVM env variables and sourcing are set below sourcing node/nvm in your fish config file"
exit 1
end
set -gx fish_user_paths "$YVM_DIR/shim" $fish_user_paths
yvm_shim
end

if [ "$command" = "use" ]
Expand All @@ -53,12 +99,20 @@ function yvm
env YVM_INSTALL_DIR=$YVM_DIR curl -fsSL https://raw.githubusercontent.com/tophat/yvm/master/scripts/install.js | node
else if [ "$command" = "init-sh" ]
yvm_init_sh
else if [ "$command" = "shim" ]
yvm_shim
yvm_echo "Now shimming yarn"
else if [ "$command" = "deactivate" ]
yvm_deactivate
yvm_echo "YVM shim and yarn versions removed from PATH"
else if [ "$command" = "unload" ]
yvm_unload
else
yvm_call_node_script $argv[1..-1]
end
end

if count $argv > /dev/null
if count $argv >/dev/null
yvm $argv
else
yvm init-sh
Expand Down
58 changes: 54 additions & 4 deletions src/shell/yvm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,64 @@ YVM_DIR=${YVM_DIR-"${HOME}/.yvm"}
yvm() {
command=$1

yvm_set_user_path() {
export PATH=${1}
}

yvm_use() {
local PROVIDED_VERSION=${1}
NEW_PATH=$(yvm_call_node_script get-new-path ${PROVIDED_VERSION})
if [ -z "${NEW_PATH}" ]; then
yvm_err "Could not get new path from yvm"
exit 1
else
PATH=${NEW_PATH}
yvm_set_user_path $NEW_PATH
yvm_echo "Now using yarn version $(yarn --version)"
fi
}

yvm_shim() {
NEW_PATH=$(yvm_call_node_script get-shim-path)
if [ -z "${NEW_PATH}" ]; then
yvm_err "Could not get shim path from yvm"
exit 1
else
yvm_set_user_path $NEW_PATH
fi
}

yvm_deactivate() {
NEW_PATH=$(yvm_call_node_script get-old-path)
if [ -z "${NEW_PATH}" ]; then
yvm_err "Could not remove yvm from system path"
exit 1
else
yvm_set_user_path $NEW_PATH
fi
}

yvm_unload() {
yvm_deactivate
unset YVM_DIR
unset -f yvm_set_user_path
unset -f yvm_use
unset -f yvm_shim
unset -f yvm_deactivate
unset -f yvm_unload
unset -f yvm_err
unset -f yvm_call_node_script
unset -f yvm_init_sh
unset -f yvm
yvm_echo "YVM configuration unloaded from shell"
unset -f yvm_echo
}

yvm_echo() {
command printf %s\\n "$*" 2>/dev/null
}

yvm_err() {
>&2 yvm_echo "$@"
yvm_echo >&2 "$@"
}

yvm_call_node_script() {
Expand All @@ -29,11 +70,12 @@ yvm() {
}

yvm_init_sh() {
if ! type "node" > /dev/null; then
if ! type "node" >/dev/null; then
yvm_err "YVM Could not find node executable."
yvm_err "Please ensure your YVM env variables and sourcing are set below sourcing node/nvm in your .zshrc or .bashrc"
exit 1
fi
export PATH="${YVM_DIR}/shim":$PATH
yvm_shim
}

if [ "${command}" = "use" ]; then
Expand All @@ -42,6 +84,14 @@ yvm() {
curl -fsSL https://raw.githubusercontent.com/tophat/yvm/master/scripts/install.js | YVM_INSTALL_DIR=${YVM_DIR} node
elif [ "${command}" = "init-sh" ]; then
yvm_init_sh
elif [ "${command}" = "shim" ]; then
yvm_shim
yvm_echo "Now shimming yarn"
elif [ "${command}" = "deactivate" ]; then
yvm_deactivate
yvm_echo "YVM shim and yarn versions removed from PATH"
elif [ "${command}" = "unload" ]; then
yvm_unload
else
yvm_call_node_script $@
fi
Expand Down
28 changes: 23 additions & 5 deletions src/util/path.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import os from 'os'
import path from 'path'
import fs from 'fs'
import { negate } from 'lodash'

import { shimRootPath, versionRootPath } from 'util/utils'

const isFishShell = shell => shell === 'fish'

Expand All @@ -11,24 +14,39 @@ export const getPathDelimiter = shell => {
return path.delimiter
}

export const toPathString = ({ shell, paths }) =>
paths.join(getPathDelimiter(shell)).trim()

export const getCurrentPath = shell => {
if (isFishShell(shell)) {
return process.env.fish_user_paths || ''
}
return process.env.PATH || ''
}

export const yvmPath = process.env.YVM_DIR || path.resolve(os.homedir(), '.yvm')

export const isYvmPath = p => p && p.startsWith(yvmPath)
const isYvmVersionPath = ({ p, rootPath = yvmPath }) =>
p.startsWith(versionRootPath(rootPath))
const isShimPath = p => p && p.endsWith(shimRootPath(yvmPath))

export const getPathEntries = shell =>
getCurrentPath(shell).split(getPathDelimiter(shell))

export const getNonYvmPathEntries = shell =>
getPathEntries(shell).filter(negate(isYvmPath))

export const getNonYvmVersionPathEntries = ({ shell, rootPath = yvmPath }) =>
getPathEntries(shell).filter(p => !isYvmVersionPath({ p, rootPath }))

export const getNonYvmShimPathEntries = shell =>
getPathEntries(shell).filter(negate(isShimPath))

export const getYarnPathEntries = shell =>
getPathEntries(shell)
.map(p => path.join(p, 'yarn'))
.filter(fs.existsSync)

export const yvmPath = process.env.YVM_DIR || path.resolve(os.homedir(), '.yvm')

export const isYvmPath = p => p && p.startsWith(yvmPath)

export const getNonYvmYarnPathEntries = shell =>
getYarnPathEntries(shell).filter(p => !isYvmPath(p))
getYarnPathEntries(shell).filter(negate(isYvmPath))
1 change: 1 addition & 0 deletions src/util/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from 'util/constants'
import log from 'util/log'

export const shimRootPath = rootPath => path.resolve(rootPath, 'shim')
export const versionRootPath = rootPath => path.resolve(rootPath, 'versions')

export const getExtractionPath = (version, rootPath) =>
Expand Down
Loading

0 comments on commit 32a2ebc

Please sign in to comment.