Current section

Files

Jump to
workspace lib mix tasks workspace.list.ex
Raw

lib/mix/tasks/workspace.list.ex

defmodule Mix.Tasks.Workspace.List do
opts = [
json: [
type: :boolean,
default: false,
doc: """
If set a `json` file will be generated with the list of workspace projects and
associated metadata. By default it will be saved in `workspace.json` in the
current directory. You can override the output path by setting the `--output`
option.
"""
],
output: [
type: :string,
default: "workspace.json",
doc: """
The output file. Applicable only if `--json` is set.
"""
],
relative_paths: [
type: :boolean,
default: false,
doc: """
If set the paths in the exported json file will be relative with respect to the
workspace path. Applicable only if `--json` is set.
"""
]
]
@options_schema Workspace.Cli.options(
[
:workspace_path,
:config_path,
:project,
:exclude,
:tags,
:excluded_tags,
:show_status
],
opts
)
@shortdoc "Display info about the workspace projects"
@moduledoc """
Shows workspace project info
$ mix workspace.list
By default the following are displayed:
- the project app name
- the project path with respect to workspace path
- the description if set
## Command line options
#{CliOptions.docs(@options_schema, sort: true)}
"""
use Mix.Task
alias Workspace.Cli
@impl Mix.Task
def run(args) do
{opts, _args, _extra} = CliOptions.parse!(args, @options_schema)
opts
|> Mix.WorkspaceUtils.load_and_filter_workspace()
|> list_or_save_workspace_projects(opts)
end
defp list_or_save_workspace_projects(workspace, opts) do
case opts[:json] do
false -> list_workspace_projects(workspace, opts[:show_status])
true -> write_json(workspace, opts)
end
end
defp list_workspace_projects(workspace, show_status) do
projects = Workspace.projects(workspace)
max_project_length = max_project_length(projects)
projects
|> Enum.sort_by(& &1.app)
|> Enum.each(&print_project_info(&1, max_project_length, show_status))
end
defp max_project_length([]), do: 0
defp max_project_length(projects) do
projects
|> Enum.map(fn project -> inspect(project.app) |> String.length() end)
|> Enum.max()
end
defp print_project_info(%Workspace.Project{skip: true}, _length, _show_status), do: :ok
defp print_project_info(project, max_project_length, show_status) do
indent_size = max_project_length - String.length(inspect(project.app))
indent = String.duplicate(" ", indent_size)
Cli.log([
" * ",
Cli.project_name(project, show_status: show_status, pretty: true),
indent,
:light_black,
" ",
Path.relative_to(project.mix_path, project.workspace_path),
:reset,
description(project.config[:description]),
tags(project.tags)
])
end
defp description(nil), do: ""
defp description(doc) when is_binary(doc), do: [" - ", doc]
defp write_json(workspace, opts) do
json_data = Workspace.Export.to_json(workspace, sort: true, relative: opts[:relative_paths])
File.write!(opts[:output], json_data)
Workspace.Cli.log([:green, "generated ", :reset, opts[:output]], prefix: :header)
end
defp tags([]), do: []
defp tags(tags) do
tags =
Enum.map(tags, fn tag -> [:tag, Workspace.Project.format_tag(tag), :reset] end)
|> Enum.intersperse(", ")
[" " | tags]
end
end