Skip to content

Commit fe901be

Browse files
committed
Make Cabal agnostic about working directory
This commit makes the library functions in Cabal agnostic of the working directory. In practice, this means that we distinguish `FilePath`s from un-interpreted `SymbolicPath`s. The latter may be paths that are relative to the working directory, and need to be interpreted with respect to a passed-in argument specifying the working directory, instead of using the working directory of the current process. See Note [Symbolic paths] in Distribution.Utils.Path. In particular, paths in the package description now use the SymbolicPath abstraction, which allows specifying whether they are allowed to be absolute, and, if they are relative, what they are relative to. For example, source files are relative to a source search directory, data files are relative to the data directory, and doc files are relative to the package root. Fixes #9702
1 parent 6678b45 commit fe901be

File tree

216 files changed

+9484
-6998
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

216 files changed

+9484
-6998
lines changed

Cabal-described/src/Distribution/Described.hs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ import Distribution.Utils.GrammarRegex
6868
-- Types
6969
import Distribution.Compat.Newtype
7070
import Distribution.Compiler (CompilerFlavor, CompilerId, knownCompilerFlavors)
71-
import Distribution.PackageDescription.FieldGrammar (CompatFilePath, CompatLicenseFile)
71+
import Distribution.PackageDescription.FieldGrammar (CompatLicenseFile, CompatDataDir)
7272
import Distribution.FieldGrammar.Newtypes
7373
import Distribution.ModuleName (ModuleName)
7474
import Distribution.System (Arch, OS, knownArches, knownOSs)
@@ -99,7 +99,7 @@ import Distribution.Types.SourceRepo (RepoType)
9999
import Distribution.Types.TestType (TestType)
100100
import Distribution.Types.UnitId (UnitId)
101101
import Distribution.Types.UnqualComponentName (UnqualComponentName)
102-
import Distribution.Utils.Path (LicenseFile, PackageDir, SourceDir, SymbolicPath)
102+
import Distribution.Utils.Path (SymbolicPath, RelativePath)
103103
import Distribution.Verbosity (Verbosity)
104104
import Distribution.Version (Version, VersionRange)
105105
import Language.Haskell.Extension (Extension, Language, knownLanguages)
@@ -578,17 +578,24 @@ instance Described SpecLicense where
578578
instance Described TestedWith where
579579
describe _ = RETodo
580580

581-
instance Described FilePathNT where
581+
582+
instance Described (SymbolicPath from to) where
583+
describe _ = describe ([] :: [Token])
584+
585+
instance Described (RelativePath from to) where
582586
describe _ = describe ([] :: [Token])
583587

584-
instance Described (SymbolicPath PackageDir SourceDir) where
588+
instance Described (SymbolicPathNT from to) where
585589
describe _ = describe ([] :: [Token])
586590

587-
instance Described (SymbolicPath PackageDir LicenseFile) where
591+
instance Described (RelativePathNT from to) where
588592
describe _ = describe ([] :: [Token])
589593

590594
instance Described CompatLicenseFile where
591595
describe _ = describe ([] :: [Token])
592596

593-
instance Described CompatFilePath where
594-
describe _ = describe ([] :: [Token])
597+
instance Described CompatDataDir where
598+
describe _ = describe ([] :: [Token])
599+
600+
instance Described FilePathNT where
601+
describe _ = describe ([] :: [Token])

Cabal-syntax/Cabal-syntax.cabal

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,13 @@ library
4545
-- See also https://github.com/ekmett/transformers-compat/issues/35
4646
transformers (>= 0.3 && < 0.4) || (>=0.4.1.0 && <0.7)
4747

48-
ghc-options: -Wall -fno-ignore-asserts -fwarn-tabs -fwarn-incomplete-uni-patterns -fwarn-incomplete-record-updates
48+
ghc-options:
49+
-Wall
50+
-fno-ignore-asserts
51+
-fwarn-tabs
52+
-fwarn-incomplete-uni-patterns
53+
-fwarn-incomplete-record-updates
54+
-fno-warn-unticked-promoted-constructors
4955

5056
if impl(ghc >= 8.0)
5157
ghc-options: -Wcompat -Wnoncanonical-monad-instances

Cabal-syntax/src/Distribution/FieldGrammar/Newtypes.hs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
{-# LANGUAGE DataKinds #-}
12
{-# LANGUAGE FlexibleContexts #-}
23
{-# LANGUAGE FlexibleInstances #-}
34
{-# LANGUAGE FunctionalDependencies #-}
5+
{-# LANGUAGE InstanceSigs #-}
46
{-# LANGUAGE OverloadedStrings #-}
57
{-# LANGUAGE RankNTypes #-}
68
{-# LANGUAGE ScopedTypeVariables #-}
@@ -42,6 +44,8 @@ module Distribution.FieldGrammar.Newtypes
4244
, Token' (..)
4345
, MQuoted (..)
4446
, FilePathNT (..)
47+
, SymbolicPathNT (..)
48+
, RelativePathNT (..)
4549
) where
4650

4751
import Distribution.Compat.Newtype
@@ -53,6 +57,7 @@ import Distribution.Compiler (CompilerFlavor)
5357
import Distribution.License (License)
5458
import Distribution.Parsec
5559
import Distribution.Pretty
60+
import Distribution.Utils.Path
5661
import Distribution.Version
5762
( LowerBound (..)
5863
, Version
@@ -277,6 +282,41 @@ instance Parsec FilePathNT where
277282
instance Pretty FilePathNT where
278283
pretty = showFilePath . unpack
279284

285+
-- | Newtype for 'SymbolicPath', with a different 'Parsec' instance
286+
-- to disallow empty paths.
287+
newtype SymbolicPathNT from to = SymbolicPathNT {getSymbolicPathNT :: SymbolicPath from to}
288+
289+
instance Newtype (SymbolicPath from to) (SymbolicPathNT from to)
290+
291+
instance Parsec (SymbolicPathNT from to) where
292+
parsec = do
293+
token <- parsecToken
294+
if null token
295+
then P.unexpected "empty FilePath"
296+
else return (SymbolicPathNT $ makeSymbolicPath token)
297+
298+
instance Pretty (SymbolicPathNT from to) where
299+
pretty = showFilePath . getSymbolicPath . getSymbolicPathNT
300+
301+
-- | Newtype for 'RelativePath', with a different 'Parsec' instance
302+
-- to disallow empty paths but allow non-relative paths (which get rejected
303+
-- later with a different error message, see 'Distribution.PackageDescription.Check.Paths.checkPath')
304+
newtype RelativePathNT from to = RelativePathNT {getRelativePathNT :: RelativePath from to}
305+
306+
instance Newtype (RelativePath from to) (RelativePathNT from to)
307+
308+
-- NB: we don't reject non-relative paths here; we allow them here and reject
309+
-- later (see 'Distribution.PackageDescription.Check.Paths.checkPath').
310+
instance Parsec (RelativePathNT from to) where
311+
parsec = do
312+
token <- parsecToken
313+
if null token
314+
then P.unexpected "empty FilePath"
315+
else return (RelativePathNT $ unsafeMakeSymbolicPath token)
316+
317+
instance Pretty (RelativePathNT from to) where
318+
pretty = showFilePath . getSymbolicPath . getRelativePathNT
319+
280320
-------------------------------------------------------------------------------
281321
-- SpecVersion
282322
-------------------------------------------------------------------------------

0 commit comments

Comments
 (0)