예제 #1
0
def config(ctx, directory: str, template_dir: str, template: str, filename: str, overwrite: bool):
    """Command that will create a project config file that can be used to supply additional information for the documentation generation process."""
    try:
        # Set the directory path based on either the passed directory arg, or the click context.
        path = SetPath(directory, ctx)
        
        # Gather the project variables to construct the object that the template will use to generate the config file.
        # Set the type of provider class to call
        if ctx.obj.get('provider').lower() == 'terraform' or ctx.obj.get('provider') == 'tf':
            Variables = TFDoc(path).BuildVarList()
            log.debug("Variable list retrieved from provided file path...")
        
        # Load, render and write the Jinja Template
        log.debug("Attempting to build project config file...")
        ConfigFile = Jinja(TemplateDir=template_dir, Template=template, OutputDir=path, OutputFile=filename)
        ConfigFile.LoadTemplate()
        ConfigFile.RenderTemplate(Variables)
        ConfigFile.WriteTemplate(Overwrite=overwrite)
        # Add the Dir Tree Variable to the Template Dictionary:
        cprint("Config file successfully written to: {}".format(os.path.join(path, filename)))
    except Exception as e:
        cprint(" ERROR ENCOUNTERED: ", 'grey', 'on_red')
        cprint("Error: Failed to complete config file creation", 'red')
        cprint(str(e), 'red')
        log.error("Error: Failed to complete config file creation")
        log.error(str(e))
        raise
        sys.exit()
예제 #2
0
def release(ctx, namespace: str, repo: str, directory: str, token: str):
    """Command that will retrieve the project repository information from the projects configured GIT repository."""
    try:
        # Set the directory path based on either the passed directory arg, or the click context.
        path = SetPath(directory, ctx)

        # If the namespace and repository were provided, then assign the values, if not check for .git/config file and parse.
        if repo is not None and namespace is not None:
            RequestObj = Github(namespace, repo, token).GetLatestRelease()
        # Try and fetch the repository URL from the configured directory.
        elif os.path.exists("{}/.git/config".format(path)):
            namespace, repo = ParseRepoUrl(path)
            RequestObj = Github(namespace, repo, token).GetLatestRelease()
        else:
            RequestObj = "Undefined"
        print("Latest Release: {}".format(RequestObj))
    except Exception as e:
        cprint(" ERROR ENCOUNTERED: ", 'grey', 'on_red')
        cprint(
            "Warning: Failed to retrieve GIT repository release data for the targeted project.",
            'red')
        cprint(str(e), 'red')
        log.error(
            "Warning: Failed to retrieve GIT repository release data for the targeted project. Check the provided namespace and repo settings and try again."
        )
        log.error(str(e))
        sys.exit()
예제 #3
0
def files(ctx, subdir: bool, directory: str):
    """Command that will retrieve a list of files from a target directory location matching the provider type specified (terraform = .tf)"""
    try:
        # Set the directory path based on either the passed directory arg, or the click context.
        path = SetPath(directory, ctx)

        # Set the type of provider class to call
        if ctx.obj.get('provider').lower() == 'terraform' or ctx.obj.get(
                'provider') == 'tf':
            Files = TFDoc(path, subdir).FetchFileList()
            log.debug("File list retrieved from provided file path...")
        # Print command results.
        cprint(
            "{} {} files found in target directory: {}".format(
                len(Files),
                ctx.obj.get('provider').lower(), path), 'green')

        # Print the results
        for item in Files:
            # For the command output remove the base path specified as its redundant
            item = item.replace("{}/".format(path), "")
            # Call SplitPath to find found results in subdirectories.
            item_path_list = SplitPath(item)
            # Print results
            if not item_path_list[0]:
                cprint(item_path_list[1], 'white')
                log.debug(item_path_list[1])
            else:
                print(colored("/{} =>".format(item_path_list[0]), 'blue'),
                      colored(item_path_list[1], 'white'))
                log.debug("{} => {}".format(item_path_list[0],
                                            item_path_list[1]))
            print("\n")
    except Exception as e:
        cprint(" ERROR ENCOUNTERED: ", 'grey', 'on_red')
        cprint(
            "Error: Failed to retrieve file list from the provided file path location, check the provided file path and try again",
            'red')
        cprint(str(e), 'red')
        log.error(
            "Error: Failed to retrieve file list from the provided file path location, check the provided file path and try again"
        )
        log.error(str(e))
        sys.exit()
예제 #4
0
def dirtree(ctx, directory: str):
    """Command that will create an ascii directory tree listing that can be used within the generated documentation."""
    try:
        # Set the directory path based on either the passed directory arg, or the click context.
        path = SetPath(directory, ctx)
        
        log.debug("Attempting to build directory tree variable...")
        # Set a variable for the Directory tree, and then call the Directory Tree Generator
        FileTree = DirTree(path)

        # Add the Dir Tree Variable to the Template Dictionary:
        print(FileTree)
    except Exception as e:
        cprint(" ERROR ENCOUNTERED: ", 'grey', 'on_red')
        cprint("Error: Failed to build directory structure tree", 'red')
        cprint(str(e), 'red')
        log.error("Error: Failed to build directory structure tree")
        log.error(str(e))
        sys.exit()
