Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read ps --format from config files #1294

Merged
merged 5 commits into from
Jan 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.D/1294.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Read ``neuro ps --format`` spec from config files if present.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ Name | Description|
|_\-d, --description DESCRIPTION_|Filter out jobs by description \(exact match).|
|_\-q, --quiet_|Run command in quiet mode \(DEPRECATED)|
|_\-w, --wide_|Do not cut long lines for terminal width.|
|_--format COLUMNS_|Output table format, use "neuro help format" for more info about the format specification.|
|_--format COLUMNS_|Output table format, use "neuro help ps-format" for more info about the format specification.|
|_--help_|Show this message and exit.|


Expand Down Expand Up @@ -1697,7 +1697,7 @@ Name | Description|
|_\-d, --description DESCRIPTION_|Filter out jobs by description \(exact match).|
|_\-q, --quiet_|Run command in quiet mode \(DEPRECATED)|
|_\-w, --wide_|Do not cut long lines for terminal width.|
|_--format COLUMNS_|Output table format, use "neuro help format" for more info about the format specification.|
|_--format COLUMNS_|Output table format, use "neuro help ps-format" for more info about the format specification.|
|_--help_|Show this message and exit.|


Expand Down
23 changes: 19 additions & 4 deletions neuromation/cli/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
CONFIG_ENV_NAME,
TRUSTED_CONFIG_PATH,
AuthorizationError,
Client,
Container,
HTTPPort,
JobDescription,
Expand Down Expand Up @@ -45,7 +46,7 @@
SimpleJobsFormatter,
TabularJobsFormatter,
)
from .parse_utils import COLUMNS, JobColumnInfo
from .parse_utils import COLUMNS, JobColumnInfo, parse_columns
from .root import Root
from .utils import (
JOB_COLUMNS,
Expand Down Expand Up @@ -478,10 +479,10 @@ async def _print_logs(root: Root, job: str) -> None:
"--format",
type=JOB_COLUMNS,
help=(
'Output table format, use "neuro help format" '
'Output table format, use "neuro help ps-format" '
"for more info about the format specification."
),
default=COLUMNS,
default=None,
)
@async_cmd()
async def ls(
Expand All @@ -492,7 +493,7 @@ async def ls(
owner: Sequence[str],
description: str,
wide: bool,
format: List[JobColumnInfo],
format: Optional[List[JobColumnInfo]],
) -> None:
"""
List all jobs.
Expand All @@ -506,6 +507,7 @@ async def ls(
neuro ps -s failed -s succeeded -q
"""

format = calc_columns(root.client, format)
statuses = calc_statuses(status, all)
owners = set(owner)
jobs = await root.client.jobs.list(statuses=statuses, name=name, owners=owners)
Expand Down Expand Up @@ -1092,3 +1094,16 @@ def calc_statuses(status: Sequence[str], all: bool) -> Set[JobStatus]:
statuses = defaults

return set(JobStatus(s) for s in statuses)


def calc_columns(
client: Client, format: Optional[List[JobColumnInfo]]
) -> List[JobColumnInfo]:
if format is None:
config = client.config.get_user_config()
section = config.get("job")
if section is not None:
format_str = section.get("ps-format")
if format_str is not None:
return parse_columns(format_str)
return COLUMNS
51 changes: 47 additions & 4 deletions neuromation/cli/topics.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from .utils import command, group
from .utils import group


@group()
def topics() -> None:
"""Help topics."""


@command()
def format() -> None:
@topics.command()
def ps_format() -> None:
"""Format for columns specification.

The format is a sequence of column specifications separated by commas or spaces:
Expand Down Expand Up @@ -59,4 +59,47 @@ def format() -> None:
"""


topics.add_command(format)
@topics.command()
def user_config() -> None:
"""\
User configuration files.

The Neuro platform supports user configuration files to provide default values for
particular command options, user defined command aliases etc.

There are two configuration files: global and local, both are optional and can be
absent.

The global file is located in the standard neuro config path. "neuro" CLI uses
~/.neuro folder by default, the path for global config file is ~/.neuro/user.toml.

The local config file is named .neuro.toml, the CLI search for this file starting
from the current folder up to the root directory.

Found local and global configurations are merged. If a parameter is present is both
global and local versions the local parameter takes a precedence.

Configuration files have a TOML format (a stricter version of well-known INI
format). See https://en.wikipedia.org/wiki/TOML and
https://github.com/toml-lang/toml#toml for the format specification details.

Supported configuration sections and parameters:

[job]

A section for "neuro job" command group settings.


ps-columns

Default value for "neuro ps --format=XXX" option.

See "neuro help ps-columns" for information about the value specification.


Examples:
# job section
[job]
ps-columns = "{id;max=30}, {status:max=10}"

"""
41 changes: 37 additions & 4 deletions tests/cli/test_job.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
import logging
from pathlib import Path
from typing import Any, Tuple
from typing import Any, Callable, Tuple

import click
import pytest

from neuromation.api import JobStatus
from neuromation.cli.job import NEUROMATION_ROOT_ENV_VAR, build_env, calc_statuses
import toml

from neuromation.api import Client, JobStatus
from neuromation.cli.job import (
NEUROMATION_ROOT_ENV_VAR,
build_env,
calc_columns,
calc_statuses,
)
from neuromation.cli.parse_utils import COLUMNS, COLUMNS_MAP


logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

_MakeClient = Callable[..., Client]


@pytest.mark.parametrize("statuses", [("all",), ("all", "failed", "succeeded")])
def test_calc_statuses__contains_all__all_statuses_true(statuses: Tuple[str]) -> None:
Expand Down Expand Up @@ -127,3 +136,27 @@ def test_build_env_reserved_env_var_conflict_passed_in_file(
match="Unable to re-define system-reserved environment variable",
):
build_env(env_1, env_file=str(env_file))


async def test_calc_columns_section_doesnt_exist(
monkeypatch: Any, tmp_path: Path, make_client: _MakeClient
) -> None:

async with make_client("https://example.com") as client:
monkeypatch.chdir(tmp_path)
local_conf = tmp_path / ".neuro.toml"
# empty config
local_conf.write_text("")
assert calc_columns(client, None) == COLUMNS


async def test_calc_columns_user_spec(
monkeypatch: Any, tmp_path: Path, make_client: _MakeClient
) -> None:

async with make_client("https://example.com") as client:
monkeypatch.chdir(tmp_path)
local_conf = tmp_path / ".neuro.toml"
# empty config
local_conf.write_text(toml.dumps({"job": {"ps-format": "{id}, {status}"}}))
assert calc_columns(client, None) == [COLUMNS_MAP["id"], COLUMNS_MAP["status"]]