Skip to content

[feature] Discover projects from marker files other than moon.yml #2640

Description

@Wtiben

I've been building a .NET toolchain plugin (moonrepo/plugins#169), and this is the one part I couldn't solve from inside a plugin.

Some context, since it's specific to how .NET lays repos out. A project is a .csproj file, its name is arbitrary, and it normally sits a level or two below anything you'd want to glob for, something like src/Billing/Billing.Service/Billing.Service.csproj. There's no moon.yml-shaped marker to key off, and the directory names on their own aren't reliable either.

Today projects.globs matches directories or moon.yml files. Anything else gets dropped with a warning rather than an error (2.4.5):

WARN moon_workspace::projects_locator  Received a file path for a project root, must be a directory  source="...\src\Foo\Foo.csproj"

So src/**/*.csproj silently gives you nothing.

A plugin can't fill the gap either. An id returned from extend_project_graph that isn't already declared fails with UnconfiguredID (crates/workspace/src/projects_builder.rs). That makes sense given the design, but it does mean discovery is the one part of a language integration a toolchain can't supply.

What's left is listing every project directory in workspace.yml by hand, which doesn't scale to a real solution. Of the repos I tested the plugin against, OrchardCore would need 238 entries and abp 671. A glob like src/*/* gets close in a tidy repo, but ids come from directory basenames, and names like Tests repeat across services in most .NET solutions, so they collide. In practice you either generate the map or drop an empty moon.yml stub in every project directory purely to mark it.

Two ways I can see to fix it:

  1. Let projects.globs match arbitrary marker files, so src/**/*.csproj declares the containing directory as a project. Ids would still need a rule, probably the directory name plus some way out of collisions.
  2. Let toolchains contribute projects, say a locate_projects returning id and source pairs, so each ecosystem picks its own naming.

1 looks smaller, and it'd help anything whose marker isn't moon.yml: Cargo.toml, go.mod, pyproject.toml, *.csproj. 2 is more work but would let ids come from something better than a directory name, which for .NET would be the project filename or the evaluated AssemblyName.

Interested in what you think, and whether there's an option I'm not seeing here. If it's not something you'd want to pick up yourself, I could have a look at a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions