Skip to content

Commit 25488bb

Browse files
committed
Placeholders are being prompted, but later still excepts.
1 parent 1887c0e commit 25488bb

File tree

3 files changed

+180
-16
lines changed

3 files changed

+180
-16
lines changed

src/aiida/cmdline/commands/cmd_computer.py

Lines changed: 91 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ def set_template_vars_in_context(ctx, param, value):
285285
return value
286286

287287

288+
288289
# Modified computer setup command
289290
@verdi_computer.command('setup')
290291
@options_computer.LABEL()
@@ -300,17 +301,19 @@ def set_template_vars_in_context(ctx, param, value):
300301
@options_computer.USE_DOUBLE_QUOTES()
301302
@options_computer.PREPEND_TEXT()
302303
@options_computer.APPEND_TEXT()
303-
# @options.NON_INTERACTIVE()
304-
# @options.CONFIG_FILE() # Keep the original config option for backward compatibility
305-
@options.TEMPLATE_FILE() # Add our new template option
304+
@options.NON_INTERACTIVE() # Uncomment this line
305+
@options.TEMPLATE_FILE()
306306
@options.TEMPLATE_VARS()
307307
@click.pass_context
308308
@with_dbenv()
309309
def computer_setup(ctx, non_interactive, template, template_vars, **kwargs):
310310
"""Create a new computer."""
311311
from aiida.orm.utils.builders.computer import ComputerBuilder
312312

313-
print('HELLO')
313+
# Debug output
314+
print(f"Debug: non_interactive = {non_interactive}")
315+
print(f"Debug: kwargs keys = {list(kwargs.keys())}")
316+
print(f"Debug: ctx.default_map = {ctx.default_map}")
314317

315318
# Handle template variables
316319
template_var_dict = None
@@ -369,6 +372,90 @@ def computer_setup(ctx, non_interactive, template, template_vars, **kwargs):
369372
profile = ctx.obj['profile']
370373
echo.echo_report(f' verdi -p {profile.name} computer configure {computer.transport_type} {computer.label}')
371374

375+
# Modified computer setup command
376+
# @verdi_computer.command('setup')
377+
# @options_computer.LABEL()
378+
# @options_computer.HOSTNAME()
379+
# @options_computer.DESCRIPTION()
380+
# @options_computer.TRANSPORT()
381+
# @options_computer.SCHEDULER()
382+
# @options_computer.SHEBANG()
383+
# @options_computer.WORKDIR()
384+
# @options_computer.MPI_RUN_COMMAND()
385+
# @options_computer.MPI_PROCS_PER_MACHINE()
386+
# @options_computer.DEFAULT_MEMORY_PER_MACHINE()
387+
# @options_computer.USE_DOUBLE_QUOTES()
388+
# @options_computer.PREPEND_TEXT()
389+
# @options_computer.APPEND_TEXT()
390+
# # @options.NON_INTERACTIVE()
391+
# # @options.CONFIG_FILE() # Keep the original config option for backward compatibility
392+
# @options.TEMPLATE_FILE() # Add our new template option
393+
# @options.TEMPLATE_VARS()
394+
# @click.pass_context
395+
# @with_dbenv()
396+
# def computer_setup(ctx, non_interactive, template, template_vars, **kwargs):
397+
# """Create a new computer."""
398+
# from aiida.orm.utils.builders.computer import ComputerBuilder
399+
400+
# print('HELLO')
401+
402+
# # Handle template variables
403+
# template_var_dict = None
404+
# if template_vars:
405+
# try:
406+
# template_var_dict = json.loads(template_vars)
407+
# except json.JSONDecodeError as e:
408+
# echo.echo_critical(f'Invalid JSON in template-vars: {e}')
409+
410+
# # Process template if provided
411+
# if template:
412+
# try:
413+
# # Load and process the template
414+
# config_data = load_and_process_template(
415+
# template, interactive=not non_interactive, template_vars=template_var_dict
416+
# )
417+
418+
# # Update kwargs with config file data
419+
# # Only update if the value wasn't explicitly provided on command line
420+
# for key, value in config_data.items():
421+
# if key not in kwargs or kwargs[key] is None:
422+
# kwargs[key] = value
423+
424+
# except Exception as e:
425+
# echo.echo_critical(f'Error processing template: {e}')
426+
427+
# # Check for existing computer
428+
# if kwargs.get('label') and kwargs['label'] in get_computer_names():
429+
# echo.echo_critical(
430+
# 'A computer called {c} already exists. '
431+
# 'Use "verdi computer duplicate {c}" to set up a new '
432+
# 'computer starting from the settings of {c}.'.format(c=kwargs['label'])
433+
# )
434+
435+
# # Convert entry points to their names
436+
# if kwargs.get('transport'):
437+
# kwargs['transport'] = kwargs['transport'].name
438+
# if kwargs.get('scheduler'):
439+
# kwargs['scheduler'] = kwargs['scheduler'].name
440+
441+
# computer_builder = ComputerBuilder(**kwargs)
442+
# try:
443+
# computer = computer_builder.new()
444+
# except (ComputerBuilder.ComputerValidationError, ValidationError) as e:
445+
# echo.echo_critical(f'{type(e).__name__}: {e}')
446+
447+
# try:
448+
# computer.store()
449+
# except ValidationError as err:
450+
# echo.echo_critical(f'unable to store the computer: {err}. Exiting...')
451+
# else:
452+
# echo.echo_success(f'Computer<{computer.pk}> {computer.label} created')
453+
454+
# echo.echo_report('Note: before the computer can be used, it has to be configured with the command:')
455+
456+
# profile = ctx.obj['profile']
457+
# echo.echo_report(f' verdi -p {profile.name} computer configure {computer.transport_type} {computer.label}')
458+
372459

