diff options
author | ThiƩbaud Weksteen <tweek@google.com> | 2020-08-28 14:58:45 +0200 |
---|---|---|
committer | ThiƩbaud Weksteen <tweek@google.com> | 2020-09-01 09:52:13 +0200 |
commit | c9ba009aab3783cca8a71389de6ec2701c916b5e (patch) | |
tree | 33fd89c4413e02f5b12d92c8c390690c8bb178b9 | |
parent | 7698778fb0f02c517ca0ffe6f85f80991e49e4a3 (diff) | |
download | repohooks-c9ba009aab3783cca8a71389de6ec2701c916b5e.tar.gz |
config: add {Local,Global}PreUploadFile classes
Creates 2 new classes to differentiate local (PREUPLOAD.cfg) and global
(GLOBAL-PREUPLOAD.cfg) files. While not useful yet, this allows to
implement validation that is specific to local files.
Ideally, PreUploadFile would be declared as @abstractclass but the
support for py2/py3 makes this constraint tedious to implement.
Test: pre-upload.py
Bug: 160223496
Change-Id: I75e0e644f713002f1ba50a405965362c1c5a7589
-rw-r--r-- | rh/config.py | 58 | ||||
-rwxr-xr-x | rh/config_unittest.py | 4 |
2 files changed, 46 insertions, 16 deletions
diff --git a/rh/config.py b/rh/config.py index 6240559..459d691 100644 --- a/rh/config.py +++ b/rh/config.py @@ -18,6 +18,7 @@ from __future__ import print_function import functools +import itertools import os import shlex import sys @@ -123,7 +124,8 @@ class PreUploadConfig(object): Args: config: A configparse.ConfigParser instance. - source: Where this config came from. + source: Where this config came from. This is used in error messages to + facilitate debugging. It is not necessarily a valid path. """ self.config = config if config else RawConfigParser() self.source = source @@ -253,7 +255,15 @@ class PreUploadConfig(object): class PreUploadFile(PreUploadConfig): - """A single config (file) used for `repo upload` hooks.""" + """A single config (file) used for `repo upload` hooks. + + This is an abstract class that requires subclasses to define the FILENAME + constant. + + Attributes: + path: The path of the file. + """ + FILENAME = None def __init__(self, path): """Initialize. @@ -263,6 +273,7 @@ class PreUploadFile(PreUploadConfig): """ super(PreUploadFile, self).__init__(source=path) + self.path = path try: self.config.read(path) except configparser.ParsingError as e: @@ -270,6 +281,31 @@ class PreUploadFile(PreUploadConfig): self._validate() + @classmethod + def from_paths(cls, paths): + """Search for files within paths that matches the class FILENAME. + + Args: + paths: List of directories to look for config files. + + Yields: + For each valid file found, an instance is created and returned. + """ + for path in paths: + path = os.path.join(path, cls.FILENAME) + if os.path.exists(path): + yield cls(path) + + +class LocalPreUploadFile(PreUploadFile): + """A single config file for a project (PREUPLOAD.cfg).""" + FILENAME = 'PREUPLOAD.cfg' + + +class GlobalPreUploadFile(PreUploadFile): + """A single config file for a repo (GLOBAL-PREUPLOAD.cfg).""" + FILENAME = 'GLOBAL-PREUPLOAD.cfg' + class PreUploadSettings(PreUploadConfig): """Settings for `repo upload` hooks. @@ -278,9 +314,6 @@ class PreUploadSettings(PreUploadConfig): settings for a particular project. """ - FILENAME = 'PREUPLOAD.cfg' - GLOBAL_FILENAME = 'GLOBAL-PREUPLOAD.cfg' - def __init__(self, paths=('',), global_paths=()): """Initialize. @@ -292,16 +325,13 @@ class PreUploadSettings(PreUploadConfig): """ super(PreUploadSettings, self).__init__() - def _search(paths, filename): - for path in paths: - path = os.path.join(path, filename) - if os.path.exists(path): - self.paths.append(path) - self.update(PreUploadFile(path)) - self.paths = [] - _search(global_paths, self.GLOBAL_FILENAME) - _search(paths, self.FILENAME) + for config in itertools.chain( + GlobalPreUploadFile.from_paths(global_paths), + LocalPreUploadFile.from_paths(paths)): + self.paths.append(config.path) + self.update(config) + # We validated configs in isolation, now do one final pass altogether. self.source = '{%s}' % '|'.join(self.paths) diff --git a/rh/config_unittest.py b/rh/config_unittest.py index 08128e8..596e17b 100755 --- a/rh/config_unittest.py +++ b/rh/config_unittest.py @@ -127,7 +127,7 @@ class PreUploadSettingsTests(unittest.TestCase): def _write_config(self, data, filename=None): """Helper to write out a config file for testing.""" if filename is None: - filename = rh.config.PreUploadSettings.FILENAME + filename = rh.config.LocalPreUploadFile.FILENAME path = os.path.join(self.tempdir, filename) with open(path, 'w') as fp: fp.write(data) @@ -135,7 +135,7 @@ class PreUploadSettingsTests(unittest.TestCase): def _write_global_config(self, data): """Helper to write out a global config file for testing.""" self._write_config( - data, filename=rh.config.PreUploadSettings.GLOBAL_FILENAME) + data, filename=rh.config.GlobalPreUploadFile.FILENAME) def testGlobalConfigs(self): """Verify global configs stack properly.""" |