Cactus
Cactus

Reputation: 27636

How to create `SymbolicPath`s?

For a quite involved custom Setup library, I need to manipulate source file location directories:

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 SymbolicPaths. Looking at Distribution.Utils.Path, the datatype SymbolicPath from to is exported abstractly only, and the combinators available are:

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:

?

Upvotes: 5

Views: 40

Answers (1)

K. A. Buhr
K. A. Buhr

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

Related Questions