All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] add support for repository-local .patman config file
@ 2022-12-19 15:50 Maxim Cournoyer
  2022-12-19 15:50 ` [PATCH 1/6] patman: fix pep8 warnings in settings module Maxim Cournoyer
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Maxim Cournoyer @ 2022-12-19 15:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: Maxim Cournoyer, Simon Glass

This series is based on top of series #333345.  It adds support for a
.patman config file local to the git repository.  A new test
'test_settings.py' test module is added; it is automatically
discovered and run via pytest, e.g.: 'cd tools/patman && pytest'.


Maxim Cournoyer (6):
  patman: fix pep8 warnings in settings module
  patman: replace deprecated SafeConfigParser with ConfigParser
  patman: import gitutil module where it is needed
  patman: set the default config_fname argument value to None
  patman: fail early in Setup when provided config file does not exist
  patman: additionally honor a local .patman config file

 tools/patman/__main__.py      |   3 +-
 tools/patman/patman.rst       |   8 ++-
 tools/patman/settings.py      | 101 +++++++++++++++++++++-------------
 tools/patman/test_settings.py |  43 +++++++++++++++
 4 files changed, 115 insertions(+), 40 deletions(-)
 create mode 100644 tools/patman/test_settings.py


base-commit: 9bd3d354a1a0712ac27c717df9ad60566b0406ee
prerequisite-patch-id: 10ced6811f0468ea30ab793f3d33a43416dc148c
prerequisite-patch-id: d841542388f09c77a7b22bc7b94d72628408fd7f
prerequisite-patch-id: 414fe8a358404113a0926217fcd75150d1aabaf6
prerequisite-patch-id: 59f0b30f075c78657a17cbbb75af471e37580bdb
prerequisite-patch-id: c7a9c4f2bd34df9da0f173c61fa40bf2f89b6929
prerequisite-patch-id: bd190cf8b6da6e8b20125f957c44cc7f7ea5dd5b
prerequisite-patch-id: 26558d3671f2a854303a959f738dfb67b25f7109
prerequisite-patch-id: 19f2332545f2c338004b1728e5cb15cce32656c0
-- 
2.38.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/6] patman: fix pep8 warnings in settings module
  2022-12-19 15:50 [PATCH 0/6] add support for repository-local .patman config file Maxim Cournoyer
@ 2022-12-19 15:50 ` Maxim Cournoyer
  2022-12-19 19:20   ` Simon Glass
  2022-12-19 15:50 ` [PATCH 2/6] patman: replace deprecated SafeConfigParser with ConfigParser Maxim Cournoyer
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Maxim Cournoyer @ 2022-12-19 15:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: Maxim Cournoyer, Simon Glass

Remove extraneous imports, variables and comply to PEP 8 maximum line
width, among other PEP 8 changes suggested by Pyflake.

Signed-off-by: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
---

 tools/patman/settings.py | 38 +++++++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/tools/patman/settings.py b/tools/patman/settings.py
index 903d6fcb0b..b6884a073e 100644
--- a/tools/patman/settings.py
+++ b/tools/patman/settings.py
@@ -4,16 +4,13 @@
 
 try:
     import configparser as ConfigParser
-except:
+except Exception:
     import ConfigParser
 
 import argparse
 import os
 import re
 
-from patman import command
-from patman import tools
-
 """Default settings per-project.
 
 These are used by _ProjectConfigParser.  Settings names should match
@@ -32,6 +29,7 @@ _default_settings = {
     },
 }
 
+
 class _ProjectConfigParser(ConfigParser.SafeConfigParser):
     """ConfigParser that handles projects.
 
@@ -83,8 +81,8 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser):
     def __init__(self, project_name):
         """Construct _ProjectConfigParser.
 
-        In addition to standard SafeConfigParser initialization, this also loads
-        project defaults.
+        In addition to standard SafeConfigParser initialization, this
+        also loads project defaults.
 
         Args:
             project_name: The name of the project.
@@ -155,6 +153,7 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser):
         item_dict.update(project_items)
         return {(item, val) for item, val in item_dict.items()}
 
+
 def ReadGitAliases(fname):
     """Read a git alias file. This is in the form used by git:
 
@@ -170,7 +169,7 @@ def ReadGitAliases(fname):
         print("Warning: Cannot find alias file '%s'" % fname)
         return
 
-    re_line = re.compile('alias\s+(\S+)\s+(.*)')
+    re_line = re.compile(r'alias\s+(\S+)\s+(.*)')
     for line in fd.readlines():
         line = line.strip()
         if not line or line[0] == '#':
@@ -190,6 +189,7 @@ def ReadGitAliases(fname):
 
     fd.close()
 
+
 def CreatePatmanConfigFile(gitutil, config_fname):
     """Creates a config file under $(HOME)/.patman if it can't find one.
 
@@ -200,12 +200,12 @@ def CreatePatmanConfigFile(gitutil, config_fname):
         None
     """
     name = gitutil.get_default_user_name()
