changeset 33551:1d1779734c99

sparse: require [section] in sparse config files (BC) Previously, [include] was implicit and pattern lines before a [section] were added to includes. Because the format may change in the future and explicit behavior, well, more explicit, this commit changes the config parser to reject pattern lines that don't occur in a [section]. Differential Revision: https://phab.mercurial-scm.org/D96
author Gregory Szorc <gregory.szorc@gmail.com>
date Sat, 15 Jul 2017 13:21:23 -0700
parents 32f348d741e5
children 754569f5e999
files hgext/sparse.py mercurial/sparse.py tests/test-sparse-profiles.t
diffstat 3 files changed, 27 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/sparse.py	Sat Jul 15 13:07:57 2017 -0700
+++ b/hgext/sparse.py	Sat Jul 15 13:21:23 2017 -0700
@@ -35,8 +35,7 @@
 
 The special lines ``[include]`` and ``[exclude]`` denote the section
 for includes and excludes that follow, respectively. It is illegal to
-have ``[include]`` after ``[exclude]``. If no sections are defined,
-entries are assumed to be in the ``[include]`` section.
+have ``[include]`` after ``[exclude]``.
 
 Non-special lines resemble file patterns to be added to either includes
 or excludes. The syntax of these lines is documented by :hg:`help patterns`.
--- a/mercurial/sparse.py	Sat Jul 15 13:07:57 2017 -0700
+++ b/mercurial/sparse.py	Sat Jul 15 13:21:23 2017 -0700
@@ -33,8 +33,10 @@
     """
     includes = set()
     excludes = set()
-    current = includes
     profiles = set()
+    current = None
+    havesection = False
+
     for line in raw.split('\n'):
         line = line.strip()
         if not line or line.startswith('#'):
@@ -45,14 +47,23 @@
             if line:
                 profiles.add(line)
         elif line == '[include]':
-            if current != includes:
+            if havesection and current != includes:
                 # TODO pass filename into this API so we can report it.
                 raise error.Abort(_('sparse config cannot have includes ' +
                                     'after excludes'))
+            havesection = True
+            current = includes
             continue
         elif line == '[exclude]':
+            havesection = True
             current = excludes
         elif line:
+            if current is None:
+                raise error.Abort(_('sparse config entry outside of '
+                                    'section: %s') % line,
+                                  hint=_('add an [include] or [exclude] line '
+                                         'to declare the entry type'))
+
             if line.strip().startswith('/'):
                 ui.warn(_('warning: sparse profile cannot use' +
                           ' paths starting with /, ignoring %s\n') % line)
--- a/tests/test-sparse-profiles.t	Sat Jul 15 13:07:57 2017 -0700
+++ b/tests/test-sparse-profiles.t	Sat Jul 15 13:21:23 2017 -0700
@@ -10,6 +10,18 @@
   > rebase=
   > EOF
 
+Config file without [section] is rejected
+
+  $ cat > bad.sparse <<EOF
+  > *.html
+  > EOF
+
+  $ hg debugsparse --import-rules bad.sparse
+  abort: sparse config entry outside of section: *.html
+  (add an [include] or [exclude] line to declare the entry type)
+  [255]
+  $ rm bad.sparse
+
   $ echo a > index.html
   $ echo x > data.py
   $ echo z > readme.txt
@@ -257,6 +269,7 @@
   > EOF
   $ touch a b
   $ cat > .hgsparse <<EOF
+  > [include]
   > a
   > EOF
   $ hg commit -Aqm 'initial'