magus v0.3.0 is out. See what's new
¶ View markdown source · ✎ Suggest an edit
2 min read

MGS1011: cross-project output names an unusable owner

A target declared an output into another project's tree, and magus cannot use the project it named as the owner of that file.

[MGS1011] workspace://producer: target "build": ctx.writesFiles declares an output
into "gen", which magus did not discover as a project; it needs a project marker
and must not sit under an ignored directory

Why

ctx.writesFiles(site.file("generated.txt")) says two things at once: this target produces that file, and the file lands in site's tree rather than its own. The second half is what makes it different from an ordinary output, and it is the half that needs a real project on the other end.

magus files the glob on the owning project, because that is the project the glob is relative to. That one record is what every consumer reads:

  • magus clean deletes it, because it asks each project what lands in its tree.
  • magus watch ignores it, so writing it does not trigger the rebuild that writes it again.
  • The merge driver regenerates it during a conflicted merge, by looking up which project produces it.
  • The dependency edge that makes site build after its writer hangs off it.

With no owner to file it on, all four silently do nothing. The file is still produced and still snapshotted into the cache, so the build looks fine - it is just a generated artifact that nothing tracks, nothing cleans, and nothing knows how to rebuild.

Dropping it quietly is the failure mode this code exists to prevent. The cross-project input side has always failed loudly on the same typo; outputs must not be quieter, because the consequence is worse. An under-declared input only weakens a cache key. An under-declared output means a later cache hit replays a build that leaves the file missing.

Two causes

The path does not resolve. The import names a directory that is not a path in this workspace at all. Check the spelling of the import "project/../<name>" line the alias comes from.

The path resolves, but magus never discovered a project there. This is the one that surprises people, because the directory exists and the import succeeds. A directory becomes a project by carrying a marker (magusfile.buzz, magus.yaml, or a language marker such as package.json). Two things stop discovery even when a marker is present:

  • The directory sits under an ignored directory. gen/, node_modules/, vendor/ and friends are pruned from the project walk, so a gen/magusfile.buzz is imported happily and never registered. Name the project something else.
  • The marker is missing entirely - the import resolved through a plain directory.

Resolution

Point the output at a discovered project:

magus ls

If the intended owner is not in that list, it is not a project yet. Add a marker to it, or move it out from under an ignored directory.

If you did not mean to write into another project at all, drop the alias and declare an ordinary same-project output:

ctx.writesFiles("dist/**");

See also

  • MGS1012 - the same declaration forming a dependency cycle
  • MGS1013 - the glob half of a cross-project output escaping its owner
MGS1011magusfileoutputscross-projectloaddiscovery
Last updated (3da15dc9)
Earlier changes on this page (1)

Full history ↗ · Blame source ↗

Glossary

Workspace

The magus root directory that owns a set of projects and shared config; the unit magus operates over. See workspace.

Project

A directory magus recognizes as a unit of work (it has a magusfile); the unit of caching, scheduling, and dependency tracking. See workspace.

Magusfile

The magusfile.buzz that declares a project's targets (as export funs) and binds its spells. See targets.

Target

A named operation (build, test, ...) you invoke with magus run <target>; it may compose a spell's tool-native operations and depend on other targets. See targets.

Spell

A language/runtime adapter (e.g. go, md) that maps generic targets onto a toolchain's real commands. See spells.

Module

A magus stdlib namespace a magusfile imports for host capabilities: filesystem, exec, vcs, and more. See the module reference.

Buzz

The language magusfiles are written in (the .buzz engine). See engines.

Cache

The content-addressed store magus consults before running a target, so unchanged work is skipped. See cache.

Snapshot

A point-in-time view of live state - the pool's occupancy or a tick of exported metrics - as opposed to accumulated history. See daemon.

Conventions

Placeholders

Angle brackets mark a value you replace with your own - never type the brackets:

magus run <target>
magus completion <shell>    # e.g. bash, zsh, fish

<target>, <path>, <shell>, <name> and the like are stand-ins, not literal text.