Developer documentation
Welcome to the developer documentation! We are excited that you are interested in contributing to our package.
Feel free to submit your work in a state you are comfortable with—we genuinely appreciate every contribution! If you are interested in following best practices and learning along the way, keep reading. But don't worry, we welcome your input just as it is 🙂.
If you haven't already, please read the Contribution guide first.
Please note that the following documentation is adapted from the BestieTemplate.jl developer documentation but has been customized to fit our needs.
Development/GitHub Workflow
Before you start coding
- Check whether there exists a GitHub issue about the topic (e.g. bug, new feature etc). If not create one with a short description of the problem or feature idea.
- Discuss your approach with the package maintainers either in the issue or via another channel.
First time clone & development version
If this is the first time you work with this repository, follow the instructions below to clone the repository and create a dev
version.
Having a dev
(development) version of a Julia package allows you to import a local version of the package with your changes instead of the registered package version (which is static).
a) If you have writing access for the GitHub repository
- Option 1: Clone this repository using
git clone
. - Option 2 (recommended): Use the Julia
dev
command to create a development version of the package:- Start a Julia session and run
cd("/path/to/your/project")
to navigate to your project folder. - Press
]
to enterpkg
mode. - Run
dev --local UnfoldSim
to clone the package to./dev/UnfoldSim
and automatically add it to your Julia project environment.
- Start a Julia session and run
If you have writing rights, whenever upstream is mentioned below, use origin instead.
b) If you don't have writing access for the GitHub repository
Fork the UnfoldSim.jl repository.
Clone your repository (this will create a
git remote
calledorigin
).Add the UnfoldSim.jl repository as a remote:
git remote add upstream https://github.com/unfoldtoolbox/UnfoldSim.jl
This will ensure that you have two remotes in your git: origin
and upstream
. You will create branches and push to origin
, and you will fetch and update your local main
branch from upstream
.
You can also use the dev
command on your fork. Run ]dev --local url/of/your/fork
to clone the package to ./dev/UnfoldSim
and automatically add it to your Julia project environment.
Revise.jl
Further, we recommend to use Revise.jl
: a Julia package which allows you to track source code changes in a running Julia session without need to restart it and reload the package.
We recommend to install it in the global environment:
julia> # Press ]
pkg> activate
pkg> add Revise
Working on a new issue
We try to keep a linear Git history in this repository, so it is important to keep your branches up-to-date.
Fetch from the remote and fast-forward your local main
git fetch upstream git switch main git merge --ff-only upstream/main
Branch from
main
to address the issue (see below for naming)git switch -c 42-add-answer-universe
Push the new local branch to your personal remote repository
git push -u origin 42-add-answer-universe
Create a pull request to merge your remote branch into the
main
branch of the original UnfoldSim.jl repository.
Branch naming
- If there is an associated issue, add the issue number.
- If there is no associated issue, and the changes are small, add a prefix such as "typo", "hotfix", "small-refactor", according to the type of update.
- If the changes are not small and there is no associated issue, then either create an issue first, or discuss in another channel with the maintainers.
- Use dash separated imperative wording related to the issue (e.g.,
14-add-tests
,15-fix-model
,16-remove-obsolete-files
).
Commit messages
- Use imperative or present tense, for instance: Add feature or Fix bug.
- Have informative titles.
- When necessary, add a body with details.
- If there are breaking changes, add the information to the commit message.
Before creating a pull request
Ideally: Make sure the tests pass (see Testing).
Add appropriate documentation (ideally using the Docstring templates).
Ideally: Follow the formatting rules from
JuliaFormatter.jl
(see Formatting).Fetch any
main
updates from upstream and rebase your branch, if necessary:git fetch upstream git rebase upstream/main BRANCH_NAME
Then you can open a pull request and work with the reviewer to address any issues.
We encourage you to share your contributions in whatever state you are comfortable with. Don’t feel overwhelmed by the number of guides — think of them as helpful resources, not strict requirements. Every contribution is valuable, and we’re happy to refine things together!
Formatting
JuliaFormatter.jl
We use JuliaFormatter.jl for formatting and recommend you to install it in your global environment:
julia> # Press ]
pkg> activate
pkg> add JuliaFormatter
Beware of reviewdog 🐶
We use the julia-format Github action to ensure that the code follows the formatting rules defined by JuliaFormatter.jl. When opening a pull request reviewdog will automatically make formatting suggestions for your code.
Testing
As with most Julia packages, you can just open Julia in the repository folder, activate the environment, and run test
:
julia> # press ]
pkg> activate .
pkg> test
Instead of running all tests, you can also run the test/setup.jl
to load all required packages, and subsequently run single tests manually either by include("test/my_test.jl")
or by opening the file and running the specific test block you want to run.
Documentation
Documentation is key to maintaining a codebase that is easy to understand and extend. Whether it is comments in the code, docstrings, or tutorials, when writing documentation, think about your future self or the next person reading the code or using your functions.
Building and viewing the documentation locally
We recommend using LiveServer.jl to build and preview the documentation locally. To simplify this process we created the docs/run_liveserver.jl
script.
Please follow these steps:
- Navigate to the
docs
folder and activate it. - Run
using Revise
(in case you decided to install it in your docs environment). - If this is the first time building the docs
- Press
]
to enterpkg
mode. - Run
pkg> dev ..
to use the development version of your package. - Press backspace to leave
pkg
mode.
- Press
- Run
include("run_liveserver.jl")
. - Click on the provided link or go to
http://0.0.0.0:8000/
in your browser.
Install Revise.jl
in the docs environment to enable live updating of docstrings in the docs preview.
We recommend using a separate Julia session (in VSCode) to run the run_liveserver.jl
script, as it continues running. This way, you can avoid "blocking" the REPL and run other code in the meantime.
Adding a documentation page
- We recommend to write a Literate.jl document and place it in
docs/literate/FOLDER/FILENAME.jl
withFOLDER
beingHowTo
,Explanation
,Tutorial
orReference
(recommended reading on the 4 categories). - Literate.jl converts the
.jl
file to a.md
automatically and places it indocs/src/generated/FOLDER/FILENAME.md
. - Edit make.jl with a reference to
docs/src/generated/FOLDER/FILENAME.md
.
Docstring templates
The following docstring templates are mainly based on the Julia manual and Blue: a Style Guide for Julia.
Function docstring template
"""
my_function(argument1:Type1; keyword_argument3::Type3 = value3)
my_function(argument1::Type1, optional_argument2::Type2; keyword_argument3::Type3 = value3)
One-line description using the imperative form ("Do this") instead of the third person and ending with a period.
If the one-line description is not sufficient, one can also write a short paragraph with additional information.
# Arguments (if needed)
- `argument1::Type1`: Description of argument1.
- `optional_argument2::Type2` (optional): Description of optional_argument2.
# Keyword arguments (if needed)
- `keyword_argument3::Type3 = value3`: Description of keyword_argument3.
# Returns
- `result::Type4` : Description of result.
# Examples
```julia-repl
julia> my_function(value1, value2)
result1
julia> my_function(value1; keyword_argument3 = value4)
result2
```
See also [`my_function2`](@ref), [`my_function3`](@ref).
"""
Special cases:
- If a function accepts many keyword arguments, only include
<keyword arguments>
as a placeholder in the signature and give a keyword list with descriptions in the Keyword arguments section of the docstring. - If a function returns more than one variable, write the Returns section in the following way:
# Returns - (result1, result2)::Tuple{Type1, Type2}: - Description of result1 - Description of result2
Type docstring template
"""
MyType <: MyAbstractType
One-line desciption of my type which ends with a period.
If the one-line description is not sufficient, one can also write a short paragraph with additional information.
# Fields
- `field1::Type1`: Description of field1.
- `optional_field2::Type2 = value2` (optional): Description of field2. If not provided, defaults to `value2`.
# Examples
```julia-repl
julia> MyType(field1, field2)
result1
```
See also [`MyType2`](@ref), [`my_function2`](@ref).
"""