diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..1b823a2c19a3eabf1719d24b74771549a44a232e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+dist
+build
diff --git a/README.md b/README.md
index dddb1640a3ffdbff6318fd38b18bfb9b7cf6327c..cd6ce4e011e1cde40a4c79c5c6d08889b23e1514 100644
--- a/README.md
+++ b/README.md
@@ -11,3 +11,12 @@ This cli requires python 3.6 or greater:
# Usage
``funkwhale --help``
+
+# Build the binary
+
+You can build the binarie for you platform using the following commands:
+
+ pip install .[dev]
+ pyinstaller cli.spec
+
+This will output a binary in `./dist/funkwhale`.
diff --git a/cli.spec b/cli.spec
new file mode 100644
index 0000000000000000000000000000000000000000..3116b1c844458af93f54a78717d930d394d59264
--- /dev/null
+++ b/cli.spec
@@ -0,0 +1,35 @@
+# -*- mode: python -*-
+
+block_cipher = None
+
+
+a = Analysis(
+ ["funkwhale_cli/cli.py"],
+ pathex=["/home/eliotberriot/projects/funkwhale/cli"],
+ binaries=[],
+ datas=[],
+ hiddenimports=[],
+ hookspath=[],
+ runtime_hooks=[],
+ excludes=[],
+ win_no_prefer_redirects=False,
+ win_private_assemblies=False,
+ cipher=block_cipher,
+ noarchive=False,
+)
+pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
+exe = EXE(
+ pyz,
+ a.scripts,
+ a.binaries,
+ a.zipfiles,
+ a.datas,
+ [],
+ name="funkwhale",
+ debug=False,
+ bootloader_ignore_signals=False,
+ strip=False,
+ upx=True,
+ runtime_tmpdir=None,
+ console=True,
+)
diff --git a/funkwhale_cli/cli.py b/funkwhale_cli/cli.py
index 1948581568d09aa488eafbbb95926768ff1b0bc3..c3170d0130f80a7ea4d4fdcde6672aee5cd01059 100644
--- a/funkwhale_cli/cli.py
+++ b/funkwhale_cli/cli.py
@@ -7,6 +7,14 @@ import datetime
import dotenv
import functools
import keyring
+
+# importing the backends explicitely is required for PyInstaller to work
+import keyring.backends.kwallet
+import keyring.backends.Windows
+import keyring.backends.OS_X
+import keyring.backends.SecretService
+import keyring.backends.chainer
+
import logging
import math
import urllib.parse
@@ -16,11 +24,12 @@ import pathvalidate
import pathlib
import urllib.parse
import tqdm
-from . import api
-from . import config
-from . import exceptions
-from . import logs
-from . import output
+
+from funkwhale_cli import api
+from funkwhale_cli import config
+from funkwhale_cli import exceptions
+from funkwhale_cli import logs
+from funkwhale_cli import output
click_log.basic_config(logs.logger)
@@ -173,7 +182,12 @@ def set_server(ctx, url, token, use_auth=True):
@TOKEN_DECORATOR
@click_log.simple_verbosity_option(logs.logger, expose_value=True)
@click.pass_context
-def cli(ctx, env_file, url, verbosity, token, quiet):
+def cli(ctx, env_file, url, verbosity, token, quiet, no_login):
+ # small hack to fix some weird issues with pyinstaller and keyring
+ # there seems to be a cache issue somewhere
+ del keyring.backend.get_all_keyring.__wrapped__.always_returns
+ keyring.core.init_backend()
+ # /end of hack
ctx.ensure_object(dict)
logs.logger.disabled = quiet
set_server(ctx, url, token, use_auth=not no_login)
diff --git a/setup.cfg b/setup.cfg
index a32bac142ab34dc26ce0e5466b25d65a2c82b3be..37b52206a221db941a37498121cf842214dad928 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -44,7 +44,7 @@ dev =
pytest
pytest-mock
pytest-env
-
+ pyinstaller
[options.packages.find]