Project: Gimli is available on Codeberg, and mirrored on GitHub.
Always ask if unsure. Don't ask to ask, just ask.
Creating an entire issue for minor problems and/or questions is fine and encouraged. However, make sure your question hasn't been asked already.
An exception to this rule is "when?". Gimli is a hobby project, we may have roadmaps, but we don't have timetables.
APIs (Application Programming Interfaces) are collections of definitions that generally don't change, allowing programs to talk with each other.
The Kotlin documentation has a neat article about the topic.
Project: Gimli maintains ABIs, that is, Application Bytecode Interfaces. ABIs are composed of compiled signatures of code elements (such as functions, classes, properties, etc.).
Each platform has its own ABI, but currently, only one is generated and checked—the JVM (including Android).
It is stored inside each module's abi
folder, as an .api
file.
To generate the ABI, run:
./gradlew apiDump
To make sure you haven't accidentally changed the ABI, run:
./gradlew apiCheck
The API's behaviour is defined by its documentation, written in KDoc.
To compile KDoc into a website, run:
./gradlew dokkaHtmlMultiModule
The result will be outputted at build/dokka/htmlMultiModule
,
and requires a web server to be viewed properly.
To compile a test coverage report, run:
./gradlew koverHtmlReport
The result will be outputted at build/reports/kover/html
.
To run all tests, run:
./gradlew test
Generally, PRs should target the development
branch of the Codeberg repository.
For breaking changes, ask the maintainer.
When moving files, make sure git recognizes the file was moved. This is usually done by creating separate commits for changing and moving a file.
We only allow merges.
- Rebasing removes commit signatures.
- Squashes destroy the branch graph.
Feel free to squash/rebase locally, as long as it only affects your own commits.
- If the version specified in
gradle.properties
is already released, increase it. - Make sure all tests succeed.
- Update or create tests for functionality you change.
- If you modify public API,
*
1. Update the ABI.
2. Make sure the changes match your expectations.
- Otherwise, check for breaking changes.
- Organize the repository via:
./gradlew organize
- Make sure the repo builds successfully, via:
This will update modules'
./gradlew build
README.md
, and will add a license notice at the top of the file. - Update or create documentation (via KDoc).
- If you update, add or remove dependencies,
- Update
DEPENDENCIES.md
. - Run:
./gradlew kotlinUpgradeYarnLock
- Update
- If you modify federation behavior, update
FEDERATION.md
.
Feel free to fork Gimli if you want to add any of the below features, because we won't. Try convincing the maintainer otherwise on their mastodon account, not via issues nor PRs.
If you don't know how to (theoretically) implement an out-of-scope feature, and/or won't be able to help, rest assured it'll remain out of scope.
Gimli is a social network, not a git forge. However, adding compatibility between Gimli and ForgeFed features is within scope, and actually planned. Gimli won't host Git repositories.
Sorry, the maintainer's cryptography knowledge is lacking. Besides, the real Web3 is the Fediverse.
Gimli is intended to be a cross-platform project. As such, we need to support platforms that don't support HTML, CSS, and JS.
Gimli is built in Kotlin. Usage of other languages is only allowed when strictly necessary to allow anyone to contribute to any part of Project: Gimli.
Gimli may have projects in other languages (in a separate repository) in the future.
It's the maintainer's personal branch—Codeberg doesn't allow forking your own repos.
Note the below is merely guidelines. Feel free to ignore them in cases they produce cursed code.
- "Code element" and "element" are any
fun
ction,val
ue,var
iable,class
,interface
,object
, etc. - "Property" is any Kotlin property.
- "
val
ue" is an explicitly immutable property. - "
var
iable" is an explicitly mutable property.
- "
Gimli code focuses on readability, not on nesting.
Kotlin is a nesting-heavy language, and nesting purists will sometimes have to survive over six levels of nestings.
For indentation, use four spaces or a tab character. However, do not refactor lines you haven't otherwise changed to use your favorite, to avoid uselessly long diffs.
Gimli may restrict indentation further in the future, only allowing tabs.
This repository contains two types of Kotlin files.
Sort code elements by usage.
If foo()
calls bar()
, bar()
should be written first.
Contain zero non-private
top-level class
es, interface
s and object
s.
Have a variety of utility fun
ctions and val
ues.
May be turned into Class Files by wrapping them with an object
, or with a class
and companion object
.
Prefer only using Utility Files in :util
and its submodules, where the classes are defined in other
modules.
When creating extension functions for a class
defined in the same module, define them in its or a
related companion object
.
Contain a single non-private
top-level code element, which must be class
, interface
, or object
.
Use a companion object
to declare extension functions within the same file.
Within classes, sort elements in the following way. Note that within categories, elements must be sorted the same way as top-level elements.
private class MyClassImpl // used by MyClass
class MyClass {
// field-ful values
val value = TODO()
// field-ful variables
var variable = TODO()
// <overriding field-ful values and variables>
// fieldless values
val getter get() = TODO()
// fieldless variables
var getterAndSetter
get() = TODO()
set(value) = TODO()
// <overriding fieldless values and variables>
// secondary constructors
constructor()
// functions and sub-classes
fun function() = TODO()
class Subclass
override fun overridingFunction() = TODO()
// and lastly, the companion object
companion object
}