Integrating npm front-end with Kallithea
Mads Kiilerich
mads at kiilerich.com
Wed Nov 8 02:46:18 UTC 2017
Hello, Community
Big parts of Dominik's front-end work around introducing Bootstrap has
landed. Thanks!
The next step require a bit of an architectural decision. I would like
to share it here to get feedback/awareness from the rest of the community.
It is about how we combine the use of the npm package manager and
packages with Kallithea primarily being distributed on pypi as GPL
application. It might be an annoying problem, but we just have to find a
solution to it.
I have a proposal that describe the problem and some solutions ... and
implement one that seems to work. It is available on
https://kallithea-scm.org/repos/kallithea-incoming/changeset/1b9cb678344f80221f14bdb9b779d5a4823d829a
for testing and experimenting, but I will also paste it here.
Does it work for you, or what do you suggest?
/Mads
# HG changeset patch
# User Mads Kiilerich <mads at kiilerich.com>
# Date 1510108450 -3600
# Wed Nov 08 03:34:10 2017 +0100
# Node ID 1b9cb678344f80221f14bdb9b779d5a4823d829a
# Parent 6bef1d7bafa6b1743ad10f644d72139e10b95b76
setup: install and run npm commands when installing Kallithea with pip
Kallithea is under the GPL license, and we can thus only distribute any
generated code if we also ship the corresponding source.
We are moving towards a web front-end that use npm to download and compile
various open source components. The components might not be GPL, but if we
distribute any parts of their code (compiled or converted to other
representation), then we also must distribute the corresponding source under
the GPL.
It doesn't seem feasible for us to distribute the source of everything
that npm
downloads and includes when we are building. It thus also doesn't seem
feasible
for us to build and ship the compiled (possibly minified) front-end code.
Instead, we have to make it as smooth as possible for our users to get
up and
running.
It doesn't seem feasible for us to ship or install npm. We must assume it is
available. That requirement must be documented clearly, and we must
recommend
how to install npm for the most common platforms.
We could perhaps just document what manual steps to run. Kallithea
doesn't work
out of the box anyway - it has to be configured and initialized. Extra steps
might not be a big problem. We could perhaps also have a custom gearbox
command
to run the commands. But running it on demand when launching the editor
would
probably scare most system administrators ... and would also create
different
problems with the different ways of running Kallithea.
But it would be nice if we could call out to npm while pip is installing
Kallithea and download the requirements and build the files. It can be
done by
customizing setuptools commands in setup.py . That is what is done here.
Python packaging is fragile. Even though we only support pip, it really
isn't
built for things like this. Custom output is muted and buffered and only
shown
if running with -v or the command fails. And pip and setup.py can be used to
build and install in so many ways that we probably can't make it work
reliably
with all ways of installing Kallithea. But we can try.
The npm invocation can be disabled by setting the environment variable
KALLITHEA_INSTALL_RUN_NPM=NO .
The custom 'install' method is used by a plain 'pip install' form pypi
or tar,
while 'develop' is used when running 'pip install -e' from source. While
developing, it might also be convenient to just run the 'less' command
directly, or to use 'nodemon' to run it automatically when the source files
change.
For now, this will just create/update style.css ... but currently probably
without any actual changes. The files created by npm (and the node_modules
directory) must *not* be a part of the release package made with 'setup.py
sdist'.
diff --git a/docs/overview.rst b/docs/overview.rst
--- a/docs/overview.rst
+++ b/docs/overview.rst
@@ -69,6 +69,10 @@ installed.
(``pip install kallithea`` from a source tree will do pretty much
the same
but build the Kallithea package itself locally instead of
downloading it.)
+Kallithea also include some front-end code that need npm_ to download
packages
+and build the front-end. The ``npm`` binary must thus be available, and
it will
+be invoked automatically and invisibly when installing with ``pip``.
+
Web server
----------
@@ -138,3 +142,4 @@ continuous hammering from the internet.
.. _WSGI: http://en.wikipedia.org/wiki/Web_Server_Gateway_Interface
.. _HAProxy: http://www.haproxy.org/
.. _Varnish: https://www.varnish-cache.org/
+.. _npm: https://www.npmjs.com/
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -3,6 +3,8 @@
import os
import sys
import platform
+import subprocess
+
if sys.version_info < (2, 6) or sys.version_info >= (3,):
raise Exception('Kallithea requires python 2.6 or 2.7')
@@ -122,6 +124,31 @@ class sdist_new(sdist_org):
self.owner = self.group = 'root'
sdist.sdist = sdist_new
+
+from setuptools.command.develop import develop
+from setuptools.command.install import install
+
+class DevelopNpm(develop):
+ def run(self):
+ develop.run(self)
+ install_npm()
+
+class InstallNpm(install):
+ def run(self):
+ install.run(self)
+ install_npm()
+
+def install_npm():
+ if os.environ.get('KALLITHEA_INSTALL_RUN_NPM') != 'NO':
+ import kallithea # has just been installed
+ rootdir =
os.path.dirname(os.path.dirname(os.path.abspath(kallithea.__file__)))
+ srcdir = os.path.join(rootdir, 'kallithea', 'public', 'less')
+ sys.stderr.write("\nRunning 'npm install' in %s to install
packages from package.json\n" % srcdir)
+ subprocess.check_call(['npm', 'install'], cwd=srcdir)
+ sys.stderr.write("\nRunning 'npm run less' in %s to build css
from package.json\n" % srcdir)
+ subprocess.check_call(['npm', 'run', 'less'], cwd=srcdir)
+
+
packages = setuptools.find_packages(exclude=['ez_setup'])
setuptools.setup(
@@ -140,6 +167,9 @@ setuptools.setup(
data_files=data_files,
packages=packages,
include_package_data=True,
+ cmdclass={
+ 'install': InstallNpm,
+ 'develop': DevelopNpm},
message_extractors={'kallithea': [
('**.py', 'python', None),
('templates/**.mako', 'mako', {'input_encoding': 'utf-8'}),
More information about the kallithea-general
mailing list