# Godocs

**Godocs** is a package that helps in the process of **building Godot documentation** by **automating the conversion** of **Godot's XML docs** to any **other format** implemented.

## 🤔 How to Use

To use this package, you'll need the **XML files generated by Godot's** `doctool` utility, using a **command** similar to the **below**:

``` sh
godot --headless --doctool <output-dir> --no-docbase --gdscript-docs res://<input-dir>
```

According to some tests, **sometimes** Godot's `doctool` **doesn't work** with projects that haven't been yet opened in the **Godot editor**, so make sure to **try opening yours** if the command isn't working.

> 💡 **NOTE**: In this documentation, when you find stuff in **diamond brackets** (like this: `<name>`), generally speaking, it means that it should be **substituted by something else**, which is explained by its name.

With the **XML files** generated by the `doctool`, `godocs` can be used to **generate** output **documentation files**.

**By itself**, though, **Godocs isn't capable of generating documentation**. That's because **to realize its full potential**, you also need to **install a constructor extension**. By default, the `godocs-jinja` plugin was created to allow the **construction of documentation through the use of Jinja2**.

> 💡 **NOTE**: Initially, both `godocs` and `godocs-jinja` were only **one package**, but the decision of **separating both** was made in order to **allow the creation of alternative constructors in the future** that would give users the liberty of **not using Jinja2** if they didn't want to.<br>
Also, the separation was made to **make the development more manageable** and the addition of **future constructors more modular**, **not requiring users to install constructors they don't really need**.

Having said that, if you have `godocs-jinja` **installed**, you can **generate your docs** in the **formats available**. In the moment, **only RST generation is implemented**, which can be **used by other generators** like [Python's Sphinx](https://www.sphinx-doc.org/en/master/) to build **outputs to other media**, like **HTML pages**.

Here's an example of how to **generate RST documentation**, having both `godocs` and `godocs-jinja` installed:

``` sh
godocs construct jinja <input-dir> <output-dir>
```

## 📥 Installation

To start using the **Godocs CLI**, you can **install** both the **main package** and the **Jinja constructor** through **PIP**.

Here's the commands:

``` sh
# To install the main CLI:
pip install godocs

# To install the Jinja2 based constructor:
pip install godocs-jinja
```

> 💡 **HINT**: Depending on your needs, it may be useful to install packages in a **virtual environment**, as to not pollute your global env. Sometimes you may want to install stuff globally, though, it really depends.<br>
Generally speaking, I'd recommend **installing globally** if you're in a **CI/ CD runner**, for example, and installing in an **environment** if you're in your **local computer testing** out in a single repository.

If you desire to **isolate installation** in a `venv`, you should previously have run these **commands**:

``` sh
# To create a venv in a .venv folder:
python -m venv .venv

# To activate the created venv on Windows:
.venv/Scripts/activate
# Or, on Unix systems or Git Bash, for example:
source .venv/Scripts/activate
```

## 🎛️ Commands

The **Godocs CLI** exposes some commands via the `godocs` entrypoint (if you installed in a **virtual environment**, make sure to have it **activated** before effectively using the program).

**Without** any **constructor plugin**, the only command available is the `construct`, which serves as the **main documentation generator**. That command doesn't do anything by itself, though, needing **at least one extension** to come into action.

If you installed the `godocs-jinja` plugin, like recommended, then you get to use the `jinja` subcommand as your **constructor**.

Down below are some quick **examples** of how to use `godocs` with `godocs-jinja` to **generate documentation**.

If you want a more **in depth overview** of the arguments, commands, and options available, you can always use the `-h` / `--help` option with **any command**.

Also, if you want **more details** on `godocs-jinja` concepts, like **models**, **templates**, **filters** and **builders**, you can read more about them in its **repository** in this [link](https://github.com/godocs-godot/godocs-jinja).

``` sh
# Generates documentation based on the XML in the input-dir inside the output-dir, in the RST language.
godocs construct jinja <input-dir> <output-dir>

# Generates documentation based on the XML from the input-dir inside the output-dir, in the RST language, translating the syntax of any text within it using the custom translator in the translator-path.
godocs construct jinja --translator <translator-path> <input-dir> <output-dir>

# Generates documentation based on the XML from the input-dir inside the output-dir, using the model specified by md-model, with the md file suffix, translating the syntax of any text within the XML using the custom translator in the md-translator path.
godocs construct jinja --translator <md-translator> --format md --model <md-model> <input-dir> <output-dir>
```

## 📝 Custom Options

The documentation process often needs some **data that can't be obtained** directly from the **XML class reference** generated by **Godot**. That's why more **properties can be passed** via a special `godocs-options.json` file.

You can write **any data** your documentation will potentially need **inside this file** and **specify its path** through the `--options-file` option in the **constructor command** chosen. **Godocs** `construct` logic will then **parse its data** and make it **available in the building context inside an options property**.

The **data needed** for docs generation will **depend on what templates you'll use**, in the case of the **Jinja constructor**, or in other constructors' logic.

## 🧑‍💻 Developing

For **development isolation**, it is recommended to be inside a **virtual environment**, which can be accomplished by following the **steps** described at the end of the **Installation section**, quickly recaping:

``` sh
python -m venv .venv

# On Windows:
.venv/Scripts/activate
# Or, on Unix:
source .venv/Scripts/activate
```

Now, the project comes with a `pyproject.toml`, which specifies its **development dependencies** (this package has **no production deps**) listed under the `[project.optional-dependencies.dev]` table.

If you want to **install** them, you can use the following **command**:

``` sh
pip install .[dev]
```

If you're going to **develop**, though, I'd rather recommend you to **install the project itself** in **editable mode**, which would allow you to **make changes** and **test them** out in **real time**, **without having to rebuild and reinstall**. Here's the command to achieve that:

``` sh
pip install --editable .
```

## 🧪 Testing

This project uses `pytest` as its **test framework**, which means in order to **execute tests**, you should use the **following command**:

``` sh
pytest
```

The **test files** are located under the `tests` directory, distributed under a **structure** that **mirrors the source code** arrangement.

## 📦 Building

To **build this project** for production, the `build` **dependency is needed**, which is specified in the **dev dependencies** from `pyproject.toml`.

With that **dependency installed** (through the **installation of the dev dependencies**, or its manual installation), the following command can be used:

``` sh
python -m build .
```

This will use the `setuptools` **build backend** in an **isolated temporary environment** to **create the distributables**.

When executed, **there should be** a `dist` folder with a `.tar.gz` archive and a `.whl` build.

## 🚀 Deploying

To deploy this package, use the following command:

``` sh
python -m twine upload dist/*
```

## 🧩 Extending
Godocs strives to be **open for configurations and extensions** from users, that's why a **plugin system** is implemented.

Currently, users can add to the application through plugin packages by extending the `Plugin` class. Users can add **custom constructors** as well as **custom CLI commands** to receive the configurations for those constructors, or any other modifications they want.

That's how the `godocs-jinja` plugin appends a new `jinja` constructor to this tool.

Keep in mind that scripts that define plugins should **expose** a `Plugin` class, that implements the base `godocs.plugin.Plugin` with its main `register` method defining what happens when this plugin is used.

A snippet showing an example of a **custom constructor plugin** that when selected prints a message describing the options chosen can be found here in the `examples` folder.

In order to be **recognized** by `godocs` and be more **easily shareable**, **plugin packages can be registered** by using **entry points**. Here's an **example** of how the `godocs-jinja` plugin **exposes itself** as a plugin so `godocs` can find and **register it**:

``` toml
# pyproject.toml
[project.entry-points."godocs.plugins"]
jinja = "godocs_jinja.main:JinjaPlugin"
```

And here's an **example** of how the `ExamplePlugin` mentioned before would be **registered**, if it was right **inside** the `src` folder in this project:

``` toml
[project.entry-points."godocs.plugins"]
example-plugin = "example_plugin:ExamplePlugin"
```
