# Contributing Read our contribution guide in our organization level [docs](https://lizardbyte.readthedocs.io/en/latest/developers/contributing.html). ## Project Patterns ### Web UI * The Web UI uses [Vite](https://vitejs.dev) as its build system. * The HTML pages used by the Web UI are found in `./src_assets/common/assets/web`. * [EJS](https://www.npmjs.com/package/vite-plugin-ejs) is used as a templating system for the pages (check `template_header.html` and `template_header_main.html`). * The Style System is provided by [Bootstrap](https://getbootstrap.com). * The JS framework used by the more interactive pages is [Vus.js](https://vuejs.org). #### Building @tabs{ @tab{CMake | ```bash cmake -B build -G Ninja -S . --target web-ui ninja -C build web-ui ```} @tab{Manual | ```bash npm run dev ```} } ### Localization Sunshine and related LizardByte projects are being localized into various languages. The default language is `en` (English). ![](https://app.lizardbyte.dev/dashboard/crowdin/LizardByte_graph.svg) @admonition{Community | We are looking for language coordinators to help approve translations. The goal is to have the bars above filled with green! If you are interesting, please reach out to us on our Discord server.} #### CrowdIn The translations occur on [CrowdIn][crowdin-url]. Anyone is free to contribute to the localization there. ##### Translation Basics * The brand names *LizardByte* and *Sunshine* should never be translated. * Other brand names should never be translated. Examples include *AMD*, *Intel*, and *NVIDIA*. ##### CrowdIn Integration How does it work? When a change is made to Sunshine source code, a workflow generates new translation templates that get pushed to CrowdIn automatically. When translations are updated on CrowdIn, a push gets made to the *l10n_master* branch and a PR is made against the *master* branch. Once the PR is merged, all updated translations are part of the project and will be included in the next release. #### Extraction ##### Web UI Sunshine uses [Vue I18n](https://vue-i18n.intlify.dev) for localizing the UI. The following is a simple example of how to use it. * Add the string to the `./src_assets/common/assets/web/public/assets/locale/en.json` file, in English. ```json { "index": { "welcome": "Hello, Sunshine!" } } ``` @note{The json keys should be sorted alphabetically. You can use [jsonabc](https://novicelab.org/jsonabc) to sort the keys.} @attention{Due to the integration with Crowdin, it is important to only add strings to the *en.json* file, and to not modify any other language files. After the PR is merged, the translations can take place on [CrowdIn][crowdin-url]. Once the translations are complete, a PR will be made to merge the translations into Sunshine.} * Use the string in the Vue component. ```html ``` @tip{More formatting examples can be found in the [Vue I18n guide](https://kazupon.github.io/vue-i18n/guide/formatting.html).} ##### C++ There should be minimal cases where strings need to be extracted from C++ source code; however it may be necessary in some situations. For example the system tray icon could be localized as it is user interfacing. * Wrap the string to be extracted in a function as shown. ```cpp #include #include std::string msg = boost::locale::translate("Hello world!"); ``` @tip{More examples can be found in the documentation for [boost locale](https://www.boost.org/doc/libs/1_70_0/libs/locale/doc/html/messages_formatting.html).} @warning{The below is for information only. Contributors should never include manually updated template files, or manually compiled language files in Pull Requests.} Strings are automatically extracted from the code to the `locale/sunshine.po` template file. The generated file is used by CrowdIn to generate language specific template files. The file is generated using the `.github/workflows/localize.yml` workflow and is run on any push event into the `master` branch. Jobs are only run if any of the following paths are modified. ```yaml - 'src/**' ``` When testing locally it may be desirable to manually extract, initialize, update, and compile strings. Python is required for this, along with the python dependencies in the `./scripts/requirements.txt` file. Additionally, [xgettext](https://www.gnu.org/software/gettext) must be installed. * Extract, initialize, and update ```bash python ./scripts/_locale.py --extract --init --update ``` * Compile ```bash python ./scripts/_locale.py --compile ``` @attention{Due to the integration with CrowdIn, it is important to not include any extracted or compiled files in Pull Requests. The files are automatically generated and updated by the workflow. Once the PR is merged, the translations can take place on [CrowdIn][crowdin-url]. Once the translations are complete, a PR will be made to merge the translations into Sunshine.} ### Testing #### Clang Format Source code is tested against the `.clang-format` file for linting errors. The workflow file responsible for clang format testing is `.github/workflows/cpp-clang-format-lint.yml`. Option 1: ```bash find ./ -iname *.cpp -o -iname *.h -iname *.m -iname *.mm | xargs clang-format -i ``` Option 2 (will modify files): ```bash python ./scripts/update_clang_format.py ``` #### Unit Testing Sunshine uses [Google Test](https://github.com/google/googletest) for unit testing. Google Test is included in the repo as a submodule. The test sources are located in the `./tests` directory. The tests need to be compiled into an executable, and then run. The tests are built using the normal build process, but can be disabled by setting the `BUILD_TESTS` CMake option to `OFF`. To run the tests, execute the following command. ```bash ./build/tests/test_sunshine ``` To see all available options, run the tests with the `--help` flag. ```bash ./build/tests/test_sunshine --help ``` @tip{See the googletest [FAQ](https://google.github.io/googletest/faq.html) for more information on how to use Google Test.} We use [gcovr](https://www.gcovr.com) to generate code coverage reports, and [Codecov](https://about.codecov.io) to analyze the reports for all PRs and commits. Codecov will fail a PR if the total coverage is reduced too much, or if not enough of the diff is covered by tests. In some cases, the code cannot be covered when running the tests inside of GitHub runners. For example, any test that needs access to the GPU will not be able to run. In these cases, the coverage can be omitted by adding comments to the code. See the [gcovr documentation](https://gcovr.com/en/stable/guide/exclusion-markers.html#exclusion-markers) for more information. Even if your changes cannot be covered in the CI, we still encourage you to write the tests for them. This will allow maintainers to run the tests locally. [crowdin-url]: https://translate.lizardbyte.dev
| Previous | Next | |:------------------------|-------------------------------------------------------------:| | [Building](building.md) | [Source Code](../third-party/doxyconfig/docs/source_code.md) |
[TOC]