Installation

From packages

Easiest way is to install pipx, then use it to install mdedup:

$ pipx install mail-deduplicate

pipx is to pip what npx is to npm: a clean way to install and run Python applications in isolated environments.

You can install the latest stable release and its dependencies with a simple pip call:

$ python -m pip install mail-deduplicate

On some system, due to the Python 2.x to 3.x migration, you’ll have to call python3 directly:

$ python3 -m pip install mail-deduplicate

Other variations includes:

$ pip install mail-deduplicate
$ pip3 install mail-deduplicate

If you have difficulties to use pip, see pip’s own installation instructions.

Binaries

Binaries are compiled at each release, so you can skip the installation process above and download the standalone executables directly.

This is the preferred way of testing mdedup without polluting your machine. They also offer the possibility of running the CLI on older systems not supporting the minimal Python version required by mdedup.

All links above points to the latest released version of mdedup.

Older releases

If you need to test previous versions for regression, compatibility or general troubleshooting, you’ll find the old binaries attached as assets to past releases on GitHub.

Development builds

Each commit to the development branch triggers the compilation of binaries. This way you can easily test the bleeding edge version of mdedup and report any issue.

Look at the list of latest binary builds. Then select the latest Build & release/release.yaml workflow run and download the binary artifact corresponding to your platform and architecture.

ABI targets

$ file ./mdedup*
./mdedup-linux-x64.bin:   ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=d0a8ae1ffa469465a836c1505504d1b1c75725b0, for GNU/Linux 3.2.0, stripped
./mdedup-macos-x64.bin:   Mach-O 64-bit executable x86_64
./mdedup-windows-x64.exe: PE32+ executable (console) x86-64, for MS Windows

Run mdedup

Mail Deduplicate should now be available system-wide:

$ mdedup --version
mdedup, version 7.0.0
(...)

If not, you can directly execute the module from Python:

$ python -m mail_deduplicate --version
mdedup, version 7.0.0
(...)

Or on some systems:

$ python3 -m mail_deduplicate --version
mdedup, version 7.0.0
(...)

Shell completion

Completion for popular shell rely on Click feature.

Add this to ~/.bashrc:

eval "$(_MDEDUP_COMPLETE=bash_source mdedup)"

Add this to ~/.zshrc:

eval "$(_MDEDUP_COMPLETE=zsh_source mdedup)"

Add this to ~/.config/fish/completions/mdedup.fish:

eval (env _MDEDUP_COMPLETE=fish_source mdedup)

Alternatively, export the generated completion code as a static script to be executed:

$ _MDEDUP_COMPLETE=bash_source mdedup > ~/.mdedup-complete.bash

Then source it from ~/.bashrc:

. ~/.mdedup-complete.bash
$ _MDEDUP_COMPLETE=zsh_source mdedup > ~/.mdedup-complete.zsh

Then source it from ~/.zshrc:

. ~/.mdedup.zsh
_MDEDUP_COMPLETE=fish_source mdedup > ~/.config/fish/completions/mdedup.fish

Python dependencies

FYI, here is a graph of Python package dependencies:

flowchart TD classDef missing stroke-dasharray: 5 alabaster["alabaster\n0.7.13"] arrow["arrow\n1.3.0"] babel["Babel\n2.14.0"] boltons["boltons\n23.1.1"] bracex["bracex\n2.4"] certifi["certifi\n2023.11.17"] charset-normalizer["charset-normalizer\n3.3.2"] click-extra["click-extra\n4.7.3"] click_0["click\n8.1.7"] cloup["cloup\n3.0.4"] commentjson["commentjson\n0.9.0"] docutils["docutils\n0.20.1"] idna["idna\n3.6"] imagesize["imagesize\n1.4.1"] jinja2["Jinja2\n3.1.3"] lark-parser["lark-parser\n0.7.8"] mail-deduplicate["mail-deduplicate\n7.3.1"] markupsafe["MarkupSafe\n2.1.4"] mergedeep["mergedeep\n1.3.4"] packaging["packaging\n23.2"] pallets-sphinx-themes["Pallets-Sphinx-Themes\n2.1.1"] pygments-ansi-color["pygments-ansi-color\n0.3.0"] pygments["pygments\n2.17.2"] python-dateutil["python-dateutil\n2.8.2"] pyyaml["PyYAML\n6.0.1"] regex["regex\n2023.12.25"] requests["requests\n2.31.0"] six["six\n1.16.0"] snowballstemmer["snowballstemmer\n2.2.0"] sphinx["sphinx\n7.1.2"] sphinxcontrib-applehelp["sphinxcontrib-applehelp\n1.0.4"] sphinxcontrib-devhelp["sphinxcontrib-devhelp\n1.0.2"] sphinxcontrib-htmlhelp["sphinxcontrib-htmlhelp\n2.0.1"] sphinxcontrib-jsmath["sphinxcontrib-jsmath\n1.0.1"] sphinxcontrib-qthelp["sphinxcontrib-qthelp\n1.0.3"] sphinxcontrib-serializinghtml["sphinxcontrib-serializinghtml\n1.1.5"] tabulate["tabulate\n0.9.0"] types-python-dateutil["types-python-dateutil\n2.8.19.20240106"] urllib3["urllib3\n2.1.0"] wcmatch["wcmatch\n8.5"] xmltodict["xmltodict\n0.13.0"] arrow -- ">=2.7.0" --> python-dateutil arrow -- ">=2.8.10" --> types-python-dateutil click-extra -- ">=0.13.0,<0.14.0" --> xmltodict click-extra -- ">=0.3.0,<0.4.0" --> pygments-ansi-color click-extra -- ">=0.9,<0.10" --> tabulate click-extra -- ">=0.9.0,<0.10.0" --> commentjson click-extra -- ">=1.3.4,<2.0.0" --> mergedeep click-extra -- ">=2.1.1,<3.0.0" --> pallets-sphinx-themes click-extra -- ">=2.14,<3.0" --> pygments click-extra -- ">=2.28.2,<3.0.0" --> requests click-extra -- ">=2023.3.22,<2024.0.0" --> regex click-extra -- ">=23.0.0,<24.0.0" --> boltons click-extra -- ">=3.0.1,<4.0.0" --> cloup click-extra -- ">=6" --> sphinx click-extra -- ">=6.0.0,<7.0.0" --> pyyaml click-extra -- ">=8.1.4,<9.0.0" --> click_0 click-extra -- ">=8.4.1,<9.0.0" --> wcmatch cloup -- ">=8.0,<9.0" --> click_0 commentjson -- ">=0.7.1,<0.8.0" --> lark-parser jinja2 -- ">=2.0" --> markupsafe mail-deduplicate -- ">=0.9.0,<0.10.0" --> tabulate mail-deduplicate -- ">=1.2.3,<2.0.0" --> arrow mail-deduplicate -- ">=23.0.0,<24.0.0" --> boltons mail-deduplicate -- ">=4.7.2,<5.0.0" --> click-extra pallets-sphinx-themes -- ">=3" --> sphinx pallets-sphinx-themes -- "any" --> packaging pygments-ansi-color -- "!=2.7.3" --> pygments python-dateutil -- ">=1.5" --> six requests -- ">=1.21.1,<3" --> urllib3 requests -- ">=2,<4" --> charset-normalizer requests -- ">=2.5,<4" --> idna requests -- ">=2017.4.17" --> certifi sphinx -- ">=0.18.1,<0.21" --> docutils sphinx -- ">=0.7,<0.8" --> alabaster sphinx -- ">=1.1.5" --> sphinxcontrib-serializinghtml sphinx -- ">=1.3" --> imagesize sphinx -- ">=2.0" --> snowballstemmer sphinx -- ">=2.0.0" --> sphinxcontrib-htmlhelp sphinx -- ">=2.13" --> pygments sphinx -- ">=2.25.0" --> requests sphinx -- ">=2.9" --> babel sphinx -- ">=21.0" --> packaging sphinx -- ">=3.0" --> jinja2 sphinx -- "any" --> sphinxcontrib-applehelp sphinx -- "any" --> sphinxcontrib-devhelp sphinx -- "any" --> sphinxcontrib-jsmath sphinx -- "any" --> sphinxcontrib-qthelp wcmatch -- ">=2.1.1" --> bracex