예제 #5
0
def outputs(ctx, subdir: bool, directory: str):
    """Command that will retrieve a list of all of the project outputs from the specified project path."""
    try:
        # Set the directory path based on either the passed directory arg, or the click context.
        path = SetPath(directory, ctx)

        # Set the type of provider class to call
        if ctx.obj.get('provider').lower() == 'terraform' or ctx.obj.get(
                'provider') == 'tf':
            Outputs = TFDoc(path, subdir).BuildOutputList()
            log.debug("Variable list retrieved from provided file path...")
        # Print Outputs.
        cprint(
            "{} {} outputs found in target project: {}".format(
                len(Outputs),
                ctx.obj.get('provider').lower(), path), 'green')

        # To make the print format uniform, cycle through the outputs object and get a max length to use for an offset value.
        Output_MaxLength = 0
        for output in Outputs:
            if len(output.get('Name')) > Output_MaxLength:
                Output_MaxLength = len(output.get('Name'))
        # Print Outputs:
        for output in Outputs:
            offset = Output_MaxLength - len(output.get('Name'))
            print(
                colored("{}{} =".format(output.get('Name'), " " * offset),
                        'blue'),
                colored(str(output.get('OutputValue')), 'green'))
        print("\n")
    except Exception as e:
        cprint(" ERROR ENCOUNTERED: ", 'grey', 'on_red')
        cprint(
            "Error: Failed to retrieve output list from the provided file path location, check the provided file path and try again",
            'red')
        cprint(str(e), 'red')
        log.error(
            "Error: Failed to retrieve outputs list from the provided file path location, check the provided file path and try again"
        )
        log.error(str(e))
        raise
        sys.exit()
예제 #6
0
def readme(ctx, directory: str, template_dir: str, template: str, filename: str, configfile: str, overwrite: bool, backup: bool, namespace: str, repo: str, token: str):
    """Command that will create a project readme.md for a repository ."""
    try:
        # Define the dictionary object that will be passed to the readme template.
        ReadmeObj = {}
        # Set the directory path based on either the passed directory arg, or the click context.
        path = SetPath(directory, ctx)

        # Call the config parser to parse a config file if one exists within the target directory.
        ReadmeConfig = Config(path, configfile)
        # print(json.dumps(ReadmeConfig.config, indent=4, sort_keys=True))
        ReadmeObj.update(git=ReadmeConfig.config.get('GitConfig', {}))
        ReadmeObj.update(readme=ReadmeConfig.config.get('ReadMeConfig', {}))
        
        # Gather the project variables to construct the object that the template will use to generate the readme document.
        # Set the type of provider class to call
        if ctx.obj.get('provider').lower() == 'terraform' or ctx.obj.get('provider') == 'tf':
            Variables = TFDoc(path).BuildVarList()
            log.debug("Variable list retrieved from provided file path...")
            ReadmeObj.update(variables=Variables)
            # Add the required and optional images
            ReadMeObjVar = ReadmeObj.get('variables')
            ReadMeObjVar.update(required_image=ReadmeConfig.config.get('VariablesConfig').get('Required').get('Image'))
            ReadMeObjVar.update(optional_image=ReadmeConfig.config.get('VariablesConfig').get('Optional').get('Image'))
            
            # Gather the project outputs to use to construct the object that the template will use to generate the readme document.
            Outputs = TFDoc(path).BuildOutputList()
            log.debug("Output list retrieved from provided file path...")
            ReadmeObj.update(outputs=Outputs)

            # Graph the things
            GraphImage = TFDoc(path).BuildGraph()
            if GraphImage != "None":
                ReadmeObj.update(tfdiagram=GraphImage)

        # Update the variable objects with the data from the config pull
        ReadmeConfig.UpdateVars(ReadmeObj)
        log.info("ReadmeObj has been updated with variable data from the parsed config.")
        # print(json.dumps(ReadmeObj, indent=4, sort_keys=True))

        # Add the Build Tree
        BuildTree = DirTree(path)
        log.debug("Dirtree created:\n{}".format(BuildTree))
        ReadmeObj.update(tree=BuildTree)
        
        # Last attempt to fetch GitRepo Data and add it to the ReadMeObj before we generate the documentation.
        # If the namespace and repository were provided, then assign the values, if not check for .git/config file and parse.
        # Set variables to hold the Namespace and Repo
        GitNameSpace = None
        GitRepo = None  
        
        # Try and use the variables first
        if repo is not None and namespace is not None:
            GitNameSpace = namespace
            GitRepo = repo
            log.debug("Configuring Git NameSpace and Repo from command variables...")
            log.debug("GitNameSpace set to value: {}".format(namespace))
            log.debug("GitRepo set to value: {}".format(repo))
        # Try and fetch the repository URL from the configured directory.
        elif isinstance(ReadmeObj.get('git'), dict):
            GitNameSpace = ReadmeObj.get('git').get('NameSpace')
            GitRepo = ReadmeObj.get('git').get('Name')
            log.debug("Configuring Git NameSpace and Repo from the project config file...")
            log.debug("GitNameSpace set to value: {}".format(ReadmeObj.get('git').get('NameSpace')))
            log.debug("GitRepo set to value: {}".format(ReadmeObj.get('git').get('Name')))
        elif os.path.exists("{}/.git/config".format(path)):
            GitNameSpace, GitRepo = ParseRepoUrl(path)
            log.debug("Configuring Git NameSpace and Repo from the project .git/config file...")
            log.debug("GitNameSpace set to value: {}".format(GitNameSpace))
            log.debug("GitRepo set to value: {}".format(GitRepo))
        # Attempt to make the call to the repository to fetch repo and release data.
        log.debug("Attempting to make request from Github...")
        if GitNameSpace is not None and GitRepo is not None:
            RequestObj = Github(GitNameSpace, GitRepo, token).GetGitHubData()
            log.debug("Git Repository Request State: {}".format(RequestObj))
            if RequestObj.get('state') != "fail":
                ReadmeObj.update(repo=RequestObj)
                log.debug("Template Object has been updated to include the repository response object.")
        log.info("Generation of template dictionary object completed: {}".format(json.dumps(ReadmeObj, indent=4, sort_keys=True)))
        # Load, render and write the Jinja Template
        log.debug("Attempting to build project config file...")
        DocTemplate = Jinja(TemplateDir=template_dir, Template=template, OutputDir=path, OutputFile=filename)
        DocTemplate.LoadTemplate()
        DocTemplate.RenderTemplate(ReadmeObj)
        DocTemplate.WriteTemplate(Overwrite=overwrite, Backup=backup)
        # Add the Dir Tree Variable to the Template Dictionary:
        cprint("Template file successfully written to: {}".format(os.path.join(path, filename)))
    except Exception as e:
        cprint(" ERROR ENCOUNTERED: ", 'grey', 'on_red')
        cprint("Error: Failed to complete config file creation", 'red')
        cprint(str(e), 'red')
        log.error("Error: Failed to complete config file creation")
        log.error(str(e))
        raise
        sys.exit()
