import sys import yaml with open(sys.argv[1]) as fp: data = fp.read() if not data.find("---") == 0: # no head print("NO YAML HEAD FOUND") sys.exit(-1) data = data[3:] head_end = data.find("---") head = data[0:head_end] data = data[head_end+3:] metadata = yaml.safe_load(head) cats = metadata.pop('categories', None) if cats != None: if type(cats) == list: tags = cats elif type(cats) == str: tags = cats.split() tags = list(map(lambda t: t.lower(), tags)) metadata["tags"] = ", ".join(tags) new_data = f"---\n{yaml.dump(metadata, default_flow_style=False)}---{data}" # write it print(f"coverted: categories to tags: {tags} - {sys.argv[1]}") with open(sys.argv[1], "w") as fp: fp.write(new_data) sys.exit(0) if not metadata.get("tags", None): metadata["tags"] = "untagged" new_data = f"---\n{yaml.dump(metadata, default_flow_style=False)}---{data}" print(f"untagged: {sys.argv[1]}") # write it with open(sys.argv[1], "w") as fp: fp.write(new_data) sys.exit(0) print("No changes needed")
3.3 KiB
comments | date | layout | tags | title |
---|---|---|---|---|
true | 2019-01-08 | post | rc, freebsd, haskell | Misplaced inodes - Recurse Center Day # 2 |
I am part of the Winter 2 batch of RC and today is day #2!
One of the (many!!) things I wanted to do at RC was to write more here, but
turns out neglect had broken the code a bit. This blog is generated from bunch
of markdown files using hakyll and I was no longer able to build it on my laptop. At this point I should mention that my laptop is running FreeBSD 13-CURRENT r342798
.
Errors
As most haskell projects, build is managed by stack. On a good day stack build
is all one need to build the project. stack takes care of setting up the compiler, downloading imported libraries and so on.
Not today..
Cabal-simple_mPHDZzAJ_1.24.2.0_ghc-8.0.2: No cabal file found.
Please create a package description file <pkgname>.cabal
That's weird, also not very helpful - because it has nothing do with the code I wrote.
Knee-Jerk solutions
My first thought after the usual fast solutions (updating stack and moving to a newer lts etc) was to ditch stack altogether and use cabal to build the
package, this proved to be a bit risky because I have haskell packages (like
xmonad) installed using pkg(7)
from freebsd package repo, and cabal was not
happy about them. I could have maybe made it work with sandboxes but I am not
familiar with them and decided to keep that as a backup plan.
Reproducing errors
Next step was to reproduce the error on a smaller project, turns out stack new test && cd test && stack build
raises the same error. So its not the code base
but the entire toolchain that's broken 😰
Armed with this information and web-search-foo lead me to this github issue, and one key work stood out ino64
change.
inodes
are datastructures that hold metadata information about an object in the filesystem. FreeBSD used to use 32bit value to hold this limiting number of objects you could have in the file system to 2^32. ino64 change expands this to 64bit. However this made all pre-compiled ghc versions stack downloads incompatible with FreeBSD versions >= 12.
Since inode structures are different ghc was somehow not able find files! 🛑
The solution
Even though there is a patch landed for this problem in stack, it didn't make it
to the latest release v1.9.3
.
So I opted to use the system-ghc for my build by adding following in stack.yaml
system-ghc: true
However this line doesn't have any effect unless you are on a resolver
that uses the system ghc version, so I downgraded the resolver to lts-12.26
that uses ghc version 8.4.4
installed from ports.
And ... builds are back! 🥳
Reflections
- The
stack
fix is landed on master, so next release should fix it (I did not test it). - A fellow freebsd haskeller suggested looking at ghcup, they don't support FreeBSD atm, but I like the idea of having a lightweight tool to manage different ghc versions.
stack
is ports is outdated (v1.7.1
) and seems to be unmaintained, I should probably try to fix it. 🙂