a
    2bKQ                    @   s   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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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 ddlmZ ddlmZ dd	lmZm Z m!Z!m"Z" dd
l#m$Z$ ddl%m&Z&m'Z'm(Z(m)Z) ddl*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0 ddl1m2Z2m3Z3m4Z4m5Z5 ddl6m7Z7 ddl8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z? ddl@mAZA ddlBmCZCmDZD ddlEmFZFmGZGmHZHmIZImJZJmKZK ddlLmMZM eNdZOe
Pe
QeCdZRe
QeRdZSdZTdZUG dd de2ZVdd ZWdd ZXdd  ZYd!d" ZZdd#d$Z[dd%d&Z\dd'd(Z]dd)d*Z^d+d, Z_dd-d.Z`dd/d0ZaG d1d2 d2e;Zbd3d4 Zcdd5d6Zddd7d8Zedd:d;Zfdd<d=Zgdd>d?ZhddAdBZiddCdDZjddFdGZkddHdIZlddJdKZmddLdMZnddNdOZoddPdQZpddRdSZqddTdUZrddVdWZsdXdY ZtG dZd[ d[euZvd\d] Zwd^d_ Zxdd`daZydbdc Zzddde Z{dfdg Z|dhdi Z}djdk Z~dldm Zdndo Zdpdq ZddrdsZddtduZddvdwZdxdy Zdzd{ Zd|d} Zd~d Zdd Zdd ZdddZdd ZedkreaeC dS )zJupyterLab command handler    N)deepcopy)glob)Path)TemporaryDirectory)Event)URLError)Requestquoteurljoinurlopen)jupyter_config_path)GREEN_ENABLEDGREEN_OKRED_DISABLEDRED_X)	LabConfigget_federated_extensionsget_package_urlget_page_configget_static_page_configwrite_page_config)ProcessWatchHelperlist2cmdlinewhich)Version)BoolDict	HasTraitsInstanceListUnicodedefault
CoreConfig)HERE	YARN_PATH)Rangegtgteltltemake_semver)__version__z'.*theme-light-extension/style/theme.cssz..dev_modezpin@zhttps://registry.yarnpkg.comc                   @   s   e Zd ZdddZdd ZdS )ProgressProcessNc                 C   s   t |ttfstd|r*| r*tdt|| _d| _|| _| j	dt
|  | j||tjtjddd| _|pxt | _tj|  dS )	a  Start a subprocess that can be run asynchronously.

        Parameters
        ----------
        cmd: list
            The command to run.
        logger: :class:`~logger.Logger`, optional
            The logger instance.
        cwd: string, optional
            The cwd of the process.
        kill_event: :class:`~threading.Event`, optional
            An event used to kill the process operation.
        env: dict, optional
            The environment for the process.
        zCommand must be given as a listzProcess aborted z> Tutf-8)cwdenvstderrstdoutZuniversal_newlinesencodingN)
isinstancelisttuple
ValueErroris_set_ensure_loggerloggerZ
_last_linecmddebugr   Z_create_process
subprocessZSTDOUTPIPEprocr   _kill_eventr   Z_procsadd)selfr>   r=   r2   
kill_eventr3    rG   2lib/python3.9/site-packages/jupyterlab/commands.py__init__C   s$    
zProgressProcess.__init__c                 C   s   g }| j }| j}tg d}| d u rtjt| tj	  tjd |
 rh|   tdz|jdd\}}|| W q tjy   Y qY q0 q| jd| tj	  |  S )N)-\|/zProcess was abortedg?)timeout
)rB   rC   	itertoolscycleZpollsysr5   writenextflushr;   Z	terminater:   Zcommunicateappendr@   ZTimeoutExpiredr=   r?   join)rE   cacherB   rF   Zspinnerout_rG   rG   rH   waitk   s&    

zProgressProcess.wait)NNNN)__name__
__module____qualname__rI   r\   rG   rG   rG   rH   r/   A   s     
(r/   c                  G   s   t t j|  S )z&Join paths to create a real path.
    )ospabspathrX   )argsrG   rG   rH   pjoin   s    rc   c                  C   s,   t jd} | p tt d dd} t| S )z;Get the configured JupyterLab user settings directory.
    ZJUPYTERLAB_SETTINGS_DIRr   labzuser-settingsosenvirongetrc   r   r`   ra   )Zsettings_dirrG   rG   rH   get_user_settings_dir   s
    ri   c                  C   s,   t jd} | p tt d dd} t| S )z8Get the configured JupyterLab workspaces directory.
    ZJUPYTERLAB_WORKSPACES_DIRr   rd   Z
workspacesre   )Zworkspaces_dirrG   rG   rH   get_workspaces_dir   s
    rj   c                  C   s   t jdr"ttt jd  S ttjddd} t	t
drDt
  tt
dd}t|rt| |stt|ddd} n$tjdrt| std	rd	} tt|  S )
z1Get the configured JupyterLab app directory.
    ZJUPYTERLAB_DIRZshareZjupyterrd   getuserbase	USER_BASENz/usrz/usr/local/share/jupyter/lab)rf   rg   rh   strr   resolverc   rS   prefixhasattrsiterk   getattrr%   
startswithr`   exists)app_diruserbaserG   rG   rH   get_app_dir   s    
rw   c                 C   sD   t dtddddg| |d dk}|r@t dtg| |d}|  dS )	aO   `yarn-deduplicate` with the `fewer` strategy to minimize total
        packages installed in a given staging directory

        This means a extension (or dependency) _could_ cause a downgrade of an
        version expected at publication time, but core should aggressively set
        pins above, for example, known-bad versions
    nodezyarn-deduplicatez-sZfewerz--failr2   r=   r   N)r/   r&   r\   )pathr=   Z	had_dupes	yarn_procrG   rG   rH   dedupe_yarn   s    r|   c                 C   sZ   t |}tdtddg| |d}| }|dkrRtdtg| |d}|  tt| |dkS )z_Ensure that node_modules is up to date.

    Returns true if the node_modules was updated.
    rx   checkz--verify-treery   r   )r<   r/   r&   r\   r|   	REPO_ROOT)r2   r=   r{   retrG   rG   rH   ensure_node_modules   s    
r   c                 C   sF   t | } ttd}tt| s&t|sBtdtdgt| d}|	  dS )z.Ensure that the dev assets are available.
    staticrx   buildry   N)
r<   rc   DEV_DIRr   r~   r`   rt   r/   r&   r\   )r=   targetr{   rG   rG   rH   
ensure_dev   s    
r   c                 C   sR   t td}t| } t tdd}t|sNt||  tdtdg|| d}|  dS )z/Ensure that the core assets are available.
    stagingr   
index.htmlrx   r   ry   N)	rc   r%   r<   r`   rt   r   r/   r&   r\   )r=   r   r   r{   rG   rG   rH   ensure_core   s    


r   c                 C   s&   t t| ddrdS d|  dg}|S )zEnsure that an application directory is available.

    If it does not exist, return a list of messages to prompt the user.
    r   r   Nz/JupyterLab application assets not found in "%s"z?Please run `jupyter lab build` or use a different app directory)r`   rt   rc   )ru   msgsrG   rG   rH   
ensure_app   s    r   c                 C   sH   t | } tt|  tttdd}d}tdtddg|| |d}|gS )zRun watch mode for the source packages.

    Parameters
    ----------
    logger: :class:`~logger.Logger`, optional
        The logger instance.

    Returns
    -------
    A list of `WatchHelper` objects.
    packagesZmetapackagez/.* Found 0 errors\. Watching for file changes\.rx   runwatchr2   r=   startup_regex)r<   r   r~   r`   ra   rX   r   r&   )r=   Zts_dirZts_regexZts_procrG   rG   rH   watch_packages  s    
r   c                 C   s2   t | } t| }tdtddgt| td}||g S )zRun watch mode in a given directory.

    Parameters
    ----------
    logger: :class:`~logger.Logger`, optional
        The logger instance.

    Returns
    -------
    A list of `WatchHelper` objects.
    rx   r   r   r   )r<   r   r   r&   r   WEBPACK_EXPECT)r=   package_procsZwp_procrG   rG   rH   	watch_dev   s    r   c                       s   e Zd ZdZd fdd	ZeddZedddZe	e
jd	dZe	ed
dZe	edddZee ddZeddZedddZeddd Zeddd Zeddd Zeddd Z  ZS )
AppOptionszOptions object for build systemNc                    sT   |d ur||d< |d ur ||d< d|v r:|d s:| d tt| jf i | d S )Ncore_configr=   ru   )popsuperr   rI   )rE   r=   r   kwargs	__class__rG   rH   rI   ;  s    
zAppOptions.__init__zThe application directory)helpTzKWhether to shadow the default app_dir if that is set to a non-default valuezThe logger to usezConfiguration for core datarG   zEvent for aborting call)rb   r   z7The paths to look in for prebuilt JupyterLab extensionszNPM packages registry URLFz*Splice source packages into app directory.r=   c                 C   s
   t dS )N
jupyterlabloggingZ	getLoggerrE   rG   rG   rH   _default_loggerZ  s    zAppOptions._default_loggerru   c                 C   s   t  S N)rw   r   rG   rG   rH   _default_app_dir`  s    zAppOptions._default_app_dirr   c                 C   s   t  S r   r#   r   rG   rG   rH   _default_core_configd  s    zAppOptions._default_core_configregistryc                 C   s   t | jd }|dtS )Nyarn configr   )_yarn_configr=   rh   YARN_DEFAULT_REGISTRYrE   configrG   rG   rH   _default_registryh  s    zAppOptions._default_registry)NN)r]   r^   r_   __doc__rI   r!   ru   r   use_sys_dirr   r   ZLoggerr=   r$   r   r   rF   r    labextensions_pathr   splice_sourcer"   r   r   r   r   __classcell__rG   rG   r   rH   r   8  s*   




r   c                 C   s0   | du rt  S t| jt r| S t f i | S dS )z-Helper to use deprecated kwargs for AppOptionN)r   
issubclassr   )optionsrG   rG   rH   _ensure_optionsn  s
    r   c                 C   s<   t | } t| j t| }| jr,t| j}ng }||  S )zWatch the application.

    Parameters
    ----------
    app_options: :class:`AppOptions`, optional
        The application options.

    Returns
    -------
    A list of processes to run asynchronously.
    )r   _node_checkr=   _AppHandlerr   r   r   )app_optionshandlerr   rG   rG   rH   r   x  s    
r   c                 C   s(   t |}t|j t|}|j| |dS )zInstall an extension package into JupyterLab.

    The extension is first validated.

    Returns `True` if a rebuild is recommended, `False` otherwise.
    pin)r   r   r=   r   install_extension)	extensionr   r   r   rG   rG   rH   r     s    
r   Fc                 C   s4   t |}t|j t|}|du r*| S || S )zpUninstall an extension by name or path.

    Returns `True` if a rebuild is recommended, `False` otherwise.
    T)r   r   r=   r   uninstall_all_extensionsuninstall_extension)namer   all_r   rG   rG   rH   r     s    
r   c                 C   s4   t |}t|j t|}|du r*| S || S )zUpdate an extension by name, or all extensions.
    Either `name` must be given as a string, or `all_` must be `True`.
    If `all_` is `True`, the value of `name` is ignored.
    Returns `True` if a rebuild is recommended, `False` otherwise.
    T)r   r   r=   r   update_all_extensionsupdate_extension)r   r   ru   r   r   rG   rG   rH   r     s    
r   c                    s  t   t } j} j}|d| |ttdkr>td|ttdkrTtdt ddrx|d| t	|| n\g d	} fd
d|D }|D ]<}t||}t
|r|d| t|| q|d| q|d t ddst ddr|d dS )z+Clean the JupyterLab application directory.zCleaning %s...devzCannot clean the dev appcorezCannot clean the core appallFzRemoving everything in %s...)
extensionssettingsr   r   c                    s   g | ]}t  |r|qS rG   )rr   ).0tr   rG   rH   
<listcomp>      zclean.<locals>.<listcomp>zRemoving %s...z%s not present, skipping...zSuccess!r   zIAll of your extensions have been removed, and will need to be reinstalledN)r   r   r=   ru   inforc   r%   r:   rr   _rmtree_starr`   rt   _rmtree)r   r   r=   ru   ZpossibleTargetstargetsr   r   rG   r   rH   clean  s.    


r   Tc           	      C   s0   t |}t|j t|}|j| |||||dS )z&Build the JupyterLab application.
    )r   version
static_url
productionminimizeclean_staging)r   r   r=   r   r   )	r   r   r   rF   r   r   r   r   r   rG   rG   rH   r     s    

r   c                 C   s   t | }|  |jS )z3Get a dictionary of information about the app.
    )r   _ensure_disabled_infor   r   r   rG   rG   rH   get_app_info  s    r   
sys_prefixc                 C   s   t |}|j| d|dS )zgEnable a JupyterLab extension.

    Returns `True` if a rebuild is recommended, `False` otherwise.
    Flevelr   toggle_extensionr   r   r   r   rG   rG   rH   enable_extension  s    r   c                 C   s   t |}|j| d|dS )zfDisable a JupyterLab package.

    Returns `True` if a rebuild is recommended, `False` otherwise.
    Tr   r   r   rG   rG   rH   disable_extension  s    r   c                 C   s   t |}|| |S )z<Check if a JupyterLab extension is enabled or disabled.
    )r   check_extension)r   Z	installedr   r   rG   rG   rH   r      s    r   c                 C   s"   t | } t| j t| }| S )zSDetermine whether JupyterLab should be built.

    Returns a list of messages.
    )r   r   r=   r   build_checkr   rG   rG   rH   r     s    
r   c                 C   s   t | }| S )zList the extensions.
    )r   list_extensionsr   rG   rG   rH   r     s    r   c                 C   s   t |}|| S )zuLink a package against the JupyterLab build.

    Returns `True` if a rebuild is recommended, `False` otherwise.
    )r   link_package)rz   r   r   rG   rG   rH   r     s    r   c                 C   s   t |}|| S )zzUnlink a package from JupyterLab by path or name.

    Returns `True` if a rebuild is recommended, `False` otherwise.
    )r   unlink_package)packager   r   rG   rG   rH   r   "  s    r   c                 C   s   t | }|jd S )zGet the application version.r   )r   r   r   rG   rG   rH   get_app_version+  s    r   c                 C   s   t |}|| S )z=Get the latest compatible version of a list of packages.
    )r   "latest_compatible_package_versions)namesr   r   rG   rG   rH   &get_latest_compatible_package_versions1  s    r   c                 C   sL   t | d}|d}t| d}dd | D |d< |  |S )z5Read the package data in a given target tarball.
    rzpackage/package.jsonutf8c                 S   s   g | ]}|j td d qS )zpackage/N)rz   lenr   frG   rG   rH   r   >  s   z read_package.<locals>.<listcomp>jupyterlab_extracted_files)	tarfileopenextractfilejsonloadsreaddecodeZ
