Support wildcard within sync_list entries (#1063)

* Support wildcard within sync_list entries
* Update usage documentation
This commit is contained in:
abraunegg 2020-09-16 17:03:00 +10:00 committed by GitHub
parent 0c770efa96
commit 1364f36aba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 1 deletions

View file

@ -425,6 +425,8 @@ Here is an example of `sync_list`:
Backup
# Include this single document
Documents/latest_report.docx
# Include all PDF documents
Documents/*.pdf
# Include all Work/Project directories
Work/Project*
notes.txt

View file

@ -4,6 +4,7 @@ import std.file;
import std.path;
import std.regex;
import std.stdio;
import std.string;
import util;
import log;
@ -128,6 +129,8 @@ final class SelectiveSync
// Match against sync_list only
bool isPathExcludedViaSyncList(string path)
{
// Debug output that we are performing a 'sync_list' inclusion / exclusion test
log.vdebug("sync_list evaluation for: ", path);
return .isPathExcluded(path, paths);
}
@ -194,23 +197,46 @@ final class SelectiveSync
// if there are no allowed paths always return false
private bool isPathExcluded(string path, string[] allowedPaths)
{
string wildcard = "*";
// always allow the root
if (path == ".") return false;
// if there are no allowed paths always return false
if (allowedPaths.empty) return false;
path = buildNormalizedPath(path);
foreach (allowed; allowedPaths) {
auto comm = commonPrefix(path, allowed);
// What are we comparing against?
log.vdebug("Evaluation against 'sync_list' entry: ", allowed);
// is path is an exact match
if (comm.length == path.length) {
// the given path is contained in an allowed path
log.vdebug("Evaluation against 'sync_list' result - direct match");
return false;
}
// is path is a subitem
if (comm.length == allowed.length && path[comm.length] == '/') {
// the given path is a subitem of an allowed path
log.vdebug("Evaluation against 'sync_list' result - parental path match");
return false;
}
// does the allowed path contain a wildcard? (*)
if (canFind(allowed, wildcard)) {
// allowed path contains a wildcard
// manually escape '/'
string escapedAllowed = replace(allowed, "/", "\\/");
// manually escape '*'
escapedAllowed = replace(escapedAllowed, "*", ".*");
auto allowedMask = regex(escapedAllowed);
if (matchAll(path, allowedMask)) {
// regex wildcard evaluation matches
log.vdebug("Evaluation against 'sync_list' result - wildcard pattern match");
return false;
}
}
}
log.vdebug("Evaluation against 'sync_list' result - NO MATCH");
return true;
}