B
    XM\ùn  ã               @   sÌ  d Z ddlmZmZmZ ddlZddlmZ ddlmZ ddl	Z	ddl
Z
ddlZddlm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mZ dd	lmZmZ dd
lmZmZ ddlmZ ddlmZmZ ddlmZ ddl m!Z!m"Z" ddl#m$Z$ ddl%Z%dZ&dZ'dZ(g Z)G dd„ de*ƒZ+G dd„ deƒZ,dd„ Z-dd„ Z.dd„ Z/d:d d!„Z0ed"d#„ ƒZ1d$d%„ Z2ed&d'„ ƒZ3d(d)„ Z4ed*d+„ ƒZ5d,d-„ Z6d.d/„ Z7ed0d1„ ƒZ8d2d3„ Z9d;d4d5„Z:d6d7„ Z;d8d9„ Z<dS )<z6
Tools for converting CPAN packages to conda recipes.
é    )Úabsolute_importÚdivisionÚprint_functionN)Úparse_version)Úglob)Úmakedirs)ÚbasenameÚdirnameÚjoinÚexists)Ú	get_index)ÚTmpDownloadÚdownload)Ú	MatchSpecÚResolve)Úmemoized)ÚCondaHTTPErrorÚ
CondaError)Úget_or_merge_config)Úon_winÚcheck_call_env)Úget_default_varianta^  {{% set name = "{packagename}" %}}
{{% set version = "{version}" %}}
{{% set sha256 = "{sha256}" %}}

package:
  name: {{{{ name }}}}
  version: {{{{ version }}}}

{source_comment}source:
  {useurl}fn: {filename}
  {useurl}url: {cpanurl}
  {usesha256}sha256: {{{{ sha256 }}}}

# If this is a new build for the same version, increment the build
# number. If you do not include this key, it defaults to 0.
build:
  number: 0

requirements:
  build:
    - perl{build_depends}

  run:
    - perl{run_depends}

{import_comment}test:
  # Perl 'use' tests
  {import_comment}imports:{import_tests}

  # You can also put a file called run_test.pl (or run_test.py) in the recipe
  # that will be run at test time.

about:
  home: {homeurl}
  license: {license}
  summary: {summary}

# See
# http://docs.continuum.io/conda/build.html for
# more information about meta.yaml
aŒ  #!/bin/bash

# If it has Build.PL use that, otherwise use Makefile.PL
if [ -f Build.PL ]; then
    perl Build.PL
    perl ./Build
    perl ./Build test
    # Make sure this goes in site
    perl ./Build install --installdirs site
elif [ -f Makefile.PL ]; then
    # Make sure this goes in site
    perl Makefile.PL INSTALLDIRS=site
    make
    make test
    make install
else
    echo 'Unable to find Build.PL or Makefile.PL. You need to modify build.sh.'
    exit 1
fi

# Add more build steps here, if they are necessary.

# See
# http://docs.continuum.io/conda/build.html
# for a list of environment variables that are set during the build process.
a4  :: If it has Build.PL use that, otherwise use Makefile.PL
IF exist Build.PL (
    perl Build.PL
    IF %ERRORLEVEL% NEQ 0 exit 1
    Build
    IF %ERRORLEVEL% NEQ 0 exit 1
    Build test
    :: Make sure this goes in site
    Build install --installdirs site
    IF %ERRORLEVEL% NEQ 0 exit 1
) ELSE IF exist Makefile.PL (
    :: Make sure this goes in site
    perl Makefile.PL INSTALLDIRS=site
    IF %ERRORLEVEL% NEQ 0 exit 1
    make
    IF %ERRORLEVEL% NEQ 0 exit 1
    make test
    IF %ERRORLEVEL% NEQ 0 exit 1
    make install
) ELSE (
    ECHO 'Unable to find Build.PL or Makefile.PL. You need to modify bld.bat.'
    exit 1
)

:: Add more build steps here, if they are necessary.

