Skip to content

Instantly share code, notes, and snippets.

View rrbutani's full-sized avatar
🐢
slowly but surely

Rahul Butani rrbutani

🐢
slowly but surely
  • 23:33 (UTC -08:00)
View GitHub Profile

VCS UUM Library Experiments

....

Notes on Library Ordering

notes:

  • post-order (children before parents) order is what makes sense for

default on attr.label (and attr.label_list, attr.string_keyed_label_dict) can be a function!

  • but: only for private attributes

this includes things like "late bound defaults"

but also your own functions can ask for other (public) attributes of the rule as keyword args and use them to compute a default!

a neat alternative to initializers on rules

Previously we explored a way to have some degree of dynamic dependencies in Bazel (input "subsetting") using TreeArtifacts.

The particular use case modeled in the previous gist involved:

  • a language with somewhat coarse library and binary rules (i.e. each rule describes a collection of files and their collective dependencies — the default for most Bazel rulesets)
  • a monolithic (and slow!) compiler whose compilation unit size is the entire binary (rather than something smaller like modules or source files)
    • i.e. exacerbating the pain of not having "perfect" file-level dependency information
  • source files that can be easily (and quickly) scanned to determine which dependencies are unused
❯ pytest --chrome-trace parallel-baseline.json -n auto --dist=worksteal
664 passed, 24 warnings in 9.08s

chrome trace of running pytest w/xdist's workstealing strategy

❯ pytest --chrome-trace parallel-reordered.json -n auto --dist=worksteal --expensive-tests-first
We couldn’t find that file to show.

observations:

  1. path mapping does not really[^1] "mask" out the repo name from non-main repo paths: source files OR generated artifacts
    • this means that whether you build a particular target (or really produce a particular action for the target) when that target is in the main (root) repo vs. when its in an "external" repo effects the paths used in the action
    • i.e. you will not get cache hits if you build //:your_target and then pull your repo into another bazel workspace as @foo and build @foo//:your_target
    • TODO: would be nice to repo names as well...
  2. path mapping silently falls back to using unmapped paths if the set of mapped paths has any conflicts (see :example_both)
  • note that ctx.actions.run(_shell)'s inputs does influence path mapping and does appear to factor into how conflicts are detected but... if you try to add a path to the command line (i.e. via arguments) that you haven't listed in inputs it isn't an error — some path mapping heuristi

Enforcement of allowed dep edges

the idea is to have testonly-esque checks

consider a project where we want to partition content (for an existing rule) into three categories:

  • "open-source"; a.k.a. oss
  • "proprietary"; a.k.a. prp
  • "development-only"; a.k.a. dev
//! for a given `N`, how many unique shapes of `N` contiguous minos (all connected via at least one
//! of the four cardinal directions) are possible?
//!
//! a shape is unique if no translation or rotation of a shape makes it the same as another shape
use std::{collections::HashSet, fmt};
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct Coord<const N: usize> {
x: u8, // 0 <= x < N