
    5ij                        d Z ddlmZmZmZmZ ddlZddlZddlZddl	Z	ddl
Z
ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ h dZej1                  h d      Zej1                  h d      Z G d de      Zd Zd Zd Zd Z d Z!d,dZ"d,dZ#d,dZ$d Z%d Z&d-dZ'd Z(d Z)d Z*d Z+d Z,d  Z-d! Z.d" Z/d.d#Z0d$ Z1d% Z2d& Z3d' Z4d( Z5d) Z6d* Z7d+ Z8y)/zz
Workflow Builder Library
+++++++++++++++++++

Contains utility methods useful for deploying workflows onto the platform.
    )print_functionunicode_literalsdivisionabsolute_importN   )INTERACTIVE_CLI)process_extra_args)fill)json_load_raise_on_duplicates)err_exit)logger>   titledetailssummarydescriptiondeveloperNotes>   nametagsdxapibillToversion
categoriesregionalOptions>   folderinputsstagesoutputsproject
propertiesignoreReuseoutputFolderc                       e Zd ZdZy)WorkflowBuilderExceptionzb
    This exception is raised by the methods in this module when workflow
    building fails.
    N)__name__
__module____qualname____doc__     w/home/marpiech/ifpan-abm-pgxpred/analysis/marpiech-gwas-test/venv/lib/python3.12/site-packages/dxpy/workflow_builder.pyr#   r#   -   s     	r)   r#   c                 0   t         j                  j                  |       s |j                  dj	                  |              t         j                  j                  t         j                  j                  | |            st        dj	                  |             t        t         j                  j                  | |            5 }	 t        |      cddd       S # t        $ r*}t        dj	                  ||j                              d}~ww xY w# 1 sw Y   yxY w)z
    Returns the parsed contents of a json specification.
    Raises WorkflowBuilderException (exit code 3) if this cannot be done.
    z{} is not a directoryz]Directory {} does not contain dxworkflow.json: not a valid DNAnexus workflow source directoryNz#Could not parse {} file as JSON: {})ospathisdirerrorformatexistsjoinr#   openr   	Exceptionargs)src_dirjson_file_nameparserdesces        r*   _fetch_spec_from_dxworkflowjsonr;   5   s    
 77==!,33G<=77>>"'',,w?@&kVG_ 	 
bggll7N3	4 q	q06q q  	q*+P+W+WXfhihnhn+opp	qq qs*    D
C	D	%DD		DDc                     dd l }|j                  ddt        j                  |             j	                  dd      }t        j
                  |      S )Nr   z""\w*": (null|\{\}|""|\[\])(\,|)\s* z, }})resubjsondumpsreplaceloads)	json_specr?   
clean_jsons      r*   _cleanup_empty_keysrG   H   s?    @DJJyDYZbbchilmJ::j!!r)   c                 `   d}	 ddl m} | j                  d      ru| d   j                  d      rat        | d   j                  d            }|j                  d      d   } ||       ||      k  rt        d	j                  | d
   |            y t        d      # t        $ r	 ddlm} Y w xY w)Nz2.8.0r   )StrictVersionr   )Versionr   r   -zjSource workflow {} is not compiled using dxCompiler (version>={}) that supports creating global workflows.r   zCannot find the dxCompiler version from the dxworkflow.json/source workflow spec. Please specify it by updating the details field of the dxworkflow.json/source workflow spec using the 'version' key.)
distutils.versionrI   ImportErrorutils.versionrJ   getstrsplitr#   r0   )rE   SUPPORTED_DXCOMPILER_VERSIONrJ   compiler_version_usedcompiler_version_no_snapshots        r*   _check_dxcompiler_versionrU   M   s    #* +> }}YIi$8$<$<Y$G #Ii$8$<$<Y$G H'<'B'B3'G'J$/07;W3XX*  ,X  ,_  ,_  `i  jp  `q  sO  ,P  Q  Q Y '  (p  q  	q  +*+s   B B-,B-c                 p    | d   j                  dd      }|rt        dj                  | d                y y )Nr   staticInstanceTypeSelectionFzNote: {workflow} was compiled with -instanceTypeSelection=static and will produce a global workflow that relies on instance types that may not be available to all users.r   workflowrO   printr0   )rE   	is_statics     r*   _notify_instance_type_selectionr]   [   sA    )$(()FNI yvy0v1	3 r)   c                 h    | j                  d      }|rt        dj                  | d                y y )Nr   zNote: {workflow} was compiled with unbundled dependencies. Please check the workflow description and make sure access to these dependencies is provided to all authorized users.r   rX   rZ   )rE   dependency_lists     r*   _notify_dependenciesr`   b   s9     !}}]3_	 Fvy0v1
3 	r)   c                     |r|S d| v r| d   S t         j                  rt         j                  S d}|dz  }t        |      )a8  
    Returns destination project in which the workflow should be created.
    In can be set in multiple ways whose order of precedence is:
    1. --destination, -d option supplied with `dx build`,
    2. 'project' specified in the json file,
    3. project set in the dxpy.WORKSPACE_ID environment variable.
    r   zBCan't create a workflow without specifying a destination project; zDplease use the -d/--destination flag to explicitly specify a project)dxpyWORKSPACE_IDr#   )rE   r5   build_project_id	error_msgs       r*   _get_destination_projectrf   k   sP     I##   TIWWI
"9
--r)   c                 d    |xs | j                  d      xs d}|j                  d      s|dz   }|S )a   
    Returns destination project in which the workflow should be created.
    It can be set in the json specification or by --destination option supplied
    with `dx build`.
    The order of precedence is:
    1. --destination, -d option,
    2. 'folder' specified in the json file.
    r   /)rO   endswith)rE   folder_namedest_folders      r*   _get_destination_folderrl   ~   s:     ?x!8?CK$!C'r)   c                 ,    |xs | j                  d      S )a0  
    Returns the name of the workflow to be created. It can be set in the json
    specification or by --destination option supplied with `dx build`.
    The order of precedence is:
    1. --destination, -d option,
    2. 'name' specified in the json file.
    If not provided, returns empty string.
    r   )rO   )rE   workflow_names     r*   _get_workflow_namero      s     1IMM&11r)   c                 6    | D cg c]	  }||vs| c}S c c}w Nr(   )keyssupported_keyskeys      r*   _get_unsupported_keysru      s    =C3n#<C===s   	c                    t        |t              sJ t        j                  j	                  |       d   }t        |      j                  t        |            }t        |      j                  t        |            }|r,t        j                  j                  | dt        |      i       |r-t        j                  j                  | dt        |      i       yy)zo
    Note: Categories are set on the workflow series level,
    i.e. the same set applies to all versions.
    r   input_paramsN)	
isinstancelistrb   apiglobal_workflow_list_categoriesset
differenceglobal_workflow_add_categories!global_workflow_remove_categories)global_workflow_idcategories_to_setexisting_categoriescategories_to_addcategories_to_removes        r*   _set_categories_on_workflowr      s    
 './.((BBCUVWcd-.99#>Q:RS23>>sCT?UV//0B>JDQbLc=d 	0 	f223EAMtThOi@j 	3 	l r)   c                 (   	 | d   }| d   }||k(  r||k(  ry	 t        j                  j                  d| d   z   | d   ddddi      }|d   | d   k(  xr |d   | d   k(  S #  t        d      xY w# t        j                  j
                  $ r Y y	  xY w)
aK  
    Returns True if a global workflow with the given name and version
    already exists in the platform and the user has developer rights
    to the workflow. "name" and "version" can be passed if we already
    made a "describe" API call on the global workflow and so know the
    requested name and version already exists.
    r   r   z}Both 'name' and 'version' fields must be given in the dxworkflow.json/source workflow spec to build/update a global workflow.Tglobalworkflow-fields)r   r   aliasrx   F)r#   rb   r{   global_workflow_describe
