static folder not found when Yesod app run from monorepo using cabal.project
Closed this issue · 4 comments
I'm on NixOS 23.05 and using Cabal to manage a monorepo (using cabal.project
) with a Yesod app project (let's call it myyesod
) inside it. I noticed that starting the app with cabal run myproject
from the monorepo repository root folder fails with
monorepo$ cabal run myyesod
myyesod: static: getDirectoryContents:openDirStream: does not exist (No such file or directory)
while running it from the myyesod
project (sub)folder works fine:
monorepo/myyesod$ cabal run myyesod
...
Preprocessing executable 'myyesod' for myyesod-0.0.0..
Building executable 'myyesod' for myyesod-0.0.0
I do not understand Yesod deep enough (yet) to create a fix myself, but i hope someone else might be able to. At least there's a workaround by just switching into the project folder for now.
Steps to reproduce: I got error when testing with the Yesod example project https://github.com/yesodweb/yesod-scaffold/tree/sqlite
inside a monorepo using stack new myyesod yesodweb/sqlite
and adding that folder to cabal.project
. I got the following Haskell package versions:
yesod 1.6.2.1
yesod-static 1.6.1.0
yesod-auth 1.6.11.1
yesod-core 1.6.24.4
yesod-form 1.7.4
yesod-newsfeed 1.7.0.0
yesod-persistent 1.6.0.8
The static dir is defined in config/settings.yml
(at least in my project) as:
static-dir: "_env:YESOD_STATIC_DIR:static"
So unless there is a env variable defined, Yesod uses the relative path static
. That means you have to start your app from the correct directory. Or you export an env variable.
I see. This still feels inconsistent however, because other project-relative paths like config/settings.yaml
(see definition)
-- | Raw bytes at compile time of @config/settings.yml@
configSettingsYmlBS :: ByteString
configSettingsYmlBS = $(embedFile configSettingsYml)
are found and loaded correctly from outside the project (i.e. from the monorepo root).
Are you sure that config/settings.yml
is converted to an absolute path? I haven't looked up the definition of embedFile
but it looks like the file is read and embedded at compile time; compilation is usually done from the project root.
Ah that makes sense. At compile time a relative project path can be resolved. At runtime the app can only know relative paths relative to the process working directory.