sudoblockio / tackle

Tackle is a programmable configuration language for building modular utilities, code generators, and CLIs with schema validation baked in.
Apache License 2.0
53 stars 2 forks source link

Hooks Dir as Base #240

Open robcxyz opened 10 months ago

robcxyz commented 10 months ago

Hooks Dir as Base

Allow the base of a provider be either a hooks dir or tackle file

Overview

When there is no tackle file in a directory, it would be appropriate to instead check if there is a hooks dir as well since if there was a tackle file, then those hooks in the hooks dir would also be parsed.

Relates to current-directory

Implementation


CONTEXT_FILES = {

    '.tackle.yaml',

    '.tackle.yml',

    '.tackle.json',

    'tackle.yaml',

    'tackle.yml',

    'tackle.json',

}

def find_tackle_file(provider_dir) -> str:

    """Find the tackle files based on some defaults and return the path."""

    provider_contents = os.listdir(provider_dir)

    for i in provider_contents:

        if i in CONTEXT_FILES:

            return os.path.join(provider_dir, i)

    raise InvalidConfiguration(f"Can't find tackle file in {provider_dir}")

This should instead return a tuple with the tackle file and the hooks dir.

Use 1:


def import_local_provider_source(context: 'Context', provider_dir: str):

    """

    Import a provider from a path by checking if the provider has a tackle file and

    returning a path.

    """

    context.input_dir = provider_dir

    if context.input_file is None:

        context.input_file = find_tackle_file(provider_dir)

    if context.directory:

        context.input_file = os.path.join(context.input_file, context.directory)

    extract_base_file(context)

Use 2


    elif is_directory_with_tackle(first_arg):

        # Special case where the input is a path to a directory. Need to override some

        # settings that would normally get populated by zip / repo refs. Does not need

        # a file reference as otherwise would be given absolute path to tackle file.

        context.input_file = os.path.basename(find_tackle_file(first_arg))

        context.input_dir = Path(first_arg).absolute()

Done? No. Will need to check:

Most likely also need to update extract_base_file(context: 'Context')


def extract_base_file(context: 'Context'):

    """Read the tackle file and initialize input_context."""

    if context.find_in_parent:

        try:

            path = find_in_parent(context.input_dir, [context.input_file])

        except NotADirectoryError:

            ...

def find_in_parent(dir: str, targets: list, fallback=None) -> str:

    """Recursively search in parent directories for a path to a target file."""

    for i in os.listdir(dir):

        if i in targets:

            return os.path.abspath(os.path.join(dir, i))

# Errors...