Detects the project root by walking up from a file path and looking for root marker files or directories.
This is the shared detection logic used by both Minga.Project (editor-wide
project awareness) and Minga.LSP.RootDetector (per-language-server roots).
Pure functions, no process state.
Detection order
Walks up from the file's parent directory. The first directory containing any marker wins. Markers are checked in the order given, but since we stop at the nearest directory, the marker list order only matters when multiple markers exist in the same directory.
Default markers
default_markers/0 returns a broad set covering common project types:
.git, mix.exs, Cargo.toml, package.json, go.mod, pyproject.toml,
.minga (sentinel file users can drop into any directory to mark a project root).
Summary
Functions
Returns the default marker list as {filename, project_type} tuples.
Detects the project root for a file using the default marker list.
Detects the project root for a file using a custom marker list.
Finds the project root for a file given a flat list of marker filenames.
Types
@type project_type() :: atom()
Project type inferred from the marker that matched.
@type result() :: {:ok, root :: String.t(), project_type()} | :none
Detection result.
Functions
@spec default_markers() :: [{String.t(), project_type()}]
Returns the default marker list as {filename, project_type} tuples.
Combines sentinel markers (.git, .minga) with root markers from
all registered languages. Pass a custom list to detect/2 if you
need different markers.
Detects the project root for a file using the default marker list.
Returns {:ok, root_path, project_type} or :none.
Examples
iex> {:ok, root, _type} = Minga.Project.Detector.detect("lib/minga/editor.ex")
iex> File.exists?(Path.join(root, "mix.exs"))
true
@spec detect(String.t(), [{String.t(), project_type()}]) :: result()
Detects the project root for a file using a custom marker list.
Each marker is a {filename, project_type} tuple. The walk stops at the
first directory containing any marker file.
Returns {:ok, root_path, project_type} or :none.
Finds the project root for a file given a flat list of marker filenames.
This is the compatibility API used by Minga.LSP.RootDetector. It returns
just the root path (no project type), falling back to File.cwd!/0 when
no marker is found.