(ctx, check, sync, verbose)
Validate default configuration files.

    If `check` is specified, only the check will be validated, if check value is 'changed' will only apply to changed
    checks, an 'all' or empty `check` value will validate all README files.
Validate default configuration files.
Validate default configuration files .
def config(ctx, check, sync, verbose):
    """Validate default configuration files.

    If `check` is specified, only the check will be validated, if check value is 'changed' will only apply to changed
    checks, an 'all' or empty `check` value will validate all README files.
    """

    repo_choice = ctx.obj['repo_choice']
    if repo_choice == 'agent':
        checks = ['agent']
    else:
        checks = process_checks_option(check, source='valid_checks', extend_changed=True)

    files_failed = {}
    files_warned = {}
    file_counter = []

    echo_waiting(f'Validating default configuration files for {len(checks)} checks...')
    for check in checks:
        check_display_queue = []

        manifest = Manifest.load_manifest(check)
        if not manifest:
            echo_debug(f"Skipping validation for check: {check}; can't process manifest")
            continue

        spec_file_path = manifest.get_config_spec()
        if not file_exists(spec_file_path):
            validate_config_legacy(check, check_display_queue, files_failed, files_warned, file_counter)
            if verbose:
                check_display_queue.append(lambda: echo_warning('No spec found', indent=True))
            if check_display_queue:
                echo_info(f'{check}:')
            for display in check_display_queue:
                display()
            continue

        file_counter.append(None)

        # source is the default file name
        if check == 'agent':
            display_name = 'Datadog Agent'
            source = 'datadog'
            version = None
        else:
            display_name = manifest.get_display_name()
            source = check
            version = get_version_string(check)

        spec_file_content = read_file(spec_file_path)
        default_temp = validate_default_template(spec_file_content)
        spec = ConfigSpec(spec_file_content, source=source, version=version)
        spec.load()

        if not default_temp:
            message = "Missing default template in init_config or instances section"
            check_display_queue.append(lambda **kwargs: echo_failure(message))
            annotate_error(spec_file_path, message)

        if spec.errors:
            files_failed[spec_file_path] = True
            for error in spec.errors:
                check_display_queue.append(lambda error=error, **kwargs: echo_failure(error, **kwargs))
        else:
            if spec.data['name'] != display_name:
                files_failed[spec_file_path] = True
                message = f"Spec  name `{spec.data['name']}` should be `{display_name}`"
                check_display_queue.append(lambda **kwargs: echo_failure(message, **kwargs))
                annotate_error(spec_file_path, message)

            example_location = get_data_directory(check)
            example_consumer = ExampleConsumer(spec.data)
            for example_file, (contents, errors) in example_consumer.render().items():
                file_counter.append(None)
                example_file_path = path_join(example_location, example_file)
                if errors:
                    files_failed[example_file_path] = True
                    for error in errors:
                        check_display_queue.append(lambda error=error, **kwargs: echo_failure(error, **kwargs))
                else:
                    if not file_exists(example_file_path) or read_file(example_file_path) != contents:
                        if sync:
                            echo_info(f"Writing config file to `{example_file_path}`")
                            write_file(example_file_path, contents)
                        else:
                            files_failed[example_file_path] = True
                            message = f'File `{example_file}` is not in sync, run "ddev validate config -s"'
                            if file_exists(example_file_path):
                                example_file = read_file(example_file_path)
                                for diff_line in difflib.context_diff(
                                    example_file.splitlines(), contents.splitlines(), "current", "expected"
                                ):
                                    message += f'\n{diff_line}'
                            check_display_queue.append(
                                lambda example_file=example_file, **kwargs: echo_failure(message, **kwargs)
                            )
                            annotate_error(example_file_path, message)

        if check_display_queue or verbose:
            echo_info(f'{check}:')
            if verbose:
                check_display_queue.append(lambda **kwargs: echo_info('Valid spec', **kwargs))
            for display in check_display_queue:
                display(indent=True)

    num_files = len(file_counter)
    files_failed = len(files_failed)
    files_warned = len(files_warned)
    files_passed = num_files - (files_failed + files_warned)

    if files_failed or files_warned:
        click.echo()

    if files_failed:
        echo_failure(f'Files with errors: {files_failed}')

    if files_warned:
        echo_warning(f'Files with warnings: {files_warned}')

    if files_passed:
        if files_failed or files_warned:
            echo_success(f'Files valid: {files_passed}')
        else:
            echo_success(f'All {num_files} configuration files are valid!')

    if files_failed:
        abort()
