Load Nature Items
Tests every file the job loaded against every active nature resource and records which nature matched which files. It is the op that makes nature branching work: without it, IF EXISTS nature THEN and IF ANY nature THEN find nothing and their blocks never run.
It differs from APPLY NATURE in reach. APPLY NATURE takes the one
nature you name, runs its patterns over the job's item list and leaves the matching items in a
single stash value. This op tests all of them at once, per project, and builds
a map the nature branches then index into.
Fields¶
Commit Items?¶
A single checkbox, the only control on the form. Off by default. When it is ticked, any job item that carries a namespace value and is not already stored as a resource is saved as one before it is matched. Items that are already stored are left alone.
In practice this does very little. Items built for the job out of repository revisions have no namespace, so they are skipped whatever this box says. Only items that already have a namespace are candidates, which makes this a legacy switch for pipelines that track files as resources. Leave it off unless you know you need it, because turning it on adds a resource lookup per item per nature to a loop that is already the slowest part of a large job.
Nothing in the job log records that an item was saved.
What gets matched¶
The op works through the job's projects that own at least one of the job's changesets, and for each of them reads the item list that Load Job Items into Stash built. If that op has not run, there are no items and this one finds nothing.
Only natures marked active take part. A deactivated nature resource is skipped without a word in the log, which is the quickest way to turn one off without editing rules.
Each item is tested against the Include patterns on the nature, under Paths. These are regular
expressions, and a match anywhere in the path is enough. An item that matched is then tested against
the Exclude patterns, and one match there drops it. Exclude wins.
Three values are tried against each pattern: the item's nature path, its path, and its full path. Any one of them matching counts.
A nature with an empty Include list matches nothing at all. There is no implicit "everything"
default, so an empty include list is the usual reason a nature you expect to fire never does.
Matching does not stop at the first nature. One file can belong to several natures at once, and each of them gets its own copy of it.
What lands in the stash¶
Two values are written, both keyed by the project's resource id rather than its name.
natures maps a project to the natures that matched at least one of its files. Each nature is
reachable by its name and by its resource id, so natures.<project>.sql_scripts and
natures.<project>.<mid> are the same entry. Natures that matched nothing are absent, which is
exactly what the nature branch ops test for.
project_items gains a per-nature file list for the project. Unlike natures, this one gets an
entry for every active nature, including the ones that matched nothing, so an entry existing there
does not mean anything matched.
natures is emptied at the start of every run, so placing the op twice replaces the earlier result
rather than adding to it. The lists under project_items are overwritten one nature at a time
instead of being cleared first, so a list left behind by a nature that has since been deactivated
survives the second run.
The matched natures are also attached to the job itself, which is what makes them show up on the job record in the monitor.
What you see in the log¶
One line when the analysis starts, then one line per project.
If anything matched, the line reads N nature(s) detected in job items: followed by each nature name
and the number of files it took, like sql_scripts (12), configs (3). If nothing matched, you get a
warning saying no natures were detected in job items, which is a warning rather than an error: the
job carries on. A job with no projects to work through gets the opening line and nothing else, not
even the warning.
There is no per-item detail at any level. Nothing records which item was tried against which nature, or which pattern rejected it, so a nature that comes back empty tells you only that no path matched. When you need more than that, take the paths from Load Job Items into Stash and try the pattern against them yourself. The one debug line per project carries the running count of item-to-nature checks and the seconds spent so far.
Cost¶
Every item is tested against every active nature. Twenty natures and two thousand files is forty thousand pattern tests, and expensive regular expressions multiply that. On a slow job this op is usually the place to look first. Deactivating natures you no longer use is the cheapest fix.
Failure¶
A malformed regular expression on a nature stops the rule. Everything else is soft. An empty item list, no active natures at all, or active natures that matched nothing end with the warning above, and the job carries on to the next op.
The op's own return value is a zero, so pointing Return Key at it on the Options tab stores a zero
rather than anything about the natures. Read the stash values described above instead.
Combining with other ops¶
The order that works is Load Job Items into Stash, then this op, then FOR projects with changes DO, and the nature branches inside that loop. The branches look the nature up under the project the loop is currently on, and neither of them degrades gracefully outside it. IF EXISTS nature THEN reads whichever project the last loop finished on, or stops the job when no loop has run at all. IF ANY nature THEN stops the rule from compiling.
IF EXISTS nature THEN opens a block for one nature and fills
nature_items, nature_item_paths and the comma and quoted variants for the length of that block.
IF ANY nature THEN takes a list of natures and runs its block if any of
them matched, without setting the item variables.
APPLY NATURE does not read anything this op writes. It applies its own nature directly to the item list, so it works without this op.
Examples¶
The standard nature pipeline.
JOB STEP: RUN
Load Job Items into Stash
Load Nature Items
Commit Items? (unticked)
FOR projects with changes DO
IF EXISTS nature THEN
Nature: sql_scripts
Run command or local script
Command: psql -f ${nature_item_paths}
Branch once for a whole family of natures, without needing the file list.
Load Nature Items
FOR projects with changes DO
IF ANY nature THEN
Natures: sql_scripts, db_migrations
LOG Message: this job touches the database