Skip to content

Latest commit

 

History

History
298 lines (223 loc) · 11.1 KB

CONTRIBUTING.md

File metadata and controls

298 lines (223 loc) · 11.1 KB

Contributors Guide

Thank you for considering contributing to the maintenance or development of pantry! We hope that the following information will encourage and assist you. We start with some advice about pantry's governance.

pantry's governance

People involved in maintaining or developing pantry with rights to make commits to the repository can be classified into two groups: 'committers' and 'maintainers'.

pantry's committers

We encourages a wide range of people to be granted rights to make commits to the repository.

People are encouraged to take initiative to make non-controversial changes, such as documentation improvements, bug fixes, performance improvements, and feature enhancements.

Maintainers should be included in discussions of controversial changes and tricky code changes.

Our general approach is "it's easier to ask forgiveness than permission". If there is ever a bad change, it can always be rolled back.

pantry's maintainers

pantry's maintainers are long-term contributors to the project. Michael Snoyman (@snoyberg) was the founder of pantry, and its initial maintainer - and he has added others. Michael's current interests and priorities mean that he is no longer actively involved in adding new features to pantry.

Maintainers are recognized for their contributions including:

  • Direct code contribution
  • Review of pull requests
  • Interactions on the GitHub issue tracker

The maintainer team make certain decisions when that is necessary, specifically:

  • How to proceed, if there is disagreement on how to do so on a specific topic
  • Whether to add or remove (see further below) a maintainer

Generally, maintainers are only removed due to non-participation or actions unhealthy to the project. Removal due to non-participation is not a punishment, simply a recognition that maintainership is for active participants only.

We hope that removal due to unhealthy actions will never be necessary, but would include protection for cases of:

  • Disruptive behavior in public channels related to pantry
  • Impairing the codebase through bad commits/merges

Like committers, maintainers are broadly encouraged to make autonomous decisions. Each maintainer is empowered to make a unilateral decision. However, maintainers should favor getting consensus first if:

  • They are uncertain what is the best course of action
  • They anticipate that other maintainers or users of pantry will disagree on the decision

Bug Reports

Please open an issue and use the provided template to include all necessary details.

The more detailed your report, the faster it can be resolved and will ensure it is resolved in the right way. Once your bug has been resolved, the responsible person will tag the issue as Needs confirmation and assign the issue back to you. Once you have tested and confirmed that the issue is resolved, close the issue. If you are not a member of the project, you will be asked for confirmation and we will close it.

Error messages

To support the Haskell Foundation's Haskell Error Index initiative, all pantry error messages generated by pantry itself should have a unique initial line:

Error: [S-nnn]

where nnn is a three-digit number in the range 100 to 999.

If you create a new pantry error, select a number using a random number generator (see, for example, RANDOM.ORG) and check that number is not already in use in pantry's code. If it is, pick another until the number is unique.

All exceptions generated by pantry itself are implemented using data constructors of closed sum types. Typically, there is one such type for each module that exports functions that throw exceptions.

Code

If you would like to contribute code to fix a bug, add a new feature, or otherwise improve pantry, pull requests are most welcome. It's a good idea to submit an issue to discuss the change before plowing into writing code.

Please include a ChangeLog entry with your pull request.

Code Quality

The pantry project uses yamllint as a YAML file quality tool and HLint as a code quality tool.

Linting of YAML files

The yamllint configuration extends the tools default and is set out in .yamllint.yaml. In particular, indentation is set at 2 spaces and - in sequences is treated as part of the indentation.

Linting of Haskell source code

The HLint configurations is set out in .hlint.yaml.

pantry contributors need not follow dogmatically the suggested HLint hints but are encouraged to debate their usefulness. If you find a HLint hint is not useful and detracts from readability of code, consider marking it in the configuration file to be ignored. Please refer to the HLint manual for configuration syntax.

We are optimizing for code clarity, not code concision or what HLint thinks.

You can install HLint with Stack. You might want to install it in the global project in case you run into dependency conflicts. HLint can report hints in your favourite text editor. Refer to the HLint repository for more details.

To install, command:

stack install hlint

Code Style

A single code style is not applied consistently to pantry's code and pantry is not Procrustean about matters of style. Rules of thumb, however, are:

  • keep pull requests that simply reformat code separate from those that make other changes to code; and
  • when making changes to code other than reformatting, follow the existing style of the function(s) or module(s) in question.

That said, the following may help:

  • pantry's code generally avoids the use of C preprocessor (CPP) directives. Windows and non-Windows code is separated in separate source code directories and distinguished in pantry's Cabal file. Multi-line strings are generally formatted on the assumption that GHC's CPP language pragma is not being used.
  • Language pragmas usually start with NoImplictPrelude, where applicable, and then all others are listed alphabetically. The closing #-} are aligned, for purely aesthetic reasons.
  • pantry is compiled with GHC's -Wall enabled, which includes -Wtabs (no tabs in source code). Most modules are based on two spaces (with one space for a where) for indentation but older and larger modules are still based on four spaces.
  • pantry's code and documentation tends to be based on lines of no more than 80 characters or, if longer, no longer than necessary.
  • pantry uses export lists.
  • pantry's imports are listed alphabetically. The module names are left aligned, with space left for qualified where it is absent.
  • pantry's code is sufficiently stable that explict import lists can sensibly be used. Not all modules have comprehensive explicit import lists.
  • Short explicit import lists follow the module name. Longer lists start on the line below the module name. Spaces are used to separate listed items from their enclosing parentheses.
  • In function type signatures, the :: is kept on the same line as the function's name. This format is Haskell syntax highlighter-friendly.
  • If where is used, the declarations follow on a separate line.

Continuous integration (CI)

We use GitHub Actions to do CI on pantry. The configuration of the workflows is in the YAML files in .github/workflows. The current active workflows are:

Linting - lint.yml

This workflow will run if:

  • there is a pull request
  • commits are pushed to this branch: master

The workflow has one job (style). It runs on ubuntu only and applies yamllint and Hlint.

Stan tool - stan.yml

Stan is a Haskell static analysis tool. As of stan-0.1.0.1, it supports GHC >= 9.6.3. The tool is configured by the contents of the .stan.toml file.

This workflow will run if:

  • there is a pull request
  • requested

Haskell Language Server

You may be using Visual Studio Code (VS Code) with its Haskell extension, which is powered by the Haskell Language Server (HLS).

pantry can be built with Stack (which is recommended) or with Cabal (the tool).

=== "Stack"

If you use Stack to build Stack, command `stack ghci` in the root directory
of the pantry project should work as expected, if you have first commanded
`stack build` once.

`ghc` should be on the PATH if you run VS Code itself in the Stack
environment:
~~~text
stack exec -- code .
~~~

The following [cradle (`hie.yaml`)](https://github.com/haskell/hie-bios)
should suffice to configure Haskell Language Server (HLS) explicitly for
each of the buildable components in pantry's Cabal file:
~~~yaml
cradle:
  stack:
  - path: "./src"
    component: "pantry:lib"
  - path: "./int"
    component: "pantry:lib"
  - path: "./app"
    component: "pantry:exe:test-pretty-exceptions"
  - path: "./test"
    component: "pantry:test:spec"
~~~

=== "Cabal (the tool)"

If you use Cabal (the tool) to build Stack, command `cabal repl` in the root
directory of the Stack project should work as expected, if you have GHC and
(on Windows) MSYS2 on the PATH.

`ghc` and (on Windows) MSYS2 should be on the PATH if you run commands
(including `cabal`) in the Stack environment:
~~~text
stack exec --no-ghc-package-path -- cabal repl
~~~

or
~~~text
stack exec --no-ghc-package-path -- code .
~~~

Use of GHC's environment variable `GHC_PACKAGE_PATH` is not compatible with
Cabal (the tool). That is why the `--no-ghc-package-path` flag must be
specified with `stack exec` when relying on Cabal (the tool).

The following [cradle (`hie.yaml`)](https://github.com/haskell/hie-bios)
should suffice to configure Haskell Language Server (HLS) explicitly for
each of the buildable components in pantry's Cabal file:
~~~yaml
cradle:
  cabal:
  - path: "./src"
    component: "lib:pantry"
  - path: "./int"
    component: "lib:pantry"
  - path: "./app"
    component: "exe:test-pretty-exceptions"
  - path: "./test"
    component: "test:spec"
~~~

A cradle is not committed to pantry's repository because it imposes a choice of build tool.

Slack channel

If you're making deep changes and real-time communication with the pantry team would be helpful, we have a #stack-collaborators Slack channel in the Haskell Foundation workspace. To join the workspace, follow this link.

Matrix room

There is also a Stack and Stackage room at address #haskell-stack:matrix.org on Matrix.