def config ( ctx , check , sync , verbose ) : repo_choice = ctx . obj [ 'repo_choice' ] if repo_choice == 'agent' : checks = [ 'agent' ] else : checks = process_checks_option ( check , source = 'valid_checks' , extend_changed = True ) files_failed = { } files_warned = { } file_counter = [ ] echo_waiting ( f'Validating default configuration files for {len(checks)} checks...' ) for check in checks : check_display_queue = [ ] manifest = Manifest . load_manifest ( check ) if not manifest : echo_debug ( f"Skipping validation for check: {check}; can't process manifest" ) continue spec_file_path = manifest . get_config_spec ( ) if not file_exists ( spec_file_path ) : validate_config_legacy ( check , check_display_queue , files_failed , files_warned , file_counter ) if verbose : check_display_queue . append ( lambda : echo_warning ( 'No spec found' , indent = True ) ) if check_display_queue : echo_info ( f'{check}:' ) for display in check_display_queue : display ( ) continue file_counter . append ( None ) # source is the default file name if check == 'agent' : display_name = 'Datadog Agent' source = 'datadog' version = None else : display_name = manifest . get_display_name ( ) source = check version = get_version_string ( check ) spec_file_content = read_file ( spec_file_path ) default_temp = validate_default_template ( spec_file_content ) spec = ConfigSpec ( spec_file_content , source = source , version = version ) spec . load ( ) if not default_temp : message = "Missing default template in init_config or instances section" check_display_queue . append ( lambda * * kwargs : echo_failure ( message ) ) annotate_error ( spec_file_path , message ) if spec . errors : files_failed [ spec_file_path ] = True for error in spec . errors : check_display_queue . append ( lambda error = error , * * kwargs : echo_failure ( error , * * kwargs ) ) else : if spec . data [ 'name' ] != display_name : files_failed [ spec_file_path ] = True message = f"Spec  name `{spec.data['name']}` should be `{display_name}`" check_display_queue . append ( lambda * * kwargs : echo_failure ( message , * * kwargs ) ) annotate_error ( spec_file_path , message ) example_location = get_data_directory ( check ) example_consumer = ExampleConsumer ( spec . data ) for example_file , ( contents , errors ) in example_consumer . render ( ) . items ( ) : file_counter . append ( None ) example_file_path = path_join ( example_location , example_file ) if errors : files_failed [ example_file_path ] = True for error in errors : check_display_queue . append ( lambda error = error , * * kwargs : echo_failure ( error , * * kwargs ) ) else : if not file_exists ( example_file_path ) or read_file ( example_file_path ) != contents : if sync : echo_info ( f"Writing config file to `{example_file_path}`" ) write_file ( example_file_path , contents ) else : files_failed [ example_file_path ] = True message = f'File `{example_file}` is not in sync, run "ddev validate config -s"' if file_exists ( example_file_path ) : example_file = read_file ( example_file_path ) for diff_line in difflib . context_diff ( example_file . splitlines ( ) , contents . splitlines ( ) , "current" , "expected" ) : message += f'\n{diff_line}' check_display_queue . append ( lambda example_file = example_file , * * kwargs : echo_failure ( message , * * kwargs ) ) annotate_error ( example_file_path , message ) if check_display_queue or verbose : echo_info ( f'{check}:' ) if verbose : check_display_queue . append ( lambda * * kwargs : echo_info ( 'Valid spec' , * * kwargs ) ) for display in check_display_queue : display ( indent = True ) num_files = len ( file_counter ) files_failed = len ( files_failed ) files_warned = len ( files_warned ) files_passed = num_files - ( files_failed + files_warned ) if files_failed or files_warned : click . echo ( ) if files_failed : echo_failure ( f'Files with errors: {files_failed}' ) if files_warned : echo_warning ( f'Files with warnings: {files_warned}' ) if files_passed : if files_failed or files_warned : echo_success ( f'Files valid: {files_passed}' ) else : echo_success ( f'All {num_files} configuration files are valid!' ) if files_failed : abort ( )