Blame CONTRIBUTING.md

Packit Service dff8e4
Guidelines for Contributing
Packit Service dff8e4
===========================
Packit Service dff8e4
Packit Service dff8e4
Packit Service dff8e4
Community
Packit Service dff8e4
---------
Packit Service dff8e4
Packit Service dff8e4
Check out website https://networkmanager.dev and our [GNOME page](https://wiki.gnome.org/Projects/NetworkManager).
Packit Service dff8e4
Packit Service dff8e4
The release tarballs can be found at [download.gnome.org](https://download.gnome.org/sources/NetworkManager/).
Packit Service dff8e4
Packit Service dff8e4
Our mailing list is networkmanager-list@gnome.org ([archive](https://mail.gnome.org/archives/networkmanager-list/)).
Packit Service dff8e4
Packit Service dff8e4
Find us on IRC channel `#nm` on freenode.
Packit Service dff8e4
Packit Service dff8e4
Report issues and send patches via [gitlab.freedesktop.org](https://gitlab.freedesktop.org/NetworkManager/NetworkManager/)
Packit Service dff8e4
or our mailing list.
Packit Service dff8e4
Packit Service dff8e4
Packit Service dff8e4
Legal
Packit Service dff8e4
-----
Packit Service dff8e4
Packit Service dff8e4
NetworkManager is partly licensed under terms of GNU Lesser General Public License
Packit Service dff8e4
version 2 or later ([LGPL-2.1-or-later](COPYING.LGPL)). That is for example the case for libnm.
Packit Service dff8e4
For historical reasons, the daemon itself is licensed under terms of GNU General
Packit Service dff8e4
Public License, version 2 or later ([GPL-2.0-or-later](COPYING)). See the SPDX license comment
Packit Service dff8e4
in the source files.
Packit Service dff8e4
Packit Service dff8e4
Note that all new contributions to NetworkManager **MUST** be made under terms of
Packit Service dff8e4
LGPL-2.1-or-later, that is also the case for files that are currently licensed GPL-2.0-or-later.
Packit Service dff8e4
The reason is that we might one day use the code under terms of LGPL-2.1-or-later and all
Packit Service dff8e4
new contributions already must already agree to that.
Packit Service dff8e4
For more details see [RELICENSE.md](RELICENSE.md).
Packit Service dff8e4
Packit Service dff8e4
Packit Service dff8e4
Coding Standard
Packit Service dff8e4
---------------
Packit Service dff8e4
Packit Service dff8e4
The formatting uses clang-format with clang 11.0. Run
Packit Service dff8e4
`./contrib/scripts/nm-code-format.sh -i` to reformat the code
Packit Service dff8e4
or call `clang-format` yourself.
Packit Service dff8e4
You may also call `./contrib/scripts/nm-code-format-container.sh`
Packit Service dff8e4
which runs a Fedora 33 container using podman.
Packit Service dff8e4
You are welcome to not bother and open a merge request with
Packit Service dff8e4
wrong formatting, but note that we then will automatically adjust
Packit Service dff8e4
your contribution before merging.
Packit Service dff8e4
Packit Service dff8e4
The automatic reformatting was done by commit 328fb90f3e0d4e35975aff63944ac0412d7893a5.
Packit Service dff8e4
Use `--ignore-rev` option or `--ignore-revs-file .git-blame-ignore-revs` to ignore
Packit Service dff8e4
the reformatting commit with git-blame:
Packit Service dff8e4
Packit Service dff8e4
```
Packit Service dff8e4
$ git config --add 'blame.ignoreRevsFile' '.git-blame-ignore-revs'
Packit Service dff8e4
```
Packit Service dff8e4
Packit Service dff8e4
Since our coding style is entirely automated, the following are just
Packit Service dff8e4
some details of the style we use:
Packit Service dff8e4
Packit Service dff8e4
* Indent with 4 spaces. (_no_ tabs).
Packit Service dff8e4
Packit Service dff8e4
* Have no space between the function name and the opening '('.
Packit Service dff8e4
  - GOOD: `g_strdup(x)`
Packit Service dff8e4
  - BAD:  `g_strdup (x)`
Packit Service dff8e4
Packit Service dff8e4
* C-style comments
Packit Service dff8e4
  - GOOD: `f(x);  /* comment */`
Packit Service dff8e4
  - BAD:  `f(x);  // comment`
Packit Service dff8e4
Packit Service dff8e4
* Keep assignments in the variable declaration area pretty short.
Packit Service dff8e4
  - GOOD: `MyObject *object;`
Packit Service dff8e4
  - BAD:  `MyObject *object = complex_and_long_init_function(arg1, arg2, arg3);`
Packit Service dff8e4
Packit Service dff8e4
* 80-cols is a guideline, don't make the code uncomfortable in order to fit in
Packit Service dff8e4
  less than 80 cols.
Packit Service dff8e4
Packit Service dff8e4
* Constants are CAPS_WITH_UNDERSCORES and use the preprocessor.
Packit Service dff8e4
  - GOOD: `#define MY_CONSTANT 42`
Packit Service dff8e4
  - BAD:  `static const unsigned myConstant = 42;`
Packit Service dff8e4
Packit Service dff8e4
Packit Service dff8e4
Assertions in NetworkManager code
Packit Service dff8e4
---------------------------------
Packit Service dff8e4
Packit Service dff8e4
There are different kind of assertions. Use the one that is appropriate.
Packit Service dff8e4
Packit Service dff8e4
1) `g_return_*()` from glib. This is usually enabled in release builds and
Packit Service dff8e4
  can be disabled with `G_DISABLE_CHECKS` define. This uses `g_log()` with
Packit Service dff8e4
  `G_LOG_LEVEL_CRITICAL` level (which allows the program to continue,
Packit Service dff8e4
  unless `G_DEBUG=fatal-criticals` or `G_DEBUG=fatal-warnings` is set). As such,
Packit Service dff8e4
  this is usually the preferred way for assertions that are supposed to be
Packit Service dff8e4
  enabled by default. \
Packit Service dff8e4
  \
Packit Service dff8e4
  Optimally, after a `g_return_*()` failure the program can still continue. This is
Packit Service dff8e4
  also the reason why `g_return_*()` is preferable over `g_assert()`.
Packit Service dff8e4
  For example, that is often not the case for functions that return a `GError`, because
Packit Service dff8e4
  `g_return_*()` will return failure without setting the error output. That often leads
Packit Service dff8e4
  to a crash immediately after, because the caller requires the `GError` to be set.
Packit Service dff8e4
  Make a reasonable effort so that an assertion failure may allow the process
Packit Service dff8e4
  to proceed. But don't put too much effort in it. After all, it's an assertion
Packit Service dff8e4
  failure that is not supposed to happen either way.
Packit Service dff8e4
Packit Service dff8e4
2) `nm_assert()` from NetworkManager. This is disabled by default in release
Packit Service dff8e4
  builds, but enabled if you build `--with-more-assertions`. See the `WITH_MORE_ASSERTS`
Packit Service dff8e4
  define. This is preferred for assertions that are expensive to check or
Packit Service dff8e4
  nor necessary to check frequently. It's also for conditions that can easily
Packit Service dff8e4
  be verified to be true and where future refactoring is unlikely to break the
Packit Service dff8e4
  invariant.
Packit Service dff8e4
  Use such asserts deliberately and assume they are removed from production builds.
Packit Service dff8e4
Packit Service dff8e4
3) `g_assert()` from glib. This is used in unit tests and commonly enabled
Packit Service dff8e4
  in release builds. It can be disabled with `G_DISABLE_ASSERT` define.
Packit Service dff8e4
  Since such an assertion failure results in a hard crash, you
Packit Service dff8e4
  should almost always prefer `g_return_*()` over `g_assert()` (except in unit tests).
Packit Service dff8e4
Packit Service dff8e4
4) `assert()` from C89's `<assert.h>`. It is usually enabled in release builds and
Packit Service dff8e4
  can be disabled with `NDEBUG` define. Don't use it in NetworkManager,
