Reputation: 27636
For a quite involved custom Setup
library, I need to manipulate source file location directories:
hsSourceDirs
and then read files from those directories, both directly from Setup.hs
and also indirectly by passing the filenames as string arguments to external programshsSourceDirs
The problem I am facing is that the type of hsSourceDirs
is [SymbolicPath PackageDir SourceDir]
, and I just can't get my head around how to manipulate these SymbolicPath
s. Looking at Distribution.Utils.Path
, the datatype SymbolicPath from to
is exported abstractly only, and the combinators available are:
getSymbolicPath :: SymbolicPath from to -> FilePath
, marked as "avoid using this in new code"sameDirectory :: _ => SymbolicPath from to
unsafeMakeSymbolicPath :: FilePath -> SymbolicPath from to
This leaves me with the only choice of converting immediately from SymbolicPath PackageDir SourceDir
into FilePath
using getSymbolicPath
(that apparently I'm not supposed to be using), doing all file access in terms of that FilePath
, and then producing a new FilePath
starting from e.g. buildDir
, using FilePath
combinators like </>
, ending with a call to unsafeMakeSymbolicPath
. This doesn't feel ideal.
Is there a way to, instead:
Get, perhaps in IO
, perhaps using whatever Cabal context is available in a custom Setup.hs
, the physical FilePath
from a SymbolicPath PackageDir SourceDir
Create, perhaps in IO
, perhaps using whatever Cabal context is available in a custom Setup.hs
, a new SymbolicPath
that points to a new subdirectory (either named explicitly by me, or generated randomly afresh by Cabal) under the build directory
?
Upvotes: 5
Views: 40
Reputation: 51119
Ignore the comment. It was added in the very same commit that first defined the type SymbolicPath
and the function getSymbolicPath
. I think it was a tacit admission that the author thought the whole design was bad and needed to be patched up in some future work. In the current Git HEAD, in comparison to the latest version on Hackage, Cabal-3.10.3.0, the whole design has been retooled, the comment on getSymbolicPath
has been removed, and some explanatory text about using interpretSymbolicPath
or interpretSymbolicPathCWD
has been added. These functions aren't available in Cabal-3.10.3.0.
In Cabal-3.10.3.0, a value of type SymbolicPath PackageDir SourceDir
is a reference to a source directory intended to be accessed in a context where the process's current working directory is the package directory. (The only other variant of this type that's used is SymbolicPath PackageDir LicenseFile
.)
Just take care to switch the current working directory to the package directory (and invoke any external programs with this working directory), and then use getSymbolicPath
to extract a valid relative path to the directories you're interested in. When injecting new directories, try to construct them relative to the package directory, and then use unsafeMakeSymbolicPath
without guilt or shame.
In future versions of Cabal, it looks like there will be a better interface in Distribution.Utils.Path
with improved documentation. See the comments in this recent version of Path.hs
for example. (Note that the implementation is different than in Cabal-3.10.3.0, so don't try to follow the conventions in these comments, just use them as a hint of what's to come in future Cabal version.)
Upvotes: 1