diff --git a/bob/extension/scripts/click_helper.py b/bob/extension/scripts/click_helper.py
index 8bdb097d71c9caac646071d6fbc562a2516e038c..a487a574fbb1cca674dc2e87385a3c29bd31d208 100644
--- a/bob/extension/scripts/click_helper.py
+++ b/bob/extension/scripts/click_helper.py
@@ -1,5 +1,6 @@
 from ..log import set_verbosity_level
 from ..config import load, mod_to_context
+import time
 import click
 import logging
 
@@ -172,6 +173,9 @@ class ConfigCommand(click.Command):
         **kwargs)
     # Add the config argument to the command
     click.argument(config_argument_name, nargs=-1)(self)
+    # Option for config file generation
+    click.option('-dc', '--dump-config', type=click.Path(exists=False),
+                 help="Name of the config file to be generated")(self)
 
   def invoke(self, ctx):
     config_files = ctx.params[self.config_argument_name.lower()]
@@ -180,7 +184,7 @@ class ConfigCommand(click.Command):
         config_files, entry_point_group=self.entry_point_group)
     config_context = mod_to_context(config_context)
     for param in self.params:
-      if param.name not in ctx.params:
+      if param.name not in ctx.params or param.name == 'dump_config':
         continue
       value = ctx.params[param.name]
       if not hasattr(param, 'user_provided'):
@@ -200,9 +204,27 @@ class ConfigCommand(click.Command):
         finally:
           # make sure to set this back to False for future invocations
           param.required = False
+    if 'dump_config' in ctx.params:
+      self.dump_config(ctx)
 
     return super(ConfigCommand, self).invoke(ctx)
 
+  def dump_config(self, ctx):
+    config_file = open(ctx.params.get('dump_config'), 'w')
+    config_file.write('# Configuration file automatically generated at %s '
+                      'for %s.\n\n\n' % (time.strftime("%d/%m/%Y"),
+                                   ctx.command_path))
+    for param in self.params:
+      if param.name not in ctx.params or param.name == 'dump_config':
+        continue
+      if not isinstance(param, click.Option):
+          continue
+
+      config_file.write('# %s.\n\n' % param.help)
+      config_file.write('# %s = %s \n\n' % (param.name,
+                                       str(ctx.params[param.name])))
+      config_file.write('\n\n\n')
+
 
 class ResourceOption(click.Option):
   """A click.Option that is aware if the user actually provided this option
diff --git a/bob/extension/scripts/main_cli.py b/bob/extension/scripts/main_cli.py
index 46ab57f9b6196e8d8510f0dd6c1bc2e2019fb681..3f08db409d37045ee80ca99befa69b5ae22f5921 100644
--- a/bob/extension/scripts/main_cli.py
+++ b/bob/extension/scripts/main_cli.py
@@ -3,7 +3,7 @@
 import pkg_resources
 import click
 from click_plugins import with_plugins
-from .click_helper import AliasedGroup
+from .click_helper import AliasedGroup, ConfigCommand
 from ..log import setup
 logger = setup('bob')
 
diff --git a/bob/extension/test_click_helper.py b/bob/extension/test_click_helper.py
index 2872fe1a01addac80d0f3a9f850f44c66d5d870f..dbdbb28e627ca53bd79559a821b7975c3e324466 100644
--- a/bob/extension/test_click_helper.py
+++ b/bob/extension/test_click_helper.py
@@ -171,3 +171,20 @@ def test_prefix_aliasing():
     result = runner.invoke(cli, ['test_a'], catch_exceptions=False)
     assert result.exit_code == 0, (result.exit_code, result.output)
     assert 'AAA' in result.output, (result.exit_code, result.output)
+
+
+def test_config_dump():
+    @click.group(cls=AliasedGroup)
+    def cli():
+        pass
+
+    @click.command(cls=ConfigCommand)
+    @click.option('-t', '--test', required=True, default="/my/path/test.txt",
+    help="Path leading to test blablabla", cls=ResourceOption)
+    @verbosity_option()
+    def test(config, test, **kwargs):
+        pass
+    runner = CliRunner()
+    with runner.isolated_filesystem():
+        result = runner.invoke(cli, ['test', '-dc', 'TEST_CONF'], catch_exceptions=False)
+        assert result.exit_code != 0, (result.exit_code, result.output)