Skip to content

Commit 4a295ed

Browse files
ctruedenclaude
andcommitted
Centralize Rich markup styles across the codebase
Extended styles.py to provide semantic style definitions and helper functions for consistent formatting throughout jgo. This eliminates ~100+ hardcoded style occurrences across 18 files and enables users to customize all UI elements via configuration. Changes: - Added 9 semantic style keys to DEFAULT_STYLES: error, critical, warning, filename, header, syntax, action, secondary, domain - Created 9 helper functions: error(), critical(), warning(), filepath(), header(), syntax(), action(), secondary(), domain(), tip() - Added pre-formatted string constants for common patterns: JGO_TOML, JGO_LOCK_TOML, JGO_CONF_GLOBAL, PLUS_OPERATOR, AT_MAINCLASS, DOUBLE_DASH, MAVEN_COORDINATES, MAVEN_REPOSITORIES, TIP_DRY_RUN - Refactored 15 command files and 3 core modules to use centralized styles instead of inline markup - Standardized section headers to "bold cyan" style for consistency - Fixed malformed close tag [/cyan] → [/] in config.py - Updated test expectations in wrap.t for new header style Benefits: - Single source of truth for all UI styling - Consistent appearance across all commands and output - All styles now customizable via [styles] section in config - Easier maintenance and future style updates - More readable code with semantic helper functions Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
1 parent f4ba7ec commit 4a295ed

File tree

16 files changed

+276
-113
lines changed

16 files changed

+276
-113
lines changed

src/jgo/cli/commands/add.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from ...config import GlobalSettings
1111
from ...env.spec import EnvironmentSpec
12-
from ...styles import COORD_HELP_FULL
12+
from ...styles import COORD_HELP_FULL, JGO_TOML, syntax
1313
from ..args import build_parsed_args
1414
from ..output import handle_dry_run
1515
from . import sync as sync_cmd
@@ -20,7 +20,7 @@
2020
_log = logging.getLogger(__name__)
2121

2222

23-
@click.command(help="Add dependencies to [cyan]jgo.toml[/].")
23+
@click.command(help=f"Add dependencies to {JGO_TOML}.")
2424
@click.argument(
2525
"coordinates",
2626
nargs=-1,
@@ -31,7 +31,7 @@
3131
@click.option(
3232
"--no-sync",
3333
is_flag=True,
34-
help="Don't automatically [yellow]sync[/] after adding dependencies",
34+
help=f"Don't automatically {syntax('sync')} after adding dependencies",
3535
)
3636
@click.pass_context
3737
def add(ctx, coordinates, no_sync):

src/jgo/cli/commands/config.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from ...config import GlobalSettings
1313
from ...config.manager import get_settings_path
1414
from ...config.settings import parse_config_key
15+
from ...styles import JGO_CONF_GLOBAL, JGO_TOML, error, filepath
1516
from ...util.toml import load_toml_file
1617
from ..args import build_parsed_args
1718
from ..console import console_print
@@ -188,7 +189,7 @@ def _get_config(config_file: Path, config_type: str, key: str, args: ParsedArgs)
188189

189190
if not config_file.exists():
190191
console_print(
191-
f"[red]Error:[/] No {config_type} configuration file found at {config_file}",
192+
error(f"No {config_type} configuration file found at {config_file}"),
192193
stderr=True,
193194
)
194195
return 1
@@ -322,7 +323,7 @@ def _set_toml(
322323
data = load_toml_file(config_file)
323324
if data is None:
324325
console_print(
325-
f"[red]Error:[/] No local configuration file found at {config_file}",
326+
error(f"No local configuration file found at {config_file}"),
326327
stderr=True,
327328
)
328329
console_print(
@@ -360,7 +361,7 @@ def _unset_config(
360361

361362
if not config_file.exists():
362363
console_print(
363-
f"[red]Error:[/] No {config_type} configuration file found at {config_file}",
364+
error(f"No {config_type} configuration file found at {config_file}"),
364365
stderr=True,
365366
)
366367
return 1
@@ -380,7 +381,7 @@ def _unset_jgorc(config_file: Path, section: str, key: str, args: ParsedArgs) ->
380381

381382
if not config_file.exists():
382383
console_print(
383-
f"[red]Error:[/] No configuration file found at {config_file}",
384+
error(f"No configuration file found at {config_file}"),
384385
stderr=True,
385386
)
386387
return 1
@@ -494,13 +495,13 @@ def _parse_value(value: str) -> str | int | float | bool:
494495
"--global",
495496
"global_config",
496497
is_flag=True,
497-
help="Use global configuration ([cyan]~/.config/jgo.conf[/]).",
498+
help=f"Use global configuration ({JGO_CONF_GLOBAL}).",
498499
)
499500
@click.option(
500501
"--local",
501502
"local_config",
502503
is_flag=True,
503-
help="Use local configuration ([cyan]jgo.toml[/]).",
504+
help=f"Use local configuration ({JGO_TOML}).",
504505
)
505506
@click.pass_context
506507
def list_cmd(ctx, global_config, local_config):
@@ -527,19 +528,19 @@ def list_cmd(ctx, global_config, local_config):
527528
@click.argument(
528529
"key",
529530
cls=click.RichArgument,
530-
help="Configuration key in dot notation (e.g., [cyan]repositories.scijava[/])",
531+
help=f"Configuration key in dot notation (e.g., {filepath('repositories.scijava')})",
531532
)
532533
@click.option(
533534
"--global",
534535
"global_config",
535536
is_flag=True,
536-
help="Use global configuration ([cyan]~/.config/jgo.conf[/])",
537+
help=f"Use global configuration ({JGO_CONF_GLOBAL})",
537538
)
538539
@click.option(
539540
"--local",
540541
"local_config",
541542
is_flag=True,
542-
help="Use local configuration ([cyan]jgo.toml[/])",
543+
help=f"Use local configuration ({JGO_TOML})",
543544
)
544545
@click.pass_context
545546
def get_cmd(ctx, key, global_config, local_config):
@@ -566,20 +567,20 @@ def get_cmd(ctx, key, global_config, local_config):
566567
@click.argument(
567568
"key",
568569
cls=click.RichArgument,
569-
help="Configuration key in dot notation (e.g., [cyan]repositories.scijava[/])",
570+
help=f"Configuration key in dot notation (e.g., {filepath('repositories.scijava')})",
570571
)
571572
@click.argument("value", cls=click.RichArgument, help="Configuration value to set")
572573
@click.option(
573574
"--global",
574575
"global_config",
575576
is_flag=True,
576-
help="Use global configuration ([cyan]~/.config/jgo.conf[/])",
577+
help=f"Use global configuration ({JGO_CONF_GLOBAL})",
577578
)
578579
@click.option(
579580
"--local",
580581
"local_config",
581582
is_flag=True,
582-
help="Use local configuration ([cyan]jgo.toml[/cyan])",
583+
help=f"Use local configuration ({JGO_TOML})",
583584
)
584585
@click.pass_context
585586
def set_cmd(ctx, key, value, global_config, local_config):
@@ -606,19 +607,19 @@ def set_cmd(ctx, key, value, global_config, local_config):
606607
@click.argument(
607608
"key",
608609
cls=click.RichArgument,
609-
help="Configuration key in dot notation (e.g., [cyan]repositories.scijava[/])",
610+
help=f"Configuration key in dot notation (e.g., {filepath('repositories.scijava')})",
610611
)
611612
@click.option(
612613
"--global",
613614
"global_config",
614615
is_flag=True,
615-
help="Use global configuration ([cyan]~/.config/jgo.conf[/]).",
616+
help=f"Use global configuration ({JGO_CONF_GLOBAL}).",
616617
)
617618
@click.option(
618619
"--local",
619620
"local_config",
620621
is_flag=True,
621-
help="Use local configuration ([cyan]jgo.toml[/]).",
622+
help=f"Use local configuration ({JGO_TOML}).",
622623
)
623624
@click.pass_context
624625
def unset_cmd(ctx, key, global_config, local_config):

src/jgo/cli/commands/info.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from ...env.jar import parse_manifest, read_raw_manifest
1515
from ...parse.coordinate import Coordinate
1616
from ...parse.endpoint import Endpoint
17-
from ...styles import COORD_HELP_FULL
17+
from ...styles import AT_MAINCLASS, COORD_HELP_FULL, JGO_TOML, PLUS_OPERATOR
1818
from ..args import build_parsed_args
1919
from ..console import console_print
2020
from ..context import create_environment_builder, create_maven_context
@@ -35,8 +35,8 @@
3535
"endpoint",
3636
required=False,
3737
cls=click.RichArgument,
38-
help="Maven coordinates (single or combined with [yellow]+[/]) "
39-
"optionally followed by [yellow]@MainClass[/]",
38+
help=f"Maven coordinates (single or combined with {PLUS_OPERATOR}) "
39+
f"optionally followed by {AT_MAINCLASS}",
4040
)
4141
@click.pass_context
4242
def classpath(ctx, endpoint):
@@ -72,8 +72,8 @@ def classpath(ctx, endpoint):
7272
"endpoint",
7373
required=False,
7474
cls=click.RichArgument,
75-
help="Maven coordinates (single or combined with [yellow]+[/]) "
76-
"optionally followed by [yellow]@MainClass[/]",
75+
help=f"Maven coordinates (single or combined with {PLUS_OPERATOR}) "
76+
f"optionally followed by {AT_MAINCLASS}",
7777
)
7878
@click.pass_context
7979
def envdir(ctx, endpoint):
@@ -109,8 +109,8 @@ def envdir(ctx, endpoint):
109109
"endpoint",
110110
required=False,
111111
cls=click.RichArgument,
112-
help="Maven coordinates (single or combined with [yellow]+[/]) "
113-
"optionally followed by [yellow]@MainClass[/]",
112+
help=f"Maven coordinates (single or combined with {PLUS_OPERATOR}) "
113+
f"optionally followed by {AT_MAINCLASS}",
114114
)
115115
@click.pass_context
116116
def jars(ctx, endpoint):
@@ -253,7 +253,7 @@ def javainfo(ctx, endpoint):
253253
ctx.exit(0)
254254

255255

256-
@click.command(help="Show entrypoints from [cyan]jgo.toml[/].")
256+
@click.command(help=f"Show entrypoints from {JGO_TOML}.")
257257
@click.pass_context
258258
def entrypoints(ctx):
259259
"""Show available entrypoints defined in jgo.toml."""
@@ -439,7 +439,9 @@ def _print_deps(ctx, endpoint, list_mode: bool):
439439
ctx.exit(1)
440440
spec = EnvironmentSpec.load(spec_file)
441441
try:
442-
coordinates = [Coordinate.parse(coord_str) for coord_str in spec.coordinates]
442+
coordinates = [
443+
Coordinate.parse(coord_str) for coord_str in spec.coordinates
444+
]
443445
except ValueError as e:
444446
_log.error(f"Invalid coordinate format: {e}")
445447
ctx.exit(1)

src/jgo/cli/commands/init.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
from ...config import GlobalSettings
1313
from ...env import EnvironmentSpec
14+
from ...styles import AT_MAINCLASS, JGO_TOML, PLUS_OPERATOR
1415
from ..args import build_parsed_args
1516
from ..output import handle_dry_run
1617

@@ -20,13 +21,13 @@
2021
_log = logging.getLogger(__name__)
2122

2223

23-
@click.command(help="Create a new [cyan]jgo.toml[/] environment file.")
24+
@click.command(help=f"Create a new {JGO_TOML} environment file.")
2425
@click.argument(
2526
"endpoint",
2627
required=False,
2728
cls=click.RichArgument,
28-
help="Maven coordinates (single or combined with [yellow]+[/]) "
29-
"optionally followed by [yellow]@MainClass[/]",
29+
help=f"Maven coordinates (single or combined with {PLUS_OPERATOR}) "
30+
f"optionally followed by {AT_MAINCLASS}",
3031
)
3132
@click.pass_context
3233
def init(ctx, endpoint):