Packit Service dff8e4
  it's basically like g_assert().
Packit Service dff8e4
Packit Service dff8e4
5) `g_log()` from glib. These are always compiled in, depending on the logging level
Packit Service dff8e4
  they act as assertions too. `G_LOG_LEVEL_ERROR` messages abort the program, `G_LOG_LEVEL_CRITICAL`
Packit Service dff8e4
  log a critical warning (like `g_return_*()`, see `G_DEBUG=fatal-criticals`)
Packit Service dff8e4
  and `G_LOG_LEVEL_WARNING` logs a warning (see `G_DEBUG=fatal-warnings`).
Packit Service dff8e4
  `G_LOG_LEVEL_DEBUG` level is usually not printed, unless `G_MESSAGES_DEBUG` environment
Packit Service dff8e4
  variable enables it. \
Packit Service dff8e4
  \
Packit Service dff8e4
  In general, avoid using `g_log()` in NetworkManager. We have nm-logging instead
Packit Service dff8e4
  which logs to syslog or systemd-journald.
Packit Service dff8e4
  From a library like libnm it might make sense to log warnings (if something
Packit Service dff8e4
  is really wrong) or debug messages. But better don't. If it's important,
Packit Service dff8e4
  find a way to report the condition via the API to the caller. If it's
Packit Service dff8e4
  not important, keep silent.
Packit Service dff8e4
  In particular, don't use levels `G_LOG_LEVEL_CRITICAL` and `G_LOG_LEVEL_WARNING` because
Packit Service dff8e4
  we treat them as assertions and we want to run all out tests with `G_DEBUG=fatal-warnings`.
Packit Service dff8e4
Packit Service dff8e4
6) `g_warn_if_*()` from glib. These are always compiled in and log a `G_LOG_LEVEL_WARNING`
Packit Service dff8e4
  warning. Don't use this.
