
    <Bhu>                       S r SSKJr  SSKrSSKrSSKrSSKrSSKJr  SSK	J
r
Jr  SSKJr  SSKJr  SS	KJr  SS
KJrJrJr  SSKJrJr  SSKJrJr  SSKJr  \" \5      rSr \(       a  SOSr!Sr" " S S\#5      r$SS jr%\\RL                  \RN                  4           SS jjr( S           SS jjr)  S            S!S jjr*S"S jr+        S#S jr,S$S jr- S%     S&S jjr.g)'zTools for cross-OS portability.    )annotationsN)	getLogger)basenamerealpath   )dals)PREFIX_PLACEHOLDER)context)on_linuxon_macon_win)BinaryPrefixReplacementErrorCondaIOError)CancelOperationupdate_file_in_place_as_binary)FileModes(   ^(#!(?:[ ]*)(/(?:\\ |[^ \n\r\t])*)(.*))$   i   )utf-8z	utf-16-lez	utf-16-bez	utf-32-lez	utf-32-bec                      \ rS rSrSrg)_PaddingError0    N)__name__
__module____qualname____firstlineno____static_attributes__r       6lib/python3.13/site-packages/conda/core/portability.pyr   r   0   s    r   r   c                h    SU ;   a'  U R                  5       R                  SS5      u  pUS:H  $ [        $ )z
Determine if the given `subdir` corresponds to a Windows operating system.