예제 #7
0
def variables(ctx, subdir: bool, directory: str):
    """Command that will retrieve a list of all of the project variables from the specified project path."""
    try:
        # Set the directory path based on either the passed directory arg, or the click context.
        path = SetPath(directory, ctx)

        # Set the type of provider class to call
        if ctx.obj.get('provider').lower() == 'terraform' or ctx.obj.get(
                'provider') == 'tf':
            Variables = TFDoc(path, subdir).BuildVarList()
            log.debug("Variable list retrieved from provided file path...")

        # Print Required Variable Results.
        cprint(
            "{} {} required variables found in target project: {}".format(
                len(Variables.get('required_vars')),
                ctx.obj.get('provider').lower(), path), 'green')
        for reqvar in Variables.get('required_vars', []):
            offset = Variables.get('required_vars_maxlength') - len(
                reqvar.get('Name'))
            print(
                colored("{}{} =".format(reqvar.get('Name'), " " * offset),
                        'blue'), colored("Value Required", 'green'))
        print("\n")
        # Print Optional Variable Results.
        cprint(
            "{} {} optional variables found in target project: {}".format(
                len(Variables.get('optional_vars')),
                ctx.obj.get('provider').lower(), path), 'green')
        for optvar in Variables.get('optional_vars', []):
            offset = Variables.get('optional_vars_maxlength') - len(
                optvar.get('Name'))
            # Try to make the output nice and pretty, but if it fails, then default to normal print
            try:
                if 'list' in optvar.get('Type') and len(
                        optvar.get('DefaultValue')) > 0:
                    print(
                        colored(
                            "{}{} =".format(optvar.get('Name'), " " * offset),
                            'blue'), colored('[', 'green'))
                    for item in optvar.get('DefaultValue'):
                        if isinstance(item, dict):
                            cprint(json.dumps(item, indent=4, sort_keys=True),
                                   'green')
                        else:
                            cprint("    {}".format(item), 'green')
                    cprint(']', 'green')
                elif 'map' in optvar.get('Type'):
                    print(
                        colored(
                            "{}{} =".format(optvar.get('Name'), " " * offset),
                            'blue'),
                        colored(
                            json.dumps(optvar.get('DefaultValue'),
                                       indent=4,
                                       sort_keys=True), 'green'))
                else:
                    print(
                        colored(
                            "{}{} =".format(optvar.get('Name'), " " * offset),
                            'blue'),
                        colored(optvar.get('DefaultValue'), 'green'))
            except Exception:
                print(
                    colored("{}{} =".format(optvar.get('Name'), " " * offset),
                            'blue'),
                    colored(optvar.get('DefaultValue'), 'green'))
        print("\n")
    except Exception as e:
        cprint(" ERROR ENCOUNTERED: ", 'grey', 'on_red')
        cprint(
            "Error: Failed to retrieve variable list from the provided file path location, check the provided file path and try again",
            'red')
        cprint(str(e), 'red')
        log.error(
            "Error: Failed to retrieve variable list from the provided file path location, check the provided file path and try again"
        )
        log.error(str(e))
        sys.exit()