Skip to content

Commit

Permalink
add tests and changelog
Browse files Browse the repository at this point in the history
  • Loading branch information
NorthIsUp committed Jan 19, 2024
1 parent 6bc5ebf commit 274b7e7
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Added support for rtx (via @dnicolson)
- Add support for new TOML config for Alacritty (via @syphar)
- Remove dependency on the six package
- Add support for changing the config file location via environment variables (via @northisup)

## Mackup 0.8.40

Expand Down
12 changes: 11 additions & 1 deletion doc/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
# Configuration

All the configuration is done in a file named `.mackup.cfg` stored at the
root of your home folder.
root of your home folder. This location can be overridden via environment
variables.

To configure Mackup, create a file named `.mackup.cfg` in your home directory.

```bash
vi ~/.mackup.cfg
```

### Configuration file location

Config files are searched in the following order. If none is found, Mackup will
use the default config location of `~/.mackup.cfg`

- `~/.mackup.cfg`
- `$MACKUP_CONFIG`
- `$XDG_CONFIG_HOME/mackup/mackup.cfg` or `~/.config/mackup/mackup.cfg`

## Storage

You can specify the storage type Mackup will use to store your configuration
Expand Down
72 changes: 56 additions & 16 deletions mackup/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

import os
import os.path
from pathlib import Path

from .constants import (
CUSTOM_APPS_DIR,
ENGINE_DROPBOX,
ENGINE_FS,
ENGINE_GDRIVE,
ENGINE_ICLOUD,
ENGINE_FS,
MACKUP_BACKUP_PATH,
MACKUP_CONFIG_FILE,
)
from .utils import (
error,
Expand Down Expand Up @@ -138,27 +141,64 @@ def _setup_parser(self, filename=None):
"""
assert isinstance(filename, str) or filename is None

# If we are not overriding the config filename
if not filename:
if os.path.exists(MACKUP_CONFIG_FILE):
filename = MACKUP_CONFIG_FILE
elif "MACKUP_CONFIG_FILE" in os.environ:
filename = os.environ["MACKUP_CONFIG_FILE"]
elif "XDG_CONFIG_HOME" in os.environ:
filename = os.path.join(
os.environ["XDG_CONFIG_HOME"],
MACKUP_CONFIG_FILE.lstrip("."),
)
else:
filename = MACKUP_CONFIG_FILE

parser = configparser.ConfigParser(
allow_no_value=True, inline_comment_prefixes=(";", "#")
)
parser.read(os.path.join(os.path.join(os.environ["HOME"], filename)))
parser.read(self._best_config_path(filename))

return parser

def _best_config_path(self, filename=None):
"""
If no filename is provided, we try to find one in according to the following
order, note that we will always check the original default of `~/.mackup.cfg`
first before checking the other options:
- ~/.mackup.cfg
- $MACKUP_CONFIG
- $XDG_CONFIG_HOME/mackup/mackup.cfg
- ~/.config/mackup/mackup.cfg
if none of these files exist, we create ~/.mackup.cfg
Args:
filename (_type_, optional): _description_. Defaults to None.
Returns:
str: the absolute path to the config file
"""
assert isinstance(filename, str) or filename is None

# If we are not overriding the config filename
if not filename:
default = Path.home() / MACKUP_CONFIG_FILE
search_paths = [
# 1. the default config file is ~/.mackup.cfg
default,
# 2. check for the MACKUP_CONFIG envvar
Path(os.environ.get("MACKUP_CONFIG", "")).expanduser(),
# 3. check for a config file in the XDG_CONFIG_HOME directory
(
Path(os.environ.get("XDG_CONFIG_HOME", "~/.config")).expanduser()
/ "mackup"
/ MACKUP_CONFIG_FILE.lstrip(".")
),
]
filename = next((p for p in search_paths if p.is_file()), default)
else:
filename = Path.home() / filename

try:
# Make sure the config file is in the home directory
filename.relative_to(Path.home())
except ValueError:
error(
f"The config file '{filename}' is not in your home directory. Aborting."
)

# return the absolute path to the config file
return str(filename.absolute())

def _warn_on_old_config(self):
"""Warn the user if an old config format is detected."""
# Is an old section in the config file?
Expand Down
58 changes: 55 additions & 3 deletions tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,72 @@
import unittest
import os
import os.path
import unittest
from pathlib import Path

from mackup.config import Config, ConfigError
from mackup.constants import (
ENGINE_DROPBOX,
ENGINE_FS,
ENGINE_GDRIVE,
ENGINE_ICLOUD,
ENGINE_FS,
MACKUP_CONFIG_FILE,
)
from mackup.config import Config, ConfigError


def assert_correct_config_read(testtype):
assert testtype == Config()._parser.get("test", "testtype")


class TestConfig(unittest.TestCase):
def setUp(self):
realpath = os.path.dirname(os.path.realpath(__file__))
os.environ["HOME"] = os.path.join(realpath, "fixtures")

# these may be set on some user's systems
os.environ.pop("XDG_CONFIG_HOME", None)
os.environ.pop("MACKUP_CONFIG", None)

def test_config_envvar(self):
os.environ["MACKUP_CONFIG"] = "~/mackup-envarcheck.cfg"
assert_correct_config_read("test_config_envvar")

def test_config_xdg(self):
os.environ["XDG_CONFIG_HOME"] = "~/xdg-config-home/"
assert_correct_config_read("test_config_xdg")

def test_config_find_correct_default(self):
config_path = Path.home() / MACKUP_CONFIG_FILE

try:
# create a default config file, this must be cleaned up after the test
config_path.write_text(f"[test]\ntesttype = test_config_default")

# nothing else set, should find the default file
assert_correct_config_read("test_config_default")

# set MACKUP_CONFIG, but should still find the default file
os.environ["MACKUP_CONFIG"] = "~/mackup-envarcheck.cfg"
assert_correct_config_read("test_config_default")

# set XDG_CONFIG_HOME, but should still find the default file
os.environ["XDG_CONFIG_HOME"] = "~/xdg-config-home/"
assert_correct_config_read("test_config_default")
except Exception:
raise
finally:
config_path.unlink(missing_ok=True)

assert config_path.exists() is False

def test_config_finds_correct_envvar(self):
# set XDG_CONFIG_HOME, but should still find the default file
os.environ["XDG_CONFIG_HOME"] = "~/xdg-config-home/"
assert_correct_config_read("test_config_xdg")

# set MACKUP_CONFIG, but should still find the default file
os.environ["MACKUP_CONFIG"] = "~/mackup-envarcheck.cfg"
assert_correct_config_read("test_config_envvar")

def test_config_no_config(self):
cfg = Config()

Expand Down

0 comments on commit 274b7e7

Please sign in to comment.