Commit 16837065 authored by Guillaume Bernard's avatar Guillaume Bernard 💬 Committed by Claude Paroz
Browse files

docs: adding a contributing guide

parent dbc30994
# Contribution guide
This document will help you understand how `damned-lies` works and how to contribute and push code to it.
This document is organized as follows:
- [Introduction](#introduction)
- [Responsibilities](#exclamation-responsibilities)
- [Your first contribution](#construction_worker-your-first-contribution)
- [Installation](#installation)
- [Software requirements](#gear-software-requirements)
- [Python environment](#snake-python-environment)
- [System setup](#system-setup)
- [Running tests](#running-tests)
- [Translations](#translations)
- [Guidelines](#guidelines)
- [Django coding style](#django-coding-style)
- [Custom rules](#custom-rules)
- [PEP8 advices](#pep-8-advices)
# Introduction
`damned-lies` is a Python 3 Web application written using the [Django framework](https://www.djangoproject.com/). It is
the GNOME application used to manage the GNOME translation process. A running instance is available
at [l10n.gnome.org](https://l10n.gnome.org).
`damned-lies` is part of the GNOME software environment. As of it, please first read
the [GNOME newcomers guide](https://wiki.gnome.org/Newcomers/). You can also join
the [GNOME i18n room on Matrix](https://gnome.element.io/#/room/#i18n:gnome.org) and say hello. This document inherits
from all the guidelines used by the GNOME community.
**Note:** if you wish to contribute as a translator in any team, please go to
the [`damned-lies`](https://l10n.gnome.org) instance instead.
## :exclamation: Responsibilities
- Assume people mean well: when you’re discussing or debating with others, please assume they mean well. We’re here to
cooperate.
- Ensure your code respects the [Python PEP8 standards](https://www.python.org/dev/peps/pep-0008/) (a pipeline checks
this). You can use the `prospector` tool to do so. Please read the [Guidelines](#guidelines) section.
- Ensure your strings are written in a proper English.
- Ensure the strings you changed are also present in
the [`gettext`](https://www.gnu.org/software/gettext/manual/gettext.html#Why) PO files. Please, refer to
the [Django documentation on internationalisation](https://docs.djangoproject.com/en/stable/topics/i18n/). `gettext`
is the utility used in almost every Free Software development project and used to localise strings showed to the end
users.
- If you wish to make major changes or enhancements, **open an issue** to discuss it. Discuss things transparently and
get community feedback.
- Be welcoming to newcomers and encourage diverse new contributors from all backgrounds. See
the [Python Community Code of Conduct](https://www.python.org/psf/codeofconduct/).
## :construction_worker: Your First Contribution
As part of your first contribution, there are a few things and skills you have to acquire or to already have:
- You are comfortable with HTML, Javascript and CSS languages and technologies.
- You are able to understand and write [Python](https://www.python.org/) code.
- You know what is Bootstrap and how to
use [Bootstrap 4](https://getbootstrap.com/docs/4.0/getting-started/introduction/).
- You know what is a [web framework](https://en.wikipedia.org/wiki/Web_framework) and you understand its behaviour.
- `damned-lies` is written in **Python** and utilizes the **Django** web framework. It uses a **Bootstrap** custom theme
as its CSS framework.
**Note:** If you are not already familiar with Django, we recommend you to go through
the [Django Tutorial](https://docs.djangoproject.com/en/stable/intro/tutorial01/).
# Installation
## :gear: Software requirements
To run properly on any system, `damned-lies` requires some libraries and software to be installed on your system.
- `gettext`: the tool used to handle software translations.
- [`intltool`](https://freedesktop.org/wiki/Software/intltool/): *set of tools to centralize translation of many file
formats using GNU gettext-compatible PO files*.
- [`itstool`](http://itstool.org/): library that *allows you to translate your XML documents with PO files*.
- `yelp-tools`: *a collection of scripts and build utilities to help create, manage, and publish documentation* for
GNOME applications.
- `gnome-doc-utils`: used for statistics generation. This is a legacy dependency that provides, among others,
the `xml2po` program.
- **MariaDB client library**: the underlying library that is used through Python to connect to a MySQL/MariaDB instance.
- **ICU library**: internationalization libraries of the Unicode Consortium.
- **Development tools**: used to compile some other dependencies listed in `requirements.txt`, just as `pillow`.
You can install them on your operating system using the following command line examples:
* On **Debian** based systems:
```bash
apt install gettext intltool gnome-doc-utils itstool libmariadbclient-dev libicu-dev python3-dev yelp-tools build-essential
```
* On **Fedora** based systems:
```
dnf install gettext intltool gnome-doc-utils itstool mariadb-devel libicu-devel python-devel yelp-tools @development-tools
```
## :snake: Python environment
Once libraries are installed on your OS, the recommended method to run `damned-lies` is to use
a [virtual environment](https://docs.python.org/en/3/library/venv.html). Python dependencies are listed in
the `requirements.txt` file.
### Optional requirements
You can install the [`django-debug-toolbar`](https://pypi.org/project/django-debug-toolbar/) which will give extra
information about the current Django development.
Once installed using `pip`, define `USE_DEBUG_TOOLBAR` to `True` in `damnedlies/local_settings.py` to use it.
## System setup
Once Python dependencies are installed, you will need some further steps in order to have a working environment.
1. Create a `damnedlies/local_settings.py` and overwrite settings to match your requirements and your configuration
layouts. Typical settings to customize include: `DATABASES`, `SECRET_KEY`, `DEBUG`, `STATIC_SERVE`, `ADMINS`
, `ADMIN_GROUP`, `SITE_DOMAIN`, `SCRATCHDIR`, and various `EMAIL` settings.
Please refer to Database configuration below for more information.
`SCRATCHDIR` should point to an existing directory, writable by the web application user.
Create the `MEDIA_ROOT` directory, and the `upload` and `upload-backup` directories inside it, also writable by the
web application user.
Note also that if you don’t want to really send mail when testing the app, you can set the `EMAIL_BACKEND` setting as
follows to redirect mail to the console:
```python
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
```
2. Run the following command to execute the database migrations:
```bash
./manage.py migrate
```
3. In production, you will have to run the following command:
```bash
./manage.py collectstatic
```
Then configure your Web server to statically serve this directory. For example, with the HTTPd server (*aka* Apache
HTTP Server), a simple alias directive is enough:
```apacheconf
Alias /static /absolute/path/to/djamnedlies/static
```
**Note**: to deploy `damned-lies` in a production environment, please refer to
the [Django documentation dedicated to deployment](https://docs.djangoproject.com/en/stable/howto/deployment/).
4. **Optionally**, if you want to populate the database with sample data, run:
```bash
./manage.py loaddata sample_data
```
5. Additionally, you may want
to [create a superuser](https://docs.djangoproject.com/en/stable/topics/auth/default/#creating-superusers), in order
to access the Django admin backend.
```bash
./manage.py createsuperuser
```
6. You should now be able to launch the development server to check if all is running well:
```bash
./manage.py runserver
```
7. Configure Sites in admin interface (“View on site” link, site address in sent mail).
## Running tests
To execute the tests, you need to compile translations first, as some tests require translation. To do so run this command:
```bash
python manage.py compile-trans
```
Then, you can run the test suite with:
```bash
python3 manage.py test --settings=damnedlies.settings_tests
```
A good practice is to ensure your tests do not degrade the current code coverage. We use
the [`coverage`](https://coverage.readthedocs.io/en/coverage-5.5/) module to run tests and compute testing coverage.
```bash
coverage run manage.py test --settings=damnedlies.settings_tests
```
Read [the Django testing documentation](https://docs.djangoproject.com/en/stable/topics/testing/) for more details about
testing in Django projects.
## Translations
To be able to extract strings from various database fields, a wrapper script has been created around the standard
Django `makemessages` command. The script also copies po files to the `/po` directory.
Run `python manage.py update-trans` to update translations when there are string changes.
After translation files in po directory have been updated, there is another script to put back po files
in `locale/<ll>/LC_MESSAGES/django.po` and call Django’s compile_messages command.
Run `python manage.py compile-trans`.
# Guidelines
Below are listed the guidelines every contribution should follow to ensure style consistency. In case of conflict,
Django coding style has precedence over custom rules, which themselves have precedence over the PEP8 standard.
**Note:** to check the correctness of your code, you can use [`prospector`](http://prospector.landscape.io/en/master/)
and run it in the project root’s directory. We provide a custom profile called `.prospector.yml`.
## Django Coding Style
`damned-lies` is written following
the [Django Coding Style](https://docs.djangoproject.com/en/stable/internals/contributing/writing-code/coding-style/).
Ensure to respect these rules when committing files.
## Custom rules
### Do not expand unused arguments when overriding a parent method
Let’s assume a class B inherits from a class A. In B, you want to override a method with numerous named parameters that
come from A. If you know you will not use all or any named parameters, you should remove named parameters from the B
method signature and let other parameters live in `**kwargs`.
An example is shown below. We assume we wish to implement a new `ModelBackend` by inheriting from it and re-implementing
its `authenticate()` method. The method takes a required argument (`request`) and two optional named
parameters (`username` and `password`).
```python
from django.contrib.auth.backends import BaseBackend
class ModelBackend(BaseBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
pass
```
In case your custom implementation does not use any of the optional parameters, they should be removed from the method
signature. In Python, these arguments will live in the `**kwargs` variable anyway.
```python
from django.contrib.auth.backends import ModelBackend
class TokenBackend(ModelBackend):
def authenticate(self, request, **kwargs):
pass
```
## PEP-8 advices
The eighth PEP (Python Enhancement Proposal) rules Python coding style. It’s well known as the “PEP8
standards”. [PEP-8 is a standard for coding in Python](https://www.python.org/dev/peps/pep-0008/).
\ No newline at end of file
......@@ -3,134 +3,67 @@
# `damned-lies`
`damned-lies` is a **translation-tracking Web application** originally aimed to help the GNOME Translation project. It is written in Python based on the [Django](https://www.djangoproject.com) framework.
`damned-lies` is a **translation-tracking Web application** originally aimed to help the GNOME Translation project. It
is written in Python and is based on the [Django](https://www.djangoproject.com) framework.
You can find the Data model in the `/docs` directory.
## Requirements
## Contribute and install
To run properly, `damned-lies` requires at least **Python 3.6** and **Django 3**.
Python dependencies are listed in the `requirements.txt` file alongside this README document. In order to install them, you will need to have the following dependencies installed:
* **Debian-based systems**: `gettext intltool gnome-doc-utils itstool libmariadbclient-dev libicu-dev build-essential python3-dev`
* **Fedora-based systems**: `gettext intltool gnome-doc-utils itstool mariadb-devel libicu-devel python-devel @development-tools @development-libraries`
Please, refer to the [Contribution guide](CONTRIBUTING.md) in order to know how to install `damned-lies` in a
development environment.
Note: `gnome-docs-utils` are used for stats generation.
Then, you will be able to install dependencies using the `pip install -r requirements.txt` command.
### Optional requirements
* You can install a debug bar which will give extra information about the current Django development.
```bash
git clone git://github.com/jazzband/django-debug-toolbar.git
```
Then, define `USE_DEBUG_TOOLBAR` to `True` in `damnedlies/local_settings.py` to use it.
## Installation
Once Python dependencies are installed, you will need some further steps in order to have a working environment.
1. Create a `damnedlies/local_settings.py` and overwrite settings to match your requirements and your configuration layouts. Typical settings to customize include: `DATABASES`, `SECRET_KEY`, `DEBUG`, `STATIC_SERVE`, `ADMINS`, `ADMIN_GROUP`, `SITE_DOMAIN`, `SCRATCHDIR`, and various `EMAIL` settings.
Please refer to Database configuration below for more information.
`SCRATCHDIR` should point to an existing directory, writable by the web application user.
Create the `MEDIA_ROOT` directory, and the `upload` and `upload-backup` directories inside it, also writable by the web application user.
Note also that if you don’t want to really send mail when testing the app, you can set the `EMAIL_BACKEND` setting as follows to redirect mail to the console:
```python
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
```
2. Run the following command to execute the database migrations:
```bash
./manage.py migrate
```
3. In production, you will have to run the following command:
```bash
./manage.py collectstatic
```
Then configure your Web server to statically serve this directory. For example, with the HTTPd server (*aka* Apache HTTP Server), a simple alias directive is enough:
```apacheconf
Alias /static /absolute/path/to/djamnedlies/static
```
4. **Optionally**, if you want to populate the database with sample data, run:
```bash
./manage.py loaddata sample_data
```
5. You should now be able to launch the development server to check if all is running well:
```bash
./manage.py runserver
```
6. Configure Sites in admin interface (“View on site” link, site address in sent mail).
## Running tests
To execute the tests, run this command:
```bash
python manage.py test [optional path to run partial tests]
```
Read [the Django testing documentation](https://docs.djangoproject.com/en/stable/topics/testing/) for more details about testing in Django projects.
<!-- This should be moved to a documentation instead of remaining in the README file -->
## Maintenance tasks
There is a management command to run maintenance tasks (clean never-activated accounts, inactivate unused roles, …):
```bash
./manage.py run-maintenance
```
Note: it might be useful to add the command in a cron schedule.
<!-- This should be moved to a documentation instead of remaining in the README file -->
## Databases
It’s important to use the Unix Domain Socket connection to obtain good performances.
### PostgreSQL
In the `DATABASES['default']` dictionary, you just need to define `ENGINE = 'django.db.backends.postgresql_psycopg2'` and the `NAME` key.
Leave the `HOST` setting empty to use `UDS`.
In the `DATABASES['default']` dictionary, you just need to define `ENGINE = 'django.db.backends.postgresql'`
and the `NAME` key. Leave the `HOST` setting empty to use `UDS`.
### MySQL
Create a database in UTF8, either with `default-character-set = utf8` under `[mysqld]` section in the `my.cnf` file or with an explicit SQL instruction:
Create a database in UTF8, either with `default-character-set = utf8` under `[mysqld]` section in the `my.cnf` file or
with an explicit SQL instruction:
```sql
CREATE DATABASE <DATABASE_NAME> charset=utf8;
CREATE
DATABASE <DATABASE_NAME> charset=utf8;
```
Then, you have to update your `damnedlies/local_settings.py`:
```python
DATABASES = {
'default' {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '<your database name>',
'USER': '<your user>',
'PASSWORD': '<your password>',
'HOST' = '/var/run/mysqld/mysqld.sock',
'OPTIONS' = {
'HOST': '/var/run/mysqld/mysqld.sock',
'OPTIONS': {
'read_default_file': '/etc/mysql/my.cnf',
}
}
}
```
Grep for `ANSI_QUOTES` in the source code to find the `models.py` which use a hack to workaround the double quotes interpretation in MySQL. The best solution is to run the MySQL server with the [`ANSI_QUOTES` mode](http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html) (`sql-mode="ANSI_QUOTES"` in `my.cnf`), but it can be damaging for other applications.
## Translations
To be able to also extract strings from various database fields, a wrapper script has been created around the standard Django `makemessages` command. The script also copy po files in `/po` directory.
Run `python manage.py update-trans` to update translations when there are string changes.
After translation files in po directory have been updated, there is another script to put back po files in `locale/<ll>/LC_MESSAGES/django.po` and call Django’s compile_messages command.
Run `python manage.py compile-trans`.
Grep for `ANSI_QUOTES` in the source code to find the `models.py` which use a hack to workaround the double quotes
interpretation in MySQL. The best solution is to run the MySQL server with
the [`ANSI_QUOTES` mode](http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html) (`sql-mode="ANSI_QUOTES"` in `my.cnf`),
but it can be damaging for other applications.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment