Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- Added support for notion-enhancer (via @fharper)
- Added support for GitFox (via @L3K0V)
- Updated support for Bartender through SetApp (via @dbhagen)
- Added support for glob pattern in application config files (via @jneuendorf and @semkagtn)

## Mackup 0.8.33

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ release: clean
pipenv run twine upload dist/*

black:
black --target-version py27 .
pipenv run black --target-version py34 .
Comment thread
jneuendorf marked this conversation as resolved.
Outdated
3 changes: 1 addition & 2 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ docopt = "*"
six = "*"

[dev-packages]
# Black is still a pre-release. Replaced with `brew install black` for now.
# black = "*"
black = "*"
coverage = "*"
nose = "*"
twine = "*"
284 changes: 175 additions & 109 deletions Pipfile.lock

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions mackup/applications/traktor.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[application]
name = Traktor

[options]
enable_glob = true

[configuration_files]
Documents/Native Instruments/Traktor *.*.*/Traktor Settings.tsi
29 changes: 23 additions & 6 deletions mackup/appsdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
The Applications Database provides an easy to use interface to load application
data from the Mackup Database (files).
"""
import glob
import os
from pathlib import Path

try:
import configparser
Expand Down Expand Up @@ -34,25 +36,27 @@ def __init__(self):
if config.read(config_file):
# Get the filename without the directory name
filename = os.path.basename(config_file)
# The app name is the cfg filename with the extension
# The app name is the cfg filename without the extension
app_name = filename[: -len(".cfg")]

# Start building a dict for this app
self.apps[app_name] = dict()
app = dict()

# Add the fancy name for the app, for display purpose
app_pretty_name = config.get("application", "name")
self.apps[app_name]["name"] = app_pretty_name
app["name"] = app_pretty_name

# Add the configuration files to sync
self.apps[app_name]["configuration_files"] = set()
app["configuration_files"] = set()
if config.has_section("configuration_files"):
for path in config.options("configuration_files"):
if path.startswith("/"):
raise ValueError(
"Unsupported absolute path: {}".format(path)
)
self.apps[app_name]["configuration_files"].add(path)
app["configuration_files"] |= self.get_resolves_paths(
path, config
)

# Add the XDG configuration files to sync
home = os.path.expanduser("~/")
Expand All @@ -72,7 +76,11 @@ def __init__(self):
)
path = os.path.join(xdg_config_home, path)
path = path.replace(home, "")
(self.apps[app_name]["configuration_files"].add(path))
app["configuration_files"] |= self.get_resolves_paths(
path, config
)

self.apps[app_name] = app

@staticmethod
def get_config_files():
Expand Down Expand Up @@ -168,3 +176,12 @@ def get_pretty_app_names(self):
pretty_app_names.add(self.get_name(app_name))

return pretty_app_names

def get_resolves_paths(self, path, config):
if config.getboolean("options", "enable_glob", fallback=False):
return {
str(p.relative_to(os.environ["HOME"]))
for p in Path(os.environ["HOME"]).glob(path)
}
else:
return set([path])
2 changes: 1 addition & 1 deletion mackup/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def _setup_parser(self, filename=None):
filename = MACKUP_CONFIG_FILE

parser = configparser.SafeConfigParser(allow_no_value=True)
parser.read(os.path.join(os.path.join(os.environ["HOME"], filename)))
parser.read(os.path.join(os.environ["HOME"], filename))

return parser

Expand Down
5 changes: 2 additions & 3 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ Feel free to add more, the more the better!
## How to run the tests

```bash
cd src/mackup
pip install -r requirements.txt
nosetests
pipenv install --dev
make test
```

And you should see
Expand Down
57 changes: 57 additions & 0 deletions tests/apps_config_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import os
import tempfile
import unittest
from unittest.mock import patch
import stat

from mackup import utils
from mackup.appsdb import ApplicationsDatabase


realpath = os.path.dirname(os.path.realpath(__file__))
APPLICATIONS_DIR = os.path.join(realpath, "..", "mackup", "applications")
FIXTURES_DIR = os.path.join(realpath, "fixtures")


class TestMackup(unittest.TestCase):
config_file_path = os.path.join(APPLICATIONS_DIR, "test-app.cfg")

def setUp(self):
os.environ["HOME"] = FIXTURES_DIR

with open(self.config_file_path, "w") as config_file:
config_file.write(
"\n".join(
[
"[application]",
"name = Test App",
"",
"[options]",
"enable_glob = true",
"",
"[configuration_files]",
"Library/Application Support/Test App/*/data.txt",
]
)
)

def tearDown(self):
os.remove(self.config_file_path)

def test_glob_configuration_paths(self):
with patch.object(
ApplicationsDatabase,
"get_config_files",
return_value=[self.config_file_path],
) as method:
app_db = ApplicationsDatabase()
print(app_db.apps)

self.assertEqual(
app_db.get_files("test-app"),
{
"Library/Application Support/Test App/2020/data.txt",
"Library/Application Support/Test App/2021/data.txt",
"Library/Application Support/Test App/2022/data.txt",
},
)
60 changes: 30 additions & 30 deletions tests/config_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ def test_config_no_config(self):
assert cfg.path == "/home/some_user/Dropbox"

assert isinstance(cfg.directory, str)
assert cfg.directory == u"Mackup"
assert cfg.directory == "Mackup"

assert isinstance(cfg.fullpath, str)
assert cfg.fullpath == u"/home/some_user/Dropbox/Mackup"
assert cfg.fullpath == "/home/some_user/Dropbox/Mackup"

assert cfg.apps_to_ignore == set()
assert cfg.apps_to_sync == set()
Expand All @@ -43,13 +43,13 @@ def test_config_empty(self):
assert cfg.engine == ENGINE_DROPBOX

assert isinstance(cfg.path, str)
assert cfg.path == u"/home/some_user/Dropbox"
assert cfg.path == "/home/some_user/Dropbox"

assert isinstance(cfg.directory, str)
assert cfg.directory == u"Mackup"
assert cfg.directory == "Mackup"

assert isinstance(cfg.fullpath, str)
assert cfg.fullpath == u"/home/some_user/Dropbox/Mackup"
assert cfg.fullpath == "/home/some_user/Dropbox/Mackup"

assert cfg.apps_to_ignore == set()
assert cfg.apps_to_sync == set()
Expand All @@ -61,13 +61,13 @@ def test_config_engine_dropbox(self):
assert cfg.engine == ENGINE_DROPBOX

assert isinstance(cfg.path, str)
assert cfg.path == u"/home/some_user/Dropbox"
assert cfg.path == "/home/some_user/Dropbox"

assert isinstance(cfg.directory, str)
assert cfg.directory == u"some_weirld_name"
assert cfg.directory == "some_weirld_name"

assert isinstance(cfg.fullpath, str)
assert cfg.fullpath == u"/home/some_user/Dropbox/some_weirld_name"
assert cfg.fullpath == "/home/some_user/Dropbox/some_weirld_name"

assert cfg.apps_to_ignore == set()
assert cfg.apps_to_sync == set()
Expand All @@ -79,13 +79,13 @@ def test_config_engine_filesystem_absolute(self):
assert cfg.engine == ENGINE_FS

assert isinstance(cfg.path, str)
assert cfg.path == u"/some/absolute/folder"
assert cfg.path == "/some/absolute/folder"

assert isinstance(cfg.directory, str)
assert cfg.directory == u"custom_folder"
assert cfg.directory == "custom_folder"

assert isinstance(cfg.fullpath, str)
assert cfg.fullpath == u"/some/absolute/folder/custom_folder"
assert cfg.fullpath == "/some/absolute/folder/custom_folder"

assert cfg.apps_to_ignore == set(["subversion", "sequel-pro"])
assert cfg.apps_to_sync == set()
Expand All @@ -98,15 +98,15 @@ def test_config_engine_filesystem(self):

assert isinstance(cfg.path, str)
assert cfg.path.endswith(
os.path.join(os.environ[u"HOME"], u"some/relative/folder")
os.path.join(os.environ["HOME"], "some/relative/folder")
)

assert isinstance(cfg.directory, str)
assert cfg.directory == u"Mackup"
assert cfg.directory == "Mackup"

assert isinstance(cfg.fullpath, str)
assert cfg.fullpath == os.path.join(
os.environ[u"HOME"], u"some/relative/folder", u"Mackup"
os.environ["HOME"], "some/relative/folder", "Mackup"
)

assert cfg.apps_to_ignore == set()
Expand All @@ -119,13 +119,13 @@ def test_config_engine_google_drive(self):
assert cfg.engine == ENGINE_GDRIVE

assert isinstance(cfg.path, str)
assert cfg.path == u"/Users/whatever/Google Drive"
assert cfg.path == "/Users/whatever/Google Drive"

assert isinstance(cfg.directory, str)
assert cfg.directory == u"Mackup"
assert cfg.directory == "Mackup"

assert isinstance(cfg.fullpath, str)
assert cfg.fullpath.endswith(u"/Google Drive/Mackup")
assert cfg.fullpath.endswith("/Google Drive/Mackup")

assert cfg.apps_to_ignore == set(["subversion", "sequel-pro", "sabnzbd"])
assert cfg.apps_to_sync == set(["sublime-text-3", "x11", "sabnzbd"])
Expand All @@ -137,13 +137,13 @@ def test_config_engine_copy(self):
assert cfg.engine == ENGINE_COPY

assert isinstance(cfg.path, str)
assert cfg.path == u"/Users/someuser/Copy"
assert cfg.path == "/Users/someuser/Copy"

assert isinstance(cfg.directory, str)
assert cfg.directory == u"Mackup"
assert cfg.directory == "Mackup"

assert isinstance(cfg.fullpath, str)
assert cfg.fullpath.endswith(u"/Copy/Mackup")
assert cfg.fullpath.endswith("/Copy/Mackup")

assert cfg.apps_to_ignore == set(["subversion", "sequel-pro", "sabnzbd"])
assert cfg.apps_to_sync == set(["sublime-text-3", "x11", "sabnzbd"])
Expand All @@ -160,10 +160,10 @@ def test_config_engine_icloud(self):
)

assert isinstance(cfg.directory, str)
assert cfg.directory == u"Mackup"
assert cfg.directory == "Mackup"

assert isinstance(cfg.fullpath, str)
assert cfg.fullpath.endswith(u"/com~apple~CloudDocs/Mackup")
assert cfg.fullpath.endswith("/com~apple~CloudDocs/Mackup")

assert cfg.apps_to_ignore == set(["subversion", "sequel-pro", "sabnzbd"])
assert cfg.apps_to_sync == set(["sublime-text-3", "x11", "sabnzbd"])
Expand All @@ -186,10 +186,10 @@ def test_config_apps_to_ignore(self):
assert cfg.path == "/home/some_user/Dropbox"

assert isinstance(cfg.directory, str)
assert cfg.directory == u"Mackup"
assert cfg.directory == "Mackup"

assert isinstance(cfg.fullpath, str)
assert cfg.fullpath == u"/home/some_user/Dropbox/Mackup"
assert cfg.fullpath == "/home/some_user/Dropbox/Mackup"

assert cfg.apps_to_ignore == set(["subversion", "sequel-pro", "sabnzbd"])
assert cfg.apps_to_sync == set()
Expand All @@ -201,13 +201,13 @@ def test_config_apps_to_sync(self):
assert cfg.engine == ENGINE_DROPBOX

assert isinstance(cfg.path, str)
assert cfg.path == u"/home/some_user/Dropbox"
assert cfg.path == "/home/some_user/Dropbox"

assert isinstance(cfg.directory, str)
assert cfg.directory == u"Mackup"
assert cfg.directory == "Mackup"

assert isinstance(cfg.fullpath, str)
assert cfg.fullpath == u"/home/some_user/Dropbox/Mackup"
assert cfg.fullpath == "/home/some_user/Dropbox/Mackup"

assert cfg.apps_to_ignore == set()
assert cfg.apps_to_sync == set(["sabnzbd", "sublime-text-3", "x11"])
Expand All @@ -219,13 +219,13 @@ def test_config_apps_to_ignore_and_sync(self):
assert cfg.engine == ENGINE_DROPBOX

assert isinstance(cfg.path, str)
assert cfg.path == u"/home/some_user/Dropbox"
assert cfg.path == "/home/some_user/Dropbox"

assert isinstance(cfg.directory, str)
assert cfg.directory == u"Mackup"
assert cfg.directory == "Mackup"

assert isinstance(cfg.fullpath, str)
assert cfg.fullpath == u"/home/some_user/Dropbox/Mackup"
assert cfg.fullpath == "/home/some_user/Dropbox/Mackup"

assert cfg.apps_to_ignore == set(["subversion", "sequel-pro", "sabnzbd"])
assert cfg.apps_to_sync == set(["sabnzbd", "sublime-text-3", "x11", "vim"])
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2020
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2021
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2022