Skip to content

Instantly share code, notes, and snippets.

@spy16
Last active January 14, 2020 13:57
Show Gist options
  • Save spy16/52710929b5261c148b3bd3b3adf6e363 to your computer and use it in GitHub Desktop.
Save spy16/52710929b5261c148b3bd3b3adf6e363 to your computer and use it in GitHub Desktop.
Simple Virtual Environments Manager
#!/usr/bin/env python3
"""Virtual Environments Manager."""
import sys
import os
import subprocess
import shutil
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
# ========================== 'new' subcommand ==========================
new_command = subparsers.add_parser("new",
description="Create a new venv")
new_command.add_argument("name")
new_command.add_argument("-s", "--show-stdout", action="store_true")
new_command.add_argument("-p2", "--python2",
help="use python2 instead of python3",
action="store_true")
# ========================== 'list' subcommand ==========================
list_command = subparsers.add_parser("list")
# ========================= 'delete' subcommand =========================
delete_command = subparsers.add_parser("delete")
delete_command.add_argument("name")
commands = {}
COMMAND = "virtualenv {path} {options}"
app_dir = os.path.join(os.path.expanduser("~"), ".myenv")
env_dir = os.path.join(app_dir, "environments")
sym_dir = os.path.join(app_dir, "bins")
def cmd(name):
"""Command decorator."""
def decorator(f):
commands[name] = f
return f
return decorator
def main():
"""Run CLI."""
paths = os.getenv("PATH").split(":")
if sym_dir not in paths:
print("warning: add '{}' to PATH".format(sym_dir))
if not os.path.exists(env_dir):
os.makedirs(env_dir)
if not os.path.exists(sym_dir):
os.makedirs(sym_dir)
rest = sys.argv[1:]
if len(rest) == 0:
rest.append("--help")
cmd = rest[0]
args = parser.parse_args(rest)
kwargs = dict(args._get_kwargs())
commands[cmd](**kwargs)
def create_symlinks(name, path):
"""Create symlinks in bins directory."""
os.system("ln {}/bin/activate {}/my_{}".format(path, sym_dir, name))
@cmd("list")
def _list():
"""List My Environments."""
for env in os.listdir(env_dir):
print("=> {}".format(env))
@cmd("new")
def new_environment(name, python2, show_stdout):
"""Create new virtualenv with python3."""
path = os.path.join(env_dir, name)
if os.path.exists(path):
print("Err: environment with name '{}' already exists.".format(name))
sys.exit(-1)
opts = []
if python2:
opts.append("-p python2")
else:
opts.append("-p python3")
option_str = " ".join(opts)
cmd = COMMAND.format(path=path, options=option_str)
if show_stdout:
os.system(cmd)
else:
subprocess.check_output(cmd, shell=True)
print("my_{}".format(name))
create_symlinks(name, path)
@cmd("delete")
def delete_environment(name):
"""Delete an environment."""
path = os.path.join(env_dir, name)
sym_path = os.path.join(sym_dir, "my_{}".format(name))
if os.path.exists(path):
shutil.rmtree(path)
if os.path.exists(sym_path):
os.remove(sym_path)
if __name__ == '__main__':
main()
@spy16
Copy link
Author

spy16 commented Mar 11, 2017

  1. mv myenv.py /usr/bin/myenv
  2. chmod +x /usr/bin/myenv
  3. Edit .bashrc and append ~/.myenv/bins/ to PATH
  4. source $(myenv new hello)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment