From 7a47df7a3859386afe6c62574a5a83d692da7c59 Mon Sep 17 00:00:00 2001 From: abraunegg Date: Sun, 24 Feb 2019 17:19:45 +1100 Subject: [PATCH] Implement --skip-dot-files (#386) * Implement new CLI option --skip-dot-files to skip .files and .folders if option is used --- README.md | 13 +++++++++++-- onedrive.1.in | 3 +++ src/config.d | 2 ++ src/main.d | 11 +++++++++++ src/sync.d | 33 ++++++++++++++++++++++++++++++++- 5 files changed, 59 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 965a38a9..e92eb82d 100644 --- a/README.md +++ b/README.md @@ -237,11 +237,11 @@ The 'skilion' version contains a significant number of defect's in how the local Additionally, if you are using a 'config' file within your configuration directory (`~/.config/onedrive/`), please ensure that you update the `skip_file = ` option as per below: **Invalid configuration:** -``` +```text skip_file = "= .*|~*" ``` **Minimum valid configuration:** -``` +```text skip_file = "~*" ``` Do not use a skip_file entry of `.*` as this will prevent correct searching of local changes to process. @@ -265,6 +265,7 @@ Config path = /home/alex/.config/onedrive Config file found in config path = false Config option 'sync_dir' = /home/alex/OneDrive Config option 'skip_file' = ~* +Config option 'skip_dotfiles' = false Config option 'skip_symlinks' = false Config option 'monitor_interval' = 45 Config option 'min_notif_changes' = 5 @@ -395,6 +396,7 @@ This file does not get created by default, and should only be created if you wan Available options: * `sync_dir`: directory where the files will be synced * `skip_file`: any files or directories that match this pattern will be skipped during sync +* `skip_dotfiles`: skip any .files or .folders during sync * `skip_symlinks`: any files or directories that are symlinked will be skipped during sync * `monitor_interval`: time interval in seconds by which the monitor process will process local and remote changes * `min_notif_changes`: minimum number of pending incoming changes to trigger a desktop notification @@ -416,6 +418,11 @@ Patterns are case insensitive. `*` and `?` [wildcards characters](https://techne **Note:** Do not use a skip_file entry of `.*` as this will prevent correct searching of local changes to process. +### skip_dotfiles +Example: `skip_dotfiles = "true"` + +Setting this to `"true"` will skip all .files and .folders while syncing. + ### skip_symlinks Example: `skip_symlinks = "true"` @@ -619,6 +626,8 @@ Options: Remove a directory on OneDrive - no sync will be performed. --single-directory ARG Specify a single local directory within the OneDrive root to sync. + --skip-dot-files + Skip dot files and folders from syncing --skip-symlinks Skip syncing of symlinks --source-directory ARG diff --git a/onedrive.1.in b/onedrive.1.in index a363f631..c4c19da7 100644 --- a/onedrive.1.in +++ b/onedrive.1.in @@ -81,6 +81,9 @@ Remove a directory on OneDrive \- no sync will be performed. \fB\-\-single\-directory\fP ARG Specify a single local directory within the OneDrive root to sync. .TP +\fB\-\-skip\-dot\-files\fP +Skip dot files and folders from syncing +.TP \fB\-\-skip\-symlinks\fP Skip syncing of symlinks .TP diff --git a/src/config.d b/src/config.d index 6dc9256c..a6e37243 100644 --- a/src/config.d +++ b/src/config.d @@ -31,6 +31,8 @@ final class Config // Configure to skip ONLY temp files (~*.doc etc) by default // Prior configuration was: .*|~* setValue("skip_file", "~*"); + // By default skip dot files & folders are not skipped + setValue("skip_dotfiles", "false"); // By default symlinks are not skipped (using string type // instead of boolean because hashmap only stores string types) setValue("skip_symlinks", "false"); diff --git a/src/main.d b/src/main.d index 217bba8d..6bc0c112 100644 --- a/src/main.d +++ b/src/main.d @@ -61,6 +61,8 @@ int main(string[] args) string removeDirectory; // This allows for selective directory syncing instead of everything under ~/OneDrive/ string singleDirectory; + // Skip dot files & folders - eg .file or /.folder/ + bool skipDotFiles = false; // Add option to skip symlinks bool skipSymlinks = false; // The source directory if we are using the OneDrive client to rename a directory @@ -104,6 +106,7 @@ int main(string[] args) "resync", "Forget the last saved state, perform a full sync", &resync, "remove-directory", "Remove a directory on OneDrive - no sync will be performed.", &removeDirectory, "single-directory", "Specify a single local directory within the OneDrive root to sync.", &singleDirectory, + "skip-dot-files", "Skip dot files and folders from syncing", &skipDotFiles, "skip-symlinks", "Skip syncing of symlinks", &skipSymlinks, "source-directory", "Source directory to rename or move on OneDrive - no sync will be performed.", &sourceDirectory, "syncdir", "Specify the local directory used for synchronization to OneDrive", &syncDirName, @@ -205,6 +208,13 @@ int main(string[] args) } // command line parameters to override default 'config' & take precedence + // Set the client to skip dot files & folders if --skip-dot-files was passed in + if (skipDotFiles) { + // The user passed in an alternate skip_dotfiles as to what was either in 'config' file or application default + log.vdebug("CLI override to set skip_dotfiles to: true"); + cfg.setValue("skip_dotfiles", "true"); + } + // Set the client to skip symbolic links if --skip-symlinks was passed in if (skipSymlinks) { // The user passed in an alternate skip_symlinks as to what was either in 'config' file or application default @@ -296,6 +306,7 @@ int main(string[] args) // Config Options writeln("Config option 'sync_dir' = ", syncDir); writeln("Config option 'skip_file' = ", cfg.getValue("skip_file")); + writeln("Config option 'skip_dotfiles' = ", cfg.getValue("skip_dotfiles")); writeln("Config option 'skip_symlinks' = ", cfg.getValue("skip_symlinks")); writeln("Config option 'monitor_interval' = ", cfg.getValue("monitor_interval")); writeln("Config option 'min_notif_changes' = ", cfg.getValue("min_notif_changes")); diff --git a/src/sync.d b/src/sync.d index bd42f747..05e93501 100644 --- a/src/sync.d +++ b/src/sync.d @@ -75,6 +75,21 @@ private bool hasId(const ref JSONValue item) return ("id" in item) != null; } +private bool isDotFile(string path) +{ + // always allow the root + if (path == ".") return false; + + path = buildNormalizedPath(path); + auto paths = pathSplitter(path); + foreach(base; paths) { + if (startsWith(base, ".")){ + return true; + } + } + return false; +} + // construct an Item struct from a JSON driveItem private Item makeItem(const ref JSONValue driveItem) { @@ -767,6 +782,14 @@ final class SyncEngine unwanted = true; } } + + // skip downloading dot files if configured + if (cfg.getValue("skip_dotfiles") == "true") { + if (isDotFile(path)) { + log.vlog("Skipping item - .file or .folder: ", path); + unwanted = true; + } + } // skip unwanted items early if (unwanted) { @@ -1311,7 +1334,15 @@ final class SyncEngine if(path.byGrapheme.walkLength < maxPathLength){ // path is less than maxPathLength - + + // skip dot files if configured + if (cfg.getValue("skip_dotfiles") == "true") { + if (isDotFile(path)) { + log.vlog("Skipping item - .file or .folder: ", path); + return; + } + } + if (isSymlink(path)) { // if config says so we skip all symlinked items if (cfg.getValue("skip_symlinks") == "true") {