Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions alot/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from alot.commands import *
from alot.commands import CommandParseError, COMMANDS
from alot.utils import argparse as cargparse
from alot.utils.notmuch import find_db

from twisted.internet import asyncioreactor
asyncioreactor.install()
Expand Down Expand Up @@ -120,8 +121,7 @@ def main():
settings.set('colourmode', options.colour_mode)

# get ourselves a database manager
indexpath = settings.get_notmuch_setting('database', 'path')
indexpath = options.mailindex_path or indexpath
indexpath = options.mailindex_path or find_db(settings)
dbman = DBManager(path=indexpath, ro=options.read_only)

# determine what to do
Expand Down
26 changes: 26 additions & 0 deletions alot/utils/notmuch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# encoding=utf-8

# SPDX-FileCopyrightText: 2020 Kirill Elagin <https://kir.elagin.me/>
# SPDX-License-Identifier: GPL-3.0-or-later

from os import environ
import os.path


# Replicate the logic for locating the notmuch database:
#
# * Can be absolute or relative to $HOME.
# * Default: $MAILDIR variable if set, otherwise $HOME/mail.
def find_db(settings):
path_from_settings = settings.get_notmuch_setting('database', 'path')
if path_from_settings is None:
maildir = environ.get('MAILDIR')
if maildir is not None:
return maildir
else:
return os.path.join(environ.get('HOME'), 'mail')
else:
if not os.path.isabs(path_from_settings):
return os.path.join(environ.get('HOME'), path_from_settings)
else:
return path_from_settings
66 changes: 66 additions & 0 deletions tests/utils/test_notmuch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# encoding=utf-8

# SPDX-FileCopyrightText: 2020 Kirill Elagin <https://kir.elagin.me/>
# SPDX-License-Identifier: GPL-3.0-or-later

"""Tests for alot.utils.notmuch"""

import unittest
from unittest import mock

import os.path

from alot.utils import notmuch

# Good descriptive test names often don't fit PEP8, which is meant to cover
# functions meant to be called by humans.
# pylint: disable=invalid-name


class MockSettings:
def __init__(self, database_path):
self._database_path = database_path

def get_notmuch_setting(self, section, key):
if section == 'database' and key == 'path':
return self._database_path
else:
return None

db_path_rel = os.path.join('path', 'to', 'db')
home = os.path.abspath(os.path.join(os.path.sep, 'home', 'someuser'))
maildir = os.path.abspath(os.path.join(os.path.sep, 'var', 'mail'))

class TestFindDb(unittest.TestCase):
"""Tests for the find_db function."""

@mock.patch.dict(os.environ, {}, clear=True)
def test_absolute_path(self):
db_path_abs = os.path.abspath(os.path.join(os.path.sep, db_path_rel))
settings = MockSettings(db_path_abs)
self.assertEqual(notmuch.find_db(settings), db_path_abs)

@mock.patch.dict(os.environ, {'HOME': home}, clear=True)
def test_relative_path(self):
settings = MockSettings(db_path_rel)
self.assertEqual(notmuch.find_db(settings), os.path.join(home, db_path_rel))

@mock.patch.dict(os.environ, {'MAILDIR': maildir}, clear=True)
def test_maildir(self):
settings = MockSettings(None)
self.assertEqual(notmuch.find_db(settings), maildir)

@mock.patch.dict(os.environ, {'HOME': home}, clear=True)
def test_home_mail(self):
settings = MockSettings(None)
self.assertEqual(notmuch.find_db(settings), os.path.join(home, 'mail'))


# Additional tests to make sure we closely replicate the behaviour
# of notmuch even if the user’s environment is weird/wrong.

@mock.patch.dict(os.environ, {'HOME': home, 'MAILDIR': ''}, clear=True)
def test_empty_maildir(self):
"""Empty maildir should not be treated as unset."""
settings = MockSettings(None)
self.assertEqual(notmuch.find_db(settings), '')