Thank you for your interest in contributing to the Agda standard library. Hopefully this guide should make it easy to do so! Feel free to ask any questions on the Agda mailing list. Before you start please read the style-guide.
-
The contribution should be useful in a diverse set of areas.
-
The bar for accepting contributions that use the FFI to depend on external (i.e. Haskell, JavaScript) packages is much higher.
-
If the same concept already exists in the library, there needs to be a very good reason to add a different formalisation.
-
There should be evidence that the code works. Usually this will be proofs, but sometimes for purely computational contributions this will involve adding tests.
-
It should use the minimal set of Agda features, i.e. it should normally use the Agda option pragmas
--cubical-compatible
and--safe
, with the occasional use of--with-K
,--sized
,--guardedness
in certain situations.
In general, if something is in a general undergraduate Computer Science or Mathematics textbook it is probably (!) contributable.
Before making changes to a Data
module please have a look at related modules
and see if they have any content along similar lines. If so, then please
follow those conventions (e.g. naming, argument order).
For example, if working on Data.Rational
, please check Data.Rational.Unnormalised
or if working on Data.Vec
please check Data.List
and vice versa.
Likewise, if adding to such modules, please try to make companion additions
to the related ones, or at least to make a task-list in the comments on your PR,
indicating what outstanding work may be left for subsequent contributions/contributors.
The typical workflow when contributing to the standard library's repository is to interact with two remote versions of the repository:
-
agda/agda-stdlib, the official one from which you can pull updates so that your contributions end up on top of whatever the current state is.
-
USER/agda-stdlib, your fork to which you can push branches with contributions you would like to merge
This tutorial guides you to set up a local copy of agda-stdlib so that you can start contributing. Once things are set up properly, you can stick to only steps 5., 6., 7., 8. and 9. for future contributions.
- Fork the agda-stdlib repository
Go to https://github.com/agda/agda-stdlib/ and click the 'Fork' button in the top right corner. This will create a copy of the repository under your username. We assume in the rest of this document that this username is 'USER'.
- Double check-line ending settings if not on Linux
If you are on a Mac, make sure that your git options has autocrlf
set to input
.
This can be done by executing
git config --global core.autocrlf input
If you are on Windows, make sure that your editor can deal with Unix format files.
- Obtain a local copy of agda/agda-stdlib
Obtain a local copy of the agda-stdlib repository. Here we are going to retrieve
it from the agda/agda-stdlib
repository so that master
always points to the
state the official library is in.
git clone [email protected]:agda/agda-stdlib
NB:
if you have not added a public key to your github profile to set up
git over ssh, you may need to use the https url instead of the git@ one
(https://github.com/agda/agda-stdlib
)
- Add your fork as a secondary remote
As we have mentioned earlier the idea is to pull updates from agda/agda-stdlib
and to push branches to your fork. For that to work you will need to explain to
git how to refer to your fork. This can be done by declaring a remote like so
(again you may need to use the https url if you haven't configured git over ssh)
git remote add USER [email protected]:USER/agda-stdlib
You can check that this operation succeeded by fetching this newly added remote. Git should respond with a list of branches that were found on your fork.
git fetch USER
End of initial setup. When creating a future PRs one should start here..
- Create a branch for your new feature
Now that we have a local copy, we can start working on our new feature.
The first step is to make sure we start from an up-to-date version of the
repo by synchronising master
with its current state on agda/agda-stdlib
.
git checkout master
git pull
The second step is to create a branch for that feature based off master
.
Make sure to pick a fresh name in place of new_feature
. We promptly push
this new branch to our fork using the -u
option for push
.
git checkout -b new_feature
git push USER -u new_feature
- Make your changes
You can then proceed to make your changes. Please follow existing
conventions in the library, see
style-guide.
for details. Document your changes in agda-stdlib-fork/CHANGELOG.md
.
If you are creating new modules, please make sure you are having a proper header, and a brief description of what the module is for, e.g.
------------------------------------------------------------------------
-- The Agda standard library
--
-- {PLACE YOUR BRIEF DESCRIPTION HERE}
------------------------------------------------------------------------
If possible, each module should use the options --safe
and
--cubical-compatible
. You can achieve this by placing the following
pragma under the header and before any other line of code (including
the module name):
{-# OPTIONS --cubical-compatible --safe #-}
If a module cannot be made safe or needs the --with-K
option then it should be
split into a module which is compatible with these options and an auxiliary
one which will either be called SOME/PATH/Unsafe.agda
or SOME/PATH/WithK.agda
or explicitly declared as either unsafe or needing K in GenerateEverything.hs
- [ Optional ] Run test suite locally
NB this step is optional as these tests will be run automatically by our CI infrastructure when you open a pull request on Github, but it can be useful to run it locally to get a faster turn around time when finding problems.
Ensure your changes are compatible with the rest of the library by running the commands
make clean
make test
inside the agda-stdlib-fork
folder. Continue to correct any bugs
thrown up until the tests are passed. Note that the tests
require the use of a tool called fix-whitespace
. See the
instructions at the end of this file for how to install this.
- Add, commit and push your changes to your fork
Use the git add X
command to add changes to file X
to the commit,
or git add .
to add all the changed files.
Run the command git commit
and enter a meaningful description for
your changes.
Upload your changes to your fork by running git push
.
- Open a PR
Once you're satisfied with your additions, you can make sure they have been pushed to the feature branch by running
git status
and making sure there is nothing left to commit or no local commits to push. You should get something like:
On branch new_feature
Your branch is up-to-date with 'USER/new_feature'.
nothing to commit, working tree clean
You can then go to https://github.com/agda/agda-stdlib/pulls
, click on
the green 'New pull request' button and then the 'compare across forks' link.
You can then select your fork as the 'head repository' and the corresponding feature branch and click on the big green 'Create pull request' button. The library maintainers will then be made aware of your requested changes and should be in touch soon.
- Update the PR
If after opening a PR you realise you have forgotten something, or have received a review asking you to change something, you can simply push more commits to the branch and they will automatically be added to the PR.
This tool is kept in the main agda organization. It can be installed by following these instructions:
git clone https://github.com/agda/fix-whitespace --depth 1
cd fix-whitespace/
cabal install
You can add the following code to the file .git/hooks/pre-commit
to
get git to run fix-whitespace before each git commit
and ensure
you are never committing anything with a whitespace violation:
#!/bin/sh
fix-whitespace --check
-
By default the README files are not exported in the
standard-library.agda-lib
file in order to avoid clashing with other people's README files. -
If you wish to type-check a README file, then you will need to change the present working directory to
doc/
where an appropriatestandard-library-doc.agda-lib
file is present.
The file .github/workflows/haskell-ci.yml
tests building the helpers specified in agda-stdlib-utils.cabal
.
It is autogenerated by the tool haskell-ci
but has some custom modification which need to be restored after each regeneration of this workflow.
haskell-ci creates the workflow file from settings in the cabal.haskell-ci
file
and from the contents of the tested-with
field in the agda-stdlib-utils.cabal
file.
After updating this field, run the following:
haskell-ci regenerate
patch --input=.github/haskell-ci.patch .github/workflows/haskell-ci.yml