getmembersclose)r   tarr   datarG   rG   rH   read_package8  s    

r   c                   @   sf  e Zd Zdd ZdWddZdXdd	Zd
d Zdd ZdYddZdd Z	dd Z
dd Zdd Zdd Zdd Zdd ZdZdd Zd[d!d"Zd#d$ Zd%d& Zd'd( Zd)d* Zd\d+d,Zd]d-d.Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zd9d: Zd;d< Zd=d> Zd?d@ Z dAdB Z!dCdD Z"dEdF Z#dGdH Z$dIdJ Z%d^dKdLZ&d_dMdNZ'dOdP Z(dQdR Z)dSdT Z*dUdV Z+dS )`r   c                 C   sf   t |}|| _|j| _|jr"t n| j| _|j| _t|jj	| _
|j| _|j| _|j| _|  | _dS )z(Create a new _AppHandler object
        N)r   _optionsru   r   rw   sys_dirr=   r   r   _data	core_datar   rF   r   _get_app_infor   )rE   r   rG   rG   rH   rI   L  s    z_AppHandler.__init__Nc                 C   s.  t |}| jd }|| jd v rp|  }|dg }||v rl| jd|  || ||d< | | dS dS |   t  }| j	|||d}W d   n1 s0    Y  |d	 }	|d
 r|  }|
dt }
|d |
|	< | | |	|v r*||	 }|d |d kr*|d dkr*t|d  dS )zInstall an extension package into JupyterLab.

        The extension is first validated.

        Returns `True` if a rebuild is recommended, `False` otherwise.
        r   core_extensionsuninstalled_core_extensionszInstalling core extension %sTFr   Nr   is_dirlocal_extensionssourcerz   locationapp)_normalize_pathr   _read_build_configrh   r=   remove_write_build_config_ensure_app_dirsr   _install_extension
setdefaultdictrf   )rE   r   existingr   r   r   uninstalledtempdirr   r   localotherrG   rG   rH   r   ]  s4    


.

 z_AppHandler.install_extensionFTc                 C   sN  |du r| j d p| j d  }|s&d}| jjrPtt| jd | jdtdgtd |rXd	nd
g}|rt||rndnd | j dd	| d | j
}| j||||d t|d}	| jdtddg|	d}
|
dkrd}| j| t|t|	| j d|rdnd |r
dnd }| jdtd|g|	d}
|
dkrJd}| j| t|dS )zBuild the application.
        Nlinked_packagesr  Fr=   rx   zbuild:packagesr2   r   ZdevelopmentZ	minimizedznot minimizedzBuilding jupyterlab assets (z, ))r   r   r   r   r   installz--non-interactiver   z"npm dependencies failed to installzbuild:Zprodr   z	:minimizer0   r   zJupyterLab failed to build)r   r   r   r   r~   r=   _runr&   rW   rX   ru   _populate_stagingrc   r?   RuntimeErrorr|   )rE   r   r   r   r   r   r   r   ru   r   r   msgZcommandrG   rG   rH   r     s:    
 
z_AppHandler.buildc                 C   s\   t | jd}|   | jdtdg|d t|| j tdtddgt | jdt| jd}|gS )zXStart the application watcher and then run the watch in
        the background.
        r   rx   r  r  r   r   )r2   r   r=   )	rc   ru   r  r  r&   r|   r=   r   r   )rE   r   rB   rG   rG   rH   r     s    
z_AppHandler.watchc                    sJ  |    | j| j}d|d   |d s6|d rB|  |d< |d rR|   |d r|d | |d | |d |d	 }|rd
 t|D ]}d||| f  q|d }|rd t|D ]"}|| d }d||f  q|d }|r&d fddt|D  t|d t|d  t|d    fdd|d D }|rd t|D ]&}	|	 v r|	d7 }	d|	  qxg }
| jd D ]B}| jd | d }| jd | d }t||ds|
	| q|
rd fddt|
D  | j
dd}|rFd fdd|D  d S )!z+Print an output of the extensions.
        zJupyterLab v%sr   federated_extensionsr   compat_errorsz+Other labextensions (built into JupyterLab)r  rS   r  z
   local extensions:z        %s: %sr  z
   linked packages:r  uninstalled_corez
Uninstalled core extensions:c                    s   g | ]}  d | qS     %sr   r   itemr  rG   rH   r     r   z/_AppHandler.list_extensions.<locals>.<listcomp>r   c                    s"   g | ]}| d d  v r|qS ):r   )	partition)r   i)all_extsrG   rH   r     r   disabledz
Disabled extensions:z (all plugins)r!  shadowed_extsTzO
The following source extensions are overshadowed by older prebuilt extensions:c                    s   g | ]}  d | qS r   r"  )r   r   r  rG   rH   r     r   )fastz3
Build recommended, please run `jupyter lab build`:c                    s   g | ]}  d | qS r   r"  r#  r  rG   rH   r     r   N)r   r=   r   _get_extension_compat_list_federated_extensions_list_extensionssortedr8   r)   rW   r   )rE   r   r  r   r  keyr  r  r)  r$  Zimproper_shadowedZext_nameZsource_versionZprebuilt_versionmessagesrG   )r(  r=   rH   r     s`    



$



z_AppHandler.list_extensionsc                 C   sp  | j }| jd }| jd }g }t|dd}t|s:dgS | jd }|d }|dt }	|d	d
}
|
ds|d	 }t|
t|krd}||
|f gS | jd }| j	|d}|d }|dt }dD ]p}|| D ](}||v rq||| vr|
d|  q|| D ]0}||v rq||| vr|
d|  qqttd}| D ]v\}}|	|d
|rnqN||	vr|qN||v sN||v rqN|	| |krNd}|
|||	| || f  qN| D ]F\}}|s||v rqt|d}| |||r|
d|  q| D ]L\}}|s||v r:qt|dd}| ||d |r|
d|  q|S )z[Determine whether JupyterLab should be built.

        Returns a list of messages.
        r  r  r   package.jsonzNo built applicationstatic_datar   dependenciesr   r0   -splicedz*Version mismatch: %s (built), %s (current)r*  )silent)r   mimeExtensionsz %s needs to be included in buildz!%s needs to be removed from buildr   z%s changed from %s to %sr   z%s content changedr   r  )ru   r   rc   r`   rt   rh   r  endswithr   _get_package_templaterW   r~   itemsrs   _check_local)rE   r+  ru   r  linkedr1  pkg_pathr3  Zold_jlabZold_depsZstatic_versionZcore_versionr  r*  Znew_packageZnew_jlabZnew_depsext_typeextZsrc_pkg_dirpkgZdepr   r  dnamer$  rG   rG   rH   r     sn    








 
z_AppHandler.build_checkc                 C   s^  | j }| j}||d v rh|d | dt ddrV|d|d | d d   n|d|  dS ||d v r|  }|d	g }||vr| d
|  || ||d	< | | dS dS |d }|d  D ]t\}}|d }	||krd|t	
|	f }
| |
 t|	 ||v rD|  }|dt }||= | |  dS q|d|  dS )zpUninstall an extension by name.

        Returns `True` if a rebuild is recommended, `False` otherwise.
        r  r  ZuninstallInstructionsNz.JupyterLab cannot uninstall this extension. %szJupyterLab cannot uninstall %s since it was installed outside of JupyterLab. Use the same method used to install this extension to uninstall this extension.Fr   r  zUninstalling core extension %sTr  r   rz   zUninstalling %s from %s$No labextension named "%s" installed)r   r=   rh   r  errorr  rW   r
  r:  r`   dirnamerf   r	  r  warn)rE   r   r   r=   r   r  r  extnamer   rz   r  rG   rG   rH   r   ^  s@     





z_AppHandler.uninstall_extensionc                 C   s2   d}| j d  D ]\}}| |}|p*|}q|S )ziUninstalls all extensions

        Returns `True` if a rebuild is recommended, `False` otherwise
        Fr   )r   r:  r   )rE   should_rebuildrF  r[   r  rG   rG   rH   r     s
    

z$_AppHandler.uninstall_all_extensionsc                 C   sB   d}| j d  D ]*\}}|| j d v r*q| |}|p:|}q|S )zqUpdate all non-local extensions.

        Returns `True` if a rebuild is recommended, `False` otherwise.
        Fr   r  )r   r:  _update_extension)rE   rG  rF  r[   updatedrG   rG   rH   r     s    

z!_AppHandler.update_all_extensionsc                 C   s,   || j d vr"| jd|  dS | |S )mUpdate an extension by name.

        Returns `True` if a rebuild is recommended, `False` otherwise.
        r   rB  F)r   r=   warningrH  )rE   r   rG   rG   rH   r     s    z_AppHandler.update_extensionc                 C   s   | j d | }|d r*| jd|  dS z| |}W n tyL   Y dS 0 |du rl| jd|f  dS ||d kr| j d|  dS | j d	||f  | d
||f S )rJ  r   alias_package_sourcez(Skipping updating pinned extension '%s'.FNz#No compatible version found for %s!r   zExtension %r already up to datezUpdating %s to version %s%s@%s)r   r=   rE  "_latest_compatible_package_versionr   r   )rE   r   r   ZlatestrG   rG   rH   rH    s     z_AppHandler._update_extensionc                    s   t |}t|rt|s,d}t|| t } ||}W d   n1 sT0    Y  t|d }|sx |S  j	
d|  fdd|D    }|dt }|d ||d	 <  | d
S )zrLink a package at the given path.

        Returns `True` if a rebuild is recommended, `False` otherwise.
        z/Cannot install "%s" only link local directoriesNr   zNInstalling %s as a linked package because it does not have extension metadata:c                    s   g | ]} j d | qS )z   %s)r=   rK  )r   mr   rG   rH   r     r   z,_AppHandler.link_package.<locals>.<listcomp>r  r  r   T)r  r`   rt   isdirr:   r   _extract_package_validate_extensionr   r=   rK  r  r  r  r
  )rE   rz   r  r  r   r1  r   r<  rG   r   rH   r     s     *

z_AppHandler.link_packagec                 C   s   t |}|  }|dt }d}| D ]\}}||ksB||kr*|}q*|rT||= nZ|dt }| D ]\}}||ks||krj|}qj|r||= | jd | d }t| |std| | 	| dS )zUnlink a package by name or at the given path.

        A ValueError is raised if the path is not an unlinkable package.

        Returns `True` if a rebuild is recommended, `False` otherwise.
        r  Nr  r   rz   zNo linked package for %sT)
r  r  r  r  r:  r   rf   r	  r:   r
  )rE   rz   r   r<  foundr   r  r  rG   rG   rH   r     s*    

z_AppHandler.unlink_packager   c           
      C   s   t  }t| jd}t|| j|d}|di }d}||d}	|rV|	sVd||< d}n|sj|	rjd||< d}|r||d< t||d |S )zsEnable or disable a lab extension.

        Returns `True` if a rebuild is recommended, `False` otherwise.
        r   )app_settings_dirr=   r   disabledExtensionsFTr   )r   r`   rX   ru   r   r=   rh   r   )
rE   r   valuer   Z
lab_configrT  page_configr)  Zdid_somethingZis_disabledrG   rG   rH   r     s     z_AppHandler.toggle_extensionc                 C   sZ   |    | j}||d v r(| |||S ||d v rL| jd|tf  dS | |||S )z8Check if a lab extension is enabled or disabled
        r   r  %s:%sT)r   r   _check_core_extensionr=   r   _check_common_extension)rE   r   check_installed_onlyr   rG   rG   rH   r     s    z_AppHandler.check_extensionc                 C   s|   ||d v r$| j d|tf  dS |r@| j d|tf  dS ||d v rd| j d|tf  dS | j d|tf  dS )z9Check if a core extension is enabled or disabled
        r  rX  F%s: %sTdisabled_core)r=   r   r   r   r   r   )rE   r   r   r[  rG   rG   rH   rY  .  s    z!_AppHandler._check_core_extensionc                 C   s   ||d vr$| j d|tf  dS |  | }|rL| j d|tf  dS |rh| j d|tf  dS t||d r| j d|tf  dS | j d|tf  dS )zFCheck if a common (non-core) extension is enabled or disabled
        r   rX  Fz%s:%s (compatibility errors)r\  Tr)  )r=   r   r   r,  r   _is_disabledr   r   )rE   r   r   r[  errorsrG   rG   rH   rZ  =  s"    z#_AppHandler._check_common_extensionc                    s2  t   | j  d< }| |  d< }|   d< |   d< g   d< }g   d< }| D ]:\}}| d v |d< |d d	kr|| q^|| q^|   d
< t| j	 d<  d p|}|d d  d< |d 
dd d< | j d< | j	 d< t| j d< t| j d<  fdd d D  d<  S )z'Get information about the app.
        r   r   r  r  Zapp_extensionsZsys_extensionsis_localr  r  r  r3  r   r   	staticUrlr0   r   ru   r   r  c                    s   g | ]}| d  v r|qS )r  rG   )r   r?  r"  rG   rH   r   u  r   z-_AppHandler._get_app_info.<locals>.<listcomp>r*  )r  r   _get_extensions_get_local_extensions_get_linked_packagesr:  rW    _get_uninstalled_core_extensions_get_static_dataru   rh   r   _get_core_extensionsr   r   )rE   r   r   r  rS   r   r   Zapp_datarG   r"  rH   r   U  s.    

z_AppHandler._get_app_infoc                 C   s   | j }d|v rd S | j}t| jd}t||| jd}|di }t|t	rZdd |D }||d< g }|d D ]}||d v rn|
| qn||d< d S )	Nr)  r   )rT  r=   rU  c                 S   s   i | ]
}|d qS )TrG   )r   r   rG   rG   rH   
<dictcomp>  r   z5_AppHandler._ensure_disabled_info.<locals>.<dictcomp>r   r]  )r   r   r`   rX   ru   r   r=   rh   r7   r8   rW   )rE   r   r   rT  rW  r)  r]  r0  rG   rG   rH   r   x  s    
z!_AppHandler._ensure_disabled_infoc           #   
   C   s
  | j }t|d}|r8t|r8| jd| t|| j |   |sV| jd d d }| jj	}|r|| j
d t}td }n
ttd}t|d}	t|	rt|	}
t|
}W d	   n1 s0    Y  |d dd
|krt|| j t| dD ] }t||}tt||| qdD ]$}t||}tttd|| q t|d}t|rht|| j ztt|d| W nV tjy } z:dt|vodt|v}|st|s W Y d	}~n
d	}~0 0 t|d}t|rt|| j t| | jd }d}| jd  D ]b\}}||vr^|  }|dt }||= | | d}qt|d}| ||||| d q|r|  | jd< | jd }| D ]*\}}t|d}| ||d ||d q|   }|d }|r||d< |r ||d< |r||d< |rt!tt"dddD ]t}t#t$|}t%t&|j'dd}|d }||d v r~||d |< ||d |< ||d v r&||d |< q&t$tt"d}||d  d!< t(|d"d#d}t|d"}t|rtj)|dd$ t|d}	t|	d% }
tj*||
d&d' W d	   n1 s(0    Y  t|d(}ttdd(} | j+t,krt| dd}!|!- }"W d	   n1 s0    Y  |".t,| j+/d)}"t|d%dd}!|!0|" W d	   n1 s0    Y  n,t|st| | t1|t2j3t2j4B  d	S )*z4Set up the assets in the staging directory.
        r   zCleaning %sr   r   r   z)Splicing dev packages into app directory.r5  r2  Nr0   )index.jszbootstrap.jszpublicpath.jszwebpack.config.jszwebpack.prod.config.jszwebpack.prod.minimize.config.js)z.yarnrczyarn.js	templatesz
[Errno 22]z	[Errno 5]r  r   Fr  Tr  r   ra  r   *r1   )r6   r4  linkedPackagesresolutionsZbuilderZdevDependenciesz@jupyterlab/buildernode_modulesz@jupyterlab)ignore_errorsw   indentz	yarn.lockrM   )5ru   rc   r`   rt   r=   r   r   r  r   r   r?   r   r-   r%   r   r   loadrh   rf   makedirsshutilcopycopytreeErrorrm   r:  r  r  r  r
  _update_localrc  r9  r   r~   rD  ra   r   r   	read_textrX   rmtreedumpr   r   r   replacestriprT   chmodstatS_IWRITES_IREAD)#rE   r   r   r   r   ru   r   r   Z
source_dirr=  fidr   fnamer   rj  rC  Z
real_errorZ
linked_dirr   Zremovedr0  r  r   rA  r<  r$  jlabrz   Z
local_pathZpkg_datarn  Z	lock_pathZlock_templater   templaterG   rG   rH   r    s    





(













0
(,z_AppHandler._populate_stagingc                    s<   j }t jd } jd } jd } jd } jd }|d } fdd}	t |d	< | D ]<\}
}|
|v rtqb||d	 |
< d
 jd |
 d  |d |
< qb| D ]^\}
}|
|v rqt jdd}t||d }|	||d |
< |d |d	 |
< |	||d |
< qt |d d<   }| D ]\}
}||
 }|rX|s&t||
|d | q&|	|d |d |
< |d }dD ]J}|	|d}|sqx|du rd}|||d  |
< ||d d |
< qxq& jd D ]d}||d v r|d d 
| n ||d v r|d d 
| ||d v r|d 
| q|S )z<Get the template the for staging package.json file.
        r   r  r  r   r*  r   c                    s<   t | t jd} d| tjd } tjdkr8|  } | S )Nr   file:rM   nt)	r`   relpathrc   ru   r~  rf   sepr   lower)rz   r   rG   rH   format_path0  s
    
z6_AppHandler._get_package_template.<locals>.format_pathrl  r  rz   rm  r   filenamer4  r  ZextensionMetadatar   )r   mimeExtensionFTr0   sr  r7  )r=   r   r   r  r:  rc   ru   r,  _log_single_compat_errorsrh   r   )rE   r6  r=   r   r  r<  r   r*  r  r  r0  r  r$  rz   r  rV  r_  Z	jlab_datar?  rG   r   rH   r9  $  sd    




 
z!_AppHandler._get_package_templatec                 C   sP   t  6}| ||}t||d }t| W  d   S 1 sB0    Y  dS )zwCheck if a local package has changed.

        `dname` is the directory name of existing package tar archives.
        r  N)r   rQ  rc   r`   rt   )rE   r   r  rA  r  r   r   rG   rG   rH   r;  r  s    z_AppHandler._check_localc           	      C   s   |d }t t||sd}t T}| ||}|d |krN|W  d   S t|d t||d  W d   n1 s|0    Y  |rtt|| |d |d< t|d |d |d< |d S )z>Update a local dependency.  Return `True` if changed.
        r  r0   Nrz   tar_dir)	r`   rt   rc   r   rQ  rv  moverf   r	  )	rE   r   r  rA  r   Zdtyper  r  r   rG   rG   rH   rz    s    8z_AppHandler._update_localc                 C   sh   | j }t }t| jd}t| j d}| | j|}t|d}||ksNt|sR|S || || |S )z0Get the extensions for the application.
        r   )ru   r  rc   r   _get_extensions_in_dirr`   rt   update)rE   r   ru   r   Zsys_pathZapp_pathrG   rG   rH   rb    s    
z_AppHandler._get_extensionsc                 C   s   t  }|| jkrdnd}tt|ddD ]}t|}|dt  }|d }|dt  }	t|}
t|}|	t
r|tt
td  }nd	}t|}t |
t|
||d
 |r|nd	|	|t|
|d	||p|< q(|S )z1Get the extensions in a given directory.
        r  rS   r   *.tgzr4  r   r   .tgzNr   )	rz   r  urlr   rL  r   r4  r  r  )r  ru   r   rc   r   rh   r`   ra   basenamers   
PIN_PREFIXr   r   rD  )rE   rA  r   r   r  r   r   depsr   r  rz   r  aliasr  rG   rG   rH   r    s0    




z"_AppHandler._get_extensions_in_dirc                 C   s   t  }| jd }t }| jd  D ]*\}}|d }t|||||< || q$| jd  D ]*\}}||v rpq^|d }t|||||< q^|S )z.Get the extension compatibility info.
        r   r  r4  r   )r  r   setr:  _validate_compatibilityrD   )rE   compatr   seenr   r   r  rG   rG   rH   r,    s    
z!_AppHandler._get_extension_compatc                 C   s
   |  dS )z.Get the locally installed extensions.
        r  )_get_local_datar   rG   rG   rH   rc    s    z!_AppHandler._get_local_extensionsc                 C   s   |  d}t| jdd}| D ]\}}t|d|d||< q t|sJ|S tt|dD ]t}t|}t	|}|d }||vr| j
d|  t| qX|| }t||d< ||d	< |d
 |d
< ||d< qX|S )z!Get the linked packages.
        r  r   r0   )r  r  r  r  r   z#Removing orphaned linked package %sr  rz   r   r   )r  rc   ru   r:  r  r`   rt   r   ra   r   r=   rE  rf   r	  r  )rE   r   rA  r   r  rz   r   r$  rG   rG   rH   rd    s(    




z _AppHandler._get_linked_packagesc                 C   s   |   }|dg S )z-Get the uninstalled core extensions.
        r  )r  rh   r   rG   rG   rH   re    s    z,_AppHandler._get_uninstalled_core_extensionsc                 C   sn   g d}|D ]\}t | j|}t|szt| W q tyf } z|jtjkrR W Y d}~qd}~0 0 qdS )z-Ensure that the application directories exist)r   r   r   ZschemasZthemesN)	rc   ru   r`   rt   rf   ru  OSErrorerrnoZEEXIST)rE   dirsrA  rz   erG   rG   rH   r    s    
z_AppHandler._ensure_app_dirsc                 C   s:  |    | j}|d|  }|s"dS |d|  }i }|d||f  t|D ]}||d v r^qL|d | }|d }	|d | }
d	}t||d
 r|dt 7 }n|dt 7 }|
r|dt 7 }n|dt 7 }|d r|d7 }|d }|r|d|||	|f  n|d||	|f  |
rL|	|
f||< qLt	|| |d	 dS )z-List the extensions of a given type.
        z%s_extensionsNz%s_dirz   %s dir: %sr  r   r   r  r0   r)   %sr`  rk  rL  z        %s %s v%s%s        %s v%s%s)