:param subdir: The subdirectory name which may contain an OS identifier.
:return: Returns True if `subdir` indicates a Windows OS; otherwise, False.
-   win)lowersplitr   )subdiros_s      r   _subdir_is_winr)   4   s6     f}$$S!,U{ r   c           	     ^  ^ ^^^^ [        T5      (       a&  T[        R                  :X  a  TR                  SS5      mUUU UU4S jn[	        [        T 5      U5      nU(       aL  T[        R                  :X  a7  TS:X  a0  [        (       a$  [        R                  " SSSS[        T 5      /S	S
9  ggggg)aq  
Update the prefix in a file or directory.

:param path: The path to the file or directory.
:param new_prefix: The new prefix to replace the old prefix with.
:param placeholder: The placeholder to use for the old prefix. Defaults to PREFIX_PLACEHOLDER.
:param mode: The file mode. Defaults to FileMode.text.
:param subdir: The subdirectory. Defaults to context.subdir.
\/c           	       > [        TU TTT5      n[        T5      (       d  [        TU5      nX:X  a
  [        5       eT[        R
                  :X  a9  [        U5      [        U 5      :w  a!  [        TTT[        U 5      [        U5      5      eU$ )z
A function that updates the prefix in a file or directory.

:param original_data: The original data to be updated.

:return: The updated data after prefix replacement.
)replace_prefixr)   replace_long_shebangr   r   binarylenr   )original_datadatamode
new_prefixpathplaceholderr&   s     r   _update_prefix%update_prefix.<locals>._update_prefixX   s     dM;
FS f%%'d3D  !## 8??"s4yC4F'F.k:s=/A3t9  r   z	osx-arm64z/usr/bin/codesignz-sr!   z-fT)capture_outputN)
r)   r   textreplacer   r   r0   r   
subprocessrun)r6   r5   r7   r4   r&   r8   updateds   `````  r   update_prefixr@   C   s      f$(--"7  ''c2
 : -Xd^^LG48??*v/D $T8D>BSW	
 JP/D*wr   c           	     N   [          GH  nU [        R                  :X  a  [        U5      (       dq  UR	                  S5      nUS:  aZ  USU XS pSU 3R                  U5      n	X;   a9  SU 3R                  SS5      R                  U5      n
UR                  X5      nXx-   nUR                  UR                  U5      UR                  U5      5      nM  U [        R                  :X  a.  [        UUR                  U5      UR                  U5      UUS9nGM  [        SU < 35      e   U$ )	a"  
Replaces `placeholder` text with the `new_prefix` provided. The `mode` provided can
either be text or binary.

We use the `POPULAR_ENCODINGS` module level constant defined above to make several
passes at replacing the placeholder. We do this to account for as many encodings as
possible. If this causes any performance problems in the future, it could potentially
be removed (i.e. just using the most popular "utf-8" encoding").

More information/discussion available here: https://github.com/conda/conda/pull/9946

:param mode: The mode of operation.
:param original_data: The original data to be updated.
:param placeholder: The placeholder to be replaced.
:param new_prefix: The new prefix to be used.
:param subdir: The subdirectory to be used.
:return: The updated data after prefix replacement.
   
N#! \ )encodingr&   zInvalid mode: )
POPULAR_ENCODINGSr   r;   r)   findencoder<   r0   binary_replacer   )r4   r3   r7   r5   r&   rG   newline_posshebang_linerest_of_datashebang_placeholderescaped_shebangs              r   r.   r.   ~   s9   2 &%8== !&)) #ii.#15l{1CT,EW,,.{m*<*C*CH*M'*:,.zl*;*C*CC*O*V*V$+ (4';';/(  ,:<<""8,j.?.?.ID X__$!""8,!!(+!D x899? &@ Kr   c                |  ^^ SR                  U5      n[        U5      (       a  [        U 5      (       a  [        U TT5      $ U $ SUU4S jjn[	        U 5      n[
        R                  " [
        R                  " T5      S-   U-   S-   U-   [
        R                  S9nUR                  X`5      n [	        U 5      U:X  d   eU $ )a  
Replaces occurrences of a search string with a replacement string in a given byte string.

:param data: The byte string in which to perform the replacements.
:param search: The string to search for in the byte string.
:param replacement: The string to replace occurrences of the search string with.
:param encoding: The encoding to use when encoding and decoding strings. Defaults to "utf-8".
:param subdir: The subdirectory to search for. Defaults to "noarch".
:return: The byte string with the replacements made.
:raises _PaddingError: If the padding calculation results in a negative value.

This function performs replacements only for pyzzer-type entry points on Windows.
For all other cases, it returns the original byte string unchanged.
 c                   > U R                  5       R                  T5      n[        T5      [        T5      -
  U-  nUS:  a  [        eU R                  5       R	                  TT5      SU-  -   $ )a  
Replaces occurrences of the search string with the replacement string in a matched group.

:param match: The matched group containing the search string.

:return: The replaced string with padding.
:raises _PaddingError: If the padding calculation results in a negative value.
r       )groupcountr1   r   r<   )matchoccurrencespaddingreplacementsearchs      r   r<   binary_replace.<locals>.replace   sb     kkm))&1v;[!11[@Q;{{}$$V[9EGOKKr   s	   (?:(?!(?:s   )).)*)flags)rW   zre.Match[bytes]returnbytes)
rJ   r)   has_pyzzer_entry_point"replace_pyzzer_entry_point_shebangr1   recompileescapeDOTALLsub)	r3   r[   rZ   rG   r&   zerosr<   original_data_lenpats	    ``      r   rK   rK      s    * KK!Ef "$''5dFKPPKL L D	
**
		&L(508;eC299C 777!Dt9))))Kr   c                .    U R                  S5      nUS:  $ )z
Check if the given byte string contains a pyzzer entry point.

:param data: The byte string to check.
:return: True if the byte string contains a pyzzer entry point, False otherwise.
   PKr   )rfind)r3   poss     r   r`   r`      s     zz-(C!8Or   c                   S=p4U R                  S5      nUS:  a  XS-   US-    n[        R                  " SU5      u  pxXW-
  U-
  n	X	S n
U	S:  a(  U R                  SSU	5      nUS:  a  XU	 nUS:  a  U SU nU
(       av  U(       ao  U(       ah  [        US5      (       a  UR	                  S	5      n[        US5      (       a  UR	                  S	5      nUR                  X5      nS
R                  X4U
/5      n U $ )a  
Code adapted from pyzzer. This is meant to deal with entry point exe's created by distlib,
which consist of a launcher, then a shebang, then a zip archive of the entry point code to run.
We need to change the shebang.
https://bitbucket.org/vinay.sajip/pyzzer/src/5d5740cb04308f067d5844a56fbe91e7a27efccc/pyzzer/__init__.py?at=default&fileviewer=file-view-default#__init__.py-112  # NOQA

:param all_data: The byte string to search for the entry point.
:param placeholder: The placeholder string to search for in the entry point.
:param new_prefix: The new prefix to replace the placeholder string with.
:return: The updated byte string with the replaced shebang.
Nrk   r         z<LLs   #!rJ   r   r   )rl   structunpackhasattrrJ   r<   join)all_datar7   r5   launchershebangrm   end_cdrcdr_size
cdr_offsetarc_posr3   s              r   ra   ra      s    B H
..
'C
ax8cBh/%}}UG<.:-!Q;..73Cax"w/7'~HG{H--)009z8,,'..w7
ook>GxxD 9:HOr   c                   U [         R                  :X  a  [        U[        5      (       d   [        USS9n[
        R                  " [        U[
        R                  5      nU(       a  UR                  5       u  p4nUR                  S5      R                  SS5      u  pg[        U5      [        :  d  SU;   a6  SU UR                  S5       3nUR                  X8R	                  S5      5      nU$  U$ !   UR	                  S5      n N= f)z
Replace long shebang lines in text mode with a shorter one.

:param mode: The file mode.
:param data: The byte string to search for the entry point.
:return: The updated byte string with the replaced shebang.
r   )rG   r,   r"   rF   #!/usr/bin/env )r   r;   
isinstancer_   rJ   rb   rW   SHEBANG_REGEX	MULTILINEgroupsdecodersplitr1   MAX_SHEBANG_LENGTHr<   )	r4   r3   shebang_matchwhole_shebang
executableoptionsprefixexecutable_namenew_shebangs	            r   r/   r/   5  s     x}}$&&,TG4 bllC1>1E1E1G.Mw&0&7&7&@&G&GQ&O#F=!$66%6/%o%6w~~g7N6OP  ||M3E3Eg3NO
 K 	K!,{{7+s   
C0 0Dc                    SU  S3n[         R                  R                  S5      S:X  a  SU ;   a  U$ [        U5      [        :  d  SU ;   a'  U(       a  S[        U 5       S3nU$ [        SU  S	35      nU$ )
a  
This function can be used to generate a shebang line for Python entry points.

Use cases:
- At install/link time, to generate the `noarch: python` entry points.
- conda init uses it to create its own entry point during conda-build

:param executable: The path to the Python executable.
:param with_usr_bin_env: Whether to use the `/usr/bin/env` approach.
:return: The generated shebang line.
rD   
CONDA_BUILD1z/_h_env_placeholdrE   r}   z5
                #!/bin/sh
                '''exec' "z!" "$0" "$@" #'''
                )r'   environgetr1   r   r   r   )r   with_usr_bin_envrw   s      r    generate_shebang_for_entry_pointr   U  s     :,b!G	zz~~m$+0Cz0Q
 
 7|((C:,= ((<'=R@G( N %, 'G Nr   )r&   strr^   bool)r6   r   r5   r   r7   r   r4   r   r&   r   r^   None)noarch)r4   r   r3   r_   r7   r   r5   r   r&   r   r^   r_   )r   r   )r3   r_   r[   r_   rZ   r_   rG   r   r&   r   r^   r_   )r3   r_   r^   r   )ru   r_   r7   r_   r5   r   r^   r_   )r4   r   r3   r_   r^   r_   )F)r   r   r   r   r^   r   )/__doc__
__future__r   r'   rb   rq   r=   loggingr   os.pathr   r   
auxlib.ishr   base.constantsr	   base.contextr
   common.compatr   r   r   
exceptionsr   r   gateways.disk.updater   r   models.enumsr   r   logr   r   rH   	Exceptionr   r)   r;   r&   r@   r.   rK   r`   ra   r/   r   r   r   r   <module>r      s   & " 	 	    &  / " 4 4 C R #
  %S# 
 	I 	$ *]]..8

8
8
 8
 	8

 8
 
8
@ 9
9
9 9 	9
 9 9@ 4
44 4 	4
 4 4n66"'6586
6rB /422'+22r   