3
sd+                 @   s   d Z ddl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 ddlmZ ddlmZ efd	d
Zdd ZddedddfddZdd ZdZG dd deZG dd deZdd ZdS )z  Distutils / setuptools helpers     N)joinsplitsplitext)ConfigParser)LooseVersion)build_py)install_scripts)logc                s   G  fddd }|S )aZ   Return extended build command class for recording commit

    The extended command tries to run git to find the current commit, getting
    the empty string if it fails.  It then writes the commit hash into a file
    in the `pkg_dir` path, named ``COMMIT_INFO.txt``.

    In due course this information can be used by the package after it is
    installed, to tell you what commit it was installed from if known.

    To make use of this system, you need a package with a COMMIT_INFO.txt file -
    e.g. ``myproject/COMMIT_INFO.txt`` - that might well look like this::

        # This is an ini file that may contain information about the code state
        [commit hash]
        # The line below may contain a valid hash if it has been substituted during 'git archive'
        archive_subst_hash=$Format:%h$
        # This line may be modified by the install process
        install_hash=

    The COMMIT_INFO file above is also designed to be used with git substitution
    - so you probably also want a ``.gitattributes`` file in the root directory
    of your working tree that contains something like this::

       myproject/COMMIT_INFO.txt export-subst

    That will cause the ``COMMIT_INFO.txt`` file to get filled in by ``git
    archive`` - useful in case someone makes such an archive - for example with
    via the github 'download source' button.

    Although all the above will work as is, you might consider having something
    like a ``get_info()`` function in your package to display the commit
    information at the terminal.  See the ``pkg_info.py`` module in the nipy
    package for an example.
    c                   s   e Zd ZdZ fddZdS )z#get_comrec_build.<locals>.MyBuildPyz6 Subclass to write commit data into installation tree c                s    j |  dd l}|jd|j|jdd}|j \}}t|}t }|jtd |j	dd| t| j
d}|jt|d d S )	Nr   zgit rev-parse --short HEADT)stdoutstderrshellzCOMMIT_INFO.txtzcommit hashZinstall_hashwt)run
subprocessPopenPIPEcommunicatestrr   readpjoinset	build_libwriteopen)selfr   procZrepo_commit_Z
cfg_parserZout_pth)	build_cmdpkg_dir //tmp/pip-build-7vycvbft/nibabel/nisext/sexts.pyr   4   s    
z'get_comrec_build.<locals>.MyBuildPy.runN)__name__
__module____qualname____doc__r   r   )r   r   r   r    	MyBuildPy2   s   r%   r   )r   r   r%   r   )r   r   r    get_comrec_build   s    #r&   c             C   s@   || krg | |< nt | | tr.| | g| |< | | j| dS )z6 Helper for appending dependencies to setuptools args N)
isinstancer   append)Zin_dictkeyvaluer   r   r    _add_append_keyG   s
    
r+   Fc             C   sp  |dk	}t |}|dkr dd }|dkr,i }ddddd}	|	j| t| |||\}
}|
d	krbdS |s|
d
kr|st|	d
 |  tj|	d |  |	d   dS |
dkrtd|  |
dkst|st|	d || |f tj|	d || |f |	d   dS |rt|t rtd| }|r4|d| 7 }|r`d|krLi |d< t	|d || dS t	|d| dS )a   Check if package `pkg_name` is present and has good enough version

    Has two modes of operation.  If `setuptools_args` is None (the default),
    raise an error for missing non-optional dependencies and log warnings for
    missing optional dependencies.  If `setuptools_args` is a dict, then fill
    ``install_requires`` key value with any missing non-optional dependencies,
    and the ``extras_requires`` key value with optional dependencies.

    This allows us to work with and without setuptools.  It also means we can
    check for packages that have not been installed with setuptools to avoid
    installing them again.

    Parameters
    ----------
    pkg_name : str
       name of package as imported into python
    version : {None, str}, optional
       minimum version of the package that we require. If None, we don't
       check the version.  Default is None
    optional : bool or str, optional
       If ``bool(optional)`` is False, raise error for absent package or wrong
       version; otherwise warn.  If ``setuptools_args`` is not None, and
       ``bool(optional)`` is not False, then `optional` should be a string
       giving the feature name for the ``extras_require`` argument to setup.
    checker : callable, optional
       callable with which to return comparable thing from version
       string.  Default is ``distutils.version.LooseVersion``
    version_getter : {None, callable}:
       Callable that takes `pkg_name` as argument, and returns the
       package version string - as in::

          ``version = version_getter(pkg_name)``

       If None, equivalent to::

          mod = __import__(pkg_name); version = mod.__version__``
    messages : None or dict, optional
       dictionary giving output messages
    setuptools_args : None or dict
       If None, raise errors / warnings for missing non-optional / optional
       dependencies.  If dict fill key values ``install_requires`` and
       ``extras_require`` for non-optional and optional dependencies.
    Nc             S   s   t | }|jS )N)
__import____version__)pkg_namemodr   r   r    version_getter   s    z%package_check.<locals>.version_getterz-Cannot import package "%s" - is it installed?zMissing optional package "%s"z; you may get run-time errorsz=You have version %s of package "%s" but we need version >= %s)missingzmissing optz
opt suffixzversion too old	satisfiedr1   zmissing optz
opt suffixz
no-versionzCannot find version for zlow-versionzversion too oldz'Not-False optional arg should be stringz>=extras_requireinstall_requires)
boolupdate_package_statusRuntimeErrorr	   warnAssertionErrorr'   r   r+   )r.   versionoptionalcheckerr0   messagesZsetuptools_argsZsetuptools_modeZoptional_tfZmsgsstatushave_version
dependencyr   r   r    package_checkT   sd    2




rB   c             C   sl   yt |  W n tk
r    dS X |s*dS y|| }W n tk
rJ   dS X ||||k rdd|fS d|fS )Nr1   r2   
no-versionzlow-version)r1   N)r2   N)rC   N)r,   ImportErrorAttributeError)r.   r;   r0   r=   r@   r   r   r    r7      s    r7   a0  @echo off
REM wrapper to use shebang first line of {FNAME}
set mypath=%~dp0
set pyscript="%mypath%{FNAME}"
set /p line1=<%pyscript%
if "%line1:~0,2%" == "#!" (goto :goodstart)
echo First line of %pyscript% does not start with "#!"
exit /b 1
:goodstart
set py_exe=%line1:~2%
call "%py_exe%" %pyscript% %*
c               @   s   e Zd ZdZdd ZdS )install_scripts_bata   Make scripts executable on Windows

    Scripts are bare file names without extension on Unix, fitting (for example)
    Debian rules. They identify as python scripts with the usual ``#!`` first
    line. Unix recognizes and uses this first "shebang" line, but Windows does
    not. So, on Windows only we add a ``.bat`` wrapper of name
    ``bare_script_name.bat`` to call ``bare_script_name`` using the python
    interpreter from the #! first line of the script.

    Notes
    -----
    See discussion at
    https://matthew-brett.github.io/pydagogue/installing_scripts.html and
    example at git://github.com/matthew-brett/myscripter.git for more
    background.
    c       
      C   s   t j|  tjdksd S x| j D ]}t|d}|j }W d Q R X |jdoXd|j ksft	j
d q"t|\}}t|\}}t||d }tjd|}	t	j
d| d	|  | jrq"t|d
}|j|	 W d Q R X q"W d S )Nntrtz#!pythonz3No #!python executable found, skipping .bat wrapperz.batz{FNAME}zMaking z wrapper for r   )r   r   osnameget_outputsr   readline
startswithlowerr	   infopsplitr   r   BAT_TEMPLATEreplacedry_runr   )
r   filepathfobj
first_linepthfnameZfrootextZbat_fileZbat_contentsr   r   r    r      s&    



zinstall_scripts_bat.runN)r!   r"   r#   r$   r   r   r   r   r    rF      s   rF   c               @   s   e Zd Zdd ZdS )Bunchc             C   s0   x*|j  D ]\}}|jdrq
|| j|< q
W d S )N__)itemsrN   __dict__)r   varsr)   rK   r   r   r    __init__  s    
zBunch.__init__N)r!   r"   r#   r`   r   r   r   r    r[     s   r[   c          
   C   s0   i }t | d}t|j | W dQ R X t|S )a   Read variables from Python text file

    Parameters
    ----------
    ver_file : str
        Filename of file to read

    Returns
    -------
    info_vars : Bunch instance
        Bunch object where variables read from `ver_file` appear as
        attributes
    rH   N)r   execr   r[   )Zver_filensrV   r   r   r    read_vars_from  s    rc   )r$   rJ   os.pathr   r   r   rQ   r   configparserr   distutils.versionr   Zdistutils.command.build_pyr   !distutils.command.install_scriptsr   	distutilsr	   r&   r+   rB   r7   rR   rF   objectr[   rc   r   r   r   r    <module>   s(   8f*