mirror of
https://github.com/tcsenpai/nixvenv.git
synced 2025-06-04 10:10:07 +00:00
159 lines
6.6 KiB
Python
159 lines
6.6 KiB
Python
import os
|
|
import subprocess
|
|
import json
|
|
from pprint import pprint
|
|
import sys
|
|
import shutil
|
|
|
|
environment = os.environ.copy()
|
|
config = {}
|
|
nvenv_name = ""
|
|
local_bin_folder = ""
|
|
load_file = ""
|
|
hostname = ""
|
|
username = ""
|
|
|
|
# INFO Entry point
|
|
def main(config_file="./config.json", new=False, delete=False):
|
|
print("[ Welcome to NixVenv, the *nix compatible virtual shell environment manager ]")
|
|
global environment, config, cmds, local_bin_folder, load_file, nvenv_name, shell, hostname, username
|
|
p = subprocess.run("whoami", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
username = p.stdout.decode('utf-8').strip()
|
|
p = subprocess.run("hostname", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
hostname = p.stdout.decode('utf-8').strip()
|
|
p = subprocess.run("echo $SHELL", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
shell = p.stdout.decode('utf-8').strip()
|
|
print(shell)
|
|
cmds = 'echo "[ Setting environment variables ]"\n'
|
|
config = open(config_file, "r")
|
|
config = json.loads(config.read())
|
|
print("[*] Config file loaded: " + config_file)
|
|
nvenv_name = config["nvenv_name"]
|
|
# Halt if we have to delete the environment
|
|
if delete:
|
|
if not os.path.exists(nvenv_name):
|
|
print("[*] Environment does not exist: " + nvenv_name)
|
|
else:
|
|
shutil.rmtree(nvenv_name, ignore_errors=True)
|
|
print("[*] Deleted environment: " + nvenv_name)
|
|
os._exit(0)
|
|
# Else we use the environment
|
|
print("[*] Reading from environment: " + nvenv_name)
|
|
local_bin_folder = os.getcwd() + "/" + nvenv_name + "/" + config["local_bin"]
|
|
print("[*] Local bin folder: " + local_bin_folder)
|
|
load_file = os.getcwd() + "/" + nvenv_name + "/" + config["load_file"]
|
|
new_environment(new)
|
|
load_config()
|
|
load_environment()
|
|
|
|
# INFO Load a configuration file
|
|
def load_config():
|
|
global cmds, local_bin_folder, load_file, hostname
|
|
# Overwrites replace environment variables fully or create a new one
|
|
overwrites = config['overwrites']
|
|
for key in overwrites:
|
|
cmds += "export " + key + "=" + overwrites[key] + "\n"
|
|
print("[*] Overwriting enviromental variable: " + key)
|
|
# Additions add the value to the environment variable preserving the original value
|
|
additions = config["additions"]
|
|
for key in additions:
|
|
cmds += "export " + key + "=${" + key + "}:" + additions[key] + "\n"
|
|
print("[*] Adding to enviromental variable: " + key)
|
|
# Setting our environment variables
|
|
print("[*] Setting our environment variables")
|
|
cmds += "export PATH=" + local_bin_folder + ":" + os.environ["PATH"]
|
|
# Loading the static environment variables defined in the config file
|
|
print("[*] Setting the environment name as " + config["nvenv_name"])
|
|
cmds += "export NVENV_NAME=" + config["nvenv_name"] + "\n"
|
|
print("[*] Changing to: " + config["working_dir"])
|
|
cmds += "cd " + config["working_dir"] + "\n"
|
|
cmds += 'echo "nvenv environment loaded: $NVENV_NAME"\n'
|
|
# Setting up customizations
|
|
cmds += 'export PS1="' + username + ' [' + config["nvenv_name"] + '@' + hostname+ '] :> "\n'
|
|
# Finally, writing to the load file
|
|
print("[*] Writing to the load file: " + load_file)
|
|
with open(load_file, "w") as f:
|
|
f.write(cmds)
|
|
|
|
# INFO Loading the local environment fully
|
|
def load_environment():
|
|
print("[*] Loading the environment")
|
|
global environment, load_file, shell
|
|
# Multiple shells are supported
|
|
if "zsh" in shell:
|
|
cmd = "source " + load_file + " && " + shell + " -f -d"
|
|
else:
|
|
cmd = shell + " --rcfile " + load_file
|
|
# Finally, loading the environment by sourcing the load file
|
|
print("[+] Executing: " + cmd)
|
|
print("\nNOTE: Digit 'exit' and press ENTER to return to the previous environment\n")
|
|
os.system(cmd)
|
|
|
|
# INFO Environemnt creation
|
|
def new_environment(new_flag=False):
|
|
global cmds, local_bin_folder
|
|
if os.path.exists(os.getcwd() + "/" + nvenv_name):
|
|
if not new_flag:
|
|
raise Exception("[x] Environment already exists: " + nvenv_name)
|
|
print("[+] Environment already exists: " + nvenv_name)
|
|
return
|
|
# Creating the local_bin_folder if it doesn't exist
|
|
if not os.path.exists(local_bin_folder):
|
|
os.makedirs(local_bin_folder)
|
|
# Reading the init commands
|
|
init_cmds_list = config["init_cmds"]
|
|
for cmd in init_cmds_list:
|
|
# Replacing folders if needed
|
|
if (cmd == "here"):
|
|
running_dir = os.getcwd()
|
|
elif (cmd == "nvenv_folder"):
|
|
running_dir = os.getcwd() + "/" + nvenv_name
|
|
elif (cmd == "local_bin_folder"):
|
|
running_dir = local_bin_folder
|
|
else:
|
|
# Support for custom directories
|
|
# REVIEW Security note: limit it to the current working directory
|
|
if not os.path.exists(running_dir):
|
|
raise Exception("Running directory does not exist: " + running_dir)
|
|
# Compiling the command to be executed before the environment is activated
|
|
single_cmd = init_cmds_list[cmd]
|
|
actual_cmd = "cd '" + running_dir + "' && " + single_cmd
|
|
print("[*] Executing: " + actual_cmd)
|
|
os.system(actual_cmd)
|
|
# Support files
|
|
files = config["files"]
|
|
for file in files:
|
|
origin = file[0]
|
|
destination = file[1]
|
|
if not os.path.exists(origin):
|
|
raise Exception("[x] Origin file does not exist: " + origin)
|
|
if os.path.exists(destination):
|
|
raise Exception("[x] Destination file already exists: " + destination)
|
|
print("[*] Copying file: " + origin + " to: " + destination)
|
|
shutil.copy(origin, destination)
|
|
|
|
if __name__ == '__main__':
|
|
# Argument parsing
|
|
args_len = len(sys.argv)
|
|
print(sys.argv)
|
|
filename = sys.argv[0]
|
|
params = {
|
|
"operation": "run",
|
|
"config_file": "config.json",
|
|
}
|
|
# Getting parameters
|
|
for param in sys.argv[1:]:
|
|
if "operation=" in param:
|
|
params["operation"] = param.split("=")[1]
|
|
if "config_file=" in param:
|
|
params["config_file"] = param.split("=")[1]
|
|
# Sanity checks
|
|
if not os.path.exists(params["config_file"]):
|
|
raise Exception("[x] Config file does not exist: " + params["config_file"])
|
|
# Runs based on operation
|
|
if params["operation"] == "activate" or params["operation"] == "run":
|
|
main(config_file=params["config_file"])
|
|
elif params["operation"] == "new":
|
|
main(config_file=params["config_file"], new=True)
|
|
elif params["operation"] == "remove":
|
|
main(config_file=params["config_file"], delete=True) |