haskell / haskell/cabal

Troubles with setting the `license` field

Open
#7,971 11 comments 2 reactions 0 assignees View on GitHub
documentation re: error-message
Dominant language
Haskell
Stars
1.7k
Forks
750
Avg merge
4d 3h
Merged PRs (30d)
28

Description

**Describe the bug**

Sometimes it is hard to discover & put appropriate license. Especially in proprietary, default case (`NONE`) or corner cases, or when licenses have compounds in names/versions.

**To Reproduce**

Lets follow how Haskell developers form a package, & populate `license: ` field:

Because project/package bootstrapping can take quite a time, or there is some customization involved - people frequently use other projects & samples. Previously I copied particular files manually, or used real projects & deleted code from them, or used `summoner` tool.
Now - I've made a bootstrap for myself & so copied [bootstrap/sample](https://github.com/Anton-Latukha/haskell-bootstrap-sample).

Then during the renaming of things in the `.cabal` - since project/package is a private project, testing assignment, company project - `license` field needs to be changed.

Haskeller googles `"Haskell cabal licenses"` & because person is Haskeller:
![Screenshot-2022-02-11-20:46:42](https://user-images.githubusercontent.com/20933385/153651295-18427bdd-b965-4185-968f-236e19c4e46c.png)

(looking into the future - SPDX search also would return nothing particularly useful)
![Screenshot-2022-02-11-20:09:04](https://user-images.githubusercontent.com/20933385/153649181-14cd6ff5-d73b-4807-9a00-76b24410ca8c.png)

Websearch engine determines as relevant & advertises Hoogle, particularly https://hackage.haskell.org/package/Cabal-3.6.2.0/docs/Distribution-License.html.

Which is great. Seems like `License` data type is what `license` field wants.

And in a number of cases that assumption would be true - `MIT`, `BSD*` indeed would fit.

Lets look at `UnspecifiedLicense` or `AllRightsReserved`.

Since all countries in the world signed the agreement that no license defaults to be https://en.wikipedia.org/wiki/All_rights_reserved

`license: UnspecifiedLicense`:
```
> cabal v2-build (1)
Errors encountered when parsing cabal file ./project.cabal:

project.cabal:11:35: error:
unexpected Unknown SPDX license identifier: 'UnspecifiedLicense'

10 | maintainer: user@email.com
11 | license: UnspecifiedLicense
```

This error is not healful at all. The #5697 situation strongly applies here. SPDX happens to be an open-source license list - it has no accounting for any default closed source license scenarios.

`license: AllRightsReserved`:
```
> cabal v2-build (1)
Errors encountered when parsing cabal file ./project.cabal:

project.cabal:11:35: error:
unexpected Unknown SPDX license identifier: 'AllRightsReserved' You can use NONE as a value of the license field.

10 | maintainer: user@email.com
11 | license: AllRightsReserved
```

This error is a bit better - it mentions the ability to use `NONE` for a license field.

After that - I become curious:
1. Why it seems that [Distribution.License](https://hackage.haskell.org/package/Cabal-3.6.2.0/docs/Distribution-License.html) is a valid source of information - the closest possible source right to reading source code directly, but it does not work.
2. What is the acronym SPDX that tooling keeps referring to. The first idea - it probably some Haskell type, maybe Cabal-internal one, or maybe some conventional filetype, or conventional spec.
3. Hey, `cabal` asks for SPDX & its module source of truth [Distribution.License](https://hackage.haskell.org/package/Cabal-3.6.2.0/docs/Distribution-License.html) happens to have function: `knownLicenses :: [License]`, it probably should give the index:
```haskell
λ> knownLicenses
[GPL Nothing,GPL (Just (mkVersion [2])),GPL (Just (mkVersion [3])),LGPL Nothing,LGPL (Just (mkVersion [2,1])),LGPL (Just (mkVersion [3])),AGPL Nothing,AGPL (Just (mkVersion [3])),BSD2,BSD3,MIT,ISC,MPL (mkVersion [2,0]),Apache Nothing,Apache (Just (mkVersion [2,0])),PublicDomain,AllRightsReserved,OtherLicense]
it :: [License]
```

(I've tried/experimented to put values literally - maybe that is a universal way of giving the Cabal license values)

```
> cabal v2-build (1)
Errors encountered when parsing cabal file ./project.cabal:

project.cabal:11:35: error:

unexpected Unknown SPDX license identifier: 'AGPL'

10 | maintainer: user@email.com
11 | license: AGPL (Just (mkVersion [3]))
```

`Unknown SPDX license identifier: 'AGPL'` - confusing :confused:, which values then it accepts.

4. Ok Cabal error message always talks about SPDX values.

In [Distribution.License](https://hackage.haskell.org/package/Cabal-3.6.2.0/docs/Distribution-License.html) there is [`licenseToSPDX :: License -> License` - great - a converter to SPDX - which Cabal keept nagging me into:

```
λ> licenseToSPDX AllRightsReserved
NONE
```
It works!

```
licenseToSPDX $ PublicDomain
License (ELicense (ELicenseRef (LicenseRef {_lrDocument = Nothing, _lrLicense = "PublicDomain"})) Nothing)
it :: Distribution.SPDX.License.License
```
Tried the `License ..`, then entered the `ELicense ..` value into `license: ` field, received unhelpful messages.

Checked `PublicDomain` & received a direction toward using anything more substantial then `PublicDomain` value.

Ok, lets check some default open source license:
```
λ> licenseToSPDX $ AGPL (Just (mkVersion [3]))
License (ELicense (ELicenseId AGPL_3_0_only) Nothing)
it :: Distribution.SPDX.License.License
```
Again, now with this SPDX value - tried to enter the `License ..`, then tried to enter `ELicense ..` value into `license: ` field, received unhelpful messages.
```
unexpected Unknown SPDX license identifier: 'License'

10 | maintainer: user@email.com
11 | license: License (ELicense (ELicenseId AGPL_3_0_only) Nothing)
| ^

...
unexpected Unknown SPDX license identifier: 'ELicense'

10 | maintainer: user@email.com
11 | license: ELicense (ELicenseId AGPL_3_0_only) Nothing
```

So, `licenseToSPDX` function was not helpful for the user.

[`Distribution.SPDX.License`](https://hackage.haskell.org/package/Cabal-3.6.2.0/docs/Distribution-SPDX-License.html) points to that `License ...` expression is a SPDX format. But if Cabal wants to get SPDX format, and value is in SPDX format - why Cabal does not accepts the SPDX that is generated with its own functions.

**Expected behavior**

- [ ] Cabal checker error message form should direct Haskeller into proper direction:
- [ ] Since it is Haskellers - to make them perfectly happy (also because people love to read/use code directly more then reading long documentation) - give them info on how to locate where to look in Hoogle or in sources/which module API to look into - to give them direction to the proper source of truth to construct/generate the values that satisfy the checker.
- [ ] Give a function to list simple licenses (unilicenses in Cabal/SPDX expression terms).
- [ ] Have a permalink into listing of the majority (by use cases) of the values accepted & where it explains the corner cases, as `NONE` & directs somewhere in situations with complex licenses.
- [ ] `Alternative`: Link to the source code of the checker, or mention how to find it, so Haskellers can see what constitutes accepted `license: ` values, since SPDX happens to be a DLS language also.
- [ ] Since SPDX is also a DSL language `Maybe` , maybe it is sound to allow SPDX expressions (seems like expressions are allowed, just happens that produced by `licenseToSPDX` expressions are not SPDX expression language), or `Distribution.License` values to be accepted in the `license` field.

**System information**
```
cabal-install version 3.6.2.0
compiled using version 3.6.2.0 of the Cabal library
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.