Given a directory structure like this:
.
├── frontend
│ ├── _build/ -- build dir, all files produced by shake, except for Frontend.elm, go here
│ ├── Build.hs -- the build script
│ ├── build.sh -- wrap Build.hs with `stack exec build -- $@`
│ ├── other files ...
│ ├── Frontend.elm -- generated by a rule in Build.hs, `protoc -I../proto --elm_out=. ../proto/frontend.proto`
│ ├── Index.elm -- hand written source file
│ └── other elms ... -- hand written source files
└── proto
└── frontend.proto -- protocol buffer message defination, hand written
Target _build/index.js depends on all .elm files, including Frontend.elm,
but Frontend.elm is generated by a rule in Build.hs,
if I blindly do:
want ["_build/index.js"]
"_build/index.js" %> \out -> do
elms <- filter (not . elmStuff)
<$> (liftIO $ getDirectoryFilesIO "" ["//*.elm"])
need elms
blah blah
want ["Frontend.elm"]
"Frontend.elm" %> \_out -> do
cmd ["protoc", "blah", "blah"]
build.sh clean would give me:
Lint checking error - value has changed since being depended upon:
Key: Frontend.elm
Old: File {mod=0x608CAAF7,size=0x53D,digest=NEQ}
New: File {mod=0x608CAB5B,size=0x53D,digest=NEQ}
Is there a way to tell shake to watch out for the dynamically generated Frontend.elm, maybe build it first so it doesn't change during the rest of the build, I tried priority 100 ("Frontend.elm" %> ...), doesn't work.
You should probably:
getDirectoryFilesIO, which does not track changes to the file system, togetDirectoryFiles, which does.Frontend.elm, which you know you need even if it does not exist in the filesystem yet (hence might not be visible togetDirectoryFiles).wantingFrontend.elm, since you only wanted it as a hack to enable_build/index.js.With these changes, it would look like this:
Caveat lector: I have not tested this solution.