r   r=   r   r/  r^  r   r   r   r   _log_multiple_compat_errors)rE   r   r>  r=   r   rA  error_accumulatorr   r   r   r_  extrarL  rG   rG   rH   r.    s>    
z_AppHandler._list_extensionsc                 C   sj  |    | j}| j}i }tdd | jD }|d  D ]}d||d < q8| D ]\}}|sbqR|| |d D ]}|d | }	|	d |krqt|	d }
|d | }d}t||d	 r|d
t 7 }n|d
t	 7 }|r|d
t
 7 }n|d
t 7 }|	d r|d7 }|	d}|r*|d|d |d f 7 }|d||
|f  |rt|
|f||< qt|d qRt|| d S )Nc                 s   s   | ]}|d fV  qdS )FNrG   )r   prG   rG   rH   	<genexpr>D  r   z9_AppHandler._list_federated_extensions.<locals>.<genexpr>r  Text_dirr   r  r0   r)  r  r`  rk  r  z	 (%s, %s)ZpackageManagerZpackageNamer  )r   r   r=   r  r   valuesr:  r^  r   r   r   r   rh   r  )rE   r   r=   r  Zext_dirsrV  r  Zhas_extsr   r   r   r_  r  r  rG   rG   rH   r-  =  sJ    


z&_AppHandler._list_federated_extensionsc                 C   sR   t | jdd}t|si S t|}t|W  d   S 1 sD0    Y  dS )z3Get the build config data for the app dir.
        r   build_config.jsonN)rc   ru   r`   rt   r   r   rt  )rE   r   r  rG   rG   rH   r  m  s
    

z_AppHandler._read_build_configc                 C   sT   |    t| jdd}t|d }tj||dd W d   n1 sF0    Y  dS )z/Write the build config to the app dir.
        r   r  rp  rq  rr  N)r  rc   ru   r   r   r}  )rE   r   r   r  rG   rG   rH   r
  w  s    z_AppHandler._write_build_configc                 C   s   |   }||t }g }| D ]\}}t|s"|| q"|D ].}|dd}d||f }| j	| ||= qD|r| 
| |S )z>Get the local data for extensions or linked packages.
        r[    z**Note: Removing dead %s "%s")r  r  r  r:  r`   rt   rW   r~  r=   rE  r
  )rE   r  r   r   Zdeadr   Z	link_typer  rG   rG   rH   r    s    

z_AppHandler._get_local_datac                 C   s  | j |||d}|d }d|dd vo0|d  }|d }t|}|rd}	|	|d	|f }	|rz| |}
W q ty   t|	Y q0 nt|	|d
t }t||| j	}|rt
|d |d |}	|rz| |}
W n ty   t|	Y n0 |
r^|r^| jd| | jd|
 t $}| d||
f |W  d   S 1 sT0    Y  d	|	 dd }d| |d|f}	t|	t| jd|d }t|rt| t|d | ||d< |S )zKInstall an extension with validation and return the name and path.
        r   r   @   Nr  r   z!"%s" is not a valid extension:
%srP   r4  r   zIncompatible extension:
%szFound compatible version: %srM     r0   z

r   r  rz   )rQ  rR  rX   rN  r   r:   rh   r  r  r   _format_compatibility_errorsr=   r?   r   r  
splitlines%_format_no_compatible_package_versionrc   ru   r`   rt   rf   r	  rv  r  )rE   r   r  r   r   r   Zallow_fallbackr   r1  r  r   r  r_  Ztempdir2	conflictsr   rG   rG   rH   r    sZ    $
z_AppHandler._install_extensionc                 C   sH  t |ot |}|r<t t|ds<| jdtdg|d t||d}| jtdd|g|d}|dkrxd	}t|| t	t|d
d }t
||d< |rt| |d< }	|dd|	 }
t||
 |
|d< n||d< |r|d }tt |dt|}t|| ||d< t |d |d< |d d |d< |d d |d< |S )zCall `npm pack` for an extension.

        The pack command will download the package tar if `source` is
        a package name, or run `npm pack` locally if `source` is a
        directory.
        rn  rx   r  r  )r  r  npmpackr   "%s" is not a valid npm packager  r   shar  z-%s.tgzrz   z{}{}.tgzr  r   r   )r`   rt   rP  rc   r  r&   r  r   r:   r   r   _tarsumr~  rv  r  rD  formatr  r  )rE   r  r  r   r  r   r   r  rz   r  r   Zold_pathnew_pathrG   rG   rH   rQ    s2    
z_AppHandler._extract_packagec              	   C   s   | j d }zt| j|| j}W n ty2   Y dS 0 |di }dd }t| |ddD ]\}}|di }t|||}	|	sZd	|v r| j	d
||f  qZt
 $}
| d||f |
}W d   n1 s0    Y  t|d r dS |  S qZdS ).Get the latest compatible version of a packager   Nversionsc                 S   s   t | d ddS Nr   T)prerelease_first_semver_key	key_valuerG   rG   rH   sort_key	  s    z@_AppHandler._latest_compatible_package_version.<locals>.sort_keyTr0  reverser4  
deprecatedzEDisregarding compatible version of package as it is deprecated: %s@%srM  r   )r   _fetch_package_metadatar   r=   r   rh   r/  r:  r  r?   r   rQ  rR  )rE   r   r   metadatar  r  r   r   r  r_  r  r   rG   rG   rH   rN    s8    
"z._AppHandler._latest_compatible_package_versionc              	   C   s|  | j d }g }|D ]}zt| j|| j}W n ty@   Y qY n0 |di }dd }t| |ddD ]D\}}	d|	v rzqh|	di }
t||
|}|sh|	d	||f   qqhqi }|s|S t
 }| jtd
dg| |d}|dkrd}t|| |D ]\}|d dd|dd dddd d }tt||}	t|	s|	d ||	d < qW d   n1 sn0    Y  |S )zGet the latest compatible versions of several packages

        Like _latest_compatible_package_version, but optimized for
        retrieving the latest version for several packages in one go.
        r   r  c                 S   s   t | d ddS r  r  r  rG   rG   rH   r  5  s    z@_AppHandler.latest_compatible_package_versions.<locals>.sort_keyTr  r  r4  rM  r  r  r  r   r  r  r0   r  NrJ   rM   r  r   r   )r   r  r   r=   r   rh   r/  r:  r  rW   r   r  r   r:   r~  r   r`   rX   rR  )rE   r   r   keysr   r  r  r  r   r   r  r_  r  r   r  r0  r  rG   rG   rH   r   $  sD    

02z._AppHandler.latest_compatible_package_versionsc                 C   s  | j d }d}d}zt| j|| j}W n ty8   Y n0 |di }dd }tt| |dd}|d d	 d
i }	|d }
|d d }|	 D ]:\}}||v rt	|
| |dd}|p|dk }|p|dk}q|rd| S dg}|r|
d d|j|dS )r  r   Fr  c                 S   s   t | d ddS r  r  r  rG   rG   rH   r  j  s    zC_AppHandler._format_no_compatible_package_version.<locals>.sort_keyTr  r   r  r4  rm  r   singletonPackagesdrop_prerelease1zKThe extension "%s" does not yet support the current version of JupyterLab.
zcNo version of {extension} could be found that is compatible with the current version of JupyterLab.)z9However, it seems to support a new version of JupyterLab.zConsider upgrading JupyterLab.r  r   )r   r  r   r=   r   rh   r9   r/  r:  _compare_rangesextendrX   r  )rE   r   r   Zlab_newer_than_latestZlatest_newer_than_labr  r  r  storeZlatest_deps	core_deps
singletonsr0  rV  cpartsrG   rG   rH   r  Z  s4    

z1_AppHandler._format_no_compatible_package_versionc                 K   s>   | j  rtd| j|d< | j |d< t|fi |}| S )z]Run the command using our logger and abort callback.

        Returns the exit code.
        zCommand was killedr=   rF   )rF   r;   r:   r=   r/   r\   )rE   r>   r   rB   rG   rG   rH   r    s    


z_AppHandler._run)NN)NNNFTT)F)r   )F)NNNF)F)N)N),r]   r^   r_   rI   r   r   r   r   r   r   r   r   r   rH  r   r   r   r   rY  rZ  r   r   r  r9  r;  rz  rb  r  r,  rc  rd  re  r  r.  r-  r  r
  r  r  rQ  rN  r   r  r  rG   rG   rG   rH   r   J  s\   
.  
.B
Q.
"

#  
 
N.0

B
(%60r   c                 C   sj   t d}z&tj|dgtd}| |d W n6 tyd   t j}|d d }d| }t	|Y n0 dS )z@Check for the existence of nodejs with the correct version.
    rx   znode-version-check.jsr  r1   ZenginesztPlease install nodejs %s before continuing. nodejs may be installed using conda or directly from the nodejs website.N)
r   r@   check_outputr%   r?   r   	Exceptionr$   r   r:   )r=   rx   outputr   Zverr  rG   rG   rH   r     s    r   c                 C   s~  i i d}zt d}W n  ty6   | d | Y S 0 z,ztj|tdddgtjtd}|d}t	|
 }zR|D ]H}t|}|d	 d
krv|d }tt|}	|	d	 dkrv|	d ||< qvW n ty   Y n0 | d W n~ tjy, }
 z.| d|
jd|
jd W Y d}
~
n>d}
~
0  ty` }
 z| d|
 W Y d}
~
n
d}
~
0 0 W |S |     Y S 0 dS )zGet the yarn configuration.

    Returns
    -------
    {"yarn config": dict, "npm config": dict} if unsuccessfull the subdictionary are empty
    )r   z
npm configrx   z9NodeJS was not found. Yarn user configuration is ignored.r   r8   z--json)r4   r2   r1   typer   r   inspectzYarn configuration loaded.z(Fail to get yarn configuration. {!s}{!s}Nz$Fail to get yarn configuration. {!s})r   r:   r?   r@   r  r&   rA   r%   r   iterr  r   r   rU   StopIterationZCalledProcessErrorrC  r  r4   r  r  )r=   Zconfigurationrx   Zoutput_binaryr  linesliner   r0  r  r  rG   rG   rH   r     s4    




6(r   c                 C   s   | pt dS )zEnsure that we have a loggerr   r   r  rG   rG   rH   r<     s    r<   c                 C   s"   t | } t | rt | } | S )z1Normalize a given extension if it is a path.
    )r`   
expanduserrt   ra   r  rG   rG   rH   r    s    


r  c                    s    fdd}t j| |d dS )zRemove a tree, logging errorsc                     s    j d| d d S )NzError in shutil.rmtreeexc_info)r?   r  r  rG   rH   onerror  s    z_rmtree.<locals>.onerror)r  N)rv  r|  )rz   r=   r  rG   r  rH   r     s    r   c                 C   s8   zt |  W n$ ty2   |jdt d Y n0 dS )zRemove a file, logging errorszError in os.unlinkr  N)rf   unlinkr  r?   rS   r  )rz   r=   rG   rG   rH   _unlink  s    r  c                 C   sT   t | D ]D}t| |}t|s.t|r:t|| q
t|r
t|| q
dS )z3Remove all files/trees within a dir, logging errorsN)	rf   listdirr`   rX   isfileislinkr  rP  r   )rz   r=   r  Z	file_pathrG   rG   rH   r     s    
r   c                    s  |  dd}|du rdgS t|ts*dgS | dd}| dd}| dd	| d
d	 g }|sp|sp|d ||krd}|| | d }|  dd}|ds|d7 }|du r|}n|r|ds|d7 }|du r|}n|r|ds|d7 }|r||vr|d|  |r0||vr0|d|  r\tfdd|D s\|d   rt fdd|D s|d   |S )z`Detect if a package is an extension using its metadata.

    Returns any problems it finds.
    r   NzNo `jupyterlab` keyz*The `jupyterlab` key must be a JSON objectr   Fr  	themePathr0   	schemaDirz-No `extension` or `mimeExtension` key presentz?`mimeExtension` and `extension` must point to different modulesr   mainri  z.jsTzMissing extension module "%s"z!Missing mimeExtension module "%s"c                 3   s    | ]}| tt V  qd S r   rs   rm   r   r   )r  rG   rH   r    r   z&_validate_extension.<locals>.<genexpr>zthemePath is empty: "%s"c                 3   s    | ]}| tt V  qd S r   r  r   )r  rG   rH   r  !  r   zschemaDir is empty: "%s")rh   r7   r  rW   r8  any)r   r  r   Zmime_extensionr1  r  filesr  rG   )r  r  rH   rR    sH    



rR  c                 C   sd   t | d}d}td}|D ]<}| s,q||}||}|r|| ||}q@q| S )z6
    Compute the recursive sha sum of a tar file.
    r   i  Zsha1)	r   r   hashlibnewr  r   r   r  Z	hexdigest)Z
input_filer   Z
chunk_sizehmemberr   r   rG   rG   rH   r  '  s    



