summaryrefslogtreecommitdiff
path: root/tools/patman/settings.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/patman/settings.py')
-rw-r--r--tools/patman/settings.py77
1 files changed, 63 insertions, 14 deletions
diff --git a/tools/patman/settings.py b/tools/patman/settings.py
index d66b22be1df..17229e0d823 100644
--- a/tools/patman/settings.py
+++ b/tools/patman/settings.py
@@ -9,8 +9,10 @@ except Exception:
import ConfigParser
import argparse
+from io import StringIO
import os
import re
+import sys
from u_boot_pylib import gitutil
@@ -226,7 +228,7 @@ nxp = Zhikang Zhang <zhikang.zhang@nxp.com>
f.close()
-def _UpdateDefaults(main_parser, config):
+def _UpdateDefaults(main_parser, config, argv):
"""Update the given OptionParser defaults based on config.
We'll walk through all of the settings from all parsers.
@@ -242,6 +244,7 @@ def _UpdateDefaults(main_parser, config):
updated.
config: An instance of _ProjectConfigParser that we will query
for settings.
+ argv (list of str or None): Arguments to parse
"""
# Find all the parsers and subparsers
parsers = [main_parser]
@@ -252,10 +255,45 @@ def _UpdateDefaults(main_parser, config):
# Collect the defaults from each parser
defaults = {}
parser_defaults = []
+ argv = list(argv)
+ orig_argv = argv
+
+ bad = False
+ full_parser_list = []
for parser in parsers:
- pdefs = parser.parse_known_args()[0]
- parser_defaults.append(pdefs)
- defaults.update(vars(pdefs))
+ argv_list = [orig_argv]
+ special_cases = []
+ if hasattr(parser, 'defaults_cmds'):
+ special_cases = parser.defaults_cmds
+ for action in parser._actions:
+ if action.choices:
+ argv_list = []
+ for choice in action.choices:
+ argv = None
+ for case in special_cases:
+ if case[0] == choice:
+ argv = case
+ argv_list.append(argv or [choice])
+
+ for argv in argv_list:
+ parser.message = None
+ old_val = parser.catch_error
+ try:
+ parser.catch_error = True
+ pdefs = parser.parse_known_args(argv)[0]
+ finally:
+ parser.catch_error = old_val
+
+ # if parser.message:
+ # print('bad', argv, parser.message)
+ # bad = True
+
+ parser_defaults.append(pdefs)
+ defaults.update(vars(pdefs))
+ full_parser_list.append(parser)
+ if bad:
+ print('Internal parsing error')
+ sys.exit(1)
# Go through the settings and collect defaults
for name, val in config.items('settings'):
@@ -270,12 +308,18 @@ def _UpdateDefaults(main_parser, config):
defaults[name] = val
else:
print("WARNING: Unknown setting %s" % name)
+ if 'cmd' in defaults:
+ del defaults['cmd']
+ if 'subcmd' in defaults:
+ del defaults['subcmd']
# Set all the defaults and manually propagate them to subparsers
main_parser.set_defaults(**defaults)
- for parser, pdefs in zip(parsers, parser_defaults):
+ assert len(full_parser_list) == len(parser_defaults)
+ for parser, pdefs in zip(full_parser_list, parser_defaults):
parser.set_defaults(**{k: v for k, v in defaults.items()
if k in pdefs})
+ return defaults
def _ReadAliasFile(fname):
@@ -334,7 +378,7 @@ def GetItems(config, section):
return []
-def Setup(parser, project_name, config_fname=None):
+def Setup(parser, project_name, argv, config_fname=None):
"""Set up the settings module by reading config files.
Unless `config_fname` is specified, a `.patman` config file local
@@ -347,8 +391,9 @@ def Setup(parser, project_name, config_fname=None):
parser: The parser to update.
project_name: Name of project that we're working on; we'll look
for sections named "project_section" as well.
- config_fname: Config filename to read. An error is raised if it
- does not exist.
+ config_fname: Config filename to read, or None for default, or False
+ for an empty config. An error is raised if it does not exist.
+ argv (list of str or None): Arguments to parse, or None for default
"""
# First read the git alias file if available
_ReadAliasFile('doc/git-mailrc')
@@ -357,12 +402,16 @@ def Setup(parser, project_name, config_fname=None):
if config_fname and not os.path.exists(config_fname):
raise Exception(f'provided {config_fname} does not exist')
- if not config_fname:
+ if config_fname is None:
config_fname = '%s/.patman' % os.getenv('HOME')
- has_config = os.path.exists(config_fname)
+ git_local_config_fname = os.path.join(gitutil.get_top_level() or '',
+ '.patman')
- git_local_config_fname = os.path.join(gitutil.get_top_level(), '.patman')
- has_git_local_config = os.path.exists(git_local_config_fname)
+ has_config = False
+ has_git_local_config = False
+ if config_fname is not False:
+ has_config = os.path.exists(config_fname)
+ has_git_local_config = os.path.exists(git_local_config_fname)
# Read the git local config last, so that its values override
# those of the global config, if any.
@@ -371,7 +420,7 @@ def Setup(parser, project_name, config_fname=None):
if has_git_local_config:
config.read(git_local_config_fname)
- if not (has_config or has_git_local_config):
+ if config_fname is not False and not (has_config or has_git_local_config):
print("No config file found.\nCreating ~/.patman...\n")
CreatePatmanConfigFile(config_fname)
@@ -382,7 +431,7 @@ def Setup(parser, project_name, config_fname=None):
for name, value in GetItems(config, 'bounces'):
bounces.add(value)
- _UpdateDefaults(parser, config)
+ return _UpdateDefaults(parser, config, argv)
# These are the aliases we understand, indexed by alias. Each member is a list.