Packit Service dff8e4
Packit Service dff8e4
7) `G_TYPE_CHECK_INSTANCE_CAST()` from glib. Unless building with `WITH_MORE_ASSERTS`,
Packit Service dff8e4
  we set `G_DISABLE_CAST_CHECKS`. This means, cast macros like `NM_DEVICE(ptr)`
Packit Service dff8e4
  translate to plain C pointer casts. Use such cast macros deliberately, in production
Packit Service dff8e4
  code they are cheap, with more asserts enabled they check that the pointer type is
Packit Service dff8e4
  suitable.
Packit Service dff8e4
Packit Service dff8e4
Of course, every assertion failure is a bug, and calling it must have no side effects.
Packit Service dff8e4
Packit Service dff8e4
Theoretically, you are welcome to set `G_DISABLE_CHECKS`, `G_DISABLE_ASSERT` and
Packit Service dff8e4
`NDEBUG` in production builds. In practice, nobody tests such a configuration, so beware.
Packit Service dff8e4
Packit Service dff8e4
For testing, you also want to run NetworkManager with environment variable
Packit Service dff8e4
`G_DEBUG=fatal-warnings` to crash upon `G_LOG_LEVEL_CRITICAL` and `G_LOG_LEVEL_WARNING`
Packit Service dff8e4
`g_log()` message. NetworkManager won't use these levels for regular logging
Packit Service dff8e4
but for assertions.
Packit Service dff8e4
Packit Service dff8e4
Packit Service dff8e4
Git Notes (refs/notes/bugs)
Packit Service dff8e4
---------------------------
Packit Service dff8e4
Packit Service dff8e4
We use special tags in commit messages like "Fixes", "cherry picked from" and "Ignore-Backport".
Packit Service dff8e4
The [find-backports](contrib/scripts/find-backports) script uses these to find patches that
Packit Service dff8e4
should be backported to older branches. Sometimes we don't know a-priory to mark a commit
Packit Service dff8e4
with these tags so we can instead use the `bugs` notes.
Packit Service dff8e4
Packit Service dff8e4
The git notes reference is called "refs/notes/bugs".
Packit Service dff8e4
Packit Service dff8e4
So configure:
Packit Service dff8e4
Packit Service dff8e4
```
Packit Service dff8e4
$ git config --add 'remote.origin.fetch' 'refs/notes/bugs:refs/notes/bugs'
Packit Service dff8e4
$ git config --add 'notes.displayref' 'refs/notes/bugs'
Packit Service dff8e4
```
Packit Service dff8e4
Packit Service dff8e4
For example, set notes with
Packit Service dff8e4
Packit Service dff8e4
```
Packit Service dff8e4
$ git notes --ref refs/notes/bugs add -m "(cherry picked from $COMMIT_SHA)" HEAD
Packit Service dff8e4
```
Packit Service dff8e4
Packit Service dff8e4
You should see the notes in git-log output as well.
Packit Service dff8e4
Packit Service dff8e4
To resync our local notes use:
Packit Service dff8e4
Packit Service dff8e4
```
Packit Service dff8e4
$ git fetch origin refs/notes/bugs:refs/notes/bugs -f
Packit Service dff8e4
```
Packit Service dff8e4
Packit Service dff8e4
Code Structure
Packit Service dff8e4
---------------------------
Packit Service dff8e4
Packit Service dff8e4
`./contrib`- Contains a lot of required package, configuration for different platform and environment, build NM from source tree.
Packit Service dff8e4
Packit Service dff8e4
`./data`- Contains some configurations and rules.
Packit Service dff8e4
Packit Service dff8e4
`./docs`- Contains the generated documentation for libnm and for the D-Bus API.
Packit Service dff8e4
Packit Service dff8e4
`./examples`- Some code examples for basic networking operations and status checking.
Packit Service dff8e4
Packit Service dff8e4
`./introspection`- XML docs describing various D-Bus interface and their properties.
Packit Service dff8e4
Packit Service dff8e4
`./m4`- Contains M4 macros source files for autoconf.
Packit Service dff8e4
Packit Service dff8e4
`./man`- NM manual files.
Packit Service dff8e4
Packit Service dff8e4
`./po`- contains text-based portable object file. These .PO files are referenced by GNU gettext as a property file and these files are human readable used for translating purpose.
Packit Service dff8e4
Packit Service dff8e4
`./src`- source code for libnm, nmcli, nm-cloud-setup, nmtui…
Packit Service dff8e4
Packit Service dff8e4
`./tools`- tools for generating the intermediate files or merging the file.
Packit Service dff8e4
Packit Service dff8e4
Cscope/ctags
Packit Service dff8e4
---------------------------
Packit Service dff8e4
Packit Service dff8e4
NetworkManager's source code is large. It may be a good idea to use tools like cscope/ctags to index the
Packit Service dff8e4
source code and navigate it. These tools can integrate with editors like `Vim` and `Emacs`. See:
Packit Service dff8e4
Packit Service dff8e4
- http://cscope.sourceforge.net/cscope_vim_tutorial.html
Packit Service dff8e4
- https://www.emacswiki.org/emacs/CScopeAndEmacs