exceptions
DXAPIError)rE   r   r   requested_namerequested_versiondesc_outputs         r*   _version_existsr      s    h"6*%i0 "3w">		((;;<MPYZ`Pa<aBKIBVJR]a`dUf Jg < hK v&)F*;;nI@VZcdmZn@nnh&  (g  h  	h )) 		s   
A  AA0  A-0BBc                     d| vrt        dj                  |            h d}t        | j                         |      }t	        |      dkD  r)t        dj                  dj                  |                   | S )N
executablez3executable is not specified for stage with index {}>   idr   inputr   r   executionPolicysystemRequirementsr   zMWarning: the following stage fields are not supported and will be ignored: {}, )r#   r0   ru   rr   lenr[   r2   )stagestage_indexrs   unsupported_keyss       r*   _get_validated_stager      su    5 &AHHUW 	W?N,UZZ\>J
q ]vdii 012	4 Lr)   c                    t        |t              st        d      t        |      }d|v rt	        |      dk(  ryt        | D cg c]  }|j                  d       c}      }|D ]   }||vst        dj                  |             yc c}w )z
    Checks if each stage ID specified in ignore_reuse_stages exists in
    the workflow definition. If ignore_reuse_stages contains
    only '*', the field is valid.
    z9"IgnoreReuse must be a list of strings - stage IDs or "*"*r   Nr   z]Stage with ID {} not found. Add a matching "id" for the stage you wish to set ignoreReuse for)ry   rz   r#   r}   r   rO   r0   )r   ignore_reuse_stagesignore_reuse_setr   	stage_idsignoreds         r*   validate_ignore_reuser      s     )40'(cd	d./
3'7#8A#=&9UYYt_9:I# A)#*ovvw~A AA :s   Bc                     t        | t              st        d      g }t        |       D ]   \  }}|j	                  t        ||             " |S )zE
    Validates stages of the workflow as a list of dictionaries.
    z2Stages must be specified as a list of dictionaries)ry   rz   r#   	enumerateappendr   )r   validated_stagesindexr   s       r*   _get_validated_stagesr      sV     fd#&'[\\!&) Du 4UE BCDr)   c                     i }t         j                  j                  |j                        \  }}}t	        | ||      |d<   t        | |      |d<   t        | |      }|st        d       |S ||d<   |S )zT
    Validates fields used only for building a regular, project-based workflow.
    r   r   z'Warning: workflow name is not specifiedr   )rb   executable_builderget_parsed_destinationdestinationrf   rl   ro   r[   )rE   r5   	validatedoverride_project_idoverride_folderoverride_workflow_namern   s          r*   #_validate_json_for_regular_workflowr      s     I66t7G7GH A*@3ItEXYIi1)_MIh&y2HIM78  *	&r)   c           	         d| vrt        d      t        j                  j                  j	                  | d         st        d      | d   | d   j                         k7  r't        j                  dj                  | d                d| vrt        d      t        j                  j                  j	                  | d         s't        j                  dj                  | d                d| v rt        | d   t              st        d	      d
| v r\t        | d
   t              r=| d
   r8t        | d
   j                         D cg c]  }t        |t               c}      st        d      yyc c}w )z
    Validates fields used for building a global workflow.
    Since building a global workflow is done after all the underlying workflows
    are built, which may be time-consuming, we validate as much as possible here.
    r   zldxworkflow.json/source workflow spec contains no 'name' field, but it is required to build a global workflowz8The name of your workflow must match /^[a-zA-Z0-9._-]+$/z*workflow name "{}" should be all lowercaser   zodxworkflow.json/source workflow spec contains no 'version' field, but it is required to build a global workflowz@"version" {} should be semver compliant (e.g. of the form X.Y.Z)r   z(The field "details" must be a dictionaryr   zXThe field "regionalOptions" must be a non-empty dictionary whose values are dictionariesN)r#   rb   r   GLOBAL_EXEC_NAME_REmatchlowerr   warnr0   GLOBAL_EXEC_VERSION_REry   dictallvalues)rE   r5   is      r*   "_validate_json_for_global_workflowr     sv    Y&z| 	|""66<<Yv=NO&FH 	HIf-3355@GG	RXHYZ[	!&} 	""99??	)@TUV]]^ghq^rstI)I.5*:< < I%9%67>/0i@Q6R6Y6Y6[\At,\]*jl l ^ & ]s   E,c                 $   | sy|syt        j                  |       }t        |j                         t              }t        |      dkD  r3t        j                  dj                  dj                  |                   d|v rt        |d         |d<   d|v r|j                  svt        j                  j                  t        j                  j                  |j                               }||d   k7  r(t        j                  dj                  |d   |             d|v rt#        |d   |d          t%        ||      }|j'                  |       |j(                  d	k(  rt+        | |      }|j'                  |       |j(                  d
k(  rt-        ||       |S )z
    Validates workflow spec and returns the json that can be sent with the
    /workflow/new API or /globalworkflow/new request.
    Nr   zRWarning: the following root level fields are not supported and will be ignored: {}r   r   r   z;workflow name "{}" does not match containing directory "{}"r    rY   globalworkflow)copydeepcopyru   rr   SUPPORTED_KEYSr   r   r   r0   r2   r   _fromr,   r-   basenamenormpathr6   r   '_get_validated_json_for_build_or_updateupdatemoder   r   )rE   r5   validated_specr   dir_namevalidated_documentation_fieldsr   s          r*   _get_validated_jsonr   2  sn   
 ]]9-N -^-@-@-BNS
q `		"234	6
 >!#89Q#Rx 

77##BGG$4$4T\\$BC~f--KKMTTUcdjUkmuvx &nX6}8UV%L^]a%b"89 yyJ7	4H	i( yy$$*>4@r)   c                 z   t        j                  |       }|j                  s*t        j                  j                  ||j                         d| vrt        j                  d       d| vrt        j                  d       |S | d   j                  d      r't        j                  dj                  | d                |S )z
    Validates those fields that can be used when either building
    a new version (of a local, project-based workflow) or updating
    an existing version (of a global workflow).
    r   z\dxworkflow.json/source workflow spec is missing a title, please add one in the 'title' fieldr   z`dxworkflow.json/source workflow spec is missing a summary, please add one in the 'summary' field.z:summary {} should be a short phrase not ending in a period)r   r   r   rb   r   inline_documentation_filesr6   r   r   ri   r0   )rE   r5   r   s      r*   r   r   a  s     i(I::::9dllSirs	!vw
  Y((-KKT[[\efo\prsr)   c           	      v   | s| S t        |j                  d      D cg c]  }|j                  d       c}      }|D ]  }|j                  d      rot        j                  |      j
                  }t        j                  |      j                  }|h| k7  sZt        dj                  |dj                  |                   |j                  d      rt        j                  j                  |ddd	ii
      }t        |d   j                               }| j                  |      r| j!                  |      }	dj                  |dj                  |      dj                  |             }
|
dj                  dj                  |	            z  }
|
dj                  dj                  |	            z  }
t#        j$                  |
       | j'                  |       |j                  d      r-t        j                  j)                  |      }t+        | |      } |j                  d      st        d       | S c c}w )aa  
    Check if the dependent apps/applets/subworkflows in the workflow are enabled in requested regions
    Returns the subset of requested regions where all the dependent executables are enabled
    If the workflow contains any applets, then the workflow can be currently enabled
    in only one region - the region in which the applets are stored.
    r   r   zapplet-z<The applet {} is not available in all requested region(s) {},zapp-r   r   Trw   zDThe app {} is enabled in regions {} while the global workflow in {}.r   z, The workflow will not be able to run in {}.zg If you are a developer of the app, you can enable the app in {} to run the workflow in that region(s).z	workflow-r   zLBuilding a global workflow with nested global workflows is not yet supported)sortedrO   
startswithrb   DXAppletr   	DXProjectregionr#   r0   r2   r{   app_describer}   rr   issubsetr~   r   r   intersection_updateworkflow_describe _assert_executable_regions_match)workflow_enabled_regionsworkflow_specr   executablesexectapplet_projectapplet_regionapp_regional_optionsapp_regionsadditional_workflow_regionsmesginner_workflow_specs               r*   r   r   x  s    $'' }7H7H7RS!!%%-STK {I&!]]5199N NN>:AAM"::./m06uchhG_>`0ac c f%#'88#8#8hYjlpXqMr#8#s 23DEJJLMK+44[A.F.Q.QR].^+]dd499[1499=U3VXFMMdiiXsNtuu  B  I  III9:< <D!(<<[Ik*"&(("<"<U"C'GH`bu'v$/0*+yzz7{: $#? Ts   H6c                     t         j                  j                  |       d   }|st         j                  j                  |       |S )z3
    Precondition: json_spec must be validated
    r   )rb   r{   workflow_newworkflow_close)rE   	keep_openworkflow_ids      r*   _build_regular_workflowr     s8     ((''	248K,r)   c           	      r   t         j                  j                  d| |j                  t              }|spg }t         j
                  sd}|dz  }|dz  }t	        |      t         j                  j                  t         j
                  dddii      d   }|j                  |       t        |      }t         j                  j                  | d	   t              }|j                  |      s8t	        d
j                  dj                  |j                  |                        t        ||       }|st!        d      |S )ax  
    Returns a set of regions (region names) in which the global workflow
    should be enabled. 
    
    1. validates and synchronizes the regions passed via CLI argument and in the regionalOptions field.
    2. checks if these regions are included in the permitted regions of the bill_to
    3. checks if the dependencies in all the stages are enabled in these regions
    r   zPA context project must be selected to enable a workflow in the project's region.zS You can use 'dx select' to select a project. Otherwise you can use --region optionz; to select a region in which the workflow should be enabledr   r   Trw   r   zlThe global workflow cannot be enabled in regions {}, which are not among the permittedRegions of the billTo.r   z7This workflow should be enabled in at least one region.)rb   r   get_enabled_regionsr   r#   PROJECT_CONTEXT_IDr{   project_describer   r}   get_permitted_regionsr   r0   r2   r~   r   AssertionError)rE   r5   enabled_regionsmsgcurrent_selected_regionbillable_regionss         r*   _get_validated_enabled_regionsr     sB    --AABRBKBF++BZ\O &&dChhCPPC*3/0"&((";";D<S<S9AHdCS8T #< #VV^#` 	67 /*O..DD(57##$45&  (V(.sxx8R8RSc8d/e(fh 	h 7	ROVWWr)   c                 <   i }| D ]T  }	 d||d}t         j                  j                  |      d   }|||<   t        j                  dj                  |             V |S #  |r-t         j                  j                  |j                                t                Y xY w)a  
    Creates a temporary project needed to build an underlying workflow
    for a global workflow. Returns a dictionary with region names as keys
    and project IDs as values

    The regions in which projects will be created can be:
    i. regions specified in the dxworkflow.json/source workflow spec "regionalOptions"
    ii. regions specified as the argument "--region" when calling "dx build"
    iii. current context project, if none of the above are set
    iv. the regions where dependent applets/apps/workflows are enabled
    z4Temporary build project for dx build global workflow)r   r   r   r   z(Created temporary project {} to build in)
rb   r{   project_newr   debugr0   r   delete_temporary_projectsr   r   )r   bill_toprojects_by_regionr   project_inputtemp_projects         r*   _create_temporary_projectsr    s     ! 	%['-'.0M  88//>tDL)5v&LLCJJ<XY 	!''AABTB[B[B]^Js   AA;Bc                 4   t        | |d         }i }	 |j                         D ]:  \  }}||d<   d|d<   t        |      }t        j                  d|z   dz          |||<   < 	 ||fS #  |r-t
        j                  j                  |j                                 xY w)z
    Creates a workflow in a temporary project for each enabled region.
    Returns a tuple of dictionaries: workflow IDs by region and project IDs by region.
    The caller is responsible for destroying the projects if this method returns properly.
    r   r   rh   r   zCreated workflow z successfully)	r  itemsr   r   r   rb   r   r   r   )r   rE   r5   r   workflows_by_regionr   r   r   s           r*   _build_underlying_workflowsr    s     4OYxEXY1779 	6OFG $+Ii "%Ih1)<KLL,{:_LM*5'	6  222##==>P>W>W>YZs   AA% %2Bc                    i i }}	 | j                  di       }|rt        |j                               t        |      k7  rJt        ddj	                  t        |      j                  t        |j                                                 t        j                  |      }nt        j                  |i       }t        || |      \  }}|j                         D ]  \  }}|||   d<    | j                  d|i       t        j                  t        | j                                     t        fd| j                         D              }	t        j                  |	      }
d|	v r|
d= d|	v r|
d= t        j                   dj#                  t%        j&                  |
                   t(        j*                  j-                  |	      d	   }t        j                   d
j#                  |	d   |	d                t        j                   d       t        j                   dj#                  |	d   |	d                |r.t(        j.                  j1                  |j3                                	 	 t5        ||	j                  dg              |S # |r.t(        j.                  j1                  |j3                                w w xY w#  t        j6                  dj#                  |	d   |	d                 xY w)z
    Creates a workflow in a temporary project for each enabled region
    and builds a global workflow on the platform based on these workflows.
    r   zThese enabled regions do have regional options specified                                            in the JSON spec or from --extra-args: {}r   rY   c              3   6   K   | ]  \  }}|v s||f  y wrq   r(   ).0kvgwf_provided_keyss      r*   	<genexpr>z)_build_global_workflow.<locals>.<genexpr>0  s!     ]AaK\F\q!f]s   	r   r   z)Will create global workflow with spec: {}r   z-Uploaded global workflow {n}/{v} successfullyr   r   )nr  z#You can publish this workflow with:z  dx publish {n}/{v}r   z>The workflow {n}/{v} was created but setting categories failed)rO   r}   rr   r#   r2   r~   r   r   r   fromkeysr  r  r   GLOBALWF_SUPPORTED_KEYSintersectionr   infor0   rA   rB   rb   r{   global_workflow_newr   r   r   r   r   )rE   r   r5   r  r   existing_regional_optionsupdated_regional_optionsr   r   gwf_final_json
print_specr   r  s               @r*   _build_global_workflowr    s   
 /1"+-[$-MM2CR$H!$,1134O8LL. 0V+.88C4H4S4STWXqXvXvXxTy4z+{} } '+mm4M&N$'+}}_b'I$ (DI 	0/#6#<#<#> 	GFK;F$V,Z8	G 	+-EFG 4@@Y^^EUAVW]1B]] ]]>2
N*=)~-+,?FFtzzR\G]^_ "XX99.I$OCJJ^\bMcM[\eMf K h 	i9:*11N64J4B94M 2 O 	P ##==>P>W>W>YZ#$68J8J<Y[8\]  ##==>P>W>W>YZ LSSVdekVlVdenVo T q	r 	s   H)I? !J4 ?2J14/K#c                 b     fd}t        d  j                         D              }t        |      }t        d |j                         D              j                  r7 |       s0t        j
                  j                  d d   z    d         d   }|S t        j                  d	       |S )
Nc                     d} rdj                  d   d   dj                              }j                  r{t        r\	 t	        d       t	        t        d|z                t	        d       t        d      }|j                         j                  d
      s2d} | S t        j                  d       d} | S t        j                  |       | S d} t        j                  d       | S # t        $ r d	}Y yw xY w)NFz]The global workflow {}/{} exists so we will update the following fields for this version: {}.r   r   r   z***zINFO: z$Confirm making these updates [y/N]: r  yTzskipping requested change to update a global workflow version. Rerun "dx build" interactively or pass --yes to confirm this change.zNothing to update)r0   r2   confirmr   r[   r
   r   KeyboardInterruptr   r   r   r   r  )skip_updateupdate_messagevaluer5   rE   non_empty_fieldss      r*   r  z,_update_global_workflow.<locals>.skip_updateU  s   |  D  D&!9Y#7CS9TVN ||"$ed8n#<=>e %&L M !;;=33C8&*  KK ^_"&K 	 N+  KKK+, - $ #$s   8C% %C32C3c              3   <   K   | ]  \  }}|t         v s||f  y wrq   )UPDATABLE_GLOBALWF_FIELDSr	  r
  r  s      r*   r  z*_update_global_workflow.<locals>.<genexpr>r  s      ^$!QqD]?]1v^s   	c              3   0   K   | ]  \  }}|s	||f  y wrq   r(   r$  s      r*   r  z*_update_global_workflow.<locals>.<genexpr>t  s     Ktq!QFKs   
	r   r   r   r   r   zSkipping making updates)	r   r  r   r   rb   r{   global_workflow_updater   r  )rE   r5   r   r  update_specr   r!  s   ``    @r*   _update_global_workflowr(  S  s    : ^)//*;^^K<[$ONK~/C/C/EKK{{;=!XX<<=NQZ[aQb=bCLYCWJZ = \\`b
  	-.r)   c                 t   	 | j                   dk(  rZt        | j                  d|      }|j                  | j                  xs i        t        ||       }t        || j                        }|S | j                   dk(  rt| j                  r| j                  }nt        | j                  d|      }| j                  r| j                  |d<   |j                  | j                  xs i        t        ||       }|j                  d      r4d|d   v r-t        |       | j                  st        |       t        |       t        |      }t         j"                  j%                  d|d   z         }|r:t'        ||j(                  |j*                        rt-        || |j.                        }|S t         j"                  j1                  | j2                  t4              |d	<   t7        ||       }t9        |||       }	 |S t5        d
j;                  | j                               # t         j<                  j>                  $ r}|d}~ww xY w)z
    Creates or updates a workflow on the platform.
    Returns the workflow ID, or None if the workflow cannot be created.
    rY   zdxworkflow.jsonr   r   r   
dxCompilerr   r   r   zUnrecognized workflow type: {}N) r   r;   r6   r   
extra_argsr   r   r   r   version_overriderO   rU   briefr]   r`   rG   rb   r   verify_developer_rightsr   r   r   r(  r   get_valid_bill_tor   r#   r   r  r0   r   r   )r5   r8   rE   r   existing_workflowr   r:   s          r*   _build_or_update_workflowr1    s   
.99
"7FWY_`IT__23+It<I1)T^^LKT S YY**zz JJ	;DLLJ[]cd	
 $$'+'<'<	)$T__23+It<I }}V$69J)J))4zz3I>(3+I6I !% 7 7 O OPadmntduPu v _Y5F5K5K5F5N5N&P 6iGXG[G[\  '+&=&=&O&OPTP\P\^v&w	(#"@D"Q4YQUV
  ++K+R+RSWS\S\+]^^??%% s,   A'H +D5H "A
H /$H H70H22H7c                 :   |j                   r/|j                  dk(  r t        j                  j	                  |       }n?|j                   r/|j                  dk(  r t        j                  j                  |       }nd| i}|t        t        j                  |             y y )NrY   r   r   )rA   r   rb   r{   r   r   r[   rB   )r   r5   outputs      r*   _print_outputr4    su    yyTYY*,++K8	tyy$4422;?$djj ! r)   c                    | t        d      	 t        |        t        | |      }t        ||        y# t        $ rI}t        dj                  |      t        j                         t        j                  d       Y d}~yd}~ww xY w)z
    Validates workflow source directory and creates a new (global) workflow based on it.
    Raises: WorkflowBuilderException if the workflow cannot be created.
    NzArguments not providedz	Error: {})file   )
r4   r	   r1  r4  r#   r[   r0   sysstderrexit)r5   r8   r   r:   s       r*   buildr;    sn    
 |0114 /f=k4(# k  ##**5s   #3 	B?B  Brq   )NN)F)9r'   
__future__r   r   r   r   r,   r8  rA   r   rb   clir   cli.parsersr	   utils.printingr
   utilsr   r   r   r=   r   r#  unionr  r   r4   r#   r;   rG   rU   r]   r`   rf   rl   ro   ru   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r(  r1  r4  r;  r(   r)   r*   <module>rB     s  $ S R 	 
      +   0   \ 399 ;d e (.. 0b c	y 	q&"
q33.&	2>l$:"A(	$lF,^.*$X(V<36>B)X4n"r)   