-    if name == None:
+    if name is None:
         name = input("Enter name: ")
 
     email = gitutil.get_default_user_email()
 
-    if email == None:
+    if email is None:
         email = input("Enter email: ")
 
     try:
@@ -220,7 +220,8 @@ me: %s <%s>
 [bounces]
 nxp = Zhikang Zhang <zhikang.zhang@nxp.com>
 ''' % (name, email), file=f)
-    f.close();
+    f.close()
+
 
 def _UpdateDefaults(main_parser, config):
     """Update the given OptionParser defaults based on config.
@@ -242,8 +243,8 @@ def _UpdateDefaults(main_parser, config):
     # Find all the parsers and subparsers
     parsers = [main_parser]
     parsers += [subparser for action in main_parser._actions
-                  if isinstance(action, argparse._SubParsersAction)
-                  for _, subparser in action.choices.items()]
+                if isinstance(action, argparse._SubParsersAction)
+                for _, subparser in action.choices.items()]
 
     # Collect the defaults from each parser
     defaults = {}
@@ -270,8 +271,9 @@ def _UpdateDefaults(main_parser, config):
     # Set all the defaults and manually propagate them to subparsers
     main_parser.set_defaults(**defaults)
     for parser, pdefs in zip(parsers, parser_defaults):
-        parser.set_defaults(**{ k: v for k, v in defaults.items()
-                                    if k in pdefs })
+        parser.set_defaults(**{k: v for k, v in defaults.items()
+                               if k in pdefs})
+
 
 def _ReadAliasFile(fname):
     """Read in the U-Boot git alias file if it exists.
@@ -298,6 +300,7 @@ def _ReadAliasFile(fname):
         if bad_line:
             print(bad_line)
 
+
 def _ReadBouncesFile(fname):
     """Read in the bounces file if it exists
 
@@ -311,6 +314,7 @@ def _ReadBouncesFile(fname):
                     continue
                 bounces.add(line.strip())
 
+
 def GetItems(config, section):
     """Get the items from a section of the config.
 
@@ -323,10 +327,9 @@ def GetItems(config, section):
     """
     try:
         return config.items(section)
-    except ConfigParser.NoSectionError as e:
+    except ConfigParser.NoSectionError:
         return []
-    except:
-        raise
+
 
 def Setup(gitutil, parser, project_name, config_fname=''):
     """Set up the settings module by reading config files.
@@ -358,6 +361,7 @@ def Setup(gitutil, parser, project_name, config_fname=''):
 
     _UpdateDefaults(parser, config)
 
+
 # These are the aliases we understand, indexed by alias. Each member is a list.
 alias = {}
 bounces = set()
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/6] patman: replace deprecated SafeConfigParser with ConfigParser
  2022-12-19 15:50 [PATCH 0/6] add support for repository-local .patman config file Maxim Cournoyer
  2022-12-19 15:50 ` [PATCH 1/6] patman: fix pep8 warnings in settings module Maxim Cournoyer
@ 2022-12-19 15:50 ` Maxim Cournoyer
  2022-12-19 19:20   ` Simon Glass
  2022-12-19 15:50 ` [PATCH 3/6] patman: import gitutil module where it is needed Maxim Cournoyer
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Maxim Cournoyer @ 2022-12-19 15:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: Maxim Cournoyer, Simon Glass

The SafeConfigParser class has been renamed in Python 3.2 to
ConfigParser, and the old alias has been deprecated since.

Signed-off-by: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
---

 tools/patman/settings.py | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/tools/patman/settings.py b/tools/patman/settings.py
index b6884a073e..7fb9d6d5a0 100644
--- a/tools/patman/settings.py
+++ b/tools/patman/settings.py
@@ -30,7 +30,7 @@ _default_settings = {
 }
 
 
-class _ProjectConfigParser(ConfigParser.SafeConfigParser):
+class _ProjectConfigParser(ConfigParser.ConfigParser):
     """ConfigParser that handles projects.
 
     There are two main goals of this class:
@@ -81,14 +81,14 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser):
     def __init__(self, project_name):
         """Construct _ProjectConfigParser.
 
-        In addition to standard SafeConfigParser initialization, this
-        also loads project defaults.
+        In addition to standard ConfigParser initialization, this also
+        loads project defaults.
 
         Args:
             project_name: The name of the project.
         """
         self._project_name = project_name
-        ConfigParser.SafeConfigParser.__init__(self)
+        ConfigParser.ConfigParser.__init__(self)
 
         # Update the project settings in the config based on
         # the _default_settings global.
@@ -100,31 +100,31 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser):
             self.set(project_settings, setting_name, setting_value)
 
     def get(self, section, option, *args, **kwargs):
-        """Extend SafeConfigParser to try project_section before section.
+        """Extend ConfigParser to try project_section before section.
 
         Args:
-            See SafeConfigParser.
+            See ConfigParser.
         Returns:
-            See SafeConfigParser.
+            See ConfigParser.
         """
         try:
-            val = ConfigParser.SafeConfigParser.get(
+            val = ConfigParser.ConfigParser.get(
                 self, "%s_%s" % (self._project_name, section), option,
                 *args, **kwargs
             )
         except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
-            val = ConfigParser.SafeConfigParser.get(
+            val = ConfigParser.ConfigParser.get(
                 self, section, option, *args, **kwargs
             )
         return val
 
     def items(self, section, *args, **kwargs):
-        """Extend SafeConfigParser to add project_section to section.
+        """Extend ConfigParser to add project_section to section.
 
         Args:
-            See SafeConfigParser.
+            See ConfigParser.
         Returns:
-            See SafeConfigParser.
+            See ConfigParser.
         """
         project_items = []
         has_project_section = False
@@ -132,7 +132,7 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser):
 
         # Get items from the project section
         try:
-            project_items = ConfigParser.SafeConfigParser.items(
+            project_items = ConfigParser.ConfigParser.items(
                 self, "%s_%s" % (self._project_name, section), *args, **kwargs
             )
             has_project_section = True
@@ -141,7 +141,7 @@ class _ProjectConfigParser(ConfigParser.SafeConfigParser):
 
         # Get top-level items
         try:
-            top_items = ConfigParser.SafeConfigParser.items(
+            top_items = ConfigParser.ConfigParser.items(
                 self, section, *args, **kwargs
             )
         except ConfigParser.NoSectionError:
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/6] patman: import gitutil module where it is needed
  2022-12-19 15:50 [PATCH 0/6] add support for repository-local .patman config file Maxim Cournoyer
  2022-12-19 15:50 ` [PATCH 1/6] patman: fix pep8 warnings in settings module Maxim Cournoyer
  2022-12-19 15:50 ` [PATCH 2/6] patman: replace deprecated SafeConfigParser with ConfigParser Maxim Cournoyer
@ 2022-12-19 15:50 ` Maxim Cournoyer
  2022-12-19 19:20   ` Simon Glass
  2022-12-19 15:50 ` [PATCH 4/6] patman: set the default config_fname argument value to None Maxim Cournoyer
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Maxim Cournoyer @ 2022-12-19 15:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: Maxim Cournoyer, Simon Glass

Instead of propagating it from the module entry point (main script).

Signed-off-by: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
---

 tools/patman/__main__.py | 3 +--
 tools/patman/settings.py | 8 +++++---
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/tools/patman/__main__.py b/tools/patman/__main__.py
index 11f19281fb..3f092367ec 100755
--- a/tools/patman/__main__.py
+++ b/tools/patman/__main__.py
@@ -22,7 +22,6 @@ if __name__ == "__main__":
 from patman import command
 from patman import control
 from patman import func_test
-from patman import gitutil
 from patman import project
 from patman import settings
 from patman import terminal
@@ -119,7 +118,7 @@ status.add_argument('-f', '--force', action='store_true',
 argv = sys.argv[1:]
 args, rest = parser.parse_known_args(argv)
 if hasattr(args, 'project'):
-    settings.Setup(gitutil, parser, args.project, '')
+    settings.Setup(parser, args.project, '')
     args, rest = parser.parse_known_args(argv)
 
 # If we have a command, it is safe to parse all arguments
diff --git a/tools/patman/settings.py b/tools/patman/settings.py
index 7fb9d6d5a0..5efad5ed78 100644
--- a/tools/patman/settings.py
+++ b/tools/patman/settings.py
@@ -11,6 +11,8 @@ import argparse
 import os
 import re
 
+from patman import gitutil
+
 """Default settings per-project.
 
 These are used by _ProjectConfigParser.  Settings names should match
@@ -190,7 +192,7 @@ def ReadGitAliases(fname):
     fd.close()
 
 
-def CreatePatmanConfigFile(gitutil, config_fname):
+def CreatePatmanConfigFile(config_fname):
     """Creates a config file under $(HOME)/.patman if it can't find one.
 
     Args:
@@ -331,7 +333,7 @@ def GetItems(config, section):
         return []
 
 
-def Setup(gitutil, parser, project_name, config_fname=''):
+def Setup(parser, project_name, config_fname=''):
     """Set up the settings module by reading config files.
 
     Args:
@@ -348,7 +350,7 @@ def Setup(gitutil, parser, project_name, config_fname=''):
 
     if not os.path.exists(config_fname):
         print("No config file found ~/.patman\nCreating one...\n")
-        CreatePatmanConfigFile(gitutil, config_fname)
+        CreatePatmanConfigFile(config_fname)
 
     config.read(config_fname)
 
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/6] patman: set the default config_fname argument value to None
  2022-12-19 15:50 [PATCH 0/6] add support for repository-local .patman config file Maxim Cournoyer
                   ` (2 preceding siblings ...)
  2022-12-19 15:50 ` [PATCH 3/6] patman: import gitutil module where it is needed Maxim Cournoyer
@ 2022-12-19 15:50 ` Maxim Cournoyer
  2022-12-19 19:20   ` Simon Glass
  2022-12-19 15:50 ` [PATCH 5/6] patman: fail early in Setup when provided config file does not exist Maxim Cournoyer
  2022-12-19 15:50 ` [PATCH 6/6] patman: additionally honor a local .patman config file Maxim Cournoyer
  5 siblings, 1 reply; 14+ messages in thread
From: Maxim Cournoyer @ 2022-12-19 15:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: Maxim Cournoyer, Simon Glass

This better matches Python conventions, allowing to easily test
whether the optional argument is provided.

Signed-off-by: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
---

 tools/patman/__main__.py | 2 +-
 tools/patman/settings.py | 9 +++++----
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/tools/patman/__main__.py b/tools/patman/__main__.py
index 3f092367ec..15fd7603d7 100755
--- a/tools/patman/__main__.py
+++ b/tools/patman/__main__.py
@@ -118,7 +118,7 @@ status.add_argument('-f', '--force', action='store_true',
 argv = sys.argv[1:]
 args, rest = parser.parse_known_args(argv)
 if hasattr(args, 'project'):
-    settings.Setup(parser, args.project, '')
+    settings.Setup(parser, args.project)
     args, rest = parser.parse_known_args(argv)
 
 # If we have a command, it is safe to parse all arguments
diff --git a/tools/patman/settings.py b/tools/patman/settings.py
index 5efad5ed78..8b846799df 100644
--- a/tools/patman/settings.py
+++ b/tools/patman/settings.py
@@ -333,19 +333,20 @@ def GetItems(config, section):
         return []
 
 
-def Setup(parser, project_name, config_fname=''):
+def Setup(parser, project_name, config_fname=None):
     """Set up the settings module by reading config files.
 
     Args:
-        parser:         The parser to update
+        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 ('' for default)
+        config_fname:   Config filename to read.
     """
     # First read the git alias file if available
     _ReadAliasFile('doc/git-mailrc')
     config = _ProjectConfigParser(project_name)
-    if config_fname == '':
+
+    if not config_fname:
         config_fname = '%s/.patman' % os.getenv('HOME')
 
     if not os.path.exists(config_fname):
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 5/6] patman: fail early in Setup when provided config file does not exist
  2022-12-19 15:50 [PATCH 0/6] add support for repository-local .patman config file Maxim Cournoyer
                   ` (3 preceding siblings ...)
  2022-12-19 15:50 ` [PATCH 4/6] patman: set the default config_fname argument value to None Maxim Cournoyer
@ 2022-12-19 15:50 ` Maxim Cournoyer
  2022-12-19 19:20   ` Simon Glass
  2022-12-19 15:50 ` [PATCH 6/6] patman: additionally honor a local .patman config file Maxim Cournoyer
  5 siblings, 1 reply; 14+ messages in thread
From: Maxim Cournoyer @ 2022-12-19 15:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: Maxim Cournoyer, Simon Glass

Rationale: if the user explicitly provide this argument, they probably
intend for it to be used.

Signed-off-by: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
---

 tools/patman/settings.py | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/patman/settings.py b/tools/patman/settings.py
index 8b846799df..c05efd2475 100644
--- a/tools/patman/settings.py
+++ b/tools/patman/settings.py
@@ -340,12 +340,16 @@ 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.
+        config_fname:   Config filename to read.  An error is raised if it
+            does not exist.
     """
     # First read the git alias file if available
     _ReadAliasFile('doc/git-mailrc')
     config = _ProjectConfigParser(project_name)
 
+    if config_fname and not os.path.exists(config_fname):
+        raise Exception(f'provided {config_fname} does not exist')
+
     if not config_fname:
         config_fname = '%s/.patman' % os.getenv('HOME')
 
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 6/6] patman: additionally honor a local .patman config file
  2022-12-19 15:50 [PATCH 0/6] add support for repository-local .patman config file Maxim Cournoyer
                   ` (4 preceding siblings ...)
  2022-12-19 15:50 ` [PATCH 5/6] patman: fail early in Setup when provided config file does not exist Maxim Cournoyer
@ 2022-12-19 15:50 ` Maxim Cournoyer
  2022-12-19 19:20   ` Simon Glass
  5 siblings, 1 reply; 14+ messages in thread
From: Maxim Cournoyer @ 2022-12-19 15:50 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: Maxim Cournoyer, Simon Glass

This enables versioning a project specific patman configuration file.
It also makes it possible to declare the the project name is,
which is not a useful thing to do in $HOME/.patman.  A new test is
added, along updated documentation.

Signed-off-by: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
---

 tools/patman/patman.rst       |  8 ++++++-
 tools/patman/settings.py      | 24 +++++++++++++++----
 tools/patman/test_settings.py | 43 +++++++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+), 5 deletions(-)
 create mode 100644 tools/patman/test_settings.py

diff --git a/tools/patman/patman.rst b/tools/patman/patman.rst
index b06399b459..02c08179af 100644
--- a/tools/patman/patman.rst
+++ b/tools/patman/patman.rst
@@ -74,7 +74,7 @@ out where to send patches pretty well.
 During the first run patman creates a config file for you by taking the default
 user name and email address from the global .gitconfig file.
 
-To add your own, create a file ~/.patman like this::
+To add your own, create a file `~/.patman` like this::
 
     # patman alias file
 
@@ -85,6 +85,12 @@ To add your own, create a file ~/.patman like this::
     wolfgang: Wolfgang Denk <wd@denx.de>
     others: Mike Frysinger <vapier@gentoo.org>, Fred Bloggs <f.bloggs@napier.net>
 
+Patman will also look for a `.patman` configuration file at the root
+of the current project git repository, which makes it possible to
+override the `project` settings variable or anything else in a
+project-specific way. The values of this "local" configuration file
+take precedence over those of the "global" one.
+
 Aliases are recursive.
 
 The checkpatch.pl in the U-Boot tools/ subdirectory will be located and
diff --git a/tools/patman/settings.py b/tools/patman/settings.py
index c05efd2475..636983e32d 100644
--- a/tools/patman/settings.py
+++ b/tools/patman/settings.py
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0+
 # Copyright (c) 2011 The Chromium OS Authors.
+# Copyright (c) 2022 Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
 #
 
 try:
@@ -336,6 +337,12 @@ def GetItems(config, section):
 def Setup(parser, project_name, config_fname=None):
     """Set up the settings module by reading config files.
 
+    Unless `config_fname` is specified, a `.patman` config file local
+    to the git repository is consulted, followed by the global
+    `$HOME/.patman`. If none exists, the later is created. Values
+    defined in the local config file take precedence over those
+    defined in the global one.
+
     Args:
         parser:         The parser to update.
         project_name:   Name of project that we're working on; we'll look
@@ -352,12 +359,21 @@ def Setup(parser, project_name, config_fname=None):
 
     if not config_fname:
         config_fname = '%s/.patman' % os.getenv('HOME')
+    has_config = os.path.exists(config_fname)
 
-    if not os.path.exists(config_fname):
-        print("No config file found ~/.patman\nCreating one...\n")
-        CreatePatmanConfigFile(config_fname)
+    git_local_config_fname = os.path.join(gitutil.get_top_level(), '.patman')
+    has_git_local_config = os.path.exists(git_local_config_fname)
 
-    config.read(config_fname)
+    # Read the git local config last, so that its values override
+    # those of the global config, if any.
+    if has_config:
+        config.read(config_fname)
+    if has_git_local_config:
+        config.read(git_local_config_fname)
+
+    if not (has_config or has_git_local_config):
+        print("No config file found.\nCreating ~/.patman...\n")
+        CreatePatmanConfigFile(config_fname)
 
     for name, value in GetItems(config, 'alias'):
         alias[name] = value.split(',')
diff --git a/tools/patman/test_settings.py b/tools/patman/test_settings.py
new file mode 100644
index 0000000000..9c14b4aaa3
--- /dev/null
+++ b/tools/patman/test_settings.py
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2022 Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
+#
+
+import argparse
+import contextlib
+import os
+import subprocess
+import tempfile
+
+from patman import settings
+
+
+@contextlib.contextmanager
+def empty_git_repository():
+    with tempfile.TemporaryDirectory() as tmpdir:
+        os.chdir(tmpdir)
+        subprocess.check_call(['git', 'init'])
+        yield tmpdir
+
+
+def test_git_local_config():
+    with empty_git_repository():
+        with tempfile.NamedTemporaryFile() as global_config:
+            global_config.write(b'[settings]\n'
+                                b'project=u-boot\n')
+            global_config.flush()
+            parser = argparse.ArgumentParser()
+            parser.add_argument('-p', '--project', default='unknown')
+
+            # Test "global" config is used.
+            settings.Setup(parser, 'unknown', global_config.name)
+            args, _ = parser.parse_known_args()
+            assert args.project == 'u-boot'
+
+            # Test local config can shadow it.
+            with open('.patman', 'w', buffering=1) as f:
+                f.write('[settings]\n'
+                        'project=guix-patches\n')
+            settings.Setup(parser, 'unknown', global_config.name)
+            args, _ = parser.parse_known_args([])
+            assert args.project == 'guix-patches'
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/6] patman: fix pep8 warnings in settings module
  2022-12-19 15:50 ` [PATCH 1/6] patman: fix pep8 warnings in settings module Maxim Cournoyer
@ 2022-12-19 19:20   ` Simon Glass
  0 siblings, 0 replies; 14+ messages in thread
From: Simon Glass @ 2022-12-19 19:20 UTC (permalink / raw)
  To: Maxim Cournoyer; +Cc: U-Boot Mailing List, Maxim Cournoyer

On Mon, 19 Dec 2022 at 08:50, Maxim Cournoyer <maxim.cournoyer@gmail.com> wrote:
>
> Remove extraneous imports, variables and comply to PEP 8 maximum line
> width, among other PEP 8 changes suggested by Pyflake.
>
> Signed-off-by: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
> ---
>
>  tools/patman/settings.py | 38 +++++++++++++++++++++-----------------
>  1 file changed, 21 insertions(+), 17 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/6] patman: replace deprecated SafeConfigParser with ConfigParser
  2022-12-19 15:50 ` [PATCH 2/6] patman: replace deprecated SafeConfigParser with ConfigParser Maxim Cournoyer
@ 2022-12-19 19:20   ` Simon Glass
  0 siblings, 0 replies; 14+ messages in thread
From: Simon Glass @ 2022-12-19 19:20 UTC (permalink / raw)
  To: Maxim Cournoyer; +Cc: U-Boot Mailing List, Maxim Cournoyer

On Mon, 19 Dec 2022 at 08:50, Maxim Cournoyer <maxim.cournoyer@gmail.com> wrote:
>
> The SafeConfigParser class has been renamed in Python 3.2 to
> ConfigParser, and the old alias has been deprecated since.
>
> Signed-off-by: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
> ---
>
>  tools/patman/settings.py | 28 ++++++++++++++--------------
>  1 file changed, 14 insertions(+), 14 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/6] patman: import gitutil module where it is needed
  2022-12-19 15:50 ` [PATCH 3/6] patman: import gitutil module where it is needed Maxim Cournoyer
@ 2022-12-19 19:20   ` Simon Glass
  0 siblings, 0 replies; 14+ messages in thread
From: Simon Glass @ 2022-12-19 19:20 UTC (permalink / raw)
  To: Maxim Cournoyer; +Cc: U-Boot Mailing List, Maxim Cournoyer

On Mon, 19 Dec 2022 at 08:50, Maxim Cournoyer <maxim.cournoyer@gmail.com> wrote:
>
> Instead of propagating it from the module entry point (main script).
>
> Signed-off-by: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
> ---
>
>  tools/patman/__main__.py | 3 +--
>  tools/patman/settings.py | 8 +++++---
>  2 files changed, 6 insertions(+), 5 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/6] patman: set the default config_fname argument value to None
  2022-12-19 15:50 ` [PATCH 4/6] patman: set the default config_fname argument value to None Maxim Cournoyer
@ 2022-12-19 19:20   ` Simon Glass
  0 siblings, 0 replies; 14+ messages in thread
From: Simon Glass @ 2022-12-19 19:20 UTC (permalink / raw)
  To: Maxim Cournoyer; +Cc: U-Boot Mailing List, Maxim Cournoyer

On Mon, 19 Dec 2022 at 08:50, Maxim Cournoyer <maxim.cournoyer@gmail.com> wrote:
>
> This better matches Python conventions, allowing to easily test
> whether the optional argument is provided.
>
> Signed-off-by: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
> ---
>
>  tools/patman/__main__.py | 2 +-
>  tools/patman/settings.py | 9 +++++----
>  2 files changed, 6 insertions(+), 5 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/6] patman: fail early in Setup when provided config file does not exist
  2022-12-19 15:50 ` [PATCH 5/6] patman: fail early in Setup when provided config file does not exist Maxim Cournoyer
@ 2022-12-19 19:20   ` Simon Glass
  0 siblings, 0 replies; 14+ messages in thread
From: Simon Glass @ 2022-12-19 19:20 UTC (permalink / raw)
  To: Maxim Cournoyer; +Cc: U-Boot Mailing List, Maxim Cournoyer

On Mon, 19 Dec 2022 at 08:50, Maxim Cournoyer <maxim.cournoyer@gmail.com> wrote:
>
> Rationale: if the user explicitly provide this argument, they probably
> intend for it to be used.
>
> Signed-off-by: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
> ---
>
>  tools/patman/settings.py | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 6/6] patman: additionally honor a local .patman config file
  2022-12-19 15:50 ` [PATCH 6/6] patman: additionally honor a local .patman config file Maxim Cournoyer
@ 2022-12-19 19:20   ` Simon Glass
  2022-12-20  3:29     ` Maxim Cournoyer
  0 siblings, 1 reply; 14+ messages in thread
From: Simon Glass @ 2022-12-19 19:20 UTC (permalink / raw)
  To: Maxim Cournoyer; +Cc: U-Boot Mailing List, Maxim Cournoyer

Hi Maxim,

On Mon, 19 Dec 2022 at 08:50, Maxim Cournoyer <maxim.cournoyer@gmail.com> wrote:
>
> This enables versioning a project specific patman configuration file.
> It also makes it possible to declare the the project name is,
> which is not a useful thing to do in $HOME/.patman.  A new test is
> added, along updated documentation.
>
> Signed-off-by: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
> ---
>
>  tools/patman/patman.rst       |  8 ++++++-
>  tools/patman/settings.py      | 24 +++++++++++++++----
>  tools/patman/test_settings.py | 43 +++++++++++++++++++++++++++++++++++
>  3 files changed, 70 insertions(+), 5 deletions(-)
>  create mode 100644 tools/patman/test_settings.py
>
> diff --git a/tools/patman/patman.rst b/tools/patman/patman.rst
> index b06399b459..02c08179af 100644
> --- a/tools/patman/patman.rst
> +++ b/tools/patman/patman.rst
> @@ -74,7 +74,7 @@ out where to send patches pretty well.
>  During the first run patman creates a config file for you by taking the default
>  user name and email address from the global .gitconfig file.
>
> -To add your own, create a file ~/.patman like this::
> +To add your own, create a file `~/.patman` like this::
>
>      # patman alias file
>
> @@ -85,6 +85,12 @@ To add your own, create a file ~/.patman like this::
>      wolfgang: Wolfgang Denk <wd@denx.de>
>      others: Mike Frysinger <vapier@gentoo.org>, Fred Bloggs <f.bloggs@napier.net>
>
> +Patman will also look for a `.patman` configuration file at the root
> +of the current project git repository, which makes it possible to
> +override the `project` settings variable or anything else in a
> +project-specific way. The values of this "local" configuration file
> +take precedence over those of the "global" one.
> +
>  Aliases are recursive.
>
>  The checkpatch.pl in the U-Boot tools/ subdirectory will be located and
> diff --git a/tools/patman/settings.py b/tools/patman/settings.py
> index c05efd2475..636983e32d 100644
> --- a/tools/patman/settings.py
> +++ b/tools/patman/settings.py
> @@ -1,5 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0+
>  # Copyright (c) 2011 The Chromium OS Authors.
> +# Copyright (c) 2022 Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
>  #
>
>  try:
> @@ -336,6 +337,12 @@ def GetItems(config, section):
>  def Setup(parser, project_name, config_fname=None):
>      """Set up the settings module by reading config files.
>
> +    Unless `config_fname` is specified, a `.patman` config file local
> +    to the git repository is consulted, followed by the global
> +    `$HOME/.patman`. If none exists, the later is created. Values
> +    defined in the local config file take precedence over those
> +    defined in the global one.
> +
>      Args:
>          parser:         The parser to update.
>          project_name:   Name of project that we're working on; we'll look
> @@ -352,12 +359,21 @@ def Setup(parser, project_name, config_fname=None):
>
>      if not config_fname:
>          config_fname = '%s/.patman' % os.getenv('HOME')
> +    has_config = os.path.exists(config_fname)
>
> -    if not os.path.exists(config_fname):
> -        print("No config file found ~/.patman\nCreating one...\n")
> -        CreatePatmanConfigFile(config_fname)
> +    git_local_config_fname = os.path.join(gitutil.get_top_level(), '.patman')
> +    has_git_local_config = os.path.exists(git_local_config_fname)
>
> -    config.read(config_fname)
> +    # Read the git local config last, so that its values override
> +    # those of the global config, if any.
> +    if has_config:
> +        config.read(config_fname)
> +    if has_git_local_config:
> +        config.read(git_local_config_fname)
> +
> +    if not (has_config or has_git_local_config):
> +        print("No config file found.\nCreating ~/.patman...\n")
> +        CreatePatmanConfigFile(config_fname)
>
>      for name, value in GetItems(config, 'alias'):
>          alias[name] = value.split(',')
> diff --git a/tools/patman/test_settings.py b/tools/patman/test_settings.py
> new file mode 100644
> index 0000000000..9c14b4aaa3
> --- /dev/null
> +++ b/tools/patman/test_settings.py
> @@ -0,0 +1,43 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +#
> +# Copyright (c) 2022 Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
> +#
> +
> +import argparse
> +import contextlib
> +import os
> +import subprocess
> +import tempfile
> +
> +from patman import settings
> +
> +
> +@contextlib.contextmanager
> +def empty_git_repository():
> +    with tempfile.TemporaryDirectory() as tmpdir:
> +        os.chdir(tmpdir)
> +        subprocess.check_call(['git', 'init'])

We normally use tools.run()

> +        yield tmpdir
> +
> +
> +def test_git_local_config():
> +    with empty_git_repository():
> +        with tempfile.NamedTemporaryFile() as global_config:
> +            global_config.write(b'[settings]\n'
> +                                b'project=u-boot\n')
> +            global_config.flush()
> +            parser = argparse.ArgumentParser()
> +            parser.add_argument('-p', '--project', default='unknown')
> +
> +            # Test "global" config is used.
> +            settings.Setup(parser, 'unknown', global_config.name)
> +            args, _ = parser.parse_known_args()
> +            assert args.project == 'u-boot'
> +
> +            # Test local config can shadow it.
> +            with open('.patman', 'w', buffering=1) as f:

Can this be created in the temporary dir? At present it looks like it
might overwrite a file in the current dir?

> +                f.write('[settings]\n'
> +                        'project=guix-patches\n')
> +            settings.Setup(parser, 'unknown', global_config.name)
> +            args, _ = parser.parse_known_args([])
> +            assert args.project == 'guix-patches'
> --
> 2.38.1
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 6/6] patman: additionally honor a local .patman config file
  2022-12-19 19:20   ` Simon Glass
@ 2022-12-20  3:29     ` Maxim Cournoyer
  0 siblings, 0 replies; 14+ messages in thread
From: Maxim Cournoyer @ 2022-12-20  3:29 UTC (permalink / raw)
  To: Simon Glass; +Cc: U-Boot Mailing List, Maxim Cournoyer

Hi Simon,

Simon Glass <sjg@chromium.org> writes:

> Hi Maxim,
>
> On Mon, 19 Dec 2022 at 08:50, Maxim Cournoyer <maxim.cournoyer@gmail.com> wrote:
>>
>> This enables versioning a project specific patman configuration file.
>> It also makes it possible to declare the the project name is,
>> which is not a useful thing to do in $HOME/.patman.  A new test is
>> added, along updated documentation.
>>
>> Signed-off-by: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
>> ---
>>
>>  tools/patman/patman.rst       |  8 ++++++-
>>  tools/patman/settings.py      | 24 +++++++++++++++----
>>  tools/patman/test_settings.py | 43 +++++++++++++++++++++++++++++++++++
>>  3 files changed, 70 insertions(+), 5 deletions(-)
>>  create mode 100644 tools/patman/test_settings.py

[...]

>> diff --git a/tools/patman/test_settings.py b/tools/patman/test_settings.py
>> new file mode 100644
>> index 0000000000..9c14b4aaa3
>> --- /dev/null
>> +++ b/tools/patman/test_settings.py
>> @@ -0,0 +1,43 @@
>> +# SPDX-License-Identifier: GPL-2.0+
>> +#
>> +# Copyright (c) 2022 Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
>> +#
>> +
>> +import argparse
>> +import contextlib
>> +import os
>> +import subprocess
>> +import tempfile
>> +
>> +from patman import settings
>> +
>> +
>> +@contextlib.contextmanager
>> +def empty_git_repository():
>> +    with tempfile.TemporaryDirectory() as tmpdir:
>> +        os.chdir(tmpdir)
>> +        subprocess.check_call(['git', 'init'])
>
> We normally use tools.run()

Adjusted like so:

--8<---------------cut here---------------start------------->8---
modified   tools/patman/test_settings.py
@@ -6,18 +6,18 @@
 import argparse
 import contextlib
 import os
-import subprocess
 import sys
 import tempfile
 
 from patman import settings
+from patman import tools
 
 
 @contextlib.contextmanager
 def empty_git_repository():
     with tempfile.TemporaryDirectory() as tmpdir:
         os.chdir(tmpdir)
-        subprocess.check_call(['git', 'init'])
+        tools.run('git', 'init', raise_on_error=True)
         yield tmpdir
--8<---------------cut here---------------end--------------->8---

>> +        yield tmpdir
>> +
>> +
>> +def test_git_local_config():
>> +    with empty_git_repository():
>> +        with tempfile.NamedTemporaryFile() as global_config:
>> +            global_config.write(b'[settings]\n'
>> +                                b'project=u-boot\n')
>> +            global_config.flush()
>> +            parser = argparse.ArgumentParser()
>> +            parser.add_argument('-p', '--project', default='unknown')
>> +
>> +            # Test "global" config is used.
>> +            settings.Setup(parser, 'unknown', global_config.name)
>> +            args, _ = parser.parse_known_args()
>> +            assert args.project == 'u-boot'
>> +
>> +            # Test local config can shadow it.
>> +            with open('.patman', 'w', buffering=1) as f:
>
> Can this be created in the temporary dir? At present it looks like it
> might overwrite a file in the current dir?

The 'empty_git_repository' context manager chdir to a temporary
directory upon entry, so anything that runs in its block such as the
open call above will be executed in that temporary directory.  See the
'os.chdir(tmpdir)' line above.

I sent a v4 with the above change.

-- 
Thanks,
Maxim

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2022-12-20  3:29 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-19 15:50 [PATCH 0/6] add support for repository-local .patman config file Maxim Cournoyer
2022-12-19 15:50 ` [PATCH 1/6] patman: fix pep8 warnings in settings module Maxim Cournoyer
2022-12-19 19:20   ` Simon Glass
2022-12-19 15:50 ` [PATCH 2/6] patman: replace deprecated SafeConfigParser with ConfigParser Maxim Cournoyer
2022-12-19 19:20   ` Simon Glass
2022-12-19 15:50 ` [PATCH 3/6] patman: import gitutil module where it is needed Maxim Cournoyer
2022-12-19 19:20   ` Simon Glass
2022-12-19 15:50 ` [PATCH 4/6] patman: set the default config_fname argument value to None Maxim Cournoyer
2022-12-19 19:20   ` Simon Glass
2022-12-19 15:50 ` [PATCH 5/6] patman: fail early in Setup when provided config file does not exist Maxim Cournoyer
2022-12-19 19:20   ` Simon Glass
2022-12-19 15:50 ` [PATCH 6/6] patman: additionally honor a local .patman config file Maxim Cournoyer
2022-12-19 19:20   ` Simon Glass
2022-12-20  3:29     ` Maxim Cournoyer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.