<commit_before># Hacking on Cockpit

Here's where to get the code:

    $ git clone https://github.com/cockpit-project/cockpit
    $ cd cockpit/

The remainder of the commands assume you're in the top level of the
Cockpit git repository checkout.

## Getting the development dependencies

Cockpit uses Node.js during development. Node.js is not used at runtime.
To make changes on Cockpit you'll want to install Node.js.

On Debian/Ubuntu:

    $ sudo apt install nodejs

On Fedora:

    $ sudo dnf install nodejs

On older OS releases you can use the [n utility](https://github.com/tj/n) to
get a current version of nodejs.

When relying on CI to run the test suite, this is all that is necessary to work
on the JavaScript components of Cockpit.

To build the Cockpit binaries from source, required to run the integration tests
locally (see [testing README](test/README.md)), you will need additional header
files and other components. The following should work in a fresh Git clone:

    $ sudo dnf install dnf-utils python-srpm-macros
    $ sudo dnf builddep --spec tools/cockpit.spec

For running the browser unit tests, the following dependencies are required:

    $ sudo dnf install chromium-headless dbus-daemon

For running integration tests, the following dependencies are required:

    $ sudo dnf install curl expect xz rpm-build chromium-headless \
        libvirt-daemon-driver-storage-core libvirt-daemon-driver-qemu libvirt-client python3-libvirt \
        python3-pyflakes python3-pycodestyle python3-pyyaml

Creating VM images locally (not necessary for running tests) needs the
following:

    $ sudo dnf install virt-install

Updating the `node_modules` (in case you need to modify `package.json`)
requires npm to be installed.

    $ sudo dnf install npm

## Building

Cockpit uses the autotools and thus there are the familiar `./configure`
script and Makefile targets.

After a fresh clone of the Cockpit sources, you need to prepare them by running
`autogen.sh` like this:

    $ ./autogen.sh --prefix=/usr --enable-debug

As shown, `autogen.sh` runs 'configure' with the given options, and it also
prepares the build tree by downloading various nodejs dependencies.

When working with a Git clone, it is therefore best to simply always
run `./autogen.sh` instead of `./configure`.

Then run

    $ make

to build everything. Cockpit has a single non-recursive Makefile. You can only
run `make` from the top-level and it will always rebuild the whole project.

You can run unit tests of the current checkout:

    $ make check

These should finish very quickly and it is good practice to do it often.

For debugging individual tests, there are compiled binaries in the build
directory. For QUnit tests (JavaScript), you can run

    $ ./test-server

which will output a URL to connect to with a browser, such as
`http://localhost:8765/dist/base1/test-dbus.html`. Adjust the path for different
tests and inspect the results there.

You can also run individual tests by specifying the `TESTS` environment
variable:

    $ make check TESTS=dist/base1/test-chan.html

There are also static code and syntax checks which you should run often:

    $ test/static-code

It is highly recommended to set up a git pre-push hook, to avoid pushing PRs
that will fail on trivial errors:

    $ ln -s ../../tools/git-hook-pre-push .git/hooks/pre-push

This calls `test/static-code` for each commit you're trying to push.

You can also set up a post-commit hook to do the same, after each commit:

    $ ln -s ../../tools/git-hook-post-commit .git/hooks/post-commit

We also have a hook to ameliorate one of the more annoying drawbacks of using
git submodules:

    $ ln -s ../../tools/git-hook-pre-rebase .git/hooks/pre-rebase

## Running the integration test suite

Refer to the [testing README](test/README.md) for details on running the Cockpit
integration tests locally.

## Running eslint

Cockpit uses [ESLint](https://eslint.org/) to automatically check JavaScript
code style in `.js` and `.jsx` files.

The linter is executed within every build as a webpack preloader.

For developer convenience, the ESLint can be started explicitly by:

    $ npm run eslint
<commit_msg>HACKING.md: mention the Python bridge<commit_after># Hacking on Cockpit

Here's where to get the code:

    $ git clone https://github.com/cockpit-project/cockpit
    $ cd cockpit/

The remainder of the commands assume you're in the top level of the
Cockpit git repository checkout.

## Getting the development dependencies

Cockpit uses Node.js during development. Node.js is not used at runtime.
To make changes on Cockpit you'll want to install Node.js.

On Debian/Ubuntu:

    $ sudo apt install nodejs

On Fedora:

    $ sudo dnf install nodejs

On older OS releases you can use the [n utility](https://github.com/tj/n) to
get a current version of nodejs.

When relying on CI to run the test suite, this is all that is necessary to work
on the JavaScript components of Cockpit.

To build the Cockpit binaries from source, required to run the integration tests
locally (see [testing README](test/README.md)), you will need additional header
files and other components. The following should work in a fresh Git clone:

    $ sudo dnf install dnf-utils python-srpm-macros
    $ sudo dnf builddep --spec tools/cockpit.spec

For running the browser unit tests, the following dependencies are required:

    $ sudo dnf install chromium-headless dbus-daemon

For running integration tests, the following dependencies are required:

    $ sudo dnf install curl expect xz rpm-build chromium-headless \
        libvirt-daemon-driver-storage-core libvirt-daemon-driver-qemu libvirt-client python3-libvirt \
        python3-pyflakes python3-pycodestyle python3-pyyaml

Creating VM images locally (not necessary for running tests) needs the
following:

    $ sudo dnf install virt-install

Updating the `node_modules` (in case you need to modify `package.json`)
requires npm to be installed.

    $ sudo dnf install npm

## Building

Cockpit uses the autotools and thus there are the familiar `./configure`
script and Makefile targets.

After a fresh clone of the Cockpit sources, you need to prepare them by running
`autogen.sh` like this:

    $ ./autogen.sh --prefix=/usr --enable-debug

As shown, `autogen.sh` runs 'configure' with the given options, and it also
prepares the build tree by downloading various nodejs dependencies.

When working with a Git clone, it is therefore best to simply always
run `./autogen.sh` instead of `./configure`.

Then run

    $ make

to build everything. Cockpit has a single non-recursive Makefile. You can only
run `make` from the top-level and it will always rebuild the whole project.

You can run unit tests of the current checkout:

    $ make check

These should finish very quickly and it is good practice to do it often.

For debugging individual tests, there are compiled binaries in the build
directory. For QUnit tests (JavaScript), you can run

    $ ./test-server

which will output a URL to connect to with a browser, such as
`http://localhost:8765/dist/base1/test-dbus.html`. Adjust the path for different
tests and inspect the results there.

You can also run individual tests by specifying the `TESTS` environment
variable:

    $ make check TESTS=dist/base1/test-chan.html

There are also static code and syntax checks which you should run often:

    $ test/static-code

It is highly recommended to set up a git pre-push hook, to avoid pushing PRs
that will fail on trivial errors:

    $ ln -s ../../tools/git-hook-pre-push .git/hooks/pre-push

This calls `test/static-code` for each commit you're trying to push.

You can also set up a post-commit hook to do the same, after each commit:

    $ ln -s ../../tools/git-hook-post-commit .git/hooks/post-commit

We also have a hook to ameliorate one of the more annoying drawbacks of using
git submodules:

    $ ln -s ../../tools/git-hook-pre-rebase .git/hooks/pre-rebase

## Running the integration test suite

Refer to the [testing README](test/README.md) for details on running the Cockpit
integration tests locally.

## Testing the Python bridge

There is currently an experimental replacement for `cockpit-bridge` being
written in Python.  It lives in `src/cockpit` with most of its rules in
`src/Makefile.am`.  This directory was chosen because it matches the standard
so-called "src layout" convention for Python packages, where each package
(`cockpit`) is a subdirectory of the `src` directory.

You can run a subset of the unit tests against this experimental code by typing
`make pycheck`.  Note that this needs to be done against a git checkout, as the
Python files are not currently included in tarball releases.

It's also possible to manually build the bridge with `make cockpit-bridge.pyz`.
You can copy the created file into the `$PATH` as `cockpit-bridge`.  It should
then be possible to get a limited Cockpit session running (for example, by
specifying `localhost` to Cockpit Client).

## Running eslint

Cockpit uses [ESLint](https://eslint.org/) to automatically check JavaScript
code style in `.js` and `.jsx` files.

The linter is executed within every build as a webpack preloader.

For developer convenience, the ESLint can be started explicitly by:

    $ npm run eslint

{'fraction_non_alphanumeric': 0.06688206785137318, 'fraction_numerical': 0.002154011847065159, 'mean_word_length': 3.713705583756345, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3156160', 'n_tokens_mistral': 2668, 'n_tokens_neox': 2510, 'n_words': 1271}