:: See
:: http://docs.continuum.io/conda/build.html
:: for a list of environment variables that are set during the build process.
c               @   s   e Zd ZdZdS )ÚInvalidReleaseErrorzR
    An exception that is raised when a release is not available on MetaCPAN.
    N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r   r   ú9lib/python3.7/site-packages/conda_build/skeletons/cpan.pyr   ‰   s   r   c               @   s   e Zd ZdZdd„ ZdS )ÚPerlTmpDownloadz_
    Subclass Conda's TmpDownload to replace : in download filenames.
    Critical on win.
    c             C   sÈ   d| j krd | _| j S d| j kr6| j  d¡}|d }n
t| j ƒ}| dd¡ t ¡ | _tj 	d¡}t
|dd	t| j ƒ dd¡ƒ}t
||ƒ}| dd¡}t|ƒ}t|ƒs¬t|ƒ t|ƒsÀt| j |ƒ |S d S )
Nz://Z	CHECKSUMSzid/é   z::ú-ú~z.conda-buildÚcpan)ÚurlZtmp_dirÚsplitr   ÚreplaceÚtempfileZmkdtempÚosÚpathÚ
expanduserr
   r	   r   r   r   )ÚselfZturlÚfilenameÚhomeZbase_dirÚdstr   r   r   Ú	__enter__˜   s(    





zPerlTmpDownload.__enter__N)r   r   r   r   r/   r   r   r   r   r   ‘   s   r   c             C   s   t tt | ƒƒƒS )N)Ústrr   )Zverr   r   r   Úloose_version·   s    r1   c          
   C   s¬   |s|   dd¡} t| ƒŠ}y@t |¡}| ¡ }W d Q R X t|dƒrN| d¡}t |¡}W nB t	k
r†   t t
j|dd ¡ ¡}Y n tk
rœ   d }Y nX W d Q R X |S )Nz::r!   Údecodez	utf-8-sigzutf-8)Úencoding)r&   r   ÚgzipÚopenÚreadÚhasattrr2   ÚjsonÚloadsÚIOErrorÚcodecsr   )r$   ÚcolonsZ	json_pathZdist_json_fileÚoutputÚrel_dictr   r   r   Úget_cpan_api_url»   s    


r?   c             C   sV   y6dd| g}t r(| dd¡ | dd¡ t|ƒ d}W n tjk
rP   d}Y nX |S )Nr#   z-Dr   z/czcmd.exeTF)r   Úinsertr   Ú
subprocessZCalledProcessError)Zpackage_nameÚcmdZin_repor   r   r   Úpackage_existsÍ   s    

rC   Ú.úhttp://fastapi.metacpan.org/v1Fc       !      C   sz  t |ƒ}|j dt|ƒd ¡}| dd¡}i }	d}
d}tƒ }|}x2| rt|  ¡ }d|krl| d¡\}}}n|}||krzqD| |¡ |}t	||||d}|dkr²t
d |¡ƒ qDn$||| d	d
¡hkrÖt
d ||¡ƒ t||d||d}t|ƒ}|dk	r
|d
 | |ksD|d
 |d  |kr"qD|	 ||ddddddddddœ
¡}|dkrT|}nt||t|ƒ||d}t|||d ƒ}t||ƒr¸|sšt
d| ƒ qDd|d< d|d< d|d< d}n¶t|||||||d\}}}}}|d  |
 dgt||B ƒ ¡7  < |d  | dgt||B ƒ ¡7  < |d  |
 dgt|ƒ ¡7  < |d  | dgt|ƒ ¡7  < |  |¡ d}d}t|ƒr’|s’t
d| ƒ qDnt|ƒr®|r®t
d| ƒ d|d< tdƒ|d< d|d< | d ¡ræt|d  ƒ|d< | d!¡r:|d! |d< t|d! ƒ\|d< }t|d! ƒ|d< t
d"|d ||f ƒ nd|d< d|d< d|d< y|d# d$ |d%< W n" tk
rˆ   d&| |d%< Y nX d'|kr®t|d' ƒ d(¡}||d)< y,t|d* tƒrÌ|d* d+ n|d* |d*< W n tk
rø   d,|d*< Y nX |d |d< | |d
 |d  ¡ | d	d
¡ d
¡d+ }d-|kr‚xDtt|d- ƒƒD ]0}| |¡rNd.|krN|d/  |
| 7  < qNW |d/ r–d|d0< nd|d0< t|ƒs°t|ƒ t
d1||d f ƒ t t|d2ƒd3ƒ} |  !t"jf |Ž¡ W dQ R X t t|d4ƒd3ƒ*} |r|  !d5¡ n|  !t#jf |Ž¡ W dQ R X t t|d6ƒd3ƒ*} |rV|  !d7¡ n|  !t$jf |Ž¡ W dQ R X qDW dS )8zS
    Loops over packages, outputting conda recipes converted from CPAN metata.
    Úperlz.*Ú z
    - z
    #- ú=)ÚconfigzvWARNING: {0} is a Perl core module that is not developed outside of Perl, so we are skipping creating a recipe for it.z::r!   zYWARNING: {0} was part of the {1} distribution, so we are making a recipe for {1} instead.NÚversionz# z'')
ÚpackagenameÚrun_dependsÚbuild_dependsZbuild_commentZtest_commandsÚ	usesha256ÚuseurlÚsource_commentÚsummaryÚimport_testsz2We found core module %s. Skipping recipe creation.ú#rO   rN   rP   T)Úrelease_dataÚperl_versionÚ
output_dirÚmeta_cpan_urlÚ	recursiverI   rM   rL   Fz?Directory %s already exists and you have not specified --force z8Directory %s already exists, but forcing recipe creationZcpanurlr,   Úsha256ÚarchiveÚdownload_urlzUsing url %s (%s) for %s.Z	resourcesZhomepageZhomeurlzhttp://metacpan.org/pod/ZabstractÚurQ   Úlicenser   Úperl_5Zprovidesz::_rR   Zimport_commentzWriting recipe for %s-%sz	meta.yamlÚwzbuild.shz"#!/bin/bash
echo "Nothing to do."
zbld.batzecho "Nothing to do."
)%r   ZvariantÚgetr   r&   ÚsetÚpopÚ	partitionÚaddÚdist_for_moduleÚprintÚformatÚget_release_infoÚperl_to_condaÚ
setdefaultr   r
   Úmetacpan_api_is_core_versionÚdeps_for_packageÚlistÚextendr   Úreprr   Úget_checksum_and_sizeÚKeyErrorÚlstripÚ
isinstancer%   ÚsortedÚ
startswithr   r5   ÚwriteÚ	CPAN_METAÚCPAN_BUILD_SHÚCPAN_BLD_BAT)!ÚpackagesrV   rJ   rW   rX   ZforcerI   Z
write_corerU   Zpackage_dictsÚindentZindent_coreZprocessed_packagesZorig_versionÚpackageÚ_Úorig_packageZlatest_release_datarK   ÚdrT   Zdir_pathZempty_recipeÚ
build_depsÚbuild_core_depsÚrun_depsÚrun_core_depsÚpackages_to_appendÚsizerQ   Zmodule_prefixZprovided_modÚfr   r   r   ÚskeletonizeÛ   s   



  







r‡   c             C   s4   | d krdS | d k	r,|dks(| t |ƒkr,dS dS d S )NF)NrG   T)r   )Úcore_versionrJ   r   r   r   Úis_core_versionŸ  s    r‰   c             C   s€   | j ddd}|jdddd |jdd	d
d |jddd |jdddd |jdddd |jdddd |jdddd d S )Nr#   zy
    Create recipe skeleton for packages hosted on the Comprehensive Perl Archive
    Network (CPAN) (cpan.org).
        )Úhelprz   ú+z-CPAN packages to create recipe skeletons for.)ÚnargsrŠ   z--output-dirz5Directory to write recipes to (default: %(default)s).rD   )rŠ   Údefaultz	--versionz(Version to use. Applies to all packages.z--meta-cpan-urlzhttp://fastapi.metacpan.org/v1zBURL to use for MetaCPAN API. It must include a version, such as v1)r   rŠ   z--recursiveÚ
store_truezTCreate recipes for dependencies if they do not already exist (default: %(default)s).)ÚactionrŠ   z--forcez;Force overwrite of existing recipes (default: %(default)s).z--write_corez<Write recipes for perl core modules (default: %(default)s). )Ú
add_parserÚadd_argument)Zreposr#   r   r   r   r   ª  s<    r   c             C   sN   t tƒ ƒ}yt| t| ƒ¡ƒ}W n   d}Y nX |rFt|d jƒ}nd}|S )zO
    :returns: the latest version of the specified conda package available
    Néÿÿÿÿ)r   r   rt   Zget_pkgsr   r   rJ   )ÚpkgÚrZpkg_listÚpkg_versionr   r   r   Úlatest_pkg_versionÎ  s    

