
    khH                     b   d Z ddl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Zddl	m	Z	 ddl
Z
ddlmZ ddlmZ ddlmZ  ej"                  d       ej"                  d	      gZedd
       Z	 ddZd Zd Zd Z	 ddZd dZd dZd Zd Zd Zd Zd Zd Z d Z!d Z"d Z#d Z$e%dk(  r e$        yy)!aV  pipreqs - Generate pip requirements.txt file based on imports

Usage:
    pipreqs [options] [<path>]

Arguments:
    <path>                The path to the directory containing the application
                          files for which a requirements file should be
                          generated (defaults to the current working
                          directory).

Options:
    --use-local           Use ONLY local package info instead of querying PyPI.
    --pypi-server <url>   Use custom PyPi server.
    --proxy <url>         Use Proxy, parameter will be passed to requests
                          library. You can also just set the environments
                          parameter in your terminal:
                          $ export HTTP_PROXY="http://10.10.1.10:3128"
                          $ export HTTPS_PROXY="https://10.10.1.10:1080"
    --debug               Print debug information
    --ignore <dirs>...    Ignore extra directories, each separated by a comma
    --no-follow-links     Do not follow symbolic links in the project
    --encoding <charset>  Use encoding parameter for file open
    --savepath <file>     Save the list of requirements in the given file
    --print               Output the list of requirements in the standard
                          output
    --force               Overwrite existing requirements.txt
    --diff <file>         Compare modules in requirements.txt to project
                          imports
    --clean <file>        Clean up requirements.txt by removing modules
                          that are not imported in project
    --mode <scheme>       Enables dynamic versioning with <compat>,
                          <gt> or <non-pin> schemes.
                          <compat> | e.g. Flask~=1.1.2
                          <gt>     | e.g. Flask>=1.1.2
                          <no-pin> | e.g. Flask
    )contextmanagerN)docopt)json2package)	HTTPError)__version__z^import (.+)$z!^from ((?!\.+).*?) import (?:.*)$c              #     K   | r| dk(  rF|rd|v rt         j                  }n;d|v rt         j                  }n&t        dj	                  |            t        | |      }	 | |t         j                  t         j                  fvr|j                          yy# |t         j                  t         j                  fvr|j                          w w xY ww)a  Open a file or ``sys.stdout`` depending on the provided filename.

    Args:
        filename (str): The path to the file that should be opened. If
            ``None`` or ``'-'``, ``sys.stdout`` or ``sys.stdin`` is
            returned depending on the desired mode. Defaults to ``None``.
        mode (str): The mode that should be used to open the file.

    Yields:
        A file handle.

    -rwzInvalid mode for file: {}N)sysstdinstdout
ValueErrorformatopenclose)filenamemodefiles      K/var/www/teggl/fontify/venv/lib/python3.12/site-packages/pipreqs/pipreqs.py_openr   ;   s      x3sd{99DD[::D8??EFFHd#
		3::..JJL /4		3::..JJL /s   ACB !4C5C

Cc                 >   t               }t               }g }d}g d}|reg }	|D ]M  }
|	j                  t        j                  j	                  t        j                  j                  |
                   O |j                  |	       t        j                  | |      }|D ]  \  }}}|D cg c]	  }||vs| c}|d d  |j                  t        j                  j	                  |             |D cg c]*  }t        j                  j                  |      d   dk(  s)|, }}||D cg c]$  }t        j                  j                  |      d   & c}z  }|D ]  }t        j                  j                  ||      }t        |d|      5 }|j                         }d d d        	 t        j                        }t        j                  |      D ]  }t        |t        j                        r-|j                   D ]  }|j#                  |j$                          Jt        |t        j&                        se|j#                  |j(                            |D cg c]  }|s|	 c}D ](  }|j7                  d
      \  }}}|j#                  |       * |t        |      |z  z
  }t1        j8                  dj;                  |             t        t        d      d      5 }|D ch c]  }|j=                          }}d d d        t?        |z
        S c c}w c c}w c c}w # 1 sw Y   xY w# t*        $ rT}|r3t-        j.                  |       t1        j2                  d	|z         Y d }~t1        j4                  d	|z         |d }~ww xY wc c}w c c}w # 1 sw Y   xY w)NF)z.hgz.svnz.gitz.tox__pycache__envvenv)followlinks   z.pyr   r
   encodingzFailed on file: %s.zFound packages: {0}stdlib) setappendospathbasenamerealpathextendwalksplitextjoinr   readastparse
isinstanceImportnamesaddname
ImportFrommodule	Exception	traceback	print_excloggingwarnerror	partitiondebugr   striplist)r%   r   extra_ignore_dirsfollow_linksimportsraw_imports
candidatesignore_errorsignore_dirsignore_dirs_parseder)   rootdirsfilesdfn	file_namefcontentstreenodesubnodeexcnr3   cleaned_name_packagesxdatas                                  r   get_all_importsr[   Z   s   eG%KJMOK" 	MA%%bgg&6&6rww7G7G7J&KL	M-.774\2D! dE";a{&:1;Q"''**401#Hrww'7'7';A'>%'GHH?2rww''+A.??
 	IT95Iix8 $A668$yy*HHTN 5D!$

3'+zz :G'OOGLL9:#D#..9#45	: (-q1- " "^^C0aL!" #j/G34HMM'..x89	d8nc	" &a#$%a	%%& 4  W < I?$ $   '',LL!5	!ABMM"6"BCI . && &sy   )	L3L/*LL%)LL BL)/L)N	N	NN5NL&)	N2/N'NNNNc                 2    t        |       dkD  xr | d   dk7  S )Nr   #)len)lines    r   filter_liner`      s    t9q=+T!W^+    c                 Z   t        | d      5 }t        j                  dj                  t	        |      | dj                  |D cg c]  }|d   	 c}                   d|z   dz   |j                  dj                  fd	|D              dz          d d d        y c c}w # 1 sw Y   y xY w)
Nr   z/Writing {num} requirements: {imports} to {file}, r3   )numr   rB   {name}z	{version}
c              3   p   K   | ]-  }|d    r j                   di |n dj                   di | / yw)versionre   N )r   ).0itemfmts     r   	<genexpr>z-generate_requirements_file.<locals>.<genexpr>   s@      !! #'y/JCJJx7N7NN!!s   36)r   r9   r=   r   r^   r+   write)r%   rB   symbolout_filerY   rl   s        @r   generate_requirements_filerq      s    	tS	 	)XGNNGII':Qqy:; O 
 	
 +-tyy !!!! !#'( 	)	) 	) ;		) 	)s   5B!BAB!B!!B*c                     t        d| |       y )Nr	   )rq   )rB   ro   s     r   output_requirementsrs      s    sGV4ra   c                    g }| D ]%  }	 t        j                  d|       t        j                  dj	                  ||      |      }|j
                  dk(  rPt        |j                  d      r$t        |j                  j                               }nFt        |j                        }n0|j
                  dk\  r!t        |j
                  |j                        t        j                  d	|j                  |j                  |j                         |j                  ||j                  d
       ( |S # t        $ r t        j                  d|       Y Mw xY w)NzMImport named "%s" not found locally. Trying to resolve it at the PyPI server.z{0}{1}/json)proxies   decodei,  )status_codereasonz/Package "%s" does not exist or network problemszImport named "%s" was resolved to "%s:%s" package (%s).
Please, verify manually the final list of requirements.txt to avoid possible dependency confusions.r3   rh   )r9   warningrequestsgetr   rx   hasattrcontentr   rw   r   ry   r3   latest_release_idpypi_urlr#   )rB   pypi_serverproxyresultrk   responserZ   s          r   get_imports_infor      s:   F I	OO;
  ||$$[$7HH##s*8++X6'(8(8(?(?(ABD'(8(89D%%,H,@,@'/8 8 	7 II""MM	
 	t0F0FGH=I> M  	OOA4I	s   CD00EEc           
         g }g d}t         j                  D ]C  }t        j                  |      D ]'  \  }}}|D ]  }d|v s	t        j                  j	                  ||      }t        |d|       5 }|j                  t        j                        d   j                  d      }		 |j                         j                         j                  d      }
t               }|
D ]   }||vs|	d   |vs|j                  |       " d }t        |	      d	kD  r%|	d	   j                  d
d      j                  dd      }|j                  |	d   ||d       d d d         * F |S #  Y d d d        3xY w# 1 sw Y   @xY w)N)tests_testseggEGGinfo	top_levelr
   r   r	   rf   r   r   z.dist z.egg)r3   rh   exports)r   r%   r$   r)   r+   r   splitsepr,   r>   r?   r#   r^   replace)r   rX   ignorer%   rI   rJ   rK   rk   rO   packagetop_level_modulesfiltered_top_level_modulesr5   rh   s                 r   get_locally_installed_packagesr      s   H6F $!# #	D$ "$&77<<d3DdC(; q"&**RVV"4R"8">">s"C%010@0F0Ft0L- 6:V2&7 JF!'v!5!(6!9 !; A A& IJ #'w<!+&-aj&8&8 ''--4WVR-@ $
 !$+AJ'.'A) 7 "#	$J O9%$   s7   12E0	$-E E0	%E0	-A E0	 E-"E0	-E0	0E:c                     t               }g }| D ]*  }|D ]#  }||d   v s	||d   k(  s|j                  |       % , t        |      D cg c]  \  }}|||dz   d  vs| }}}|S c c}}w )Nr   r3   r   )r   r#   	enumerate)	rB   r   localr   rk   r   rU   iresult_uniques	            r   get_import_localr      s    *,EF ' 	'G wy))TWV_-Dg&	'' $-V#4N41a!8MQNMN Os   
A&A&c                     t               }t        t        d      d      5 }t        d |D              }ddd       | D ]#  }|j	                  j                  ||             % t        |d       S # 1 sw Y   ?xY w)zGet PyPI package names from a list of imports.

    Args:
        pkgs (List[str]): List of import names.

    Returns:
        List[str]: The corresponding PyPI package names.

    mappingr
   c              3   Z   K   | ]#  }|j                         j                  d        % yw):N)r>   r   rj   rY   s     r   rm   z get_pkg_names.<locals>.<genexpr>  s     4QAGGIOOC(4s   )+Nc                 "    | j                         S Nlower)ss    r   <lambda>zget_pkg_names.<locals>.<lambda>%  s    	 ra   key)r"   r   r+   dictr2   r}   sorted)pkgsr   rO   rZ   pkgs        r   get_pkg_namesr     sx     UF	d9os	# 5q4!445 ' 	

488C%&'
 &1225 5s   A11A:c                     d| v r<t         d   j                  | j                               }|r|j                  d      d   } | j	                  d      d   j	                  d      d   j                         S )Nzimport r   z as r    )REGEXPmatchr>   groupsr<   )r3   r   s     r   get_name_without_aliasr   (  sd    Dq	

-<<?1%D>>&!!$..s3A6<<>>ra   c                     t         j                  j                  t         j                  j                  t              |       S r   )r$   r%   r+   dirname__file__)rO   s    r   r+   r+   0  s$    77<<1155ra   c                    g }g d}	 t        | d      }	 |j                         D cg c]  }|dk7  s	|j                          }}|j                          |D cg c]  }|d   j                         s| }}|D ]  }t        |D cg c]  }||v  c}      s|j                  |dd       |D ]M  }||v s|j                  |      }|d   }|d   j                  d	d
      }	||	d}||vr|j                  |          |S c c}w # |j                          w xY w# t        $ r& t        j                  dj                  |               w xY wc c}w c c}w )a  Parse a requirements formatted file.

    Traverse a string until a delimiter is detected, then split at said
    delimiter, get module name by element index, create a dict consisting of
    module:version, and add dict to list of parsed modules.

    Args:
        file_: File to parse.

    Raises:
        OSerror: If there's any issues accessing the file.

    Returns:
        tuple: The contents of the file, excluding comments.
    )<>=!~r
   rf   Failed on file: {}r   Nrz   r   r   r   )r   	readlinesr>   r   OSErrorr9   r;   r   isalphaanyr#   r   r   )
file_modulesdelimrO   rY   rZ   yr5   module_namemodule_versions
             r   parse_requirementsr   4  sY     G &E	
	'({{}B!T	AGGIBDBGGI.!qt||~A.D. E*qAF*+NNA$78 
	AEz$Qi!'!3!3C!<"-.I(NN6*
		  N- CGGI  *11%89 / +s>   D D 
DDD E3EE
D D/Ec                     t        |       }t        t        |            D cg c]
  }||   d    }}t        t        |            D cg c]
  }||   d    }}t        |      t        |      z
  }|S c c}w c c}w )aC  Compare modules in a file to imported modules in a project.

    Args:
        file_ (str): File to parse for modules to be compared.
        imports (tuple): Modules being imported in the project.

    Returns:
        tuple: The modules not imported in the project, but do exist in the
               specified file.
    r3   )r   ranger^   r"   )r   rB   r   r   modules_not_importeds        r   compare_modulesr   i  sz     !'G+0W+>?awqz&!?G?+0W+>?awqz&!?G?w<#g,6	 @?s   A3	A8c           	          t        | |      }t        j                  dj                  | dj	                  d |D                           y)zFDisplay the difference between modules in a file and imported modules.zBThe following modules are in {} but do not seem to be imported: {}rc   c              3       K   | ]  }|  y wr   ri   r   s     r   rm   zdiff.<locals>.<genexpr>  s     $E1Q$Es   N)r   r9   r   r   r+   )r   rB   r   s      r   diffr   }  s=    *5':LL	VE499$E0D$EEFHra   c                    t        | |      }t        |      dk(  rt        j                  d| z          yt	        j
                  dj                  |            }g }	 t        | d      }	 |j                         D ]%  }|j                  |      |j                  |       ' |j                  d       |j                          |D ]  }|j                  |        	 |j                          t        j                  d| z          y# |j                          w xY w# t        $ r& t        j                   dj#                  |               w xY w)z9Remove modules that aren't imported in project from file.r   zNothing to clean in N|zr+r   z(Successfully cleaned up requirements in )r   r^   r9   r   recompiler+   r   r   r   r#   seektruncatern   r   r   r;   r   )r   rB   r   	re_removeto_writerO   r   s          r   cleanr     s   *5':
 A%+e34

388$89:IH

	[[] '??1%-OOA&' FF1IJJL 
 GGILL;eCD GGI  *11%89s   D ($D AD D/Ec                 x    | dk(  r|D cg c]
  }|d   dd }}d}||fS | dk(  rd}||fS | dk(  rd}|fS c c}w )	zDEnables dynamic versioning with <compat>, <gt> or <non-pin> schemes.no-pinr3   r   rz   gtz>=compatz~=ri   )schemerB   rk   ro   s       r   dynamic_versioningr     sp    ELMTDLR8MM
 F?	 
4 F? 
8	F? Ns   7c                    | j                  d      }| j                  d      }| j                  d       }| d   }|-t        j                  j                  t        j                        }|r|j                  d      }| d   r| d   nt        j                  j                  |d      }| d   s?| d   s:| d	   s5t        j                  j                  |      rt        j                  d
       y t        ||||      }t        |      }t        j                  ddj                  |      z          d}d }| d   r| d   }| d   r| d   | d   d}| d   r#t        j                  d       t        ||      }	nt        j                  d       t        ||      }
|D cg c]S  }|j                         |
D cg c]  }|d   D ]  }|  c}}vr%j                         |
D cg c]  }|d   	 c}vrU }}}|
t        |||      z   }	t!        |	d       }	| d   rt#        | d   |	       y | d   rt%        | d   |	       y | d   r0| j                  d      }|dv rt'        ||	      \  }	}nt)        d      d }| d   r"t+        |	|       t        j,                  d!       y t/        ||	|       t        j,                  d"|z          y c c}}w c c}w c c}}w )#Nz
--encodingz--ignorez--no-follow-linksz<path>,z
--savepathzrequirements.txtz--printz--forcez<requirements.txt already exists, use --force to overwrite it)r   r@   rA   zFound imports: rc   https://pypi.python.org/pypi/z--pypi-serverz--proxy)httphttpsz--use-localz9Getting package information ONLY from local installation.r   z,Getting packages information from Local/PyPIr   r3   )r   r   c                 (    | d   j                         S )Nr3   r   )rY   s    r   r   zinit.<locals>.<lambda>  s    AfIOO,= ra   r   z--diffz--cleanz--mode)r   r   r   zFInvalid argument for mode flag, use 'compat', 'gt' or 'no-pin' insteadz==z Successfully output requirementsz(Successfully saved requirements file in )r}   r$   r%   abspathcurdirr   r+   existsr9   r{   r[   r   r=   r   r   r   r   r   r   r   r   rs   r   rq   )argsr   r@   rA   
input_pathr%   rD   r   r   rB   r   rY   r   
differencer   ro   s                   r   initr     s   xx%H,xx 344LhJWW__RYY/
-33C8"&|"4DGGLL%78 	O&Ot$ 6 	7 *23D.:<J z*JMM#dii
&;;<1KEO?+Ii4	?CMG	I":ADE h? ", CA ggi5'Oa!I,'OQ'O'OO ggi5'Aa&	'AA  C
 C *:167BD D W"=>GH~T(^W%Id9ow'H~(#//0AOGV F G G IGV,78"4&9?$FGE (P (BCs$   K1K KK(K Kc                     t        t        t              } | d   rt        j                  nt        j
                  }t        j                  |d       	 t        |        y # t        $ r t        j                  d       Y y w xY w)N)rh   z--debugz%(levelname)s: %(message)s)levelr   r   )r   __doc__r   r9   DEBUGINFObasicConfigr   KeyboardInterruptr   exit)r   	log_levels     r   mainr   
  sZ    ';/D!%igllIi0LMT
 s   A B ?B __main__)Nr
   )NNT)r   Nr   )&r   
contextlibr   r$   r   r   r9   r-   r7   r   r|   yargr   yarg.exceptionsr   pipreqsr   r   r   r   r[   r`   rq   rs   r   r   r   r   r   r+   r   r   r   r   r   r   r   __name__ri   ra   r   <module>r      s   $J & 	 
 	  
     %  BJJ BJJ34
  > CG;!|,
)5
 EI#L(V*3*?62j (HE@	UHp zF ra   