Thank you for the reply. I appreciate the information. I’ve run some tests with an error I have at the moment that seems to trigger the elm: not enough bytes
issue. My steps are (having killed my webpack process):
Not enough bytes error
$ rm -fr node_modules
$ yarn
...
$ which elm
/home/michael/root/projects/hive/server/portal/node_modules/.bin//elm
$ file /home/michael/root/projects/hive/server/portal/node_modules/.bin//elm
/home/michael/root/projects/hive/server/portal/node_modules/.bin//elm: symbolic link to ../elm/bin/elm
$ cd server/apps/business
$ rm -fr elm-stuff
$ elm make src/Business.elm
Dependencies loaded from local cache.
Dependencies ready!
Detected errors in 1 module.
-- TYPE MISMATCH ------------------------------- ./src/Business/Report/Tasks.elm
This function cannot handle the argument sent through the (|>) pipe:
91| getPostIdFromReportId session reportId
92|> |> Task.andThen
93|> (\postId ->
94|> Api.readTask
95|> { endpoint = Api.endpoint [ "api", "posts", postId, "comments" ] []
96|> , body = Http.emptyBody
97|> , success = Api.JsonBody <| Decode.field "comments" (Decode.list commentDecoder)
98|> , failure = Zap.Http.noExpectedErrorsHandler
99|> , session = session
100|> }
101| )
The argument is:
Api.Task () Post.Id
But (|>) is piping it a function that expects:
Task.Task (Zap.Http.Error ()) String
$ elm make src/Business.elm
elm: not enough bytes
CallStack (from HasCallStack):
error, called at src/Data/Binary.hs:212:21 in binary-0.8.6.0-1SWOkUSZj1B1k0FQ5fyFqI:Data.Binary
This error seems quite reproducible as I experienced it, fixed it, worked on another branch, returned to this, removed the fix and I get it again.
The State of Elmi & Elmo
If I run a script to detect missing elmi or elmo files:
#!/bin/bash -e
for elmo in $(ls elm-stuff/0.19.0/*.elmo); do
# echo $elmo
elmi=$(echo $elmo | sed 's/elmo$/elmi/')
if [ ! -e "$elmi" ]; then
echo "$elmi doesn't exist"
fi
done
for elmi in $(ls elm-stuff/0.19.0/*.elmi); do
# echo $elmo
elmo=$(echo $elmi | sed 's/elmi$/elmo/')
if [ ! -e "$elmo" ]; then
echo "$elmo doesn't exist"
fi
done
Then I get:
$ bash ./check-stuff
elm-stuff/0.19.0/Zap-View-Action.elmo doesn't exist
Deleting unmatched files
This takes a bit of time so I’ve attempted to improve it to something that runs quicker and cleans up the problematic files. I’m no expert though so this could have issues and I’m sure there is room for improvement:
elmoFiles=$(mktemp /tmp/elmo.XXXX)
elmiFiles=$(mktemp /tmp/elmo.XXXX)
ls -1 elm-stuff/0.19.0/*.elmo > $elmoFiles
ls -1 elm-stuff/0.19.0/*.elmi | sed 's/elmi/elmo/' > $elmiFiles
# Include tmp files so that we always have something and we clean up after ourselves
diff $elmoFiles $elmiFiles | tail -n +2 | sed 's/> //' | sed 's/elmo/elmi/' | xargs rm -f $elmoFiles $elmiFiles
Wrapping the compiler with flock
I’ve also created script to replace the node_modules/.bin/elm
symbolic link with a script that uses flock as you’ve suggested. The final result incorporate the cleanup above and looks like this:
#!/bin/bash -e
nodeModulesFolder=$(dirname $(dirname $0))
(
flock -e 200
# Delete all elmi files that don't have matching elmo file
elmoFiles=$(mktemp /tmp/elmo.XXXX)
elmiFiles=$(mktemp /tmp/elmo.XXXX)
ls -1 elm-stuff/0.19.0/*.elmo > $elmoFiles
ls -1 elm-stuff/0.19.0/*.elmi | sed 's/elmi/elmo/' > $elmiFiles
# Include tmp files so that we always have something and we clean up after ourselves
diff $elmoFiles $elmiFiles | tail -1 | sed 's/> //' | sed 's/elmo/elmi/' | xargs rm -f
$nodeModulesFolder/elm/bin/elm $@
) 200>/tmp/elm.lockfile
I don’t know how flock is meant to work so I’m just guessing from your example but it seems promising (note the ampersand after the first command):
$ elm make src/Business.elm &; elm make src/Business.elm
[1] 10755
Detected errors in 1 module.
-- TYPE MISMATCH ------------------------------- ./src/Business/Report/Tasks.elm
This function cannot handle the argument sent through the (|>) pipe:
91| getPostIdFromReportId session reportId
92|> |> Task.andThen
93|> (\postId ->
94|> Api.readTask
95|> { endpoint = Api.endpoint [ "api", "posts", postId, "comments" ] []
96|> , body = Http.emptyBody
97|> , success = Api.JsonBody <| Decode.field "comments" (Decode.list commentDecoder)
98|> , failure = Zap.Http.noExpectedErrorsHandler
99|> , session = session
100|> }
101| )
The argument is:
Api.Task () Post.Id
But (|>) is piping it a function that expects:
Task.Task (Zap.Http.Error ()) String
Detected errors in 1 module.
-- TYPE MISMATCH ------------------------------- ./src/Business/Report/Tasks.elm
This function cannot handle the argument sent through the (|>) pipe:
91| getPostIdFromReportId session reportId
92|> |> Task.andThen
93|> (\postId ->
94|> Api.readTask
95|> { endpoint = Api.endpoint [ "api", "posts", postId, "comments" ] []
96|> , body = Http.emptyBody
97|> , success = Api.JsonBody <| Decode.field "comments" (Decode.list commentDecoder)
98|> , failure = Zap.Http.noExpectedErrorsHandler
99|> , session = session
100|> }
101| )
The argument is:
Api.Task () Post.Id
But (|>) is piping it a function that expects:
Task.Task (Zap.Http.Error ()) String
[1] + exit 1 elm make src/Business.elm
Without the wrapper this looks much less happy.
Helper script to wrap compiler
Here is a script that I run to wrap the compiler. Useful as a yarn re-install will lose it.
#!/bin/bash -e
rm -f node_modules/.bin/elm
cat << ENDCAT > node_modules/.bin/elm
#!/bin/bash -e
nodeModulesFolder=\$(dirname \$(dirname \$0))
(
flock -e 200
# Delete all elmi files that don't have matching elmo file
elmoFiles=\$(mktemp /tmp/elmo.XXXX)
elmiFiles=\$(mktemp /tmp/elmo.XXXX)
ls -1 elm-stuff/0.19.0/*.elmo > \$elmoFiles
ls -1 elm-stuff/0.19.0/*.elmi | sed 's/elmi/elmo/' > \$elmiFiles
# Include tmp files so that we always have something and we clean up after ourselves
diff \$elmoFiles \$elmiFiles | tail -n +2 | sed 's/> //' | sed 's/elmo/elmi/' | xargs rm -f \$elmoFiles \$elmiFiles
\$nodeModulesFolder/elm/bin/elm \$@
) 200>/tmp/elm.lockfile
ENDCAT
chmod +x node_modules/.bin/elm
I’ve only just been playing around with them and maybe there are other kinds of this error that this doesn’t handle but it seems promising and perhaps this will be useful to someone. I’ll update I experience issues. I fear that my excitement at messing around with this stuff as won over my better judgement that I should only post about this when it has been tested a bit more.