pub struct Settings {
pub env_deny: Vec<String>,
pub env_allow: Vec<String>,
pub gate_pct: f64,
pub credit: bool,
pub runner_class: String,
}Expand description
Every setting tak supports, resolved.
PartialEq but not Eq: a float setting has no total equality.
Fields§
§env_deny: Vec<String>Environment variables removed from every command tak measures.
Two reasons this defaults to a non-empty list rather than to nothing.
Determinism. A CLI that finds a forge token in its environment often does more with it than without — authenticating, fetching, checking rate limits. A measurement that moves depending on whether CI happened to export a token is not a measurement of the code under test. It lands in the series as an unexplained step change on the day someone edits an unrelated workflow.
This is not a credential sandbox. The listed variables are absent from the
child’s direct environment, but a hostile binary can still inspect accessible
same-user processes and files. In particular, tak backfill downloads and
executes release binaries; run it on an isolated credential-free machine when
those assets are not fully trusted.
Setting this replaces the default list rather than adding to it. To keep the
defaults and remove more, list them alongside. To keep the defaults and remove
fewer, use env_allow — it is subtracted from this list, so the two compose
without either having to restate the other.
Names are matched exactly. There is no globbing: a benchmark whose behaviour depends on which variables happen to match a pattern is the problem this setting exists to avoid.
tak’s own network calls are unaffected. backfill authenticates with curl
directly rather than through the measurement path.
env_allow: Vec<String>Environment variables kept even though env_deny lists them.
Subtracted from env_deny, so a project can opt one variable back in without
restating the whole default list. A CLI whose measured path genuinely requires
a token — a client that cannot start unauthenticated, say — needs this.
Doing so makes the measurement depend on something outside the repository. That is a real cost, not a formality: the numbers become conditional on the environment the run happened to have, and a token expiring will read as a performance change.
Listing a variable here that env_deny does not mention has no effect. This
setting removes entries from the deny list; it does not add anything to the
environment.
gate_pct: f64How much an instruction count may rise before tak compare fails.
A percentage of the base measurement. Only instruction counts are gated. Wall clock is reported and never gated: on the same hardware it moves 4-20% run to run, so a threshold tight enough to catch a real regression would fire constantly, and one loose enough to stay quiet would catch nothing.
The default of 1% is about fifty times the ~0.02% instruction counting reproduces to, leaving room for the small differences a compiler or dependency bump can produce without turning the gate into noise.
Raise it to report without effectively failing. Setting it to zero fails on any increase at all, which sounds appealing and is not: one extra instruction on a startup path is not worth blocking a pull request over.
credit: boolWhether generated reports end with a line naming tak.
On by default. A report that appears in someone’s pull request should say what put it there — a reader who has never heard of tak needs a way to find out, and a maintainer evaluating the comment needs to know what to turn off.
Turn it off with --no-credit, TAK_CREDIT=0, or credit = false under
[report]. Nothing else about the report changes.
runner_class: StringThe machine class a measurement is recorded under, and compared within.
Empty means derive it: gha-<os>-<arch> under GitHub Actions, local-<os>-<arch>
otherwise. That is right until something about the machine changes without the
name changing.
Series are partitioned on this, and must be. Absolute instruction counts shift between machine types by more than a real regression does, so tak will not compare across classes — it reports the old series as removed and the new one as added rather than inventing a step change.
Set it when the environment changes in a way the derived name cannot see. The common case is a toolchain bump: a hosted runner image or a compiler upgrade between the base measurement and this one is attributed to the code otherwise, and on a one-percent gate that is a false failure. Encoding the compiler version into the class starts a fresh series at the bump, which is honest — the numbers either side genuinely are not comparable.
tak cannot detect this for you. It measures programs, not build systems, and has no way to know what produced the binary it is timing.
Implementations§
Source§impl Settings
impl Settings
Sourcepub const SETTINGS_PROPS: &'static [PropMeta] = <Self as ::usage_rs::config::Props>::PROPS
pub const SETTINGS_PROPS: &'static [PropMeta] = <Self as ::usage_rs::config::Props>::PROPS
Every setting this struct declares, one entry per field, flattened groups
included. The registry a build.rs used to generate, generated from the
struct instead — there is no second declaration to keep in step.
Sourcepub const SETTINGS_REGISTRY: Registry
pub const SETTINGS_REGISTRY: Registry
The registry over Self::SETTINGS_PROPS, for resolve, drift, and
the layers.
Sourcepub const SETTINGS_SPEC: ConfigSpec
pub const SETTINGS_SPEC: ConfigSpec
Metadata used only when lowering this declaration into a usage spec.
Sourcepub fn read(__usage_resolved: &Resolved) -> Result<Self, ReadErrors>
pub fn read(__usage_resolved: &Resolved) -> Result<Self, ReadErrors>
This resolution’s values, as the struct.
Every field is read before anything is returned, so the error is the whole list of what is wrong rather than the first thing found.
Sourcepub fn read_lossy(__usage_resolved: &Resolved) -> (Option<Self>, ReadErrors)
pub fn read_lossy(__usage_resolved: &Resolved) -> (Option<Self>, ReadErrors)
This resolution’s values, keeping every setting that reads.
Self::read is all or nothing, which leaves a CLI two moves when one
field is bad: refuse to start, or fall back to a struct of declared
defaults and lose the environment and every config file along with the
offending value. Neither is a choice this crate should be making.
So: a field that will not read falls back to its own declared default and
the rest keep what the merge gave them, with every failure returned
alongside for the CLI to raise, log, or ignore as it sees fit. The errors
are the same [::usage_config::ReadError]s Self::read returns, so a
caller that decides a bad value is fatal has lost nothing by asking.
None only where a setting has no value and no declared default — a hole
in the declaration rather than a bad value, and nothing to fall back to.
Source§impl Settings
impl Settings
Sourcepub fn resolve(
cli: &CliLayer,
env: &EnvLayer,
config: &TakConfigLayer,
) -> Result<Self>
pub fn resolve( cli: &CliLayer, env: &EnvLayer, config: &TakConfigLayer, ) -> Result<Self>
Resolve every setting from the given layers, highest precedence first.
Sourcepub fn from_process(cli: &CliLayer) -> Result<Self>
pub fn from_process(cli: &CliLayer) -> Result<Self>
Resolve against the real process environment and the tak.toml found
upward from the current directory.
Sourcepub fn display_value(&self, name: &str) -> Option<String>
pub fn display_value(&self, name: &str) -> Option<String>
The value of a setting, by its registry key.
Exists so display code cannot silently omit a setting: SETTINGS_PROPS
is generated, so a new entry appears in tak settings whether or not
anything can produce its value. A test asserts this returns Some for
every registry entry, which turns “added a setting, forgot the
accessor” into a build failure instead of a blank row.
Sourcepub fn scrubbed_env(&self) -> impl Iterator<Item = &str>
pub fn scrubbed_env(&self) -> impl Iterator<Item = &str>
Variables to remove from a benchmark subject: denied, less allowed.
Allow subtracts from deny rather than sitting beside it, so opting one variable back in does not mean restating the whole default list.
Trait Implementations§
Source§impl Props for Settings
impl Props for Settings
Source§const PROP_SPECS: &'static [PropSpec]
const PROP_SPECS: &'static [PropSpec]
Props::PROPS.