2017-09-18 18:30:08 +02:00
|
|
|
|
# Provisioning and third-party dependencies
|
|
|
|
|
|
|
|
|
|
Zulip is a large project, with well over 100 third-party dependencies,
|
2021-08-20 21:53:28 +02:00
|
|
|
|
and managing them well is essential to the quality of the project. In
|
2017-09-18 18:30:08 +02:00
|
|
|
|
this document, we discuss the various classes of dependencies that
|
2021-08-20 21:53:28 +02:00
|
|
|
|
Zulip has, and how we manage them. Zulip's dependency management has
|
2017-09-18 18:30:08 +02:00
|
|
|
|
some really nice properties:
|
|
|
|
|
|
2021-08-20 21:53:28 +02:00
|
|
|
|
- **Fast provisioning**. When switching to a different commit in the
|
2020-05-17 14:26:43 +02:00
|
|
|
|
Zulip project with the same dependencies, it takes under 5 seconds
|
2017-09-18 18:30:08 +02:00
|
|
|
|
to re-provision a working Zulip development environment after
|
2021-08-20 21:53:28 +02:00
|
|
|
|
switching. If there are new dependencies, one only needs to wait to
|
2017-09-18 18:30:08 +02:00
|
|
|
|
download the new ones, not all the pre-existing dependencies.
|
2021-08-20 21:53:28 +02:00
|
|
|
|
- **Consistent provisioning**. Every time a Zulip development or
|
2017-09-18 18:30:08 +02:00
|
|
|
|
production environment is provisioned/installed, it should end up
|
|
|
|
|
using the exactly correct versions of all major dependencies.
|
2021-08-20 21:53:28 +02:00
|
|
|
|
- **Low maintenance burden**. To the extent possible, we want to
|
2017-09-18 18:30:08 +02:00
|
|
|
|
avoid manual work and keeping track of things that could be
|
2021-08-20 21:53:28 +02:00
|
|
|
|
automated. This makes it easy to keep running the latest versions
|
2017-09-18 18:30:08 +02:00
|
|
|
|
of our various dependencies.
|
|
|
|
|
|
|
|
|
|
The purpose of this document is to detail all of Zulip's third-party
|
|
|
|
|
dependencies and how we manage their versions.
|
|
|
|
|
|
2017-09-22 20:18:38 +02:00
|
|
|
|
## Provisioning
|
|
|
|
|
|
|
|
|
|
We refer to "provisioning" as the process of installing and
|
2021-08-20 21:53:28 +02:00
|
|
|
|
configuring the dependencies of a Zulip development environment. It's
|
2017-09-22 20:18:38 +02:00
|
|
|
|
done using `tools/provision`, and the output is conveniently logged by
|
2021-08-20 21:53:28 +02:00
|
|
|
|
`var/log/provision.log` to help with debugging. Provisioning makes
|
|
|
|
|
use of a lot of caching. Some of those caches are not immune to being
|
|
|
|
|
corrupted if you mess around with files in your repository a lot. We
|
2017-09-22 20:18:38 +02:00
|
|
|
|
have `tools/provision --force` to (still fairly quickly) rerun most
|
|
|
|
|
steps that would otherwise have been skipped due to caching.
|
|
|
|
|
|
|
|
|
|
In the Vagrant development environment, `vagrant provision` will run
|
|
|
|
|
the provision script; `vagrant up` will boot the machine, and will
|
|
|
|
|
also run an initial provision the first time only.
|
|
|
|
|
|
2018-10-19 00:37:08 +02:00
|
|
|
|
### PROVISION_VERSION
|
|
|
|
|
|
|
|
|
|
In `version.py`, we have a special parameter, `PROVISION_VERSION`,
|
|
|
|
|
which is used to help ensure developers don't spend time debugging
|
|
|
|
|
test/linter/etc. failures that actually were caused by the developer
|
2021-08-20 21:53:28 +02:00
|
|
|
|
rebasing and forgetting to provision". `PROVISION_VERSION` has a
|
2022-07-20 22:24:54 +02:00
|
|
|
|
format of `(x, y)`; when `x` doesn't match the value from the last time
|
2022-02-08 00:13:33 +01:00
|
|
|
|
the user provisioned, or `y` is higher than the value from last
|
2018-10-19 00:37:08 +02:00
|
|
|
|
time, most Zulip tools will crash early and ask the user to provision.
|
|
|
|
|
This has empirically made a huge impact on how often developers spend
|
|
|
|
|
time debugging a "weird failure" after rebasing that had an easy
|
2021-08-20 21:53:28 +02:00
|
|
|
|
solution. (Of course, the other key part of achieving this is all the
|
2018-10-19 00:37:08 +02:00
|
|
|
|
work that goes into making sure that `provision` reliably leaves the
|
|
|
|
|
development environment in a good state.)
|
|
|
|
|
|
|
|
|
|
`PROVISION_VERSION` must be manually updated when making changes that
|
|
|
|
|
require re-running provision, so don't forget about it!
|
|
|
|
|
|
2017-09-18 18:30:08 +02:00
|
|
|
|
## Philosophy on adding third-party dependencies
|
|
|
|
|
|
|
|
|
|
In the Zulip project, we take a pragmatic approach to third-party
|
2021-08-20 21:53:28 +02:00
|
|
|
|
dependencies. Overall, if a third-party project does something well
|
2017-09-18 18:30:08 +02:00
|
|
|
|
that Zulip needs to do (and has an appropriate license), we'd love to
|
2021-08-20 21:53:28 +02:00
|
|
|
|
use it rather than reinventing the wheel. If the third-party project
|
2017-09-18 18:30:08 +02:00
|
|
|
|
needs some small changes to work, we prefer to make those changes and
|
2021-08-20 21:53:28 +02:00
|
|
|
|
contribute them upstream. When the upstream maintainer is slow to
|
2017-09-18 18:30:08 +02:00
|
|
|
|
respond, we may use a fork of the dependency until the code is merged
|
|
|
|
|
upstream; as a result, we usually have a few packages in
|
|
|
|
|
`requirements.txt` that are installed from a GitHub URL.
|
|
|
|
|
|
|
|
|
|
What we look for in choosing dependencies is whether the project is
|
2021-08-20 21:53:28 +02:00
|
|
|
|
well-maintained. Usually one can tell fairly quickly from looking at
|
2017-09-18 18:30:08 +02:00
|
|
|
|
a project's issue tracker how well-managed it is: a quick look at how
|
|
|
|
|
the issue tracker is managed (or not) and the test suite is usually
|
|
|
|
|
enough to decide if a project is going to be a high-maintenance
|
2021-08-20 21:53:28 +02:00
|
|
|
|
dependency or not. That said, we do still take on some smaller
|
2017-09-18 18:30:08 +02:00
|
|
|
|
dependencies that don't have a well-managed project, if we feel that
|
|
|
|
|
using the project will still be a better investment than writing our
|
2021-08-20 21:53:28 +02:00
|
|
|
|
own implementation of that project's functionality. We've adopted a
|
2017-09-18 18:30:08 +02:00
|
|
|
|
few projects in the past that had a good codebase but whose maintainer
|
|
|
|
|
no longer had time for them.
|
|
|
|
|
|
|
|
|
|
One case where we apply added scrutiny to third-party dependencies is
|
2021-08-20 21:53:28 +02:00
|
|
|
|
JS libraries. They are a particularly important concern because we
|
2021-05-14 00:16:30 +02:00
|
|
|
|
want to keep the Zulip web app's JS bundle small, so that Zulip
|
2017-09-18 18:30:08 +02:00
|
|
|
|
continues to load quickly on systems with low network bandwidth.
|
|
|
|
|
We'll look at large JS libraries with much greater scrutiny for
|
|
|
|
|
whether their functionality justifies their size than Python
|
|
|
|
|
dependencies, since an extra 50KB of code usually doesn't matter in
|
|
|
|
|
the backend, but does in JavaScript.
|
|
|
|
|
|
|
|
|
|
## System packages
|
|
|
|
|
|
2022-01-25 07:21:47 +01:00
|
|
|
|
For the third-party services like PostgreSQL, Redis, nginx, and RabbitMQ
|
2017-09-18 18:30:08 +02:00
|
|
|
|
that are documented in the
|
2019-09-30 19:37:56 +02:00
|
|
|
|
[architecture overview](../overview/architecture-overview.md), we rely on the
|
2017-09-18 18:30:08 +02:00
|
|
|
|
versions of those packages provided alongside the Linux distribution
|
2021-08-20 21:53:28 +02:00
|
|
|
|
on which Zulip is deployed. Because Zulip
|
2019-09-30 19:37:56 +02:00
|
|
|
|
[only supports Ubuntu in production](../production/requirements.md), this
|
2017-09-18 18:30:08 +02:00
|
|
|
|
usually means `apt`, though we do support
|
2021-08-20 21:53:28 +02:00
|
|
|
|
[other platforms in development](../development/setup-advanced.md). Since
|
2017-09-18 18:30:08 +02:00
|
|
|
|
we don't control the versions of these dependencies, we avoid relying
|
|
|
|
|
on specific versions of these packages wherever possible.
|
|
|
|
|
|
|
|
|
|
The exact lists of `apt` packages needed by Zulip are maintained in a
|
|
|
|
|
few places:
|
2021-08-20 22:54:08 +02:00
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
|
- For production, in our Puppet configuration, `puppet/zulip/`, using
|
2017-09-18 18:30:08 +02:00
|
|
|
|
the `Package` and `SafePackage` directives.
|
2021-08-20 21:45:39 +02:00
|
|
|
|
- For development, in `SYSTEM_DEPENDENCIES` in `tools/lib/provision.py`.
|
|
|
|
|
- The packages needed to build a Zulip virtualenv, in
|
2021-08-20 21:53:28 +02:00
|
|
|
|
`VENV_DEPENDENCIES` in `scripts/lib/setup_venv.py`. These are
|
2017-09-18 18:30:08 +02:00
|
|
|
|
separate from the rest because (1) we may need to install a
|
|
|
|
|
virtualenv before running the more complex scripts that, in turn,
|
|
|
|
|
install other dependencies, and (2) because that list is shared
|
|
|
|
|
between development and production.
|
|
|
|
|
|
2020-10-26 22:27:53 +01:00
|
|
|
|
We also rely on the PGroonga PPA for the PGroonga PostgreSQL
|
2019-09-30 19:37:56 +02:00
|
|
|
|
extension, used by our [full-text search](full-text-search.md).
|
2017-09-18 18:30:08 +02:00
|
|
|
|
|
|
|
|
|
## Python packages
|
|
|
|
|
|
2021-07-28 20:23:27 +02:00
|
|
|
|
Zulip uses the version of Python itself provided by the host OS for
|
2022-04-19 03:18:48 +02:00
|
|
|
|
the Zulip server. We currently support Python 3.8 and newer, with
|
|
|
|
|
Ubuntu 20.04 being the platform requiring 3.8 support. The comments
|
2021-07-28 20:23:27 +02:00
|
|
|
|
in `.github/workflows/zulip-ci.yml` document the Python versions used
|
|
|
|
|
by each supported platform.
|
|
|
|
|
|
2017-09-18 18:30:08 +02:00
|
|
|
|
We manage Python packages via the Python-standard `requirements.txt`
|
|
|
|
|
system and virtualenvs, but there’s a number of interesting details
|
|
|
|
|
about how Zulip makes this system work well for us that are worth
|
2021-08-20 21:53:28 +02:00
|
|
|
|
highlighting. The system is largely managed by the code in
|
2017-09-18 18:30:08 +02:00
|
|
|
|
`scripts/lib/setup_venv.py`
|
|
|
|
|
|
2021-08-20 21:53:28 +02:00
|
|
|
|
- **Using `pip` to manage dependencies**. This is standard in the
|
2017-09-18 18:30:08 +02:00
|
|
|
|
Python ecosystem, and means we only need to record a list of
|
|
|
|
|
versions in a `requirements.txt` file to declare what we're using.
|
|
|
|
|
Since we have a few different installation targets, we maintain
|
|
|
|
|
several `requirements.txt` format files in the `requirements/`
|
2017-11-17 02:41:06 +01:00
|
|
|
|
directory (e.g. `dev.in` for development, `prod.in` for
|
|
|
|
|
production, `docs.in` for ReadTheDocs, `common.in` for the vast
|
2021-08-20 21:53:28 +02:00
|
|
|
|
majority of packages common to prod and development, etc.). We use
|
2017-09-18 18:30:08 +02:00
|
|
|
|
`pip install --no-deps` to ensure we only install the packages we
|
|
|
|
|
explicitly declare as dependencies.
|
2021-08-20 21:53:28 +02:00
|
|
|
|
- **virtualenv with pinned versions**. For a large application like
|
2017-09-18 18:30:08 +02:00
|
|
|
|
Zulip, it is important to ensure that we're always using consistent,
|
2021-08-20 21:53:28 +02:00
|
|
|
|
predictable versions of all of our Python dependencies. To ensure
|
2017-09-18 18:30:08 +02:00
|
|
|
|
this, we install our dependencies in a [virtualenv][] that contains
|
|
|
|
|
only the packages and versions that Zulip needs, and we always pin
|
|
|
|
|
exact versions of our dependencies in our `requirements.txt` files.
|
|
|
|
|
We pin exact versions, not minimum versions, so that installing
|
2021-08-20 21:53:28 +02:00
|
|
|
|
Zulip won't break if a dependency makes a buggy release. A side
|
2017-09-18 18:30:08 +02:00
|
|
|
|
effect is that it's easy to debug problems caused by dependency
|
|
|
|
|
upgrades, since we're always doing those upgrades with an explicit
|
|
|
|
|
commit updating the `requirements/` directory.
|
2021-08-20 21:53:28 +02:00
|
|
|
|
- **Pinning versions of indirect dependencies**. We "pin" or "lock"
|
2017-11-17 02:41:06 +01:00
|
|
|
|
the versions of our indirect dependencies files with
|
2021-08-20 21:53:28 +02:00
|
|
|
|
`tools/update-locked-requirements` (powered by `pip-compile`). What
|
2017-11-17 02:41:06 +01:00
|
|
|
|
this means is that we have some "source" requirements files, like
|
|
|
|
|
`requirements/common.in`, that declare the packages that Zulip
|
2021-08-20 21:53:28 +02:00
|
|
|
|
depends on directly. Those packages have their own recursive
|
|
|
|
|
dependencies. When adding or removing a dependency from Zulip, one
|
2017-11-17 02:41:06 +01:00
|
|
|
|
simply edits the appropriate "source" requirements files, and then
|
2021-08-20 21:53:28 +02:00
|
|
|
|
runs `tools/update-locked-requirements`. That tool will use
|
2021-09-08 01:02:22 +02:00
|
|
|
|
`pip-compile` to generate the locked requirements files like
|
|
|
|
|
`prod.txt`, `dev.txt` etc files that explicitly declare versions of
|
2021-08-20 21:53:28 +02:00
|
|
|
|
all of Zulip's recursive dependencies. For indirect dependencies
|
2021-09-08 01:02:22 +02:00
|
|
|
|
(i.e. dependencies not explicitly declared in the source
|
|
|
|
|
requirements files), it provides helpful comments explaining which
|
|
|
|
|
direct dependency (or dependencies) needed that indirect dependency.
|
|
|
|
|
The process for using this system is documented in more detail in
|
2017-11-17 02:41:06 +01:00
|
|
|
|
`requirements/README.md`.
|
2021-08-20 21:53:28 +02:00
|
|
|
|
- **Caching of virtualenvs and packages**. To make updating the
|
2017-09-18 18:30:08 +02:00
|
|
|
|
dependencies of a Zulip installation efficient, we maintain a cache
|
|
|
|
|
of virtualenvs named by the hash of the relevant `requirements.txt`
|
2021-08-20 21:53:28 +02:00
|
|
|
|
file (`scripts/lib/hash_reqs.py`). These caches live under
|
|
|
|
|
`/srv/zulip-venv-cache/<hash>`. That way, when re-provisioning a
|
2017-09-18 18:30:08 +02:00
|
|
|
|
development environment or deploying a new production version with
|
|
|
|
|
the same Python dependencies, no downloading or installation is
|
2021-08-20 21:53:28 +02:00
|
|
|
|
required: we just use the same virtualenv. When the only changes
|
2017-09-18 18:30:08 +02:00
|
|
|
|
are upgraded versions, we'll use [virtualenv-clone][] to clone the
|
|
|
|
|
most similar existing virtualenv and then just upgrade the packages
|
2021-08-20 21:53:28 +02:00
|
|
|
|
needed, making small version upgrades extremely efficient. And
|
2017-09-18 18:30:08 +02:00
|
|
|
|
finally, we use `pip`'s built-in caching to ensure that a specific
|
|
|
|
|
version of a specific package is only downloaded once.
|
2021-08-20 21:53:28 +02:00
|
|
|
|
- **Garbage-collecting caches**. We have a tool,
|
2018-06-18 16:28:34 +02:00
|
|
|
|
`scripts/lib/clean_venv_cache.py`, which will clean old cached
|
2021-08-20 21:53:28 +02:00
|
|
|
|
virtualenvs that are no longer in use. In production, the algorithm
|
2017-09-18 18:30:08 +02:00
|
|
|
|
preserves recent virtualenvs as well as those in use by any current
|
|
|
|
|
production deployment directory under `/home/zulip/deployments/`.
|
|
|
|
|
This helps ensure that a Zulip installation doesn't leak large
|
|
|
|
|
amounts of disk over time.
|
2021-08-20 21:53:28 +02:00
|
|
|
|
- **Scripts**. Often, we want a script running in production to use
|
|
|
|
|
the Zulip virtualenv. To make that work without a lot of duplicated
|
2020-01-08 00:06:39 +01:00
|
|
|
|
code, we have a helpful function,
|
|
|
|
|
`scripts.lib.setup_path.setup_path`, which on import will put the
|
2021-08-20 21:53:28 +02:00
|
|
|
|
currently running Python script into the Zulip virtualenv. This is
|
2017-09-18 18:30:08 +02:00
|
|
|
|
called by `./manage.py` to ensure that our Django code always uses
|
|
|
|
|
the correct virtualenv as well.
|
2021-08-20 21:53:28 +02:00
|
|
|
|
- **Mypy type checker**. Because we're using mypy in a strict mode,
|
2018-07-27 00:06:22 +02:00
|
|
|
|
when you add use of a new Python dependency, you usually need to
|
|
|
|
|
either adds stubs to the `stubs/` directory for the library, or edit
|
2021-07-05 23:36:46 +02:00
|
|
|
|
`pyproject.toml` in the root of the Zulip project to configure
|
2021-08-20 21:53:28 +02:00
|
|
|
|
`ignore_missing_imports` for the new library. See
|
2018-07-27 00:06:22 +02:00
|
|
|
|
[our mypy docs][mypy-docs] for more details.
|
|
|
|
|
|
2019-01-03 18:52:20 +01:00
|
|
|
|
### Upgrading packages
|
|
|
|
|
|
|
|
|
|
See the [README][requirements-readme] file in `requirements/` directory
|
|
|
|
|
to learn how to upgrade a single Python package.
|
|
|
|
|
|
2019-09-30 19:37:56 +02:00
|
|
|
|
[mypy-docs]: ../testing/mypy.md
|
2021-09-01 00:15:31 +02:00
|
|
|
|
[requirements-readme]: https://github.com/zulip/zulip/blob/main/requirements/README.md#requirements
|
2019-01-03 18:52:20 +01:00
|
|
|
|
[stack-overflow]: https://askubuntu.com/questions/8653/how-to-keep-processes-running-after-ending-ssh-session
|
2019-02-26 02:49:09 +01:00
|
|
|
|
[caching]: https://help.github.com/en/articles/caching-your-github-password-in-git
|
2017-09-18 18:30:08 +02:00
|
|
|
|
|
|
|
|
|
## JavaScript and other frontend packages
|
|
|
|
|
|
|
|
|
|
We use the same set of strategies described for Python dependencies
|
|
|
|
|
for most of our JavaScript dependencies, so we won't repeat the
|
|
|
|
|
reasoning here.
|
|
|
|
|
|
2023-03-20 19:52:59 +01:00
|
|
|
|
- We use [pnpm][], a `pip`-like tool for JavaScript, to download most
|
|
|
|
|
JavaScript dependencies. pnpm talks to the standard [npm][]
|
2021-08-20 21:53:28 +02:00
|
|
|
|
repository. We use the standard `package.json` file to declare our
|
2017-10-13 08:17:10 +02:00
|
|
|
|
direct dependencies, with sections for development and
|
2023-03-20 19:52:59 +01:00
|
|
|
|
production. pnpm takes care of pinning the versions of indirect
|
|
|
|
|
dependencies in the `pnpm-lock.yaml` file; `pnpm install` updates the
|
|
|
|
|
`pnpm-lock.yaml` file.
|
2021-08-20 21:53:28 +02:00
|
|
|
|
- `tools/update-prod-static`. This process is discussed in detail in
|
2022-02-16 01:39:15 +01:00
|
|
|
|
the [static asset pipeline](html-css.md#static-asset-pipeline)
|
2019-10-23 18:23:25 +02:00
|
|
|
|
article, but we don't use the `node_modules` directories directly in
|
2021-08-20 21:53:28 +02:00
|
|
|
|
production. Instead, static assets are compiled using our static
|
2017-09-18 18:30:08 +02:00
|
|
|
|
asset pipeline and it is the compiled assets that are served
|
2021-08-20 21:53:28 +02:00
|
|
|
|
directly to users. As a result, we don't ship the `node_modules`
|
2017-09-18 18:30:08 +02:00
|
|
|
|
directory in a Zulip production release tarball, which is a good
|
|
|
|
|
thing, because doing so would more than double the size of a Zulip
|
|
|
|
|
release tarball.
|
2021-08-20 21:53:28 +02:00
|
|
|
|
- **Checked-in packages**. In contrast with Python, we have a few
|
2017-09-18 18:30:08 +02:00
|
|
|
|
JavaScript dependencies that we have copied into the main Zulip
|
2023-02-22 23:03:47 +01:00
|
|
|
|
repository under `web/third`, often with patches. These date
|
2021-08-20 21:53:28 +02:00
|
|
|
|
from an era before `npm` existed. It is a project goal to eliminate
|
2017-09-18 18:30:08 +02:00
|
|
|
|
these checked-in versions of dependencies and instead use versions
|
|
|
|
|
managed by the npm repositories.
|
|
|
|
|
|
2023-03-20 19:52:59 +01:00
|
|
|
|
## Node.js and pnpm
|
2021-09-23 02:49:03 +02:00
|
|
|
|
|
|
|
|
|
Node.js is installed by `scripts/lib/install-node` to
|
2023-03-20 19:52:59 +01:00
|
|
|
|
`/srv/zulip-node` and symlinked to `/usr/local/bin/node`. A pnpm
|
|
|
|
|
symlink at `/usr/local/bin/pnpm` is managed by
|
2023-02-09 01:13:42 +01:00
|
|
|
|
[Corepack](https://nodejs.org/api/corepack.html).
|
2021-09-23 02:49:03 +02:00
|
|
|
|
|
|
|
|
|
We don't do anything special to try to manage multiple versions of
|
2023-02-09 01:13:42 +01:00
|
|
|
|
Node.js. (Previous versions of Zulip installed multiple versions of
|
|
|
|
|
Node.js using the third-party `nvm` installer, but the current version
|
|
|
|
|
no longer uses `nvm`; if it’s present in `/usr/local/nvm` where
|
|
|
|
|
previous versions installed it, it will now be removed.)
|
2017-09-18 18:30:08 +02:00
|
|
|
|
|
2021-06-09 01:44:41 +02:00
|
|
|
|
## ShellCheck and shfmt
|
|
|
|
|
|
|
|
|
|
In the development environment, the `tools/setup/install-shellcheck`
|
|
|
|
|
and `tools/setup/install-shfmt` scripts download binaries for
|
|
|
|
|
ShellCheck and shfmt from GitHub, check them against a known hash, and
|
2021-08-20 21:53:28 +02:00
|
|
|
|
install them to `/usr/local/bin`. These tools are run as part of the
|
2021-06-09 01:44:41 +02:00
|
|
|
|
[linting system](../testing/linters.md).
|
|
|
|
|
|
2021-05-25 03:05:40 +02:00
|
|
|
|
## Puppet packages
|
|
|
|
|
|
|
|
|
|
Third-party puppet modules are downloaded from the Puppet Forge into
|
|
|
|
|
subdirectories under `/srv/zulip-puppet-cache`, hashed based on their
|
|
|
|
|
versions; the latest is always symlinked as
|
2021-08-20 21:53:28 +02:00
|
|
|
|
`/srv/zulip-puppet-cache/current`. `zulip-puppet-apply` installs
|
2021-05-25 03:05:40 +02:00
|
|
|
|
these dependencies immediately before they are needed.
|
|
|
|
|
|
2017-09-18 18:30:08 +02:00
|
|
|
|
## Other third-party and generated files
|
|
|
|
|
|
|
|
|
|
In this section, we discuss the other third-party dependencies,
|
|
|
|
|
generated code, and other files whose original primary source is not
|
|
|
|
|
the Zulip server repository, and how we provision and otherwise
|
|
|
|
|
maintain them.
|
|
|
|
|
|
|
|
|
|
### Emoji
|
|
|
|
|
|
|
|
|
|
Zulip uses the [iamcal emoji data package][iamcal] for its emoji data
|
2021-08-20 21:53:28 +02:00
|
|
|
|
and sprite sheets. We download this dependency using `npm`, and then
|
2017-09-18 18:30:08 +02:00
|
|
|
|
have a tool, `tools/setup/build_emoji`, which reformats the emoji data
|
2021-08-20 21:53:28 +02:00
|
|
|
|
into the files under `static/generated/emoji`. Those files are in
|
2022-02-24 00:17:21 +01:00
|
|
|
|
turn used by our [Markdown processor](markdown.md) and
|
2017-09-18 18:30:08 +02:00
|
|
|
|
`tools/update-prod-static` to make Zulip's emoji work in the various
|
|
|
|
|
environments where they need to be displayed.
|
|
|
|
|
|
|
|
|
|
Since processing emoji is a relatively expensive operation, as part of
|
|
|
|
|
optimizing provisioning, we use the same caching strategy for the
|
|
|
|
|
compiled emoji data as we use for virtualenvs and `node_modules`
|
2018-06-18 16:28:34 +02:00
|
|
|
|
directories, with `scripts/lib/clean_emoji_cache.py` responsible for
|
2021-08-20 21:53:28 +02:00
|
|
|
|
garbage-collection. This caching and garbage-collection is required
|
2017-09-18 18:30:08 +02:00
|
|
|
|
because a correct emoji implementation involves over 1000 small image
|
2021-08-20 21:53:28 +02:00
|
|
|
|
files and a few large ones. There is a more extended article on our
|
2019-09-30 19:37:56 +02:00
|
|
|
|
[emoji infrastructure](emoji.md).
|
2017-09-18 18:30:08 +02:00
|
|
|
|
|
|
|
|
|
### Translations data
|
|
|
|
|
|
2019-09-30 19:37:56 +02:00
|
|
|
|
Zulip's [translations infrastructure](../translating/translating.md) generates
|
2017-09-18 18:30:08 +02:00
|
|
|
|
several files from the source data, which we manage similar to our
|
|
|
|
|
emoji, but without the caching (and thus without the
|
2021-08-20 21:53:28 +02:00
|
|
|
|
garbage-collection). New translations data is downloaded from
|
2017-09-18 18:30:08 +02:00
|
|
|
|
Transifex and then compiled to generate both the production locale
|
2019-07-02 22:38:09 +02:00
|
|
|
|
files and also language data in `locale/language*.json` using
|
2017-09-18 18:30:08 +02:00
|
|
|
|
`manage.py compilemessages`, which extends the default Django
|
|
|
|
|
implementation of that tool.
|
|
|
|
|
|
|
|
|
|
### Pygments data
|
|
|
|
|
|
2020-08-11 01:47:49 +02:00
|
|
|
|
The list of languages supported by our Markdown syntax highlighting
|
2021-08-20 21:53:28 +02:00
|
|
|
|
comes from the [pygments][] package. `tools/setup/build_pygments_data` is
|
2023-02-22 23:03:47 +01:00
|
|
|
|
responsible for generating `web/generated/pygments_data.json` so that
|
2020-08-11 01:47:49 +02:00
|
|
|
|
our JavaScript Markdown processor has access to the supported list.
|
2017-09-18 18:30:08 +02:00
|
|
|
|
|
|
|
|
|
## Modifying provisioning
|
|
|
|
|
|
|
|
|
|
When making changes to Zulip's provisioning process or dependencies,
|
|
|
|
|
usually one needs to think about making changes in 3 places:
|
|
|
|
|
|
2021-08-20 21:53:28 +02:00
|
|
|
|
- `tools/lib/provision.py`. This is the main provisioning script,
|
2017-09-18 18:30:08 +02:00
|
|
|
|
used by most developers to maintain their development environment.
|
2021-08-20 21:53:28 +02:00
|
|
|
|
- `docs/development/dev-setup-non-vagrant.md`. This is our "manual installation"
|
|
|
|
|
documentation. Strategically, we'd like to move the support for more
|
2017-09-18 18:30:08 +02:00
|
|
|
|
versions of Linux from here into `tools/lib/provision.py`.
|
2021-08-20 21:53:28 +02:00
|
|
|
|
- Production. Our tools for compiling/generating static assets need
|
2017-09-18 18:30:08 +02:00
|
|
|
|
to be called from `tools/update-prod-static`, which is called by
|
|
|
|
|
`tools/build-release-tarball` (for doing Zulip releases) as well as
|
|
|
|
|
`tools/upgrade-zulip-from-git` (for deploying a Zulip server off of
|
2021-09-01 03:13:20 +02:00
|
|
|
|
`main`).
|
2017-09-18 18:30:08 +02:00
|
|
|
|
|
|
|
|
|
[virtualenv]: https://virtualenv.pypa.io/en/stable/
|
|
|
|
|
[virtualenv-clone]: https://github.com/edwardgeorge/virtualenv-clone/
|
2023-03-20 19:52:59 +01:00
|
|
|
|
[pnpm]: https://pnpm.io/
|
2019-02-06 07:05:05 +01:00
|
|
|
|
[npm]: https://npmjs.com/
|
2017-09-18 18:30:08 +02:00
|
|
|
|
[iamcal]: https://github.com/iamcal/emoji-data
|
2020-03-27 01:32:21 +01:00
|
|
|
|
[pygments]: https://pygments.org/
|