Current section
Files
Jump to
Current section
Files
lib/mix/tasks/workspace.graph.ex
defmodule Mix.Tasks.Workspace.Graph do
opts = [
format: [
type: :string,
default: "pretty",
doc: """
The output format of the graph. It can be one of the following:
* `pretty` - pretty prints the graph as a tree.
* `plain` - does not use Unicode code points for formatting the tree.
* `mermaid` - exports the graph as a mermaid graph.
* `dot` - produces a graphviz DOT graph description of the workspace.
""",
allowed: ["pretty", "plain", "mermaid", "dot"]
],
external: [
type: :boolean,
default: false,
doc: """
If set external dependencies will also be inlcuded in the generated
graph.
"""
],
show_tags: [
type: :boolean,
default: false,
doc: """
If set the project's tags are also included in the generated graph. Currently
applicable only for `:pretty` and `:plain` formatters.
""",
doc_section: :display
],
focus: [
type: :string,
doc: """
If set the graph will be focused around the given project. Should be combined
with `:proximity` in order to define the depth of inward and outward neighbours
to be displayed.
"""
],
proximity: [
type: :integer,
default: 1,
doc: """
The maximum allowed proximity between a graph's project and children or parent
projects. Only applicable if `:focus` is set.
"""
]
]
@options_schema Workspace.Cli.options(
[
:workspace_path,
:config_path,
:show_status,
:exclude,
:base,
:head
],
opts
)
@shortdoc "Prints the dependency tree"
@moduledoc """
Prints the workspace graph.
$ mix workspace.graph
## Formatters
By default the graph will be pretty printed in the terminal:
$ mix workspace.graph
:api
├── :accounts
│ └── :ecto_utils
├── :cli_tools
└── :orders
├── :string_utils
└── :warehouse
└── :ecto_utils
:back_office
└── :cli_tools
You can also format it as `mermaid` or `dot`:
$ mix workspace.graph --format dot
digraph G {
accounts -> ecto_utils;
api -> accounts;
api -> cli_tools;
api -> orders;
back_office -> cli_tools;
orders -> string_utils;
orders -> warehouse;
warehouse -> ecto_utils;
}
## Showing project's statuses
If you pass the `--show-status` flag the project statuses are also
included.
$ mix workspace.graph --show-status
:api ✚
├── :accounts ✔
│ └── :ecto_utils ✔
├── :cli_tools ✚
└── :orders ✔
├── :string_utils ✔
└── :warehouse ✔
└── :ecto_utils ✔
:back_office ●
└── :cli_tools ✚
The following color coding is used:
* Modified projects are shown in **red color**
* Affected projects are shown in **orange color**
## Focusing the graph around a project
You can focus the graph around a single project by passing the `--focus`
option.
$ mix workspace.graph --focus api
:api
├── :accounts
├── :cli_tools
└── :orders
This will print the graph around `cli_tools` including only it's children
and parents that have a distance of 1 edge from it. You can widen the
picture by setting the `--proximity` flag.
## External dependencies
By default only the workspace projects are included in the graph. You
can however include the external dependencies by passing the `--external`
flag:
$ mix workspace.graph --external
:api
├── :accounts
│ └── :ecto_utils
│ └── :poison (external)
├── :cli_tools
└── :orders
├── :string_utils
│ └── :ex_doc (external)
└── :warehouse
└── :ecto_utils
:back_office
└── :cli_tools
## Command Line Options
#{CliOptions.docs(@options_schema, sort: true, sections: Workspace.CliOptions.doc_sections())}
"""
use Mix.Task
alias Workspace.Graph.Formatter
alias Workspace.Graph.Formatters
@impl Mix.Task
def run(args) do
{opts, _args, _extra} = CliOptions.parse!(args, @options_schema)
workspace = Mix.WorkspaceUtils.load_and_filter_workspace(opts)
case opts[:format] do
"pretty" ->
Formatter.format(
Formatters.PrintTree,
workspace,
Keyword.merge(opts, pretty: true)
)
"plain" ->
Formatter.format(
Formatters.PrintTree,
workspace,
Keyword.merge(opts, pretty: false)
)
"mermaid" ->
Formatter.format(Formatters.Mermaid, workspace, opts)
"dot" ->
Formatter.format(Formatters.Dot, workspace, opts)
end
end
end