373460
@verdi_computer.command('duplicate')
374461
@arguments.COMPUTER(callback=set_computer_builder)

src/aiida/cmdline/params/options/config.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,6 @@ def configuration_callback(
7575
except Exception as exception:
7676
raise click.BadOptionUsage(option_name, f'Error reading configuration file: {exception}', ctx)
7777

78-
import ipdb
79-
80-
ipdb.set_trace()
8178
valid_params = [param.name for param in ctx.command.params if param.name != option_name]
8279
specified_params = list(config.keys())
8380
unknown_params = set(specified_params).difference(set(valid_params))

src/aiida/cmdline/params/options/main.py

Lines changed: 89 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -913,18 +913,98 @@ def set_log_level(ctx, _param, value):
913913
help='End date for node mtime range selection for node collection dumping.',
914914
)
915915

916-
# Add a new option for template variables in non-interactive mode
917-
TEMPLATE_VARS = OverridableOption(
918-
'--template-vars',
919-
type=click.STRING,
920-
help='JSON string containing template variable values for non-interactive mode. '
921-
'Example: \'{"label": "my-computer", "slurm_account": "my_account"}\'',
922-
)
916+
import click
917+
918+
from aiida.cmdline.utils import echo
919+
from aiida.cmdline.utils.template_config import load_and_process_template
920+
921+
from .overridable import OverridableOption
922+
923+
924+
class TemplateOption(OverridableOption):
925+
"""Option that processes Jinja2 templates and updates Click context defaults."""
926+
927+
def __init__(self, *args, **kwargs):
928+
"""Initialize the template option."""
929+
kwargs.setdefault('is_eager', True) # Process template before other options
930+
kwargs.setdefault('expose_value', False) # Don't pass template to the command function
931+
super().__init__(*args, **kwargs)
932+
933+
def __call__(self, **kwargs):
934+
"""Create the option with updated kwargs."""
935+
kw_copy = self.kwargs.copy()
936+
kw_copy.update(kwargs)
937+
938+
# Set the callback to process the template
939+
saved_callback = kw_copy.get('callback')
940+
kw_copy['callback'] = lambda ctx, param, value: self._process_template(ctx, param, value, saved_callback)
941+
942+
return click.option(*self.args, **kw_copy)
943+
944+
def _process_template(self, ctx, param, value, saved_callback):
945+
"""Process the template file and update context defaults."""
946+
if not value:
947+
return saved_callback(ctx, param, value) if saved_callback else value
948+
949+
ctx.default_map = ctx.default_map or {}
923950

924-
# Create an enhanced config file option
925-
TEMPLATE_FILE = OverridableOption(
951+
# Get template vars from context if they were set by TEMPLATE_VARS option
952+
template_vars = getattr(ctx, '_template_vars', None)
953+
954+
# Determine if we're in non-interactive mode
955+
non_interactive = False
956+
for ctx_param in ctx.params.values():
957+
if isinstance(ctx_param, bool) and 'non_interactive' in str(ctx_param):
958+
non_interactive = ctx_param
959+
break
960+
961+
try:
962+
# Load and process the template
963+
config_data = load_and_process_template(value, interactive=not non_interactive, template_vars=template_vars)
964+
965+
# Update the default map with template values
966+
# This will set defaults for options that haven't been explicitly provided
967+
for key, template_value in config_data.items():
968+
if key not in ctx.default_map:
969+
ctx.default_map[key] = template_value
970+
971+
except Exception as e:
972+
echo.echo_critical(f'Error processing template: {e}')
973+
974+
return saved_callback(ctx, param, value) if saved_callback else value
975+
976+
977+
# Updated TEMPLATE_FILE option
978+
TEMPLATE_FILE = TemplateOption(
926979
'--template',
927980
type=click.STRING,
928981
help='Load computer setup from configuration file in YAML format (local path or URL). '
929982
'Supports Jinja2 templates with interactive prompting.',
930983
)
984+
985+
import json
986+
987+
988+
# Helper function to set template vars in context (updated)
989+
def set_template_vars_in_context(ctx, param, value):
990+
"""Set template variables in the context for the template option to use."""
991+
if value:
992+
try:
993+
template_var_dict = json.loads(value)
994+
# Store template vars in context for the template option to use
995+
ctx._template_vars = template_var_dict
996+
except json.JSONDecodeError as e:
997+
raise click.BadParameter(f'Invalid JSON in template-vars: {e}')
998+
return value
999+
1000+
1001+
# Updated TEMPLATE_VARS option with callback
1002+
TEMPLATE_VARS = OverridableOption(
1003+
'--template-vars',
1004+
type=click.STRING,
1005+
is_eager=True, # Process before template option
1006+
callback=set_template_vars_in_context,
1007+
expose_value=False, # Don't pass to command function
1008+
help='JSON string containing template variable values for non-interactive mode. '
1009+
'Example: \'{"label": "my-computer", "slurm_account": "my_account"}\'',
1010+
)

0 commit comments

Comments
 (0)