* Rework how bin/qmk handles subcommands * qmk config wip * Code to show all configs * Fully working `qmk config` command * Mark some CLI arguments so they don't pollute the config file * Fleshed out config support, nicer subcommand support * sync with installable cli * pyformat * Add a test for subcommand_modules * Documentation for the `qmk config` command * split config_token on space so qmk config is more predictable * Rework how subcommands are imported * Document `arg_only` * Document deleting from CLI * Document how multiple operations work * Add cli config to the doc index * Add tests for the cli commands * Make running the tests more reliable * Be more selective about building all default keymaps * Update new-keymap to fit the new subcommand style * Add documentation about writing CLI scripts * Document new-keyboard * Update docs/cli_configuration.md Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Update docs/cli_development.md Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Update docs/cli_development.md Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Update docs/cli_development.md Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Address yan's comments. * Apply suggestions from code review suggestions from @noahfrederick Co-Authored-By: Noah Frederick <code@noahfrederick.com> * Apply suggestions from code review Co-Authored-By: Noah Frederick <code@noahfrederick.com> * Remove pip3 from the test runner
		
			
				
	
	
		
			97 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
"""Read and write configuration settings
 | 
						|
"""
 | 
						|
import os
 | 
						|
import subprocess
 | 
						|
 | 
						|
from milc import cli
 | 
						|
 | 
						|
 | 
						|
def print_config(section, key):
 | 
						|
    """Print a single config setting to stdout.
 | 
						|
    """
 | 
						|
    cli.echo('%s.%s{fg_cyan}={fg_reset}%s', section, key, cli.config[section][key])
 | 
						|
 | 
						|
 | 
						|
@cli.argument('-ro', '--read-only', action='store_true', help='Operate in read-only mode.')
 | 
						|
@cli.argument('configs', nargs='*', arg_only=True, help='Configuration options to read or write.')
 | 
						|
@cli.subcommand("Read and write configuration settings.")
 | 
						|
def config(cli):
 | 
						|
    """Read and write config settings.
 | 
						|
 | 
						|
    This script iterates over the config_tokens supplied as argument. Each config_token has the following form:
 | 
						|
 | 
						|
        section[.key][=value]
 | 
						|
 | 
						|
    If only a section (EG 'compile') is supplied all keys for that section will be displayed.
 | 
						|
 | 
						|
    If section.key is supplied the value for that single key will be displayed.
 | 
						|
 | 
						|
    If section.key=value is supplied the value for that single key will be set.
 | 
						|
 | 
						|
    If section.key=None is supplied the key will be deleted.
 | 
						|
 | 
						|
    No validation is done to ensure that the supplied section.key is actually used by qmk scripts.
 | 
						|
    """
 | 
						|
    if not cli.args.configs:
 | 
						|
        # Walk the config tree
 | 
						|
        for section in cli.config:
 | 
						|
            for key in cli.config[section]:
 | 
						|
                print_config(section, key)
 | 
						|
 | 
						|
        return True
 | 
						|
 | 
						|
    # Process config_tokens
 | 
						|
    save_config = False
 | 
						|
 | 
						|
    for argument in cli.args.configs:
 | 
						|
        # Split on space in case they quoted multiple config tokens
 | 
						|
        for config_token in argument.split(' '):
 | 
						|
            # Extract the section, config_key, and value to write from the supplied config_token.
 | 
						|
            if '=' in config_token:
 | 
						|
                key, value = config_token.split('=')
 | 
						|
            else:
 | 
						|
                key = config_token
 | 
						|
                value = None
 | 
						|
 | 
						|
            if '.' in key:
 | 
						|
                section, config_key = key.split('.', 1)
 | 
						|
            else:
 | 
						|
                section = key
 | 
						|
                config_key = None
 | 
						|
 | 
						|
            # Validation
 | 
						|
            if config_key and '.' in config_key:
 | 
						|
                cli.log.error('Config keys may not have more than one period! "%s" is not valid.', key)
 | 
						|
                return False
 | 
						|
 | 
						|
            # Do what the user wants
 | 
						|
            if section and config_key and value:
 | 
						|
                # Write a config key
 | 
						|
                log_string = '%s.%s{fg_cyan}:{fg_reset} %s {fg_cyan}->{fg_reset} %s'
 | 
						|
                if cli.args.read_only:
 | 
						|
                    log_string += ' {fg_red}(change not written)'
 | 
						|
 | 
						|
                cli.echo(log_string, section, config_key, cli.config[section][config_key], value)
 | 
						|
 | 
						|
                if not cli.args.read_only:
 | 
						|
                    if value == 'None':
 | 
						|
                        del cli.config[section][config_key]
 | 
						|
                    else:
 | 
						|
                        cli.config[section][config_key] = value
 | 
						|
                    save_config = True
 | 
						|
 | 
						|
            elif section and config_key:
 | 
						|
                # Display a single key
 | 
						|
                print_config(section, config_key)
 | 
						|
 | 
						|
            elif section:
 | 
						|
                # Display an entire section
 | 
						|
                for key in cli.config[section]:
 | 
						|
                    print_config(section, key)
 | 
						|
 | 
						|
    # Ending actions
 | 
						|
    if save_config:
 | 
						|
        cli.save_config()
 | 
						|
 | 
						|
    return True
 |