r–   c          
   C   sÌ  t ƒ }t ƒ }t ƒ }	t ƒ }
t ƒ }td|  dd tj ¡  | d¡sP|||	|
|fS xj|d D ]\}y8|d dkrštddd tj ¡  t||d ||d	}t|ƒ}| ¡ d
kr´w\|d dkrÈd|d< t	|d ƒ}yt
||d ||d|d W n4 tk
r$   td|| t|ƒf ƒ t	dƒ}Y nX t|ƒtdƒkrÖt|ƒ}|dkrXt||d ƒ}y0|dk	r†t|ƒt|ƒkr†|d|d  7 }W nL tk
rÔ   tdƒ td |d ¡ƒ td |¡ƒ td |¡ƒ Y nX |r6d|krtt|| dd¡ƒƒs6| d ||d f¡¡ ntt||d ƒƒs6| |¡ t||d ƒ}|d dkrp|rd|
 |¡ n
|	 |¡ n*|d dkrš|r| |¡ n
| |¡ W q\ ttfk
r¸   w\Y q\X q\W |||	|
|fS )a¢  
    Build the sets of dependencies and packages we need recipes for. This should
    only be called for non-core modules/distributions, as dependencies are
    ignored for core modules.

    :param package: Perl distribution we're checking dependencies of.
    :type package: str
    :param release_data: The metadata about the current release of the package.
    :type release_data: dict
    :param perl_version: The target version of Perl we're building this for.
                         This only really matters for core modules.
    :type perl_version: str
    :param output_dir: The output directory to write recipes to
    :type output_dir: str
    :param processed_packages: The set of packages we have built recipes for
                               already.

    :returns: Build dependencies, runtime dependencies, and set of packages to
              add to list of recipes to create.
    :rtype: 3-tuple of sets
    z!Processing dependencies for %s...rG   )ÚendÚ
dependencyZrelationshipZrequiresrD   Úmodule)rI   rF   rJ   >   rG   ÚundefÚ0T)r˜   rI   zWARNING: The version of %s listed as a dependency for %s, %s, is not available on MetaCPAN, so we are just assuming the latest version is okay.Nú z6We have got an expected error with dependency versionsz	Module {}zPkg_version {}zDep Version {}z::r!   rH   z-[v1-9][0-9.]*ZphaseZruntimeZdevelop)ra   rf   ÚsysÚstdoutÚflushr`   re   ri   Úlowerr   rh   r   r0   r1   r–   Úmetacpan_api_get_core_versionÚ	Exceptionrg   r   r
   r&   rd   r   rk   r   r   )r|   rT   rU   rV   rW   rX   rI   r€   r   r‚   rƒ   r„   Zdep_dictZ	orig_distZ	dep_entryZdep_versionr•   Zcorer   r   r   rl   ß  s„    










rl   c             C   s.   t | |ƒ}|dk	r|}nt| |ƒ}|d }|S )z]
    Given a name that could be a module or a distribution, return the
    distribution.
    NÚdistribution)Úrelease_module_dictÚcore_module_dict)Úcpan_urlr™   rU   rI   r>   r£   Úmod_dictr   r   r   re   h  s    

re   c             C   sL   yt d | |¡dd}W n. tk
r0   d }Y n tk
rF   d }Y nX |S )Nz{0}/release/{1}F)r<   )r?   rg   ÚRuntimeErrorr   )r¦   r™   r>   r   r   r   r¤   z  s    
r¤   c             C   sL   yt d | |¡dd}W n" tk
r:   t d| ¡ Y nX i }d|d< |S )Nz{0}/module/{1}T)r<   zPError: Could not find module or distribution named %s on MetaCPAN. Error was: %srF   r£   )r?   rg   r   r   Úexit)r¦   r™   r§   r   r   r   r¥   ‡  s    r¥   c             C   sf   d  | |¡}| dd¡}t |¡}|jdkr0dS d  | |¡}t |¡}|jdkrTdS t d| ¡ d S )	Nz{0}/release/{1}z::r!   éÈ   Fz{0}/module/{1}TzBError: Could not find module or distribution named %s on MetaCPAN.)rg   r&   Úrequestsr`   Zstatus_coder   r©   )r¦   r™   r$   Zreqr   r   r   rk   –  s    



