Commit 0d6343ac authored by Oleg Grenrus's avatar Oleg Grenrus

Remove fields in cabal spec 3.0

- extensions
- (singular) hs-source-dir
- build-tools

Example, with `cabal-version: 2.5`

```
[laptop] tree-diff % cabal new-build --dry
Errors encountered when parsing cabal file ./tree-diff.cabal:

tree-diff.cabal:59:3: error:
The field "extensions" is removed in the Cabal specification version 2.5. Please use 'default-extensions' or 'other-extensions' fields.

   58 | library
   59 |   extensions: CPP
      |   ^

tree-diff.cabal:60:3: error:
The field "extensions" is removed in the Cabal specification version 2.5. Please use 'default-extensions' or 'other-extensions' fields.

   59 |   extensions: CPP
   60 |   extensions: DeriveGeneric
      |   ^
```

I needed to add new CabalSpecVersion to properly issue deprecation
messages of `extensions`.
parent 19a26564
......@@ -59,6 +59,8 @@ extra-source-files:
tests/ParserTests/errors/noVersion2.errors
tests/ParserTests/errors/range-ge-wild.cabal
tests/ParserTests/errors/range-ge-wild.errors
tests/ParserTests/errors/removed-fields.cabal
tests/ParserTests/errors/removed-fields.errors
tests/ParserTests/errors/spdx-1.cabal
tests/ParserTests/errors/spdx-1.errors
tests/ParserTests/errors/spdx-2.cabal
......
......@@ -95,6 +95,13 @@ class FieldGrammar g where
-> g s a
-> g s a
-- | Removed in. If we occur removed field, parsing fails.
removedIn
:: CabalSpecVersion -- ^ version
-> String -- ^ removal message
-> g s a
-> g s a
-- | Annotate field with since spec-version.
availableSince
:: CabalSpecVersion -- ^ spec version
......
......@@ -82,5 +82,6 @@ instance FieldGrammar FieldDescrs where
prefixedFields _fnPfx _l = F mempty
knownField _ = pure ()
deprecatedSince _ _ x = x
removedIn _ _ x = x
availableSince _ _ = id
hiddenField _ = F mempty
......@@ -72,8 +72,8 @@ import Distribution.Simple.Utils (fromUTF8BS)
import Prelude ()
import qualified Data.ByteString as BS
import qualified Data.Set as Set
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import qualified Text.Parsec as P
import qualified Text.Parsec.Error as P
......@@ -253,8 +253,33 @@ instance FieldGrammar ParsecFieldGrammar where
"The field " <> show name <> " is deprecated in the Cabal specification version " ++ showCabalSpecVersion vs ++ ". " ++ msg
parser v values
| otherwise = parser v values
removedIn vs msg (ParsecFG names prefixes parser) = ParsecFG names prefixes parser' where
parser' v values
| v >= vs = do
let msg' = if null msg then "" else ' ' : msg
let unknownFields = Map.intersection values $ Map.fromSet (const ()) names
let namePos =
[ (name, pos)
| (name, fields) <- Map.toList unknownFields
, MkNamelessField pos _ <- fields
]
let makeMsg name = "The field " <> show name <> " is removed in the Cabal specification version " ++ showCabalSpecVersion vs ++ "." ++ msg'
case namePos of
-- no fields => proceed (with empty values, to be sure)
[] -> parser v mempty
-- if there's single field: fail fatally with it
((name, pos) : rest) -> do
for_ rest $ \(name', pos') -> parseFailure pos' $ makeMsg name'
parseFatalFailure pos $ makeMsg name
| otherwise = parser v values
knownField fn = ParsecFG (Set.singleton fn) Set.empty (\_ _ -> pure ())
hiddenField = id
......
......@@ -75,7 +75,11 @@ instance FieldGrammar PrettyFieldGrammar where
]
knownField _ = pure ()
deprecatedSince _ _ x = x
deprecatedSince _ _ x = x
-- TODO: as PrettyFieldGrammar isn't aware of cabal-version: we output the field
-- this doesn't affect roundtrip as `removedIn` fields cannot be parsed
-- so invalid documents can be only manually constructed.
removedIn _ _ x = x
availableSince _ _ = id
hiddenField _ = PrettyFG (\_ -> mempty)
......
......@@ -380,6 +380,8 @@ buildInfoFieldGrammar = BuildInfo
<*> monoidalFieldAla "build-tools" (alaList CommaFSep) L.buildTools
^^^ deprecatedSince CabalSpecV2_0
"Please use 'build-tool-depends' field"
^^^ removedIn CabalSpecV3_0
"Please use 'build-tool-depends' field."
<*> monoidalFieldAla "build-tool-depends" (alaList CommaFSep) L.buildToolDepends
-- {- ^^^ availableSince [2,0] [] -}
-- here, we explicitly want to recognise build-tool-depends for all Cabal files
......@@ -414,6 +416,8 @@ buildInfoFieldGrammar = BuildInfo
<*> monoidalFieldAla "extensions" (alaList' FSep MQuoted) L.oldExtensions
^^^ deprecatedSince CabalSpecV1_12
"Please use 'default-extensions' or 'other-extensions' fields."
^^^ removedIn CabalSpecV3_0
"Please use 'default-extensions' or 'other-extensions' fields."
<*> monoidalFieldAla "extra-libraries" (alaList' VCat Token) L.extraLibs
<*> monoidalFieldAla "extra-ghci-libraries" (alaList' VCat Token) L.extraGHCiLibs
<*> monoidalFieldAla "extra-bundled-libraries" (alaList' VCat Token) L.extraBundledLibs
......@@ -443,6 +447,7 @@ hsSourceDirsGrammar = (++)
<*> monoidalFieldAla "hs-source-dir" (alaList' FSep FilePathNT) wrongLens
--- https://github.com/haskell/cabal/commit/49e3cdae3bdf21b017ccd42e66670ca402e22b44
^^^ deprecatedSince CabalSpecV1_2 "Please use 'hs-source-dirs'"
^^^ removedIn CabalSpecV3_0 "Please use 'hs-source-dirs' field."
where
-- TODO: make pretty printer aware of CabalSpecVersion
wrongLens :: Functor f => LensLike' f BuildInfo [FilePath]
......
......@@ -13,7 +13,10 @@ Most directives have at least following optional arguments
`:deprecated: 1.24`
`:deprecated:`
Feature was deprecatead, and optionally since which version.
Feature was deprecated, and optionally since which version.
`:removed: 3.0`
Feature was removed
`:synopsis: Short desc`
Text used as short description on reference page.
......@@ -164,12 +167,14 @@ class Meta(object):
def __init__(self,
since=None,
deprecated=None,
removed=None,
synopsis=None,
title=None,
section=None,
index=0):
self.since = since
self.deprecated = deprecated
self.removed = removed
self.synopsis = synopsis
self.title = title
self.section = section
......@@ -213,6 +218,7 @@ class CabalSection(Directive):
option_spec = {
'name': lambda x: x,
'deprecated': parse_deprecated,
'removed': StrictVersion,
'since' : StrictVersion,
'synopsis' : lambda x:x,
}
......@@ -259,6 +265,7 @@ class CabalSection(Directive):
meta = Meta(since=self.options.get('since'),
deprecated=self.options.get('deprecated'),
removed=self.options.get('removed'),
synopsis=self.options.get('synopsis'),
index = num,
title = title)
......@@ -274,6 +281,7 @@ class CabalObject(ObjectDescription):
option_spec = {
'noindex' : directives.flag,
'deprecated': parse_deprecated,
'removed' : StrictVersion,
'since' : StrictVersion,
'synopsis' : lambda x:x
}
......@@ -299,6 +307,7 @@ class CabalObject(ObjectDescription):
title = find_section_title(self.state.parent)
return Meta(since=self.options.get('since'),
deprecated=self.options.get('deprecated'),
removed=self.options.get('removed'),
title=title,
index = num,
synopsis=self.options.get('synopsis'))
......@@ -409,6 +418,18 @@ class CabalObject(ObjectDescription):
field += field_body
field_list.insert(0, field)
if self.cabal_meta.removed is not None:
field = nodes.field('')
field_name = nodes.field_name('Removed', 'Removed')
if isinstance(self.cabal_meta.removed, StrictVersion):
since = 'Cabal ' + str(self.cabal_meta.removed)
else:
since = ''
field_body = nodes.field_body(since, nodes.paragraph(since, since))
field += field_name
field += field_body
field_list.insert(0, field)
return result
class CabalPackageSection(CabalObject):
......@@ -459,6 +480,7 @@ class CabalField(CabalObject):
option_spec = {
'noindex' : directives.flag,
'deprecated': parse_deprecated,
'removed' : StrictVersion,
'since' : StrictVersion,
'synopsis' : lambda x:x
}
......@@ -702,6 +724,11 @@ def render_deprecated(deprecated):
else:
return 'deprecated'
def render_removed(deprecated, removed):
if isinstance(deprecated, StrictVersion):
return 'removed in: ' + str(removed) + '; deprecated since: '+str(deprecated)
else:
return 'removed in: ' + str(removed)
def render_meta(meta):
'''
......@@ -709,6 +736,8 @@ def render_meta(meta):
Will render either deprecated or since info
'''
if meta.removed is not None:
return render_removed(meta.deprecated, meta.removed)
if meta.deprecated is not None:
return render_deprecated(meta.deprecated)
elif meta.since is not None:
......
......@@ -2173,7 +2173,8 @@ system-dependent values for these fields.
:pkg-field:`other-extensions` declarations.
.. pkg-field:: extensions: identifier list
:deprecated:
:deprecated: 1.12
:removed: 3.0
Deprecated in favor of :pkg-field:`default-extensions`.
......@@ -2230,7 +2231,8 @@ system-dependent values for these fields.
compatibility.
.. pkg-field:: build-tools: program list
:deprecated:
:deprecated: 2.0
:removed: 3.0
Deprecated in favor of :pkg-field:`build-tool-depends`, but :ref:`see below for backwards compatibility information <buildtoolsbc>`.
......
......@@ -22,13 +22,16 @@ relative to the respective preceding *published* version.
``cabal-version: 3.0``
----------------------
* Added the `extra-dynamic-library-flavours` field to specify non-trivial
variants of dynamic flavours. It is `extra-library-flavours` but for
* Added the :pkg-field:`extra-dynamic-library-flavours` field to specify non-trivial
variants of dynamic flavours. It is :pkg-field:`extra-library-flavours` but for
shared libraries. Mainly useful for GHC's RTS library.
* License fields use identifiers from SPDX License List version
``3.3 2018-10-24``
* Remove deprecated ``hs-source-dir``, :pkg-field:`extensions` and
:pkg-field:`build-tools` fields.
``cabal-version: 2.4``
----------------------
......
......@@ -106,6 +106,7 @@ errorTests = testGroup "errors"
, errorTest "spdx-1.cabal"
, errorTest "spdx-2.cabal"
, errorTest "spdx-3.cabal"
, errorTest "removed-fields.cabal"
]
errorTest :: FilePath -> TestTree
......
cabal-version: 2.5
name: removed-fields
version: 0
synopsis: some fields are removed
build-type: Simple
library
default-language: Haskell2010
exposed-modules: RemovedFields
build-depends: base, containers
extensions: CPP
extensions: DeriveFunctor
VERSION: Just (mkVersion [2,5])
removed-fields.cabal:13:3: The field "extensions" is removed in the Cabal specification version 3.0. Please use 'default-extensions' or 'other-extensions' fields.
removed-fields.cabal:14:3: The field "extensions" is removed in the Cabal specification version 3.0. Please use 'default-extensions' or 'other-extensions' fields.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment