crev

Don't waste time reviewing crates.

Make it count instead!

Presented at Vienna Rust Meetup 2020-03-30 and Rust Zürisee Meetup 2020-04-30 by chrysn <chrysn@fsfe.org>

Problem

Dependency trees

$ cargo tree --no-dev-dependencies
annex-to-web v0.1.0 (/home/chrysn/git/annex-to-web)
├── async-std v1.4.0
│   ├── async-task v1.3.0
│   │   └── libc v0.2.66
│   ├── crossbeam-channel v0.4.0
│   │   └── crossbeam-utils v0.7.0
│   │       ├── cfg-if v0.1.10
│   │       └── lazy_static v1.4.0
│   │       [build-dependencies]
│   │       └── autocfg v0.1.7
│   ├── crossbeam-deque v0.7.2
│   │   ├── crossbeam-epoch v0.8.0
│   │   │   ├── cfg-if v0.1.10 (*)
│   │   │   ├── crossbeam-utils v0.7.0 (*)
│   │   │   ├── lazy_static v1.4.0 (*)
│   │   │   ├── memoffset v0.5.3
│   │   │   │   [build-dependencies]
│   │   │   │   └── rustc_version v0.2.3
│   │   │   │       └── semver v0.9.0
│   │   │   │           └── semver-parser v0.7.0
│   │   │   └── scopeguard v1.0.0
│   │   │   [build-dependencies]
│   │   │   └── autocfg v0.1.7 (*)
│   │   └── crossbeam-utils v0.7.0 (*)
│   ├── crossbeam-utils v0.7.0 (*)
│   ├── futures-core v0.3.1
│   ├── futures-io v0.3.1
│   ├── futures-timer v2.0.2
│   ├── kv-log-macro v1.0.4
│   │   └── log v0.4.8
│   │       └── cfg-if v0.1.10 (*)
│   ├── log v0.4.8 (*)
│   ├── memchr v2.3.0
│   ├── mio v0.6.21
│   │   ├── cfg-if v0.1.10 (*)
│   │   ├── iovec v0.1.4
│   │   │   └── libc v0.2.66 (*)
│   │   ├── libc v0.2.66 (*)
│   │   ├── log v0.4.8 (*)
│   │   ├── net2 v0.2.33
│   │   │   ├── cfg-if v0.1.10 (*)
│   │   │   └── libc v0.2.66 (*)
│   │   └── slab v0.4.2
│   ├── mio-uds v0.6.7
│   │   ├── iovec v0.1.4 (*)
│   │   ├── libc v0.2.66 (*)
│   │   └── mio v0.6.21 (*)
│   ├── num_cpus v1.12.0
│   │   └── libc v0.2.66 (*)
│   ├── once_cell v1.3.1
│   ├── pin-project-lite v0.1.4
│   ├── pin-utils v0.1.0-alpha.4
│   └── slab v0.4.2 (*)
├── futures v0.3.1
│   ├── futures-channel v0.3.1
│   │   ├── futures-core v0.3.1 (*)
│   │   └── futures-sink v0.3.1
│   ├── futures-core v0.3.1 (*)
│   ├── futures-executor v0.3.1
│   │   ├── futures-core v0.3.1 (*)
│   │   ├── futures-task v0.3.1
│   │   └── futures-util v0.3.1
│   │       ├── futures-channel v0.3.1 (*)
│   │       ├── futures-core v0.3.1 (*)
│   │       ├── futures-io v0.3.1 (*)
│   │       ├── futures-macro v0.3.1
│   │       │   ├── proc-macro-hack v0.5.11
│   │       │   │   ├── proc-macro2 v1.0.8
│   │       │   │   │   └── unicode-xid v0.2.0
│   │       │   │   ├── quote v1.0.2
│   │       │   │   │   └── proc-macro2 v1.0.8 (*)
│   │       │   │   └── syn v1.0.14
│   │       │   │       ├── proc-macro2 v1.0.8 (*)
│   │       │   │       ├── quote v1.0.2 (*)
│   │       │   │       └── unicode-xid v0.2.0 (*)
│   │       │   ├── proc-macro2 v1.0.8 (*)
│   │       │   ├── quote v1.0.2 (*)
│   │       │   └── syn v1.0.14 (*)
│   │       ├── futures-sink v0.3.1 (*)
│   │       ├── futures-task v0.3.1 (*)
│   │       ├── memchr v2.3.0 (*)
│   │       ├── pin-utils v0.1.0-alpha.4 (*)
│   │       ├── proc-macro-hack v0.5.11 (*)
│   │       ├── proc-macro-nested v0.1.3
│   │       └── slab v0.4.2 (*)
│   ├── futures-io v0.3.1 (*)
│   ├── futures-sink v0.3.1 (*)
│   ├── futures-task v0.3.1 (*)
│   └── futures-util v0.3.1 (*)
├── git2 v0.11.0
│   ├── bitflags v1.2.1
│   ├── libc v0.2.66 (*)
│   ├── libgit2-sys v0.10.0
│   │   ├── libc v0.2.66 (*)
│   │   ├── libssh2-sys v0.2.14
│   │   │   ├── libc v0.2.66 (*)
│   │   │   ├── libz-sys v1.0.25
│   │   │   │   └── libc v0.2.66 (*)
│   │   │   │   [build-dependencies]
│   │   │   │   ├── cc v1.0.50
│   │   │   │   │   └── jobserver v0.1.21
│   │   │   │   │       └── libc v0.2.66 (*)
│   │   │   │   └── pkg-config v0.3.17
│   │   │   └── openssl-sys v0.9.54
│   │   │       └── libc v0.2.66 (*)
│   │   │       [build-dependencies]
│   │   │       ├── autocfg v1.0.0
│   │   │       ├── cc v1.0.50 (*)
│   │   │       └── pkg-config v0.3.17 (*)
│   │   │   [build-dependencies]
│   │   │   ├── cc v1.0.50 (*)
│   │   │   └── pkg-config v0.3.17 (*)
│   │   ├── libz-sys v1.0.25 (*)
│   │   └── openssl-sys v0.9.54 (*)
│   │   [build-dependencies]
│   │   ├── cc v1.0.50 (*)
│   │   └── pkg-config v0.3.17 (*)
│   ├── log v0.4.8 (*)
│   ├── openssl-probe v0.1.2
│   ├── openssl-sys v0.9.54 (*)
│   └── url v2.1.1
│       ├── idna v0.2.0
│       │   ├── matches v0.1.8
│       │   ├── unicode-bidi v0.3.4
│       │   │   └── matches v0.1.8 (*)
│       │   └── unicode-normalization v0.1.12
│       │       └── smallvec v1.2.0
│       ├── matches v0.1.8 (*)
│       └── percent-encoding v2.1.0
├── horrorshow v0.7.0
├── hyper v0.13.2
│   ├── bytes v0.5.4
│   ├── futures-channel v0.3.1 (*)
│   ├── futures-core v0.3.1 (*)
│   ├── futures-util v0.3.1 (*)
│   ├── h2 v0.2.1
│   │   ├── bytes v0.5.4 (*)
│   │   ├── fnv v1.0.6
│   │   ├── futures-core v0.3.1 (*)
│   │   ├── futures-sink v0.3.1 (*)
│   │   ├── futures-util v0.3.1 (*)
│   │   ├── http v0.2.0
│   │   │   ├── bytes v0.5.4 (*)
│   │   │   ├── fnv v1.0.6 (*)
│   │   │   └── itoa v0.4.5
│   │   ├── indexmap v1.3.1
│   │   │   [build-dependencies]
│   │   │   └── autocfg v1.0.0 (*)
│   │   ├── log v0.4.8 (*)
│   │   ├── slab v0.4.2 (*)
│   │   ├── tokio v0.2.11
│   │   │   ├── bytes v0.5.4 (*)
│   │   │   ├── fnv v1.0.6 (*)
│   │   │   ├── iovec v0.1.4 (*)
│   │   │   ├── lazy_static v1.4.0 (*)
│   │   │   ├── memchr v2.3.0 (*)
│   │   │   ├── mio v0.6.21 (*)
│   │   │   ├── pin-project-lite v0.1.4 (*)
│   │   │   └── slab v0.4.2 (*)
│   │   └── tokio-util v0.2.0
│   │       ├── bytes v0.5.4 (*)
│   │       ├── futures-core v0.3.1 (*)
│   │       ├── futures-sink v0.3.1 (*)
│   │       ├── log v0.4.8 (*)
│   │       ├── pin-project-lite v0.1.4 (*)
│   │       └── tokio v0.2.11 (*)
│   ├── http v0.2.0 (*)
│   ├── http-body v0.3.1
│   │   ├── bytes v0.5.4 (*)
│   │   └── http v0.2.0 (*)
│   ├── httparse v1.3.4
│   ├── itoa v0.4.5 (*)
│   ├── log v0.4.8 (*)
│   ├── net2 v0.2.33 (*)
│   ├── pin-project v0.4.8
│   │   └── pin-project-internal v0.4.8
│   │       ├── proc-macro2 v1.0.8 (*)
│   │       ├── quote v1.0.2 (*)
│   │       └── syn v1.0.14 (*)
│   ├── time v0.1.42
│   │   └── libc v0.2.66 (*)
│   ├── tokio v0.2.11 (*)
│   ├── tower-service v0.3.0
│   └── want v0.3.0
│       ├── log v0.4.8 (*)
│       └── try-lock v0.2.2
├── md-5 v0.8.0
│   ├── block-buffer v0.7.3
│   │   ├── block-padding v0.1.5
│   │   │   └── byte-tools v0.3.1
│   │   ├── byte-tools v0.3.1 (*)
│   │   ├── byteorder v1.3.2
│   │   └── generic-array v0.12.3
│   │       └── typenum v1.11.2
│   ├── digest v0.8.1
│   │   └── generic-array v0.12.3 (*)
│   └── opaque-debug v0.2.3
├── percent-encoding v2.1.0 (*)
├── serde v1.0.104
│   └── serde_derive v1.0.104
│       ├── proc-macro2 v1.0.8 (*)
│       ├── quote v1.0.2 (*)
│       └── syn v1.0.14 (*)
├── serde_json v1.0.45
│   ├── itoa v0.4.5 (*)
│   ├── ryu v1.0.2
│   └── serde v1.0.104 (*)
├── structopt v0.3.8
│   ├── clap v2.33.0
│   │   ├── ansi_term v0.11.0
│   │   ├── atty v0.2.14
│   │   │   └── libc v0.2.66 (*)
│   │   ├── bitflags v1.2.1 (*)
│   │   ├── strsim v0.8.0
│   │   ├── textwrap v0.11.0
│   │   │   └── unicode-width v0.1.7
│   │   ├── unicode-width v0.1.7 (*)
│   │   └── vec_map v0.8.1
│   ├── lazy_static v1.4.0 (*)
│   └── structopt-derive v0.4.1
│       ├── heck v0.3.1
│       │   └── unicode-segmentation v1.6.0
│       ├── proc-macro-error v0.4.6
│       │   ├── proc-macro-error-attr v0.4.6
│       │   │   ├── proc-macro2 v1.0.8 (*)
│       │   │   ├── quote v1.0.2 (*)
│       │   │   ├── rustversion v1.0.2
│       │   │   │   ├── proc-macro2 v1.0.8 (*)
│       │   │   │   ├── quote v1.0.2 (*)
│       │   │   │   └── syn v1.0.14 (*)
│       │   │   ├── syn v1.0.14 (*)
│       │   │   └── syn-mid v0.5.0
│       │   │       ├── proc-macro2 v1.0.8 (*)
│       │   │       ├── quote v1.0.2 (*)
│       │   │       └── syn v1.0.14 (*)
│       │   ├── proc-macro2 v1.0.8 (*)
│       │   ├── quote v1.0.2 (*)
│       │   └── syn v1.0.14 (*)
│       │   [build-dependencies]
│       │   └── rustversion v1.0.2 (*)
│       ├── proc-macro2 v1.0.8 (*)
│       ├── quote v1.0.2 (*)
│       └── syn v1.0.14 (*)
└── tokio v0.2.11 (*)

Did you ever hear the tragedy of left-pad?

I thought not.

It's not a story web developers would tell you.

Which of those crates contain unsafe code?

Did you review any of them?

Did anyone?

Code reviews

signed

published

machine readable

Review

# Package Review of somecrate 0.8.15
review:
  thoroughness: low
  understanding: medium
  rating: positive
comment: |-

Use

$ cargo crev verify
status issues flgs crate                version         latest_t
pass    0   0 ____ percent-encoding     2.1.0           =
none    0   0 ____ cfg-if               0.1.10
none    0   0 ____ pkg-config           0.3.17
...
none    1   2 CB__ memoffset            0.5.3
none    0   0 ____ num_cpus             1.12.0          ↓1.10.1
none    0   0 ____ hyper                0.13.2
local   0   0 ____ annex-to-web         0.1.0*

Share

Reviews distributed through git repositories

Explicit pushing

Signing keys managed by cargo crev

Connect

Web of Trust

transitive by default

Trust published in parallel to reviews

cargo crev fetch all crawls both trusted and generally known repositories

Networks need participation

$ apt install openssl libssl-dev libgcrypt20-dev pkg-config
$ cargo install cargo-crev
$ cargo crev id new --url https://gitlab.com/YOU/crev-proofs

Clone the template repository from GitHub or from GitLab to make your reviews discoverable for others more easily.

$ cargo crev trust https://gitlab.com/chrysn/crev-proofs
$ cargo crev fetch all
$ cargo crev crate verify
$ cargo crev crate goto your-unverified-dependency

Spend seconds to hours per file reviewing. Note this puts you in a subshell.

$ cargo crev review
$ exit
$ cargo crev repo publish

Further reading

See Vienna Rust Meetup or Rust Zürisee Meetup pages for links and slides.

Source is available as well, published under CC-BY-SA, built with Hovercraft.