Skip to content

Instantly share code, notes, and snippets.

@thomcc
Created April 2, 2021 10:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomcc/45a889aff489f7ec38a2f3827cb00239 to your computer and use it in GitHub Desktop.
Save thomcc/45a889aff489f7ec38a2f3827cb00239 to your computer and use it in GitHub Desktop.
bash function to resolve a crate version in a terrible way
# helper fn that returns version number given $crate or $crate/$semver.
# both must be url-encoded but the / must be a / if provided.
# doesn't handle cases where the version/crate/whatever doesn't exist.
resolve_version() {
# Perform `HEAD` request to `docs.rs/$1` and dump the redirected URL.
# We expect this to go to `docs.rs/crate/$crate/$version`
# or `docs.rs/$crate/$version/$crate/` depending on if the crate has
# docs or idrk. Maybe a couple other urls are possible, it
# took a bit of testing for the `sed` script to handle all cases I found.
#
# Examples:
#
# `resolve_version bindgen` => 0.54.1
# `resolve_version "bindgen/0.54"` => 0.54.1
#
# Note that the thing after the slash can be any semver version
# requirement (you must % encode it first though): e.g. '>0.49.1,<=0.52':
# `resolve_version "bindgen/%3e0.49.1%2c%3c%3d0.52"` => 0.52.0
# see https://docs.rs/semver/0.10.0/semver/#requirements for details.
#
# The one caveat is that if you provide an exact version, e.g. `0.50.1`,
# usually it is treated as `^0.50.1`, but docs.rs treats it as `=0.50.1`.
#
# So to get the newest compatible version of something, you must
# have an explicit ^ (or, rather, %5e). That is:
#
# `resolve_version bindgen/0.54.0` => 0.54.0
# `resolve_version bindgen/%5e0.54.0` => 0.54.1
#
# I made a joke about this to the owner of docs.rs, and he indicated
# that this is a cheap operation for them and that he doesn't really
# mind if people use it to resolve versions. That said, see below
# for some thoughts on how we can avoid abusing this good will.
curl -Isw '%{redirect_url}' -o /dev/null "https://docs.rs/$1" \
| sed -E 's=^https://docs.rs/(crate/)?[^/]+/==g ; s=/.+==g'
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment