Skip to content

template-haskell-2.18.0.0 has it's own makeRelativeToProject  #43

@parsonsmatt

Description

@parsonsmatt

Building shakespeare fails with this error:

Text/Shakespeare/Base.hs:288:9: error:
    Ambiguous occurrence ‘makeRelativeToProject’
    It could refer to
       either ‘Language.Haskell.TH.Syntax.makeRelativeToProject’,
              imported from ‘Language.Haskell.TH.Syntax’ at Text/Shakespeare/Base.hs:30:1-33
           or ‘Data.FileEmbed.makeRelativeToProject’,
              imported from ‘Data.FileEmbed’ at Text/Shakespeare/Base.hs:33:24-44
    |
288 |   fp <- makeRelativeToProject rawFp
    |         ^^^^^^^^^^^^^^^^^^^^^

Text/Shakespeare/Base.hs:297:9: error:
    Ambiguous occurrence ‘makeRelativeToProject’
    It could refer to
       either ‘Language.Haskell.TH.Syntax.makeRelativeToProject’,
              imported from ‘Language.Haskell.TH.Syntax’ at Text/Shakespeare/Base.hs:30:1-33
           or ‘Data.FileEmbed.makeRelativeToProject’,
              imported from ‘Data.FileEmbed’ at Text/Shakespeare/Base.hs:33:24-44
    |
297 |   fp <- makeRelativeToProject rawFp
    |         ^^^^^^^^^^^^^^^^^^^^^

Naturally, the implementation is different - in template-haskell-2.18, this is relying on a new method on the Q class, which acccepts the package-root flag.

Details:

There are a few extra flags which have been introduced to make working with multiple
units easier.

.. ghc-flag:: -working-dir ⟨dir⟩
    :shortdesc: Specify the directory a unit is expected to be compiled in.
    :type: dynamic
    :category:

    It is common to assume that a package is compiled in the directory where its
    cabal file resides. Thus, all paths used in the compiler are assumed to be relative
    to this directory. When there are multiple home units the compiler is often
    not operating in the standard directory and instead where the cabal.project
    file is located. In this case the `-working-dir` option can be passed which specifies
    the path from the current directory to the directory the unit assumes to be it's root,
    normally the directory which contains the cabal file.

    When the flag is passed, any relative paths used by the compiler are offset
    by the working directory. Notably this includes `-i`:ghc-flag: and `-I⟨dir⟩`:ghc-flag: flags.


    This option can also be queried by the ``getPackageRoot`` Template Haskell
    function. It is intended to be used with helper functions such as ``makeRelativeToProject``
    which make relative filepaths relative to the compilation directory rather than
    the directory which contains the .cabal file.

Implementation:

-- | Get the package root for the current package which is being compiled.
-- This can be set explicitly with the -package-root flag but is normally
-- just the current working directory.
--
-- The motivation for this flag is to provide a principled means to remove the
-- assumption from splices that they will be executed in the directory where the
-- cabal file resides. Projects such as haskell-language-server can't and don't
-- change directory when compiling files but instead set the -package-root flag
-- appropiately.
getPackageRoot :: Q FilePath
getPackageRoot = Q qGetPackageRoot

-- | The input is a filepath, which if relative is offset by the package root.
makeRelativeToProject :: FilePath -> Q FilePath
makeRelativeToProject fp | isRelative fp = do
  root <- getPackageRoot
  return (root </> fp)
makeRelativeToProject fp = return fp

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions