docker-mailserver/edge/contributing/coding-style/index.html
github-actions[bot] ad3b21342f deploy: 81a05ad432
2021-04-18 11:25:31 +00:00

1597 lines
48 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="A fullstack but simple mail server (SMTP, IMAP, LDAP, Antispam, Antivirus, etc.) using Docker.">
<meta name="author" content="docker-mailserver (Github Organization)">
<link rel="canonical" href="https://docker-mailserver.github.io/docker-mailserver/edge/contributing/coding-style/">
<link rel="icon" href="../../assets/logo/favicon-32x32.png">
<meta name="generator" content="mkdocs-1.1.2, mkdocs-material-7.1.2">
<title>Contributing | Coding Style - Docker Mailserver</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.6f955dcd.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/palette.ef6f36e2.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700%7CRoboto+Mono&display=fallback">
<style>:root{--md-text-font-family:"Roboto";--md-code-font-family:"Roboto Mono"}</style>
<link rel="stylesheet" href="../../assets/css/customizations.css">
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo">
<script>function __prefix(e){return new URL("../..",location).pathname+"."+e}function __get(e,t=localStorage){return JSON.parse(t.getItem(__prefix(e)))}</script>
<script>var palette=__get("__palette");if(null!==palette&&"object"==typeof palette.color)for(var key in palette.color)document.body.setAttribute("data-md-color-"+key,palette.color[key])</script>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#bash-and-shell" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../.." title="Docker Mailserver" class="md-header__button md-logo" aria-label="Docker Mailserver" data-md-component="logo">
<img src="../../assets/logo/dmo-logo-white.svg" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Docker Mailserver
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Contributing | Coding Style
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_2" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3 3.19.09m3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95 2.06.05m-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31z"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="indigo" data-md-color-accent="blue" type="radio" name="__palette" id="__palette_2">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5c-.84 0-1.65.15-2.39.42L12 2M3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29L3.34 7m.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14L3.36 17M20.65 7l-1.77 3.79a7.023 7.023 0 0 0-2.38-4.15l4.15.36m-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29L20.64 17M12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44L12 22z"/></svg>
</label>
</form>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" data-md-state="active" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
</label>
<button type="reset" class="md-search__icon md-icon" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/docker-mailserver/docker-mailserver/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
</div>
<div class="md-source__repository">
docker-mailserver
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-tabs__inner md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href="../.." class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item">
<a href="../../introduction/" class="md-tabs__link">
Introduction
</a>
</li>
<li class="md-tabs__item">
<a href="../../config/setup.sh/" class="md-tabs__link">
Configuration
</a>
</li>
<li class="md-tabs__item">
<a href="../../examples/tutorials/basic-installation/" class="md-tabs__link">
Examples
</a>
</li>
<li class="md-tabs__item">
<a href="../../faq/" class="md-tabs__link">
FAQ
</a>
</li>
<li class="md-tabs__item">
<a href="../issues-and-pull-requests/" class="md-tabs__link md-tabs__link--active">
Contributing
</a>
</li>
<li class="md-tabs__item">
<a href="https://hub.docker.com/repository/docker/mailserver/docker-mailserver" class="md-tabs__link">
DockerHub
</a>
</li>
<li class="md-tabs__item">
<a href="https://github.com/orgs/docker-mailserver/packages/container/package/docker-mailserver" class="md-tabs__link">
GHCR
</a>
</li>
</ul>
</div>
</nav>
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../.." title="Docker Mailserver" class="md-nav__button md-logo" aria-label="Docker Mailserver" data-md-component="logo">
<img src="../../assets/logo/dmo-logo-white.svg" alt="logo">
</a>
Docker Mailserver
</label>
<div class="md-nav__source">
<a href="https://github.com/docker-mailserver/docker-mailserver/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
</div>
<div class="md-source__repository">
docker-mailserver
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." class="md-nav__link">
Home
</a>
</li>
<li class="md-nav__item">
<a href="../../introduction/" class="md-nav__link">
Introduction
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3" data-md-state="indeterminate" type="checkbox" id="__nav_3" checked>
<label class="md-nav__link" for="__nav_3">
Configuration
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Configuration" data-md-level="1">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
Configuration
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../config/setup.sh/" class="md-nav__link">
Your Best Friend setup.sh
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3_2" data-md-state="indeterminate" type="checkbox" id="__nav_3_2" checked>
<label class="md-nav__link" for="__nav_3_2">
User Management
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="User Management" data-md-level="2">
<label class="md-nav__title" for="__nav_3_2">
<span class="md-nav__icon md-icon"></span>
User Management
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../config/user-management/accounts/" class="md-nav__link">
Accounts
</a>
</li>
<li class="md-nav__item">
<a href="../../config/user-management/aliases/" class="md-nav__link">
Aliases
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3_3" data-md-state="indeterminate" type="checkbox" id="__nav_3_3" checked>
<label class="md-nav__link" for="__nav_3_3">
Best Practices
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Best Practices" data-md-level="2">
<label class="md-nav__title" for="__nav_3_3">
<span class="md-nav__icon md-icon"></span>
Best Practices
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../config/best-practices/dkim/" class="md-nav__link">
DKIM
</a>
</li>
<li class="md-nav__item">
<a href="../../config/best-practices/dmarc/" class="md-nav__link">
DMARC
</a>
</li>
<li class="md-nav__item">
<a href="../../config/best-practices/spf/" class="md-nav__link">
SPF
</a>
</li>
<li class="md-nav__item">
<a href="../../config/best-practices/autodiscover/" class="md-nav__link">
Auto-discovery
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3_4" data-md-state="indeterminate" type="checkbox" id="__nav_3_4" checked>
<label class="md-nav__link" for="__nav_3_4">
Security
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Security" data-md-level="2">
<label class="md-nav__title" for="__nav_3_4">
<span class="md-nav__icon md-icon"></span>
Security
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../config/security/understanding-the-ports/" class="md-nav__link">
Understanding the Ports
</a>
</li>
<li class="md-nav__item">
<a href="../../config/security/ssl/" class="md-nav__link">
SSL/TLS
</a>
</li>
<li class="md-nav__item">
<a href="../../config/security/fail2ban/" class="md-nav__link">
Fail2Ban
</a>
</li>
<li class="md-nav__item">
<a href="../../config/security/mail_crypt/" class="md-nav__link">
Mail Encryption
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3_5" data-md-state="indeterminate" type="checkbox" id="__nav_3_5" checked>
<label class="md-nav__link" for="__nav_3_5">
Troubleshooting
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Troubleshooting" data-md-level="2">
<label class="md-nav__title" for="__nav_3_5">
<span class="md-nav__icon md-icon"></span>
Troubleshooting
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../config/troubleshooting/debugging/" class="md-nav__link">
Debugging
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../config/pop3/" class="md-nav__link">
Mail Delivery with POP3
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3_7" data-md-state="indeterminate" type="checkbox" id="__nav_3_7" checked>
<label class="md-nav__link" for="__nav_3_7">
Advanced Configuration
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Advanced Configuration" data-md-level="2">
<label class="md-nav__title" for="__nav_3_7">
<span class="md-nav__icon md-icon"></span>
Advanced Configuration
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../config/advanced/optional-config/" class="md-nav__link">
Optional Configuration
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3_7_2" data-md-state="indeterminate" type="checkbox" id="__nav_3_7_2" checked>
<label class="md-nav__link" for="__nav_3_7_2">
Maintenance
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Maintenance" data-md-level="3">
<label class="md-nav__title" for="__nav_3_7_2">
<span class="md-nav__icon md-icon"></span>
Maintenance
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../config/advanced/maintenance/update-and-cleanup/" class="md-nav__link">
Update and Cleanup
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3_7_3" data-md-state="indeterminate" type="checkbox" id="__nav_3_7_3" checked>
<label class="md-nav__link" for="__nav_3_7_3">
Override the Default Configs
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Override the Default Configs" data-md-level="3">
<label class="md-nav__title" for="__nav_3_7_3">
<span class="md-nav__icon md-icon"></span>
Override the Default Configs
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../config/advanced/override-defaults/dovecot/" class="md-nav__link">
Dovecot
</a>
</li>
<li class="md-nav__item">
<a href="../../config/advanced/override-defaults/postfix/" class="md-nav__link">
Postfix
</a>
</li>
<li class="md-nav__item">
<a href="../../config/advanced/override-defaults/user-patches/" class="md-nav__link">
Modifications via Script
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../config/advanced/auth-ldap/" class="md-nav__link">
LDAP Authentication
</a>
</li>
<li class="md-nav__item">
<a href="../../config/advanced/mail-sieve/" class="md-nav__link">
Email Filtering with Sieve
</a>
</li>
<li class="md-nav__item">
<a href="../../config/advanced/mail-fetchmail/" class="md-nav__link">
Email Gathering with Fetchmail
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3_7_7" data-md-state="indeterminate" type="checkbox" id="__nav_3_7_7" checked>
<label class="md-nav__link" for="__nav_3_7_7">
Email Forwarding
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Email Forwarding" data-md-level="3">
<label class="md-nav__title" for="__nav_3_7_7">
<span class="md-nav__icon md-icon"></span>
Email Forwarding
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../config/advanced/mail-forwarding/relay-hosts/" class="md-nav__link">
Relay Hosts
</a>
</li>
<li class="md-nav__item">
<a href="../../config/advanced/mail-forwarding/aws-ses/" class="md-nav__link">
AWS SES
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../config/advanced/full-text-search/" class="md-nav__link">
Full-Text Search
</a>
</li>
<li class="md-nav__item">
<a href="../../config/advanced/kubernetes/" class="md-nav__link">
Kubernetes
</a>
</li>
<li class="md-nav__item">
<a href="../../config/advanced/ipv6/" class="md-nav__link">
IPv6
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_4" data-md-state="indeterminate" type="checkbox" id="__nav_4" checked>
<label class="md-nav__link" for="__nav_4">
Examples
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Examples" data-md-level="1">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Examples
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_4_1" data-md-state="indeterminate" type="checkbox" id="__nav_4_1" checked>
<label class="md-nav__link" for="__nav_4_1">
Tutorials
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Tutorials" data-md-level="2">
<label class="md-nav__title" for="__nav_4_1">
<span class="md-nav__icon md-icon"></span>
Tutorials
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../examples/tutorials/basic-installation/" class="md-nav__link">
Basic Installation
</a>
</li>
<li class="md-nav__item">
<a href="../../examples/tutorials/mailserver-behind-proxy/" class="md-nav__link">
Mailserver behind Proxy
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_4_2" data-md-state="indeterminate" type="checkbox" id="__nav_4_2" checked>
<label class="md-nav__link" for="__nav_4_2">
Use Cases
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Use Cases" data-md-level="2">
<label class="md-nav__title" for="__nav_4_2">
<span class="md-nav__icon md-icon"></span>
Use Cases
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../examples/uses-cases/forward-only-mailserver-with-ldap-authentication/" class="md-nav__link">
Forward-Only Mailserver with LDAP
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../faq/" class="md-nav__link">
FAQ
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6" type="checkbox" id="__nav_6" checked>
<label class="md-nav__link" for="__nav_6">
Contributing
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Contributing" data-md-level="1">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
Contributing
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../issues-and-pull-requests/" class="md-nav__link">
Issues and Pull Requests
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
Coding Style
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
Coding Style
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#bash-and-shell" class="md-nav__link">
Bash and Shell
</a>
</li>
<li class="md-nav__item">
<a href="#styling-rules" class="md-nav__link">
Styling rules
</a>
<nav class="md-nav" aria-label="Styling rules">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#if-else-statements" class="md-nav__link">
If-Else-Statements
</a>
</li>
<li class="md-nav__item">
<a href="#variables-braces" class="md-nav__link">
Variables &amp; Braces
</a>
</li>
<li class="md-nav__item">
<a href="#loops" class="md-nav__link">
Loops
</a>
</li>
<li class="md-nav__item">
<a href="#functions" class="md-nav__link">
Functions
</a>
</li>
<li class="md-nav__item">
<a href="#error-tracing" class="md-nav__link">
Error Tracing
</a>
</li>
<li class="md-nav__item">
<a href="#comments-descriptiveness-an-example" class="md-nav__link">
Comments, Descriptiveness &amp; An Example
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#yaml" class="md-nav__link">
YAML
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../tests/" class="md-nav__link">
Tests
</a>
</li>
<li class="md-nav__item">
<a href="../documentation/" class="md-nav__link">
Documentation
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="https://hub.docker.com/repository/docker/mailserver/docker-mailserver" class="md-nav__link">
DockerHub
</a>
</li>
<li class="md-nav__item">
<a href="https://github.com/orgs/docker-mailserver/packages/container/package/docker-mailserver" class="md-nav__link">
GHCR
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#bash-and-shell" class="md-nav__link">
Bash and Shell
</a>
</li>
<li class="md-nav__item">
<a href="#styling-rules" class="md-nav__link">
Styling rules
</a>
<nav class="md-nav" aria-label="Styling rules">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#if-else-statements" class="md-nav__link">
If-Else-Statements
</a>
</li>
<li class="md-nav__item">
<a href="#variables-braces" class="md-nav__link">
Variables &amp; Braces
</a>
</li>
<li class="md-nav__item">
<a href="#loops" class="md-nav__link">
Loops
</a>
</li>
<li class="md-nav__item">
<a href="#functions" class="md-nav__link">
Functions
</a>
</li>
<li class="md-nav__item">
<a href="#error-tracing" class="md-nav__link">
Error Tracing
</a>
</li>
<li class="md-nav__item">
<a href="#comments-descriptiveness-an-example" class="md-nav__link">
Comments, Descriptiveness &amp; An Example
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#yaml" class="md-nav__link">
YAML
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<a href="https://github.com/docker-mailserver/docker-mailserver/edit/master/docs/content/contributing/coding-style.md" title="Edit this page" class="md-content__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg>
</a>
<h1>Coding Style</h1>
<h2 id="bash-and-shell"><a class="toclink" href="#bash-and-shell">Bash and Shell</a></h2>
<p>When refactoring, writing or altering scripts, that is Shell and bash scripts, in any way, adhere to these rules:</p>
<ol>
<li><strong>Adjust your style of coding to the style that is already present</strong>! Even if you do not like it, this is due to consistency. There was a lot of work involved in making all scripts consistent.</li>
<li><strong>Use <code>shellcheck</code> to check your scripts</strong>! Your contributions are checked by GitHub Actions too, so you will need to do this. You can <strong>lint your work with <code>make lint</code></strong> to check against all targets.</li>
<li><strong>Use the provided <code>.editorconfig</code></strong> file.</li>
<li>Use <code>/bin/bash</code> instead of <code>/bin/sh</code>. Adjust the style accordingly.</li>
<li><code>setup.sh</code> provides a good starting point to look for.</li>
<li>When appropriate, use the <code>set</code> builtin. We recommend <code>set -euEo pipefail</code> or <code>set -uE</code>.</li>
</ol>
<h2 id="styling-rules"><a class="toclink" href="#styling-rules">Styling rules</a></h2>
<h3 id="if-else-statements"><a class="toclink" href="#if-else-statements">If-Else-Statements</a></h3>
<div class="highlight"><pre><span></span><code><span class="c1"># when using braces, use double braces</span>
<span class="c1"># remember you do not need &quot;&quot; when using [[ ]]</span>
<span class="k">if</span> <span class="o">[[</span> &lt;CONDITION1&gt; <span class="o">]]</span> <span class="o">&amp;&amp;</span> <span class="o">[[</span> -f <span class="si">${</span><span class="nv">FILE</span><span class="si">}</span> <span class="o">]]</span>
<span class="k">then</span>
&lt;CODE TO RUN&gt;
<span class="c1"># when running commands, you don&#39;t need braces</span>
<span class="k">elif</span> &lt;COMMAND TO RUN&gt;
&lt;CODE TO TUN&gt;
<span class="k">else</span>
&lt;CODE TO TUN&gt;
<span class="k">fi</span>
<span class="c1"># equality checks with numbers are done</span>
<span class="c1"># with -eq/-ne/-lt/-ge, not != or ==</span>
<span class="k">if</span> <span class="o">[[</span> <span class="si">${</span><span class="nv">VAR</span><span class="si">}</span> -ne <span class="m">42</span> <span class="o">]]</span> <span class="o">||</span> <span class="o">[[</span> <span class="si">${</span><span class="nv">SOME_VAR</span><span class="si">}</span> -eq <span class="m">6</span> <span class="o">]]</span>
<span class="k">then</span>
&lt;CODE TO RUN&gt;
<span class="k">fi</span>
</code></pre></div>
<h3 id="variables-braces"><a class="toclink" href="#variables-braces">Variables &amp; Braces</a></h3>
<div class="admonition attention">
<p class="admonition-title">Attention</p>
<p>Variables are always uppercase. We always use braces.</p>
</div>
<p>If you forgot this and want to change it later, you can use <a href="https://regex101.com/r/ikzJpF/7">this link</a>. The used regex is <code>\$([^{("\\'\/])([a-zA-Z0-9_]*)([^}\/ \t'"\n.\]:(=\\-]*)</code>, where you should in practice be able to replace all variable occurrences without braces with occurrences with braces.</p>
<div class="highlight"><pre><span></span><code><span class="c1"># good</span>
<span class="nb">local</span> <span class="nv">VAR</span><span class="o">=</span><span class="s2">&quot;good&quot;</span>
<span class="nb">local</span> <span class="nv">NEW</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">${</span><span class="nv">VAR</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="c1"># bad -&gt; TravisCI will fail</span>
<span class="nv">var</span><span class="o">=</span><span class="s2">&quot;bad&quot;</span>
<span class="nv">new</span><span class="o">=</span><span class="nv">$var</span>
</code></pre></div>
<h3 id="loops"><a class="toclink" href="#loops">Loops</a></h3>
<p>Like <code>if-else</code>, loops look like this</p>
<div class="highlight"><pre><span></span><code><span class="k">for</span> / <span class="k">while</span> &lt;LOOP CONDITION&gt;
<span class="k">do</span>
&lt;CODE TO RUN&gt;
<span class="k">done</span>
</code></pre></div>
<h3 id="functions"><a class="toclink" href="#functions">Functions</a></h3>
<p>It's always nice to see the use of functions as it also provides a clear structure. If scripts are small, this is unnecessary, but if they become larger, please consider using functions. When doing so, provide <code>function _main</code>.</p>
<div class="highlight"><pre><span></span><code><span class="k">function</span> _&lt;name_underscored_and_lowercase&gt;
<span class="o">{</span>
&lt;CODE TO RUN&gt;
<span class="c1"># variables that can be local should be local</span>
<span class="nb">local</span> &lt;LOCAL_VARIABLE_NAME&gt;
<span class="o">}</span>
</code></pre></div>
<h3 id="error-tracing"><a class="toclink" href="#error-tracing">Error Tracing</a></h3>
<p>A construct to trace error in your scripts looks like this. Remember: Remove <code>set -x</code> in the end. This is for debugging purposes only.</p>
<div class="highlight"><pre><span></span><code><span class="nb">set</span> -xeuEo pipefail
<span class="nb">trap</span> <span class="s1">&#39;__log_err ${FUNCNAME[0]:-&quot;?&quot;} ${BASH_COMMAND:-&quot;?&quot;} ${LINENO:-&quot;?&quot;} ${?:-&quot;?&quot;}&#39;</span> ERR
<span class="nv">SCRIPT</span><span class="o">=</span><span class="s1">&#39;name_of_this_script.sh&#39;</span>
<span class="k">function</span> __log_err
<span class="o">{</span>
<span class="nb">printf</span> <span class="s2">&quot;\n \e[1m\e[31mUNCHECKED ERROR\e[0m\n%s\n%s\n%s\n%s\n\n&quot;</span> <span class="se">\</span>
<span class="s2">&quot; script = </span><span class="si">${</span><span class="nv">SCRIPT</span><span class="k">:-</span><span class="si">${</span><span class="nv">0</span><span class="si">}}</span><span class="s2">&quot;</span> <span class="se">\</span>
<span class="s2">&quot; function = </span><span class="si">${</span><span class="nv">1</span><span class="si">}</span><span class="s2"> / </span><span class="si">${</span><span class="nv">2</span><span class="si">}</span><span class="s2">&quot;</span> <span class="se">\</span>
<span class="s2">&quot; line = </span><span class="si">${</span><span class="nv">3</span><span class="si">}</span><span class="s2">&quot;</span> <span class="se">\</span>
<span class="s2">&quot; exit code = </span><span class="si">${</span><span class="nv">4</span><span class="si">}</span><span class="s2">&quot;</span> <span class="m">1</span>&gt;<span class="p">&amp;</span><span class="m">2</span>
&lt;CODE TO RUN AFTERWARDS&gt;
<span class="o">}</span>
</code></pre></div>
<h3 id="comments-descriptiveness-an-example"><a class="toclink" href="#comments-descriptiveness-an-example">Comments, Descriptiveness &amp; An Example</a></h3>
<p>Comments should only describe non-obvious matters. Comments should start lowercase when they aren't sentences. Make the code <strong>self-descriptive</strong> by using meaningful names! Make comments not longer than approximately 80 columns, then wrap the line.</p>
<p>A positive example, which is taken from <code>start-mailserver.sh</code>, would be</p>
<div class="highlight"><pre><span></span><code><span class="k">function</span> _setup_postfix_aliases
<span class="o">{</span>
_notify <span class="s1">&#39;task&#39;</span> <span class="s1">&#39;Setting up Postfix Aliases&#39;</span>
: &gt;/etc/postfix/virtual
: &gt;/etc/postfix/regexp
<span class="k">if</span> <span class="o">[[</span> -f /tmp/docker-mailserver/postfix-virtual.cf <span class="o">]]</span>
<span class="k">then</span>
<span class="c1"># fixing old virtual user file</span>
<span class="k">if</span> grep -q <span class="s2">&quot;,</span>$<span class="s2">&quot;</span> /tmp/docker-mailserver/postfix-virtual.cf
<span class="k">then</span>
sed -i -e <span class="s2">&quot;s/, /,/g&quot;</span> -e <span class="s2">&quot;s/,</span>$<span class="s2">//g&quot;</span> /tmp/docker-mailserver/postfix-virtual.cf
<span class="k">fi</span>
cp -f /tmp/docker-mailserver/postfix-virtual.cf /etc/postfix/virtual
<span class="c1"># the `to` is important, don&#39;t delete it</span>
<span class="c1"># shellcheck disable=SC2034</span>
<span class="k">while</span> <span class="nb">read</span> -r FROM TO
<span class="k">do</span>
<span class="c1"># Setting variables for better readability</span>
<span class="nv">UNAME</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> <span class="s2">&quot;</span><span class="si">${</span><span class="nv">FROM</span><span class="si">}</span><span class="s2">&quot;</span> <span class="p">|</span> cut -d @ -f1<span class="k">)</span>
<span class="nv">DOMAIN</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> <span class="s2">&quot;</span><span class="si">${</span><span class="nv">FROM</span><span class="si">}</span><span class="s2">&quot;</span> <span class="p">|</span> cut -d @ -f2<span class="k">)</span>
<span class="c1"># if they are equal it means the line looks like: &quot;user1 other@domain.tld&quot;</span>
<span class="o">[[</span> <span class="s2">&quot;</span><span class="si">${</span><span class="nv">UNAME</span><span class="si">}</span><span class="s2">&quot;</span> !<span class="o">=</span> <span class="s2">&quot;</span><span class="si">${</span><span class="nv">DOMAIN</span><span class="si">}</span><span class="s2">&quot;</span> <span class="o">]]</span> <span class="o">&amp;&amp;</span> <span class="nb">echo</span> <span class="s2">&quot;</span><span class="si">${</span><span class="nv">DOMAIN</span><span class="si">}</span><span class="s2">&quot;</span> &gt;&gt; /tmp/vhost.tmp
<span class="k">done</span> &lt; &lt;<span class="o">(</span>grep -v <span class="s2">&quot;^\s*</span>$<span class="s2">\|^\s*\#&quot;</span> /tmp/docker-mailserver/postfix-virtual.cf <span class="o">||</span> <span class="nb">true</span><span class="o">)</span>
<span class="k">else</span>
_notify <span class="s1">&#39;inf&#39;</span> <span class="s2">&quot;Warning &#39;config/postfix-virtual.cf&#39; is not provided. No mail alias/forward created.&quot;</span>
<span class="k">fi</span>
...
<span class="o">}</span>
</code></pre></div>
<h2 id="yaml"><a class="toclink" href="#yaml">YAML</a></h2>
<p>When formatting YAML files, use <a href="https://prettier.io">Prettier</a>, an opinionated formatter. There are many plugins for IDEs around.</p>
</article>
</div>
</div>
<a href="#" class="md-top md-icon" data-md-component="top" data-md-state="hidden">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"/></svg>
</a>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="Footer">
<a href="../issues-and-pull-requests/" class="md-footer__link md-footer__link--prev" rel="prev">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
</div>
<div class="md-footer__title">
<div class="md-ellipsis">
<span class="md-footer__direction">
Previous
</span>
Issues and Pull Requests
</div>
</div>
</a>
<a href="../tests/" class="md-footer__link md-footer__link--next" rel="next">
<div class="md-footer__title">
<div class="md-ellipsis">
<span class="md-footer__direction">
Next
</span>
Tests
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11H4z"/></svg>
</div>
</a>
</nav>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
<p>&copy <a href="https://github.com/docker-mailserver"><em>Docker Mailserver Organization</em></a><br/><span>This project is licensed under the MIT license.</span></p>
</div>
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "../..", "features": ["navigation.tabs", "navigation.top", "navigation.expand", "navigation.instant"], "translations": {"clipboard.copy": "Copy to clipboard", "clipboard.copied": "Copied to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.placeholder": "Type to start searching", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.term.missing": "Missing"}, "search": "../../assets/javascripts/workers/search.fe42c31b.min.js", "version": {"provider": "mike"}}</script>
<script src="../../assets/javascripts/bundle.4ea5477f.min.js"></script>
</body>
</html>