weePickle is a fork of uPickle, stabilized with MiMa and shading. It can be used safely within libraries without causing dependency hell.
Many of Rally Health's libraries need to work with JSON. However, we have found (through long painful experience) that letting them use Play-Json puts us into a particular form of Dependency Hell: the libraries wind up dependent on a specific version of Play-Json, which means that upgrading Play requires upgrading much of our ecosystem, which is a hassle. We want to decouple our libraries from Play as much as possible, to reduce this friction.
So we are encouraging libraries to make use of weePickle instead: it's popular, well-supported and fast.
However, if we allowed libraries to simply pick random versions of uPickle, we'd be right back where we were with Play-Json: if different libraries used different versions, we could wind up with evictions and runtime collisions, since uPickle isn't shaded.
So this is a shaded fork of uPickle. It is hard-shaded (instead of using sbt-assembly or something like that) because uPickle includes macros with hard-coded paths, so automatic shading isn't likely to work correctly.
The upstream https://github.com/lihaoyi/upickle macros serialize some things differently than other common libs like circe and play-json. Many of the differences have well-reasoned motivations, but hinder adoption as a drop-in replacement.
In https://github.com/rallyhealth/weePickle, the macros have been changed to work more like circe and play-json, as described here.
weePickle is based on Mill, not sbt. (There is an sbt file, but it's just for the documentation.) In order to build this, you will need to install Mill:
brew install mill
You can generate an IntelliJ project structure with:
./genIdea.sh
To build the entire system, say:
mill __.compile
In Mill, a single underscore _
is the wildcard, and a double underscore
__
is a recursive wildcard that drills into sub-modules. So the above
formula means "find all modules and submodules, and compile them".
Similarly, to run all unit tests:
mill __.test
To create the JAR files:
mill __.jar
(There's also a __.assembly
task, which I believe creates fatjars,
but I can't see why we would care in this case.)
Mill has one iffy characteristic: when something is broken in the
build.sc
file, it will often fail silently. No errors or anything;
just nothing happens.
When this occurs, the resolve
command tends to be a lifesaver. This
steps back and just shows what tasks would be run by the given
command, and it does generally show the errors.
So for example, when compile seems to be dead in the water, say:
mill resolve __.compile
and it will generally show you what's broken.
uPickle: a simple Scala JSON and Binary (MessagePack) serialization library
If you use uPickle and like it, please support it by donating to lihaoyi's Patreon: