
    ee@                     B   d Z ddl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mZ ddlmZmZ ddlmZmZmZ dd	lmZ dd
lmZ ddlmZmZmZmZ  ej@                  e!      Z"d Z#dddZ$	 ddZ%ddZ&	 dde'de(dddede)f
dZ*d Z+	 	 	 	 	 	 ddZ,y)z;Functions for generating a project from a project template.    N)OrderedDict)Path)	is_binary)EnvironmentFileSystemLoader)TemplateSyntaxErrorUndefinedError)ContextDecodingExceptionOutputDirExistsExceptionUndefinedVariableInTemplate)find_template)run_hook_from_repo_dir)create_env_with_contextmake_sure_path_existsrmtreework_inc                 p    	 |d   d   D ]  }t        j                   | |      s y 	 y# t        $ r Y yw xY w)aE  Check whether the given `path` should only be copied and not rendered.

    Returns True if `path` matches a pattern in the given `context` dict,
    otherwise False.

    :param path: A file-system path referring to a file or dir that
        should be rendered or just copied.
    :param context: cookiecutter context.
    cookiecutter_copy_without_renderTF)fnmatchKeyError)pathcontextdont_renders      5lib/python3.12/site-packages/cookiecutter/generate.pyis_copy_only_pathr   !   sK    ">23IJ 	Kt[1	   s   !) ) ) 	55Fin_dictionary_variablec          	         |j                         D ]  \  }}|| vr|s|| |<   | |   }t        |t              r|r|| |<   /t        |t              r<t        |      j	                  t        |            r|| |<   ht        | d| d|       ||v r$|j                  |       |j                  d|       t        | d| d| d      t        |t              r$t        |t              rt        ||d       || |<   || |<    y	)
zAModify the given context in place based on the overwrite_context.z$ provided for multi-choice variable z, but valid choices are r   z provided for choice variable z, but the choices are .Tr   N)
items
isinstancelistsetissubset
ValueErrorremoveinsertdictapply_overwrites_to_context)r   overwrite_contextr   variable	overwritecontext_values         r   r*   r*   5   sA     1668 ,*)7") )GH)mT*%$-!)T* y>**3}+=>(1GH%$$+%I#*$<]OM  - "((3!((I6$$+%C#*$:=/L  t,It1L'y !.GH !*GHY,*    c                 p   t        g       }	 t        | d      5 }t        j                  |t               }ddd       t
        j                  j                  |       d   }
|
j                  d	      d
   }||<   |r	 t        ||       |rt        ||       t        j                  d|       |S # 1 sw Y   yxY w# t        $ rD}t
        j                  j                  |       }t        |      }d| d| d}	t        |	      |d}~ww xY w# t        $ r"}t        j                  d|        Y d}~d}~ww xY w)a  Generate the context for a Cookiecutter project template.

    Loads the JSON file as a Python object, with key being the JSON filename.

    :param context_file: JSON file containing key/value pairs for populating
        the cookiecutter's variables.
    :param default_context: Dictionary containing config to take into account.
    :param extra_context: Dictionary containing configuration overrides
    utf-8encoding)object_pairs_hookNz#JSON decoding error while loading 'z'. Decoding error details: ''   r    r   zInvalid default received: zContext generated is %s)r   openjsonloadr&   osr   abspathstrr
   splitr*   warningswarnloggerdebug)context_filedefault_contextextra_contextr   file_handleobje
full_fpathjson_exc_messageour_exc_message	file_name	file_stemerrors                r   generate_contextrN   h   s9    "oG?,1 	H[))K;GC	H l+A.I$Q'IGI 	@'_= #C7
LL*G4N;	H 	H 	? WW__\2
q61* >((8'9< 	 '7Q>	?*  	@MM6ug>??	@sE   B: B.B: <D
 .B73B: :	D?DD
	D5D00D5c                    t         j                  d|       |j                  |      }t        j                  j                  |  |j                  di |      }t        j                  j                  |      }|rt         j                  d|       y|r6t        j                  j                  |      rt         j                  d|       yt         j                  d|       t         j                  d|       t        |      rDt         j                  d||       t        j                  ||       t        j                  ||       y|j                  t        j                  j                  d      }	 |j                  |      }	 |	j                  di |}|d
   j%                  dd	      r(|d
   d   }t         j                  dt'        |             nzt)        |d      5 }|j+                          ddd       t-        j.                  t0              r|j.                  d   n|j.                  }t         j                  dt'        |             t         j                  d|       t)        |dd|      5 }|j3                  |       ddd       t        j                  ||       y# t         $ r}
d	|
_         d}
~
ww xY w# 1 sw Y   xY w# 1 sw Y   ExY w)a/  Render filename of infile as name of outfile, handle infile correctly.

    Dealing with infile appropriately:

        a. If infile is a binary file, copy it over without rendering.
        b. If infile is a text file, render its contents and write the
           rendered infile to outfile.

    Precondition:

        When calling `generate_file()`, the root template dir must be the
        current working directory. Using `utils.work_in()` is the recommended
        way to perform this directory change.

    :param project_dir: Absolute path to the resulting generated project.
    :param infile: Input file to generate the file from. Relative to the root
        template dir.
    :param context: Dict for populating the cookiecutter's variables.
    :param env: Jinja2 template execution environment.
    zProcessing file %sz$The resulting file name is empty: %sNz%The resulting file already exists: %szCreated file at %sz Check %s to see if it's a binaryz)Copying binary %s to %s without rendering/Fr   
_new_linesz%Using configured newline character %sr1   r2   r   z#Using detected newline character %szWriting contents to file %sw)r3   newline )r@   rA   from_stringr:   r   joinrenderisdirexistsr   shutilcopyfilecopymodereplacesepget_templater   
translatedgetreprr7   readliner"   newlinestuplewrite)project_dirinfiler   envskip_if_file_existsoutfile_tmploutfilefile_name_is_emptyinfile_fwd_slashestmpl	exceptionrendered_filerS   rdfhs                  r   generate_filert      s7   * LL%v. ??6*Lggll;(;(;(;(Fg(FGGw/;WErww~~g6<gF
LL%w/ LL3V<@&'R((  S9 23  DKK*'*M~""<7.),7<d7mL
 &7+ 	rKKM	$.r{{E$B"++a.:DMJ
LL.8	gsWg	>  "
  OOFG$5    %			 	   s0   .J J7-K	J4'J//J47K Kdirnamer   
output_dirzos.PathLike[str]environmentoverwrite_if_existsc                 &   |j                  |       } |j                  di |}t        ||      }t        j	                  d||       |j                         }|r*|rt        j	                  d|       nd| d}	t        |	      t        |       || fS )zBRender name of a directory, create the directory, return its path.z+Rendered dir %s must exist in output_dir %sz2Output directory %s already exists, overwriting itzError: "z" directory already existsrT   )rU   rW   r   r@   rA   rY   r   r   )
ru   r   rv   rw   rx   	name_tmplrendered_dirnamedir_to_createoutput_dir_existsmsgs
             r   render_and_create_dirr      s     ''0I'y''2'2%56M
LL5}j &,,.LLDm ]O+EFC*3//m,////r/   c                 X    t        j                  dt        d       t        | ||||       y)a|  Run hook from repo directory, clean project directory if hook fails.

    :param repo_dir: Project template input directory.
    :param hook_name: The hook to execute.
    :param project_dir: The directory to execute the script from.
    :param context: Cookiecutter project context.
    :param delete_project_on_failure: Delete the project directory on hook
        failure?
    zmThe '_run_hook_from_repo_dir' function is deprecated, use 'cookiecutter.hooks.run_hook_from_repo_dir' instead   N)r>   r?   DeprecationWarningr   )repo_dir	hook_namerg   r   delete_project_on_failures        r   _run_hook_from_repo_dirr   
  s2     MM	B		 )['3Lr/   c           
      	   |xs t        g       }t        |      }t        | |      }t        j	                  d|       t
        j                  j                  |      d   }		 t        |	||||      \  }
}t
        j                  j                  |
      }
t        j	                  d|
       |xr | }|rt        | d|
||       t        |      5  t        dd	g      |_        t        j                   d      D ]  \  }}}g }g }|D ]  }t
        j                  j#                  t
        j                  j%                  ||            }t'        ||      r(t        j	                  d
|       |j)                  |       t|j)                  |        |D ]  }t
        j                  j#                  t
        j                  j%                  ||            }t
        j                  j#                  t
        j                  j%                  |
|            } |j+                  |      j,                  di |}t        j	                  d||       t
        j                  j/                  |      rt1        j2                  |       t1        j4                  ||        ||dd |D ]3  }t
        j                  j%                  |
||      }		 t        |	||||       5 |D ]  }t
        j                  j#                  t
        j                  j%                  ||            }t'        ||      r|j+                  |      } |j,                  di |}t
        j                  j%                  |
|      }t        j	                  d||       t1        j8                  ||       t1        j:                  ||       	 t=        |
||||         	 ddd       |rt        | d|
||       |
S # t        $ r}d|	 d}t        |||      |d}~ww xY w# t        $ rF}|rt3        |
       t
        j                  j7                  |	|      }d| d}t        |||      |d}~ww xY w# t        $ r&}|rt3        |
       d| d}t        |||      |d}~ww xY w# 1 sw Y   xY w)a}  Render the templates and saves them to files.

    :param repo_dir: Project template input directory.
    :param context: Dict for populating the template's variables.
    :param output_dir: Where to output the generated project dir into.
    :param overwrite_if_exists: Overwrite the contents of the output directory
        if it exists.
    :param skip_if_file_exists: Skip the files in the corresponding directories
        if they already exist
    :param accept_hooks: Accept pre and post hooks if set to `True`.
    :param keep_project_on_failure: If `True` keep generated project directory even when
        generation fails
    zGenerating project from %s...r6   z$Unable to create project directory 'r5   NzProject directory is %spre_gen_projectr    z../templateszFound copy only path %sz&Copying dir %s to %s without renderingzUnable to create directory 'z'Copying file %s to %s without renderingzUnable to create file 'post_gen_projectrT   )r   r   r   r@   rA   r:   r   r=   r   r	   r   r;   r   r   r   loaderwalknormpathrV   r   appendrU   rW   rX   rZ   r   copytreerelpathr[   r\   rt   )r   r   rv   rx   rj   accept_hookskeep_project_on_failureri   template_dirunrendered_dirrg   output_directory_createderrr~   r   rootdirsfiles	copy_dirsrender_dirsdd_copy_dirindiroutdir_dirfrh   rk   outfile_renderedrl   s                                  r   generate_filesr   !  s;   , (RG
!'
*C 3/L
LL0,?WW]]<03NF0EGZ6I1
-- ''//+.K
LL*K8 !9 XAX=X'g?X	
 
	 FR%sN&;<
!# C	RD$ IK 	*WW%%bggll4&;< %R1LL!:A>$$Q'&&q)	* & /((dH)EF))"'',,{E*JK7077B'BEufU
 77==(MM&)v./ "DG R!#k4!C	R)&SBUR  R))"'',,tQ*?@$VW5#&??6#:L':|':':'EW'E$ ggll;8HIGLLA67 OOFG4OOFG4R!#VWc;NR_C	RFRP %	
 Q  F4^4DAF)#sG<#EFD & R0{+77??>:FD8a@C5c3HcQR. & R0{+3F81=C5c3HcQ	REFR FRso    O 
G,Q77O3CQ7Q-Q7	O0O++O03	Q	<AP=	=Q	Q7	Q4	!Q/	/Q4	4Q77R )zcookiecutter.jsonNN)F)Nr    FFTF)-__doc__r   r8   loggingr:   rZ   r>   collectionsr   pathlibr   binaryornot.checkr   jinja2r   r   jinja2.exceptionsr   r	   cookiecutter.exceptionsr
   r   r   cookiecutter.findr   cookiecutter.hooksr   cookiecutter.utilsr   r   r   r   	getLogger__name__r@   r   r*   rN   rt   r<   r)   boolr   r   r   rT   r/   r   <module>r      s    A    	   #  ' 0 A 
 , 5  
		8	$* ;@0*h KO,^O%n !&000 #0 	0
 0B2 !Jr/   