@@ -35,10 +35,12 @@ module Distribution.Utils.Path
35
35
-- * Symbolic paths
36
36
, RelativePath
37
37
, SymbolicPath
38
+ , AbsolutePath (.. )
38
39
, SymbolicPathX -- NB: constructor not exposed, to retain type safety.
39
40
40
41
-- ** Symbolic path API
41
42
, getSymbolicPath
43
+ , getAbsolutePath
42
44
, sameDirectory
43
45
, makeRelativePathEx
44
46
, makeSymbolicPath
@@ -48,6 +50,7 @@ module Distribution.Utils.Path
48
50
, relativeSymbolicPath
49
51
, symbolicPathRelative_maybe
50
52
, interpretSymbolicPath
53
+ , interpretSymbolicPathAbsolute
51
54
52
55
-- ** General filepath API
53
56
, (</>)
@@ -215,6 +218,11 @@ type RelativePath = SymbolicPathX 'OnlyRelative
215
218
-- until we interpret them (using e.g. 'interpretSymbolicPath').
216
219
type SymbolicPath = SymbolicPathX 'AllowAbsolute
217
220
221
+ newtype AbsolutePath (to :: FileOrDir ) = AbsolutePath (forall from . SymbolicPath from to )
222
+
223
+ unsafeMakeAbsolutePath :: FilePath -> AbsolutePath to
224
+ unsafeMakeAbsolutePath fp = AbsolutePath (makeSymbolicPath fp)
225
+
218
226
instance Binary (SymbolicPathX allowAbsolute from to )
219
227
instance
220
228
(Typeable allowAbsolute , Typeable from , Typeable to )
@@ -320,6 +328,12 @@ interpretSymbolicPath mbWorkDir (SymbolicPath p) =
320
328
interpretSymbolicPathCWD :: SymbolicPathX allowAbsolute from to -> FilePath
321
329
interpretSymbolicPathCWD (SymbolicPath p) = p
322
330
331
+ getAbsolutePath :: AbsolutePath to -> FilePath
332
+ getAbsolutePath (AbsolutePath p) = getSymbolicPath p
333
+
334
+ interpretSymbolicPathAbsolute :: AbsolutePath (Dir Pkg ) -> SymbolicPathX allowAbsolute Pkg to -> FilePath
335
+ interpretSymbolicPathAbsolute (AbsolutePath p) sym = interpretSymbolicPath (Just p) sym
336
+
323
337
-- | Change what a symbolic path is pointing to.
324
338
coerceSymbolicPath :: SymbolicPathX allowAbsolute from to1 -> SymbolicPathX allowAbsolute from to2
325
339
coerceSymbolicPath = coerce
@@ -343,9 +357,9 @@ symbolicPathRelative_maybe (SymbolicPath fp) =
343
357
else Just $ SymbolicPath fp
344
358
345
359
-- | Absolute path to the current working directory.
346
- absoluteWorkingDir :: Maybe (SymbolicPath CWD to ) -> IO FilePath
347
- absoluteWorkingDir Nothing = Directory. getCurrentDirectory
348
- absoluteWorkingDir (Just wd) = Directory. makeAbsolute $ getSymbolicPath wd
360
+ absoluteWorkingDir :: Maybe (SymbolicPath CWD to ) -> IO ( AbsolutePath to )
361
+ absoluteWorkingDir Nothing = unsafeMakeAbsolutePath <$> Directory. getCurrentDirectory
362
+ absoluteWorkingDir (Just wd) = unsafeMakeAbsolutePath <$> Directory. makeAbsolute ( getSymbolicPath wd)
349
363
350
364
-- | Try to make a symbolic path relative.
351
365
--
@@ -354,8 +368,8 @@ absoluteWorkingDir (Just wd) = Directory.makeAbsolute $ getSymbolicPath wd
354
368
-- NB: this function may fail to make the path relative.
355
369
tryMakeRelative :: Maybe (SymbolicPath CWD (Dir dir )) -> SymbolicPath dir to -> IO (SymbolicPath dir to )
356
370
tryMakeRelative mbWorkDir (SymbolicPath fp) = do
357
- wd <- absoluteWorkingDir mbWorkDir
358
- return $ SymbolicPath (FilePath. makeRelative wd fp)
371
+ AbsolutePath wd <- absoluteWorkingDir mbWorkDir
372
+ return $ SymbolicPath (FilePath. makeRelative (getSymbolicPath wd) fp)
359
373
360
374
-------------------------------------------------------------------------------
361
375
@@ -425,6 +439,16 @@ instance
425
439
where
426
440
SymbolicPath p1 </> SymbolicPath p2 = SymbolicPath (p1 </> p2)
427
441
442
+ instance
443
+ (b1 ~ 'Dir b2 , c2 ~ c3 , midAbsolute ~ OnlyRelative )
444
+ => PathLike
445
+ (AbsolutePath b1 )
446
+ (SymbolicPathX midAbsolute b2 c2 )
447
+ (AbsolutePath c3 )
448
+ where
449
+ AbsolutePath (SymbolicPath p1) </> SymbolicPath p2 =
450
+ unsafeMakeAbsolutePath (p1 </> p2)
451
+
428
452
--------------------------------------------------------------------------------
429
453
-- Abstract directory locations.
430
454
0 commit comments