rk   c             C   s<   t | |ƒ}y|d d d }W n tk
r6   d }Y nX |S )Nr™   r’   rJ   )r¥   r¢   )r¦   r™   Zmodule_dictrJ   r   r   r   r¡   ª  s    

r¡   c          
   C   sž  |}t | |||d}y.td | |¡dd}t|d ƒ d¡|d< W nh tk
rª   t| |ƒ}|dk	r˜|dkst||kr˜td |¡ƒ t|ƒd	d
gi dœ}nt 	d| ¡ Y nX d}	|dk	r|t|ƒ}
t|d ƒ}tt
|
ƒƒ}y0|dk	otdƒt|
ƒkot
|ƒt|
ƒk}	W np tk
rz } zPtdƒ t|ƒ td |¡ƒ td |¡ƒ td |d ¡ƒ td |¡ƒ W dd}~X Y nX |	rštdƒ td |
|¡ƒ |S )z…
    Return a dictionary of the JSON information stored at cpan.metacpan.org
    corresponding to the given package/dist/module.
    )rI   z{0}/release/{1}F)r<   rJ   ÚvNz©WARNING: {0} is not available on MetaCPAN, but it's a core module, so we do not actually need the source file, and are omitting the URL and MD5 from the recipe entirely.rG   r^   )rJ   r[   r]   r˜   z=Error: Could not find any versions of package %s on MetaCPAN.r›   z<We have some strange version mismatches. Please investigate.z
Package {}z
Version {}zPkg Version {}zLoose Version {}zWe have a version mismatch!zVersion: {}, RelVersion: {})re   r?   rg   r0   rr   r   rk   rf   r   r©   r   r1   r¢   )r¦   r|   rJ   rU   rI   r˜   r~   r>   rˆ   Zversion_mismatchZversion_strZrel_versionZ	loose_strÚer   r   r   rh   µ  sJ    


 rh   c       	   
   C   sÌ   t | ƒ}t| ƒ}t|d ƒ¢}t|ƒŽ}d}d}d}xz|D ]r}| ¡ }| d| ¡rZd}q:|r:| d¡r~| d¡d  d	¡}q:| d
¡r | d¡d  d	¡}P q:| d¡r:P q:W W dQ R X W dQ R X ||fS )z
    Looks in the CHECKSUMS file in the same directory as the file specified
    at download_url and returns the sha256 hash and file size.
    z
/CHECKSUMSFNú'Tz'sha256'z=>r    z', z'sizeÚ})r	   r   r   r5   Ústripru   r%   )	r[   Zbase_urlr,   Zchecksum_pathZchecksum_fileZ
found_filerY   r…   Úliner   r   r   rp   ð  s(    




rp   c             C   s   d|   dd¡ ¡  S )z@ Sanitizes a Perl package name for use as a conda package name. zperl-z::r!   )r&   r    )Únamer   r   r   ri     s    ri   )rD   NrE   FFNF)F)=r   Z
__future__r   r   r   r;   Zpkg_resourcesr   r   r4   r8   r(   r   Úos.pathr   r	   r
   r   rA   r   r'   Zconda_build.conda_interfacer   r   r   r   r   r   r   r   Zconda_build.configr   Zconda_build.utilsr   r   Zconda_build.variantsr   r«   rw   rx   ry   Z	perl_corer¨   r   r   r1   r?   rC   r‡   r‰   r   r–   rl   re   r¤   r¥   rk   r¡   rh   rp   ri   r   r   r   r   Ú<module>   s^   + &  
 C$ 

: