From f957e74ff96038e69f2ffaee69b1a5e3f0727380 Mon Sep 17 00:00:00 2001 From: Doug Hellmann Date: Tue, 6 Jun 2017 10:40:58 -0400 Subject: [PATCH] add option for ignoring some notes files Make it easier to produce clean release notes by ignoring files mistakenly edited on the wrong branch. Change-Id: I74fb9e6c74af0b9de8cfe0d9c07ecfbd09cae925 Signed-off-by: Doug Hellmann --- doc/source/sphinxext.rst | 7 ++ doc/source/usage.rst | 13 +++ .../ignore-notes-option-9d0bde540fbcdf22.yaml | 8 ++ reno/config.py | 6 ++ reno/scanner.py | 9 ++ reno/sphinxext.py | 7 ++ reno/tests/test_scanner.py | 82 +++++++++++++++++++ 7 files changed, 132 insertions(+) create mode 100644 releasenotes/notes/ignore-notes-option-9d0bde540fbcdf22.yaml diff --git a/doc/source/sphinxext.rst b/doc/source/sphinxext.rst index 1ccf4d7..fb2c5f9 100644 --- a/doc/source/sphinxext.rst +++ b/doc/source/sphinxext.rst @@ -59,6 +59,13 @@ Enable the extension by adding ``'reno.sphinxext'`` to the typically set to the version used to create the branch to limit the output to only versions on that branch. + *ignore-notes* + + A string containing a comma-delimited list of filenames or UIDs + for notes that should be ignored by the scanner. It is most + useful to set this when a note is edited on the wrong branch, + making it appear to be part of a release that it is not. + Examples ======== diff --git a/doc/source/usage.rst b/doc/source/usage.rst index 420c729..5459af4 100644 --- a/doc/source/usage.rst +++ b/doc/source/usage.rst @@ -299,6 +299,19 @@ The following options are configurable: Defaults to ``True``. +`ignore_notes` + + A list of filenames or UIDs for notes that should be ignored by the + reno scanner. It is most useful to set this when a note is edited on + the wrong branch, making it appear to be part of a release that it + is not. + + .. warning:: + + Setting the option in the main configuration file makes it apply + to all branches. To ignore a note in the HTML build, use the + ``ignore-notes`` parameter to the ``release-notes`` sphinx + directive. Debugging ========= diff --git a/releasenotes/notes/ignore-notes-option-9d0bde540fbcdf22.yaml b/releasenotes/notes/ignore-notes-option-9d0bde540fbcdf22.yaml new file mode 100644 index 0000000..6fd41e4 --- /dev/null +++ b/releasenotes/notes/ignore-notes-option-9d0bde540fbcdf22.yaml @@ -0,0 +1,8 @@ +--- +features: + - | + Add a new configuration option ``ignore_notes``. Setting the value + to a list of filenames or UIDs for notes causes the reno scanner + to ignore them. It is most useful to set this when a note is + edited on the wrong branch, making it appear to be part of a + release that it is not. diff --git a/reno/config.py b/reno/config.py index 6a67515..03d0362 100644 --- a/reno/config.py +++ b/reno/config.py @@ -167,6 +167,12 @@ class Config(object): # branch appear to be part of master and/or the later stable # branch. This option allows us to ignore those. 'ignore_null_merges': True, + + # Note files to be ignored. It's useful to be able to ignore a + # file if it is edited on the wrong branch. Notes should be + # specified by their filename or UID. Setting the value in the + # configuration file makes it apply to all branches. + 'ignore_notes': [], } @classmethod diff --git a/reno/scanner.py b/reno/scanner.py index 36fc33b..61929b0 100644 --- a/reno/scanner.py +++ b/reno/scanner.py @@ -514,6 +514,10 @@ class Scanner(object): self.conf.branch_name_re, flags=re.VERBOSE | re.UNICODE, ) + self._ignore_uids = set( + _get_unique_id(fn) + for fn in self.conf.ignore_notes + ) def _get_ref(self, name): if name: @@ -1067,6 +1071,11 @@ class Scanner(object): for change in aggregator.aggregate_changes(entry, changes): uniqueid = change[0] + if uniqueid in self._ignore_uids: + LOG.info('ignoring %s based on configuration setting', + uniqueid) + continue + c_type = change[1] if c_type == diff_tree.CHANGE_ADD: diff --git a/reno/sphinxext.py b/reno/sphinxext.py index 650eaaa..45e57ef 100644 --- a/reno/sphinxext.py +++ b/reno/sphinxext.py @@ -39,6 +39,7 @@ class ReleaseNotesDirective(rst.Directive): 'collapse-pre-releases': directives.flag, 'earliest-version': directives.unchanged, 'stop-at-branch-base': directives.flag, + 'ignore-notes': directives.unchanged, } def run(self): @@ -57,6 +58,10 @@ class ReleaseNotesDirective(rst.Directive): reporoot = repo.Repo.discover(reporoot).path relnotessubdir = self.options.get('relnotessubdir', defaults.RELEASE_NOTES_SUBDIR) + ignore_notes = [ + name.strip() + for name in self.options.get('ignore-notes', '').split(',') + ] conf = config.Config(reporoot, relnotessubdir) opt_overrides = {} if 'notesdir' in self.options: @@ -74,6 +79,8 @@ class ReleaseNotesDirective(rst.Directive): 'earliest-version') if branch: opt_overrides['branch'] = branch + if ignore_notes: + opt_overrides['ignore_notes'] = ignore_notes conf.override(**opt_overrides) notesdir = os.path.join(relnotessubdir, conf.notesdir) diff --git a/reno/tests/test_scanner.py b/reno/tests/test_scanner.py index f2db5d6..f8d52fa 100644 --- a/reno/tests/test_scanner.py +++ b/reno/tests/test_scanner.py @@ -660,6 +660,88 @@ class BasicTest(Base): ) +class IgnoreTest(Base): + + def test_by_fullname(self): + self._make_python_package() + self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0') + f1 = self._add_notes_file() + f2 = self._add_notes_file() + self.c.override( + ignore_notes=[f1], + ) + self.scanner = scanner.Scanner(self.c) + raw_results = self.scanner.get_notes_by_version() + results = { + k: [f for (f, n) in v] + for (k, v) in raw_results.items() + } + self.assertEqual( + {'1.0.0-2': [f2]}, + results, + ) + + def test_by_basename(self): + self._make_python_package() + self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0') + f1 = self._add_notes_file() + f2 = self._add_notes_file() + self.c.override( + ignore_notes=[os.path.basename(f1)], + ) + self.scanner = scanner.Scanner(self.c) + raw_results = self.scanner.get_notes_by_version() + results = { + k: [f for (f, n) in v] + for (k, v) in raw_results.items() + } + self.assertEqual( + {'1.0.0-2': [f2]}, + results, + ) + + def test_by_uid(self): + self._make_python_package() + self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0') + f1 = self._add_notes_file() + f2 = self._add_notes_file() + self.c.override( + ignore_notes=[scanner._get_unique_id(f1)], + ) + self.scanner = scanner.Scanner(self.c) + raw_results = self.scanner.get_notes_by_version() + results = { + k: [f for (f, n) in v] + for (k, v) in raw_results.items() + } + self.assertEqual( + {'1.0.0-2': [f2]}, + results, + ) + + def test_by_multiples(self): + self._make_python_package() + self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0') + f1 = self._add_notes_file() + f2 = self._add_notes_file() + self.c.override( + ignore_notes=[ + scanner._get_unique_id(f1), + scanner._get_unique_id(f2), + ], + ) + self.scanner = scanner.Scanner(self.c) + raw_results = self.scanner.get_notes_by_version() + results = { + k: [f for (f, n) in v] + for (k, v) in raw_results.items() + } + self.assertEqual( + {}, + results, + ) + + class FileContentsTest(Base): def test_basic_file(self):