1212import re
1313import shlex
1414import textwrap
15- from typing import Any , Callable , Dict , List , Tuple
15+ from typing import Any , Callable , Dict , List , Tuple , Type
1616
1717from qiime2 import ResultCollection
1818import qiime2 .sdk .usage as usage
1919from qiime2 .sdk .usage import (
20- UsageVariable , Usage , UsageInputs , UsageOutputs , UsageOutputNames
20+ UsageVariable , Usage , UsageInputs , UsageOutputs
2121)
22- from qiime2 .sdk import Action
2322from qiime2 .core .archive .provenance_lib .usage_drivers import (
24- build_header , build_footer
23+ build_header , build_footer , ReplayUsageAction
2524)
2625from qiime2 .core .archive .provenance_lib import ProvDAG
2726
@@ -439,6 +438,8 @@ def to_interface_name(self):
439438
440439
441440class ReplayCLIUsage (CLIUsage ):
441+ UsageAction : Type [ReplayUsageAction ] = ReplayUsageAction
442+
442443 shebang = '#!/usr/bin/env bash'
443444 header_boundary = ('#' * 79 )
444445 set_ex = [
@@ -506,11 +507,16 @@ def _append_action_line(self, signature, param_name: str, value):
506507 'when the plugin version you have\n # installed does not '
507508 'match the version used in the original analysis.\n # '
508509 'Please see the docs and correct the parameter name '
509- 'before running.\n ' )
510- cli_name = re .sub ('_' , '-' , param_name )
511- line += self .INDENT + '--?-' + cli_name + ' ' + str (value )
512- line += ' \\ '
510+ 'before running.' )
513511 self .recorder .append (line )
512+ self ._append_unknown_param (param_name , value )
513+
514+ def _append_unknown_param (self , param_name , value ):
515+ line = ''
516+ cli_name = re .sub ('_' , '-' , param_name )
517+ line += self .INDENT + '--?-' + cli_name + ' ' + str (value )
518+ line += ' \\ '
519+ self .recorder .append (line )
514520
515521 def _make_param (self , value : Any , state : Dict ) -> List [Tuple ]:
516522 '''
@@ -630,9 +636,9 @@ def comment(self, text):
630636
631637 def action (
632638 self ,
633- action : Action ,
639+ action : ReplayUsageAction ,
634640 inputs : UsageInputs ,
635- outputs : UsageOutputNames
641+ outputs : UsageOutputs
636642 ) -> UsageOutputs :
637643 '''
638644 Overrides parent method to fill in missing outputlines from
@@ -641,18 +647,40 @@ def action(
641647
642648 Parameters
643649 ----------
644- action : Action
645- The underlying sdk. Action object .
650+ action : ReplayUsageAction
651+ The object representing the Action we are replaying .
646652 inputs : UsageInputs
647653 Mapping of parameter names to arguments for the action.
648- outputs : UsageOutputNames
654+ outputs : ReplayUsageOutputNames
649655 Mapping of registered output names to usage variable names.
650656
651657 Returns
652658 -------
653659 UsageOutputs
654660 The results returned by the action.
655661 '''
662+ plugin_name = q2cli .util .to_cli_name (action .plugin_id )
663+ action_name = q2cli .util .to_cli_name (action .action_id )
664+
665+ if action .node ._action_present_ :
666+ variables = self ._action_found (
667+ plugin_name , action_name , action , inputs , outputs
668+ )
669+ else :
670+ variables = self ._action_not_found (
671+ plugin_name , action_name , action , inputs , outputs
672+ )
673+
674+ return variables
675+
676+ def _action_found (
677+ self , plugin_name : str , action_name : str ,
678+ action : ReplayUsageAction ,
679+ inputs : UsageInputs ,
680+ outputs : UsageOutputs
681+ ):
682+ self .recorder .append ('qiime %s %s \\ ' % (plugin_name , action_name ))
683+
656684 variables = Usage .action (self , action , inputs , outputs )
657685 vars_dict = variables ._asdict ()
658686
@@ -668,11 +696,6 @@ def action(
668696 # Otherwise, we should add filler values to missing_outputs
669697 missing_outputs [output ] = f'XX_{ output } '
670698
671- plugin_name = q2cli .util .to_cli_name (action .plugin_id )
672- action_name = q2cli .util .to_cli_name (action .action_id )
673- self .recorder .append ('qiime %s %s \\ ' % (plugin_name , action_name ))
674-
675- action_f = action .get_action ()
676699 action_state = get_action_state (action_f )
677700
678701 ins = inputs .map_variables (lambda v : v .to_interface_name ())
@@ -699,6 +722,39 @@ def action(
699722 self .recorder .append ('' )
700723 return variables
701724
725+ def _action_not_found (
726+ self , plugin_name : str , action_name : str ,
727+ action : ReplayUsageAction ,
728+ inputs : UsageInputs ,
729+ outputs : UsageOutputs
730+ ):
731+ variables = Usage .action_not_found (self , action , inputs , outputs )
732+ vars_dict = variables ._asdict ()
733+
734+ ins = inputs .map_variables (lambda v : v .to_interface_name ())
735+
736+ self .recorder .append (
737+ '# FIXME: The following action was not found in your current '
738+ 'QIIME 2\n # environment. Please ensure the action and its '
739+ 'parameters are correct before\n # running.'
740+ )
741+ self .recorder .append ('qiime %s %s \\ ' % (plugin_name , action_name ))
742+
743+ for param_name , value in ins .items ():
744+ self ._append_unknown_param (param_name , value )
745+
746+ dir_name = self ._build_output_dir_name (plugin_name , action_name )
747+ self .recorder .append (
748+ self .INDENT + '--output-dir %s \\ ' % (dir_name )
749+ )
750+ self ._rename_outputs (vars_dict , dir_name )
751+
752+ self .recorder [- 1 ] = self .recorder [- 1 ][:- 2 ] # remove trailing `\`
753+
754+ self .recorder .append ('' )
755+
756+ return variables
757+
702758 def render (self , flush = False ):
703759 '''
704760 Return a newline-seperated string of CLI script.
0 commit comments