Created
May 28, 2018 16:22
-
-
Save LoveDuckie/09848cf48c744b34b4b5056742636c1b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
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