From ecd1a171bae4f101bfe956d8a22bc023fb0cc9d3 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 21 Mar 2017 12:25:03 +0000 Subject: [PATCH] Support repodir config files Not everyone wants to use build release notes separately from their main documentation. For these users, having a 'notes' directory inside the 'releasenotes' directory is unnecessary. However, this also means we must be able to move the config file out of the 'releasesnotes' directory to avoid it being picked up as a release note. Make this possible by adding support for a 'reno.yaml' file in the root directory of the project. Sadly it is not possible to apply this change to reno itself - doing so would cause the files to be picked up as belonging to the current release - but other projects can benefit from this. Change-Id: Ie96103b85d70592dd766e5174784b992fe7782c5 --- doc/source/user/usage.rst | 14 +++++----- .../repodir-config-file-b6b8edc2975964fc.yaml | 7 +++++ reno/config.py | 27 ++++++++++--------- reno/tests/test_config.py | 16 +++++++---- 4 files changed, 39 insertions(+), 25 deletions(-) create mode 100644 releasenotes/notes/repodir-config-file-b6b8edc2975964fc.yaml diff --git a/doc/source/user/usage.rst b/doc/source/user/usage.rst index 9bec262..d6e6cdb 100644 --- a/doc/source/user/usage.rst +++ b/doc/source/user/usage.rst @@ -174,13 +174,13 @@ correctness. Configuring Reno ================ -Reno looks for an optional ``config.yaml`` file in the release notes -directory. If the values in the configuration file do not apply to -the command being run, they are ignored. For example, some reno -commands take inputs controlling the branch, earliest revision, and -other common parameters that control which notes are included in the -output. Because they are commonly set options, a configuration file -may be the most convenient way to manage the values consistently. +Reno looks for an optional config file, either ``config.yaml`` in the release +notes directory or ``reno.yaml`` in the root directory. If the values in the +configuration file do not apply to the command being run, they are ignored. For +example, some reno commands take inputs controlling the branch, earliest +revision, and other common parameters that control which notes are included in +the output. Because they are commonly set options, a configuration file may be +the most convenient way to manage the values consistently. .. code-block:: yaml diff --git a/releasenotes/notes/repodir-config-file-b6b8edc2975964fc.yaml b/releasenotes/notes/repodir-config-file-b6b8edc2975964fc.yaml new file mode 100644 index 0000000..aedb19e --- /dev/null +++ b/releasenotes/notes/repodir-config-file-b6b8edc2975964fc.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + reno will now scan for a ``reno.yaml`` file in the root repo directory if a + ``config.yaml`` file does not exist in the releasenotes directory. This + allows users to do away with the unnecessary ``notes`` subdirectory in the + releasenotes directory. diff --git a/reno/config.py b/reno/config.py index 4783568..470e7d0 100644 --- a/reno/config.py +++ b/reno/config.py @@ -9,7 +9,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -import errno + import logging import os.path @@ -90,8 +90,6 @@ other: class Config(object): - _FILENAME = 'config.yaml' - _OPTS = { # The notes subdirectory within the relnotesdir where the # notes live. @@ -191,7 +189,6 @@ class Config(object): :param str relnotesdir: The directory containing release notes. Defaults to 'releasenotes'. - """ self.reporoot = reporoot if relnotesdir is None: @@ -200,22 +197,26 @@ class Config(object): # Initialize attributes from the defaults. self.override(**self._OPTS) - self._filename = os.path.join(self.reporoot, relnotesdir, - self._FILENAME) self._contents = {} self._load_file() def _load_file(self): + filenames = [ + os.path.join(self.reporoot, self.relnotesdir, 'config.yaml'), + os.path.join(self.reporoot, 'reno.yaml')] + + for filename in filenames: + if os.path.isfile(filename): + break + else: + LOG.info('no configuration file in: %s', ', '.join(filenames)) + return + try: - with open(self._filename, 'r') as fd: + with open(filename, 'r') as fd: self._contents = yaml.safe_load(fd) except IOError as err: - if err.errno == errno.ENOENT: - LOG.info('no configuration file in %s', - self._filename) - else: - LOG.warning('did not load config file %s: %s', - self._filename, err) + LOG.warning('did not load config file %s: %s', filename, err) else: self.override(**self._contents) diff --git a/reno/tests/test_config.py b/reno/tests/test_config.py index c2e0237..3a0ea62 100644 --- a/reno/tests/test_config.py +++ b/reno/tests/test_config.py @@ -77,17 +77,23 @@ collapse_pre_releases: false config.Config(self.tempdir.path) self.assertEqual(1, logger.call_count) - def test_load_file(self): - rn_path = self.tempdir.join('releasenotes') - os.mkdir(rn_path) - config_path = self.tempdir.join('releasenotes/' + - config.Config._FILENAME) + def _test_load_file(self, config_path): with open(config_path, 'w') as fd: fd.write(self.EXAMPLE_CONFIG) self.addCleanup(os.unlink, config_path) c = config.Config(self.tempdir.path) self.assertEqual(False, c.collapse_pre_releases) + def test_load_file_in_releasenotesdir(self): + rn_path = self.tempdir.join('releasenotes') + os.mkdir(rn_path) + config_path = self.tempdir.join('releasenotes/config.yaml') + self._test_load_file(config_path) + + def test_load_file_in_repodir(self): + config_path = self.tempdir.join('reno.yaml') + self._test_load_file(config_path) + def test_get_default(self): d = config.Config.get_default('notesdir') self.assertEqual('notes', d)