Disclaimer: I’ve written about similar problems but not this specific issue of false forward incompatibility. Solutions were proposed later in the discussion but no one seems to like them. My take is people don’t like change and the arguments against are very similar to those I heard against automated testing back in 2005 (Where I worked tests were done manually by clicking around). Only in this case there are no products (crystal 2.0.0 doesn’t exist) and no tests. Just made up numbers.
Disclaimer: This post contains humor and may cause allergic reactions, priapism or death in people with prexisting sticks up their butts.
Problem
Many shards are adding restrictions on future versions of crystal. Example:
- `crystal (>= 0.34.0, < 2.0.0)` required by `json_mapping 0.1.1`
After a major release this is problematic because
- No one knows if any shard will or won’t work without modification in crystal 2.x, 3.x, n.x. So the version restriction are guesses at best (I would consider it a lie)
- Unmaintained shards stop working (without ignoring crystal version restrictions). It’s fairly common in various languages to have simple libraries that everything depends on unmaintained and without new releases for years but still functioning perfectly. Artificial shards restrictions breaks this and forces maintenance.
- Shards with maintainers are forced to release on crystals release schedule. For open source software with volunteers that’s hard(er) to get everyone on board especially when life happens (new job, new home, baby etc). Some may wait weeks/months/forever for updates.
- Confidence is lost in shard version restrictions. Is it really incompatible or just complaining? Maybe i should always turn it off?
- Arguing ensues in organizations using crystal on how/when to upgrade (I’ve been through these in ruby and more). Real example. Enterprise software was 4 years out of date in php & 2 years in ruby. Do we upgrade the interpreter (compiler for crystal) 1 version at a time or jump several versions? Now hypothetically enter the shards restrictions. Now you need to upgrade every shard with an artificial restriction at the same time (along with dependencies). Want to upgrade one shard at a time? Fuhgeddaboudit. Putting each shard upgrade in it’s own commit with automated testing? Not happening.
git bisect
to tell you which shard upgrade introduced bugs? Impossible because the newer shards may have API changes.
Already this is generating support requests and confusing users from shards with restrictions of <= 1.0.0
after the 1.0.0 release. Expect a greatly increased number of users complaining about broken shard dependencies when 2.0.0 is released .
Let’s take a ruby example and later compare with crystal equivalents.
- A 3 year old sinatra application depends on gems A, B & C
- Normally I could upgrade ruby and most gems will work. Maybe C doesn’t
- The new version of gem C compatible for new ruby interpreters requires API changes. So I upgrade C leaving everything else alone and test it for n days/weeks.
- Next I upgrade the ruby interpreter 1 version at a time. Testing for n days/weeks for each version.
- Done.
Compared to crystal with artificial shards restrictions.
- A 3 year old kemal application depends on shards A, B & C
- A B & C all tell me they can’t run on a new crystal compilers. Enter office politics. Should the warnings be ignored, Do you upgrade everything at once or try to upgrade one at a time? Should we wait for new versions of A & B which don’t have any version available for the newest crystal release?
- Your team decides to wait. 3 weeks pass. During the wait Andrew wanders off and is eating by grue.
- Your berserker gets tired of waiting and attempts to upgrade C. It doesn’t play nicely because the new version specifies a new crystal version is required. She fails her intelligence check and isn’t sure if the dependency is real or just specified that way. While raging she commits an upgrade to C.
Do you use A) Use --ignore-crystal-version and test the upgrade in isolation or B) Upgrade the interpreter at the same time? [Press A or B to continue]
A) Your party decides to use --ignore-crystal-version
- It works but the build/tests and each developer needs to use
--ignore-crystal-version
which is a permanent spell and requires 1000xp. Hopefully someone will remember to remove it later before it causes a critical failure. - Continue your adventure as with the ruby version
- Did everyone remember to remove --ignore-crystal-version within n months? For those that didn’t every time they add a new shard or upgrade roll a d6. On 2-3 an upgrade with an accurate shard restriction slips past and you use a version known not to work. Lose 1-4 hours of time. On 1 your critically fail. The bug was subtle, made it to a live environment and wreaked havoc.
B) Your party decides to upgrade crystal at the same time
-
+10 fatigue/anxiety to each member handling operations.
-
Several forks have popped up with updated shards but no word from the original shards.
-
Do you C) Use a unofficial fork? D) Wait for an official update. [Press C or D to continue]
C) Use an unofficial fork
- Several forks exist. Some claim to fix compatibility with new crystal versions. Others only upgrade shard.yaml. Your wizard casts a divining spell to see which is best. Roll a d6. On 1 you choose a fork controlled by a
russian crime ringillithid. Every computer that runs the new version is under a mind control spell. Lose all your bitcoin.
D) Wait for an official update
- The update never comes. Your party dies of exhaustion from too frequently copulating under an office desk. Next time siesta instead of viagra.
Maybe your experience won’t be as bad, but most games I DM end up with the party dying of exhaustion from excessive copulation. Maybe that’s why my gf’s won’t let me non-leather DM anymore…
Pillowtalk Solutions
- Don’t specify future incompatibility unless you know it’s incompatible. Example. Your working on a maintenance release for a shard A release 1.x.x. Crystal 2.x.x is already out and fails it’s unit tests so a future compatibility restriction is accurate.
- Allow mutable shard restrictions, possibly by putting shard.yaml in it’s own branch of via some other means. When 2.0.0 is released shard.yaml can be updated for all past versions that are incompatible by testing rather than guessing.
- Write shard helper command to test each release and update the shard restrictions. Example logic:
foreach shard release
`git checkout #{tag}`
if `crystal spec`.exit_status != 0
# change shard restriction to <= CRYSTAL_VERSION
# preserving restrictions older than the current version
end
- Bonus xp awarded for testing multiple crystal compilers against each release.
- Bonus xp awarded for generating github/travis configs using matrix tests automating the entire process.
Tags: DnD, Porn, TMI, MTAW (must try at work)