src/jgo/cli/commands/list.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from ...env import EnvironmentSpec
1212
from ...parse.coordinate import Coordinate
1313
from ...parse.endpoint import Endpoint
14+
from ...styles import AT_MAINCLASS, PLUS_OPERATOR
1415
from ..args import build_parsed_args
1516
from ..context import create_environment_builder, create_maven_context
1617
from ..output import print_dependencies
@@ -26,8 +27,8 @@
2627
"endpoint",
2728
required=False,
2829
cls=click.RichArgument,
29-
help="Maven coordinates (single or combined with [yellow]+[/]) "
30-
"optionally followed by [yellow]@MainClass[/]",
30+
help=f"Maven coordinates (single or combined with {PLUS_OPERATOR}) "
31+
f"optionally followed by {AT_MAINCLASS}",
3132
)
3233
@click.option(
3334
"--direct", is_flag=True, help="Show only direct dependencies (non-transitive)"
@@ -66,7 +67,9 @@ def execute(args: ParsedArgs, config: dict) -> int:
6667
return 1
6768
spec = EnvironmentSpec.load(spec_file)
6869
try:
69-
coordinates = [Coordinate.parse(coord_str) for coord_str in spec.coordinates]
70+
coordinates = [
71+
Coordinate.parse(coord_str) for coord_str in spec.coordinates
72+
]
7073
except ValueError as e:
7174
_log.error(f"Invalid coordinate format: {e}")
7275
return 1

src/jgo/cli/commands/lock.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from ...config import GlobalSettings
1111
from ...env.lockfile import LockFile, compute_spec_hash
1212
from ...env.spec import EnvironmentSpec
13+
from ...styles import JGO_LOCK_TOML
1314
from ...util.logging import log_exception_if_verbose
1415
from ..args import build_parsed_args
1516
from ..context import create_environment_builder, create_maven_context
@@ -20,7 +21,7 @@
2021
_log = logging.getLogger(__name__)
2122

2223

23-
@click.command(help="Update [cyan]jgo.lock.toml[/] without building environment.")
24+
@click.command(help=f"Update {JGO_LOCK_TOML} without building environment.")
2425
@click.option(
2526
"--check",
2627
is_flag=True,

src/jgo/cli/commands/remove.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from ...config import GlobalSettings
1111
from ...env.spec import EnvironmentSpec
1212
from ...parse.coordinate import Coordinate
13-
from ...styles import styled
13+
from ...styles import JGO_TOML, styled, syntax
1414
from ..args import build_parsed_args
1515
from ..output import handle_dry_run
1616
from . import sync as sync_cmd
@@ -21,7 +21,7 @@
2121
_log = logging.getLogger(__name__)
2222

2323

24-
@click.command(help="Remove dependencies from [cyan]jgo.toml[/].")
24+
@click.command(help=f"Remove dependencies from {JGO_TOML}.")
2525
@click.argument(
2626
"coordinates",
2727
nargs=-1,
@@ -33,7 +33,7 @@
3333
@click.option(
3434
"--no-sync",
3535
is_flag=True,
36-
help="Don't automatically [yellow]sync[/] after removing dependencies",
36+
help=f"Don't automatically {syntax('sync')} after removing dependencies",
3737
)
3838
@click.pass_context
3939
def remove(ctx, coordinates, no_sync):

src/jgo/cli/commands/run.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@
1010

1111
from ...config import GlobalSettings
1212
from ...env import EnvironmentSpec
13+
from ...styles import (
14+
AT_MAINCLASS,
15+
DOUBLE_DASH,
16+
JGO_TOML,
17+
MAVEN_COORDINATES,
18+
PLUS_OPERATOR,
19+
TIP_DRY_RUN,
20+
action,
21+
secondary,
22+
)
1323
from ...util import is_debug_enabled
1424
from ..args import build_parsed_args, parse_remaining
1525
from ..context import (
@@ -25,40 +35,40 @@
2535

2636

2737
@click.command(
28-
help="Run a Java application from [magenta]Maven coordinates[/] or [cyan]jgo.toml[/].",
29-
epilog="[dim]TIP: Use [yellow]jgo --dry-run run[/] to see the command without executing it.[/]",
38+
help=f"Run a Java application from {MAVEN_COORDINATES} or {JGO_TOML}.",
39+
epilog=TIP_DRY_RUN,
3040
context_settings=dict(ignore_unknown_options=True, allow_interspersed_args=False),
3141
)
3242
@click.option(
3343
"--main-class",
3444
metavar="CLASS",
35-
help="Main class to run (supports [green]auto-completion[/] for simple names)",
45+
help=f"Main class to run (supports {action('auto-completion')} for simple names)",
3646
)
3747
@click.option(
3848
"--entrypoint",
3949
metavar="NAME",
40-
help="Run specific entrypoint from [cyan]jgo.toml[/]",
50+
help=f"Run specific entrypoint from {JGO_TOML}",
4151
)
4252
@click.option(
4353
"--add-classpath",
4454
multiple=True,
4555
metavar="PATH",
46-
help="Append to classpath ([dim]JARs, directories, etc.[/])",
56+
help=f"Append to classpath ({secondary('JARs, directories, etc.')})",
4757
)
4858
@click.argument(
4959
"endpoint",
5060
required=False,
5161
cls=click.RichArgument,
52-
help="Maven coordinates (single or combined with [yellow]+[/]) "
53-
"optionally followed by [yellow]@MainClass[/]",
62+
help=f"Maven coordinates (single or combined with {PLUS_OPERATOR}) "
63+
f"optionally followed by {AT_MAINCLASS}",
5464
)
5565
@click.argument(
5666
"remaining",
5767
nargs=-1,
5868
type=click.UNPROCESSED,
5969
cls=click.RichArgument,
60-
help="JVM arguments and program arguments, separated by [yellow]--[/]. "
61-
"Example: [dim]-- -Xmx2G -- script.py[/]",
70+
help=f"JVM arguments and program arguments, separated by {DOUBLE_DASH}. "
71+
f"Example: {secondary('-- -Xmx2G -- script.py')}",
6272
)
6373
@click.pass_context
6474
def run(ctx, main_class, entrypoint, add_classpath, endpoint, remaining):

0 commit comments

Comments
 (0)