r  c                 C   sR   t | dd}t|rJt|}t|W  d   S 1 s>0    Y  ndS dS )z)Get the data for the app static dir.
    r   r2  N)rc   r`   rt   r   r   rt  )ru   r   r  rG   rG   rH   rf  :  s
    

*rf  c           	      C   sd   |d }|d d }g }|  D ]>\}}||v r t|| |dd}|du r |||| |f q |S )z0Validate the compatibility of an extension.
    rm  r   r  Tr  F)r:  _test_overlaprW   )	r   r  r   r  r  r_  r0  rV  ZoverlaprG   rG   rH   r  E  s    r  c                 C   s$   t | |||d}|du rdS |dkS )zTest whether two version specs overlap.

    Returns `None` if we cannot determine compatibility,
    otherwise whether there is an overlap
    )r  drop_prerelease2Nr   r  )spec1spec2r  r  cmprG   rG   rH   r  Y  s    r  c                 C   s"  t | d}t |d}|jr |js$dS d}t|j|jD ]\}}|d j}	|d j}
|d j}|d j}|	jr~|r~|	d}	|jr|r|d}|d j}|d j}|	ds8|	drq8|	|
krt
nt}||krt
nt}|	|
krtnt}|	|
krtnt}dd	 }|	|
kr|	d
r|}||kr8|	d
r8|}t|	|drT||	|ds||
|drp||
|dst||	dr|||
ds|||	dr|||
dr dS t||
dr|du rd}q8|dkr8d}q8t|	|dr|du rd}q8|dkr8d}q8tdq8|du rd}|S )zTest whether two version specs overlap.

    Returns `None` if we cannot determine compatibility,
    otherwise return 0 if there is an overlap, 1 if
    spec1 is lower/older than spec2, and -1 if spec1
    is higher/newer than spec2.
    TNFr   patch<c                 S   s   dS )NTrG   )xyzrG   rG   rH   noop  s    z_compare_ranges.<locals>.noop>r  z(Unexpected case comparing version ranges)r'   rangerQ   productr  Zsemver
prereleaseZincoperatorrs   r+   r*   r)   r(   AssertionError)r  r  r  r  Zr1Zr2Zreturn_valueZr1setZr2setZx1Zx2Zy1Zy2Zo1Zo2ZlxZlyZgxZgyr  rG   rG   rH   r  f  sr    	





















r  c                 C   sP   |pi }|  D ]:\}}|dkr"q| |kr0 dS t|| dur dS qdS )z*Test whether the package is disabled.
    FTN)r:  recompilematch)r   r)  patternrV  rG   rG   rH   r^    s    r^  c                 C   s   g }d}d}|D ]^}|\}}}	t t|d}t t|	d}	||||	f t|t|d }t|t|d }qd}
|
| |f }
|
d7 }
|
d|7 }
|
d|7 }
|
d7 }
|D ]*\}}}	|
|||	| | d	 7 }
q|
S )
z/Format a message for compatibility errors.
    
   Tr  z6
"%s@%s" is not compatible with the current JupyterLabz
Conflicting Dependencies:
Z
JupyterLabZ	ExtensionzPackage
rP   )rm   r'   rW   maxr   ljust)r   r   r_  r   Zl0l1rC  r@  r  r?  r  rG   rG   rH   r    s&    
"r  c           	      C   s   g }g }|  D ]2\}\}}t|}|dkr8|| q|| q|rd| ddg| dg  |D ]*}|| \}}t|||}| |d  qhdS )z8Log compatibility errors for multiple extensions at oncer   z	
        z)
   The following extension are outdated:zO
   Consider running "jupyter labextension update --all" to check for updates.
rP   N)r:  _compat_error_agerW   rE  rX   r  )	r=   Z
errors_mapZoutdatedZothersr   r   r_  ager  rG   rG   rH   r    s&    r  c                 C   s<   t |}|dkr| d| nt|||}| |d  dS )z/Log compatability errors for a single extensionr   z The extension "%s" is outdated.
rP   N)r  rE  r  )r=   r   r   r_  r  r  rG   rG   rH   r  	  s
    r  c                 C   sZ   d}d}| D ]0\}}}t ||dd}|p.|dk }|p:|dk}q|rJ|sJdS |rV|sVdS dS )zCompare all incompatabilites for an extension.

    Returns a number > 0 if all extensions are older than that supported by lab.
    Returns a number < 0 if all extensions are newer than that supported by lab.
    Returns 0 otherwise (i.e. a mix).
    FTr  r   r  r  r  )r_  Z	any_olderZ	any_newerr[   r  r?  r  rG   rG   rH   r  	  s    r  c                 C   s    | d }t |d t |d  S )zGet the core extensions.
    r   r   r7  )r8   )r   r   rG   rG   rH   rg  '	  s    rg  c                 c   s,   | D ]"}t |trd|fV  q|fV  qdS )az  Sort key for prereleases.

    Precedence for two pre-release versions with the same
    major, minor, and patch version MUST be determined by
    comparing each dot separated identifier from left to
    right until a difference is found as follows:
    identifiers consisting of only digits are compare
    numerically and identifiers with letters or hyphens
    are compared lexically in ASCII sort order. Numeric
    identifiers always have lower precedence than non-
    numeric identifiers. A larger set of pre-release
    fields has a higher precedence than a smaller set,
    if all of the preceding identifiers are equal.
    r0   N)r7   int)r  entryrG   rG   rH   _semver_prerelease_key.	  s    
r  c                 C   sh   t | d}|r|jrdnd}nd}||j|j|jf }|sL|jrH|d nd}|jrd|tt|j }|S )a  A sort key-function for sorting semver version string.

    The default sorting order is ascending (0.x -> 1.x -> 2.x).

    If `prerelease_first`, pre-releases will come before
    ALL other semver keys (not just those with same version).
    I.e (1.0-pre, 2.0-pre -> 0.x -> 1.x -> 2.x).

    Otherwise it will sort in the standard way that it simply
    comes before any release with shared version string
    (0.x -> 1.0-pre -> 1.x -> 2.0-pre -> 2.x).
    T)r   )r  rG   )r,   r  majorminorr  r9   r  )r   r  vr0  rG   rG   rH   r  F	  s    
r  c              
   C   s   t t| t|ddddid}z|d|j  W n$ tyV   |d|   Y n0 zHtt	|&}t
| dW  d   W S 1 s0    Y  W n4 ty } z|d	||  W Y d}~n
d}~0 0 dS )
z6Fetch the metadata for a package from the npm registryr  )safeZAcceptzHapplication/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*)ZheaderszFetching URL: %sr1   Nz+Failed to fetch package metadata for %r: %r)r   r
   r	   r?   Zfull_urlAttributeErrorZget_full_url
contextlibclosingr   r   r   r   r   r   rK  )r   r   r=   ZreqZresponseexcrG   rG   rH   r  c	  s$    8r  __main__)N)N)N)N)N)N)N)NN)NNF)NFNN)N)NNNNFNTT)N)Nr   )Nr   )FN)N)N)N)N)N)N)N)FF)FF)N)F)r   r  r  r  rQ   r   r   rf   Zos.pathrz   r`   r  rv  r  rq   r@   rS   r   warningsrw  r   r   pathlibr   Ztempfiler   	threadingr   Zurllib.errorr   Zurllib.requestr   r	   r
   r   Zjupyter_core.pathsr   Z(jupyter_server.extension.serverextensionr   r   r   r   Zjupyterlab_server.configr   r   r   r   r   r   Zjupyterlab_server.processr   r   r   r   Zpackaging.versionr   Z	traitletsr   r   r   r   r    r!   r"   Zjupyterlab.coreconfigr$   Zjupyterlab.jlpmappr%   r&   Zjupyterlab.semverr'   r(   r)   r*   r+   r,   Zjupyterlab._versionr-   r	  r   ra   rX   r~   r   r  r   r/   rc   ri   rj   rw   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   objectr   r   r   r<   r  r   r  r   rR  r  rf  r  r  r  r^  r  r  r  r  rg  r  r  r  r]   rG   rG   rG   rH   <module>   s    $ 
@







6





!   


	
	



	
	

          X%
	
5

W


