config.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. """Read and write configuration settings
  2. """
  3. from milc import cli
  4. def print_config(section, key):
  5. """Print a single config setting to stdout.
  6. """
  7. cli.echo('%s.%s{fg_cyan}={fg_reset}%s', section, key, cli.config[section][key])
  8. def show_config():
  9. """Print the current configuration to stdout.
  10. """
  11. for section in cli.config:
  12. for key in cli.config[section]:
  13. print_config(section, key)
  14. def parse_config_token(config_token):
  15. """Split a user-supplied configuration-token into its components.
  16. """
  17. section = option = value = None
  18. if '=' in config_token and '.' not in config_token:
  19. cli.log.error('Invalid configuration token, the key must be of the form <section>.<option>: %s', config_token)
  20. return section, option, value
  21. # Separate the key (<section>.<option>) from the value
  22. if '=' in config_token:
  23. key, value = config_token.split('=')
  24. else:
  25. key = config_token
  26. # Extract the section and option from the key
  27. if '.' in key:
  28. section, option = key.split('.', 1)
  29. else:
  30. section = key
  31. return section, option, value
  32. def set_config(section, option, value):
  33. """Set a config key in the running config.
  34. """
  35. log_string = '%s.%s{fg_cyan}:{fg_reset} %s {fg_cyan}->{fg_reset} %s'
  36. if cli.args.read_only:
  37. log_string += ' {fg_red}(change not written)'
  38. cli.echo(log_string, section, option, cli.config[section][option], value)
  39. if not cli.args.read_only:
  40. if value == 'None':
  41. del cli.config[section][option]
  42. else:
  43. cli.config[section][option] = value
  44. @cli.argument('-ro', '--read-only', arg_only=True, action='store_true', help='Operate in read-only mode.')
  45. @cli.argument('configs', nargs='*', arg_only=True, help='Configuration options to read or write.')
  46. @cli.subcommand("Read and write configuration settings.")
  47. def config(cli):
  48. """Read and write config settings.
  49. This script iterates over the config_tokens supplied as argument. Each config_token has the following form:
  50. section[.key][=value]
  51. If only a section (EG 'compile') is supplied all keys for that section will be displayed.
  52. If section.key is supplied the value for that single key will be displayed.
  53. If section.key=value is supplied the value for that single key will be set.
  54. If section.key=None is supplied the key will be deleted.
  55. No validation is done to ensure that the supplied section.key is actually used by qmk scripts.
  56. """
  57. if not cli.args.configs:
  58. return show_config()
  59. # Process config_tokens
  60. save_config = False
  61. for argument in cli.args.configs:
  62. # Split on space in case they quoted multiple config tokens
  63. for config_token in argument.split(' '):
  64. section, option, value = parse_config_token(config_token)
  65. # Validation
  66. if option and '.' in option:
  67. cli.log.error('Config keys may not have more than one period! "%s" is not valid.', config_token)
  68. return False
  69. # Do what the user wants
  70. if section and option and value:
  71. # Write a configuration option
  72. set_config(section, option, value)
  73. if not cli.args.read_only:
  74. save_config = True
  75. elif section and option:
  76. # Display a single key
  77. print_config(section, option)
  78. elif section:
  79. # Display an entire section
  80. for key in cli.config[section]:
  81. print_config(section, key)
  82. # Ending actions
  83. if save_config:
  84. cli.save_config()
  85. return True