Wildcard matches are directly applied to all filenames in
subdirectories without any attempt at matching relative paths.

This change is based on the following feature request:

  http://bugs.musicpd.org/view.php?id=3729
---
 NEWS                          |  2 ++
 doc/user.xml                  |  2 ++
 src/db/update/ExcludeList.cxx |  6 ++++++
 src/db/update/ExcludeList.hxx | 10 +++++++++-
 src/db/update/Walk.cxx        | 27 +++++++++++++++++----------
 src/db/update/Walk.hxx        |  2 ++
 6 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/NEWS b/NEWS
index b6a64d4..145361c 100644
--- a/NEWS
+++ b/NEWS
@@ -36,6 +36,8 @@ ver 0.20 (not yet released)
 * support libsystemd (instead of the older libsystemd-daemon)
 * database
   - proxy: add TCP keepalive option
+* update
+  - apply .mpdignore matches to subdirectories
 
 ver 0.19.10 (2015/06/21)
 * input
diff --git a/doc/user.xml b/doc/user.xml
index a08a5ae..8a37a7c 100644
--- a/doc/user.xml
+++ b/doc/user.xml
@@ -1077,6 +1077,8 @@ database {
         To exclude a file from the update, create a file called
         <filename>.mpdignore</filename> in its parent directory.  Each
         line of that file may contain a list of shell wildcards.
+        Matching files in the current directory and all subdirectories
+        are excluded.
       </para>
     </section>
 
diff --git a/src/db/update/ExcludeList.cxx b/src/db/update/ExcludeList.cxx
index 3b54d63..b09f349 100644
--- a/src/db/update/ExcludeList.cxx
+++ b/src/db/update/ExcludeList.cxx
@@ -89,6 +89,12 @@ ExcludeList::Check(Path name_fs) const
        /* XXX include full path name in check */
 
 #ifdef HAVE_CLASS_GLOB
+       if (parent != nullptr) {
+               if (parent->Check(name_fs)) {
+                       return true;
+               }
+       }
+
        for (const auto &i : patterns)
                if (i.Check(NarrowPath(name_fs).c_str()))
                        return true;
diff --git a/src/db/update/ExcludeList.hxx b/src/db/update/ExcludeList.hxx
index de48bac..4952d29 100644
--- a/src/db/update/ExcludeList.hxx
+++ b/src/db/update/ExcludeList.hxx
@@ -36,15 +36,23 @@
 class Path;
 
 class ExcludeList {
+       const ExcludeList *const parent;
+
 #ifdef HAVE_CLASS_GLOB
        std::forward_list<Glob> patterns;
 #endif
 
 public:
+       ExcludeList()
+               :parent(nullptr) {}
+
+       ExcludeList(const ExcludeList &_parent)
+               :parent(&_parent) {}
+
        gcc_pure
        bool IsEmpty() const {
 #ifdef HAVE_CLASS_GLOB
-               return patterns.empty();
+               return ((parent == nullptr) || parent->IsEmpty()) && 
patterns.empty();
 #else
                /* not implemented */
                return true;
diff --git a/src/db/update/Walk.cxx b/src/db/update/Walk.cxx
index af039ee..3e5654a 100644
--- a/src/db/update/Walk.cxx
+++ b/src/db/update/Walk.cxx
@@ -219,6 +219,7 @@ UpdateWalk::UpdateRegularFile(Directory &directory,
 
 void
 UpdateWalk::UpdateDirectoryChild(Directory &directory,
+                                const ExcludeList &exclude_list,
                                 const char *name, const StorageFileInfo &info)
 {
        assert(strchr(name, '/') == nullptr);
@@ -236,7 +237,7 @@ UpdateWalk::UpdateDirectoryChild(Directory &directory,
 
                assert(&directory == subdir->parent);
 
-               if (!UpdateDirectory(*subdir, info))
+               if (!UpdateDirectory(*subdir, exclude_list, info))
                        editor.LockDeleteDirectory(subdir);
        } else {
                FormatDebug(update_domain,
@@ -327,7 +328,9 @@ UpdateWalk::SkipSymlink(const Directory *directory,
 }
 
 bool
-UpdateWalk::UpdateDirectory(Directory &directory, const StorageFileInfo &info)
+UpdateWalk::UpdateDirectory(Directory &directory,
+                           const ExcludeList &exclude_list,
+                           const StorageFileInfo &info)
 {
        assert(info.IsDirectory());
 
@@ -340,17 +343,17 @@ UpdateWalk::UpdateDirectory(Directory &directory, const 
StorageFileInfo &info)
                return false;
        }
 
-       ExcludeList exclude_list;
+       ExcludeList child_exclude_list(exclude_list);
 
        {
                const auto exclude_path_fs =
                        storage.MapChildFS(directory.GetPath(), ".mpdignore");
                if (!exclude_path_fs.IsNull())
-                       exclude_list.LoadFile(exclude_path_fs);
+                       child_exclude_list.LoadFile(exclude_path_fs);
        }
 
-       if (!exclude_list.IsEmpty())
-               RemoveExcludedFromDirectory(directory, exclude_list);
+       if (!child_exclude_list.IsEmpty())
+               RemoveExcludedFromDirectory(directory, child_exclude_list);
 
        PurgeDeletedFromDirectory(directory);
 
@@ -361,7 +364,7 @@ UpdateWalk::UpdateDirectory(Directory &directory, const 
StorageFileInfo &info)
 
                {
                        const auto name_fs = AllocatedPath::FromUTF8(name_utf8);
-                       if (name_fs.IsNull() || exclude_list.Check(name_fs))
+                       if (name_fs.IsNull() || 
child_exclude_list.Check(name_fs))
                                continue;
                }
 
@@ -376,7 +379,7 @@ UpdateWalk::UpdateDirectory(Directory &directory, const 
StorageFileInfo &info)
                        continue;
                }
 
-               UpdateDirectoryChild(directory, name_utf8, info2);
+               UpdateDirectoryChild(directory, child_exclude_list, name_utf8, 
info2);
        }
 
        directory.mtime = info.mtime;
@@ -468,7 +471,9 @@ UpdateWalk::UpdateUri(Directory &root, const char *uri)
                return;
        }
 
-       UpdateDirectoryChild(*parent, name, info);
+       ExcludeList exclude_list;
+
+       UpdateDirectoryChild(*parent, exclude_list, name, info);
 }
 
 bool
@@ -484,7 +489,9 @@ UpdateWalk::Walk(Directory &root, const char *path, bool 
discard)
                if (!GetInfo(storage, "", info))
                        return false;
 
-               UpdateDirectory(root, info);
+               ExcludeList exclude_list;
+
+               UpdateDirectory(root, exclude_list, info);
        }
 
        return modified;
diff --git a/src/db/update/Walk.hxx b/src/db/update/Walk.hxx
index d9fe7c8..99d54ef 100644
--- a/src/db/update/Walk.hxx
+++ b/src/db/update/Walk.hxx
@@ -129,10 +129,12 @@ private:
                               const char *name, const StorageFileInfo &info);
 
        void UpdateDirectoryChild(Directory &directory,
+                                 const ExcludeList &exclude_list,
                                  const char *name,
                                  const StorageFileInfo &info);
 
        bool UpdateDirectory(Directory &directory,
+                            const ExcludeList &exclude_list,
                             const StorageFileInfo &info);
 
        /**
-- 
2.4.9

_______________________________________________
mpd-devel mailing list
mpd-devel@musicpd.org
http://mailman.blarg.de/listinfo/mpd-devel

Reply via email to