defmodule Mix.Tasks.Workspace.Status do @options_schema Workspace.Cli.options([ :workspace_path, :config_path, :base, :head ]) @shortdoc "Display workspace's projects status." @moduledoc """ Similar to `git status` but on a workspace level. $ mix workspace.status ## Command line options #{CliOptions.docs(@options_schema, sort: true, sections: Workspace.CliOptions.doc_sections())} """ use Mix.Task @impl Mix.Task def run(args) do {opts, _args, _extra} = CliOptions.parse!(args, @options_schema) opts |> Keyword.merge(show_status: true) |> Mix.WorkspaceUtils.load_and_filter_workspace() |> show_status() end defp show_status(workspace) do modified = Workspace.Status.modified(workspace) affected = Workspace.Status.affected(workspace) show_modified(workspace, modified) show_affected(workspace, affected -- modified) end defp show_modified(_workspace, []), do: :ok defp show_modified(workspace, modified) do Workspace.Cli.log([:light_gray, "Modified projects:", :reset]) Enum.each(modified, fn name -> project = Workspace.project!(workspace, name) print_project_status(project, :modified) print_changes(workspace.git_root_path, project) end) Workspace.Cli.newline() end defp show_affected(_workspace, []), do: :ok defp show_affected(workspace, affected) do Workspace.Cli.log([:light_gray, "Affected projects:", :reset], prefix: "") Enum.each(affected, fn name -> print_project_status(Workspace.project!(workspace, name), :affected) end) Workspace.Cli.newline() end defp print_project_status(project, color) do Workspace.Cli.log([ " ", color, inspect(project.app), :reset, :mix_path, " ", Path.relative_to(project.mix_path, project.workspace_path), :reset ]) end defp print_changes(git_root_path, project) do for {path, change_type} <- project.changes do Workspace.Cli.log([ " ", change_type_color(change_type), change_type(change_type), " ", Path.relative_to(Path.join(git_root_path, path), project.workspace_path), :reset ]) end end defp change_type_color(:untracked), do: :gold defp change_type_color(_other), do: :pink defp change_type(:untracked), do: "untracked" defp change_type(_other), do: "modified " end