Skip to content

Instantly share code, notes, and snippets.

@LoveDuckie
Created May 28, 2018 16:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LoveDuckie/09848cf48c744b34b4b5056742636c1b to your computer and use it in GitHub Desktop.
Save LoveDuckie/09848cf48c744b34b4b5056742636c1b to your computer and use it in GitHub Desktop.
'''
Manage installed Visual Studio Code extensions by installing, saving, or performing other operations
'''
import os, argparse, sys, zipfile, subprocess, logging, functools, logging.handlers
from configparser import ConfigParser, SafeConfigParser
from zipfile import ZipFile
from argparse import ArgumentParser
def get_script_dir():
'''
Get the directory that the script is being ran from
'''
return os.path.dirname(__file__)
def get_workspace_dir():
'''
Get the absolute path to the workspace that this is in
'''
return os.path.abspath(os.path.join(get_script_dir(),".."))
def get_workspace_absolute_path(*paths):
'''
Generate an absolute path using the workspace dir
'''
return os.path.join(get_workspace_dir(),*paths)
def get_script_absolute_path(*paths):
'''
Get the absolute path concatenated with teh directory that the script is being launched from
'''
return os.path.join(get_script_dir(),*paths)
__argument_parser__ = ArgumentParser(description="A basic commandline tool for dumping the contents of mariadb into the local repo")
__argument_parser__.add_argument("--operation", default="save_installed_extensions", dest="operation", type=str, help="The type of operation that we are performing")
__argument_parser__.add_argument("--output-path", default="", dest="output_path", type=str, help="The path to where we are writing the installed extensions to")
__global_func_map__ = {}
def operation_func():
'''
Decorator function for performing operations
'''
global __global_func_map__
def operation_func_return(func):
if func is None:
raise Exception("The function is invalid or null")
__global_func_map__[func.func_name] = func
return operation_func_return
__commandline_arguments__ = vars(__argument_parser__.parse_known_args()[0])
if __commandline_arguments__ is None:
raise ValueError("Failed to parse the commandline arugments as required")
__logger__ = logging.Logger(name="Logging for vscode extensions")
__logger__.addHandler(logging.handlers.RotatingFileHandler(get_workspace_absolute_path("Logs","vscode_extensions.log")))
__logger__.addHandler(logging.StreamHandler())
if __commandline_arguments__ is None:
raise Exception("The commandline arguments specified are invalid or null")
if not "operation" in __commandline_arguments__:
raise KeyError("Failed to find the operation in the command line arguments")
def get_logger_name():
'''
Get an immutable name for doing logging
'''
return "vscode-extesnions-log"
def get_logger():
'''
Return the logger instance for the script
'''
global __logger__
if __logger__ is None:
__logger__ = logging.Logger(name=get_logger_name())
return __logger__
def log_warn(message, *args):
'''
Log a warning out
'''
get_logger().warn(message,*args)
def log(message, *args):
'''
Log a info message out
'''
if message is None:
raise ValueError("The message is invalid or null")
get_logger().info(message,*args)
def log_exception(exc,message,*args):
'''
Log the exception out as required
'''
if exc is None:
raise ValueError("The exc instance is invalid or null")
if message is None:
raise ValueError("The message instance is invalid or null")
get_logger().error(exc.exc_info()[0].msg,*args)
get_logger().error(message,*args)
def log_error(message, *args):
'''
Log an error message
'''
if message is None:
raise ValueError("The error message is invalid or null")
get_logger().error(message, *args)
def get_extensions_filename():
'''
Get the immutable name of the list of extensions that are to load from
'''
return "portfolio_extensions"
@operation_func()
def save_installed_extensions():
'''
Save a list of extensions to the path specified
'''
global __global_func_map__
global __commandline_arguments__
all_installed_extensions = get_installed_extensions()
if all_installed_extensions is None:
raise ValueError("The list of instllaed extensions are invalid or null")
if not isinstance(all_installed_extensions,list):
raise TypeError("The installed extensions list is not a list")
with open(get_extensions_filepath(),"w") as extensions_file:
for extension in all_installed_extensions:
extensions_file.write("%s\n"%extension)
return 0
def get_vscode_installation_path():
'''
Get the path to where Visual Studio Code is installed on the machine
'''
return "C:\\Program Files\\Microsoft VS Code"
def get_vscode_path():
'''
Get the absolute path to the binary for visual studio code
'''
return os.path.join(get_vscode_installation_path(),"bin","code.cmd")
def run_vscode_command(command, *args):
'''
Run the command against the vscode binary
'''
if not os.path.exists(vscode_path = get_vscode_path()):
raise IOError("Failed: unable to find the vscode binary at the path %s" % get_vscode_path())
output = ""
try:
output = subprocess.check_output([get_vscode_path()].extend(args),stderr=subprocess.STDOUT)
return (output,0)
except Exception as exc:
log_exception(exc,"Failed to run the vscode command")
return (output,1)
return (output,-1)
@operation_func()
def install_all_extensions():
'''
Install the extensions that are stored in teh specified list
'''
extensions_found = get_extensions_list()
if not extensions_found is list:
raise TypeError("The return value is not a list")
for extension in extensions_found:
print "Installing: installing extension %s" % extension
if not install_extension(extension):
print "Failed: unable to install extension %s" % extension
continue
print "Success: installed extension %s" % extension
return 0
def install_extension(extension_name):
'''
Install the extension that is specified.
'''
if extension_name is None:
raise ValueError("The extensions path is invalid or null")
cmd = run_vscode_command("--install-extension", extension_name)
if cmd is None:
raise ValueError("The command value is invalid or null")
if not isinstance(cmd,tuple):
raise TypeError("The command output is not a tuple. Check and try again.")
return cmd[1] == 0
def get_extensions_filepath():
'''
Get the absolute path to where the scripts are meant to be
'''
return get_script_absolute_path("%s.lst" % get_extensions_filename())
def get_extensions_list():
'''
Get a list of extensions to use
'''
absolute_extensions_path = get_extensions_filepath()
if not os.path.exists(absolute_extensions_path):
raise IOError("Failed to find the absolute path to the extensions list %s" % absolute_extensions_path)
extensions_list_contents = []
with open(absolute_extensions_path,"r") as ext_file:
extensions_list_contents = ext_file.readlines()
return extensions_list_contents
def get_installed_extensions():
'''
Get a list of all the extensions that are installed on the machine
'''
output = ""
try:
output = subprocess.check_output([get_vscode_path(),"--list-extensions"],stderr=subprocess.STDOUT)
except Exception as exc:
log_exception(exc,"Failed to complete the required operation")
all_extensions = output.splitlines()
return all_extensions
def main():
'''
The entry point for the application
'''
global __commandline_arguments__
global __global_func_map__
if __commandline_arguments__ is None:
raise ValueError("The commandline arguments are invalid or null")
if __global_func_map__ is None:
raise ValueError("The func map is invalid or null")
if not "operation" in __commandline_arguments__:
log_warn("The operation was not foudn in the collection of commandline arguments")
return 1
commandline_operation = __commandline_arguments__["operation"]
if commandline_operation is None:
raise ValueError("The commandline operation is invalid or null")
if not isinstance(commandline_operation, str):
raise ValueError("The commandline operation is not defined as str")
try:
if commandline_operation in __global_func_map__:
__global_func_map__[commandline_operation]()
return 0
except Exception as exc:
log_exception(exc,"Failed: unable to complete the operation %s" % commandline_operation)
return 1
exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment