o
    iO                    @   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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. ddl/m0Z0m1Z1m2Z2m3Z3 ddl4m5Z5 ddl6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z< ddl=m>Z> ddl?m@Z@ ddlAmBZBmCZC ddlDmEZEmFZFmGZGmHZHmIZImJZJ eKdZLe
Me
NeBdZOe
NeOdZPdZQdZRG dd de0ZSdd ZTdd ZUdd  ZVd!d" ZWdd#d$ZXdd%d&ZYdd'd(ZZdd)d*Z[d+d, Z\dd-d.Z]dd/d0Z^G d1d2 d2e8Z_d3d4 Z`dd5d6Zadd7d8Zbdd:d;Zcdd<d=Zddd>d?Ze					9		@	@ddAdBZfddCdDZgddFdGZhddHdIZiddJdKZjddLdMZkddNdOZlddPdQZmddRdSZnddTdUZoddVdWZpdXdY ZqG dZd[ d[Zrd\d] Zsd^d_ Ztdd`daZudbdc Zvddde Zwdfdg Zxdhdi Zydjdk Zzdldm Z{dndo Z|dpdq Z}ddrdsZ~ddtduZddvdwZdxdy Zdzd{ Zd|d} Zd~d Zdd Zdd ZdddZdd Zedkre^eB dS dS )zJupyterLab command handler    N)deepcopy)glob)Path)TemporaryDirectory)Event)URLError)Requestquoteurljoinurlopen)jupyter_config_dir)GREEN_ENABLEDGREEN_OKRED_DISABLEDRED_X)get_federated_extensionsget_package_urlget_page_configget_static_page_configwrite_page_config)ProcessWatchHelperlist2cmdlinewhich)Version)Bool	HasTraitsInstanceListUnicodedefault)__version__
CoreConfig)HERE	YARN_PATH)Rangegtgteltltemake_semverz'.*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d}t||r| rd}t|t|| _d| _|| _| j	dt
|  | j||tjtjddd| _|pAt | _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stdoutuniversal_newlinesencodingN)
isinstancelisttuple
ValueErroris_set_ensure_loggerlogger
_last_linecmddebugr   _create_process
subprocessSTDOUTPIPEprocr   _kill_eventr   _procsadd)selfr>   r<   r0   
kill_eventr1   msg rK   N/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/jupyterlab/commands.py__init__C   s(   
zProgressProcess.__init__c                 C   s   g }| j }| j}tg d}| d u rVtjt| tj	  tjd |
 r6|   d}t|z|jdd\}}|| W n
 tjyO   Y qw | d u s| jd| tj	  |  S )N)-\|/zProcess was abortedg?)timeout
)rD   rE   	itertoolscyclepollsysr3   writenextflushr:   	terminater9   communicateappendrA   TimeoutExpiredr<   r?   join)rH   cacherD   rI   spinnerrJ   out_rK   rK   rL   waitl   s,   

zProgressProcess.wait)NNNN)__name__
__module____qualname__rM   re   rK   rK   rK   rL   r-   B   s    
)r-   c                  G   s   t t j|  S )z!Join paths to create a real path.)ospabspathr`   )argsrK   rK   rL   pjoin   s   rl   c                  C   (   t jd} | ptt dd} t| S )z6Get the configured JupyterLab user settings directory.JUPYTERLAB_SETTINGS_DIRlabzuser-settingsosenvirongetrl   r   ri   rj   )settings_dirrK   rK   rL   get_user_settings_dir      
ru   c                  C   rm   )z3Get the configured JupyterLab workspaces directory.JUPYTERLAB_WORKSPACES_DIRro   
workspacesrp   )workspaces_dirrK   rK   rL   get_workspaces_dir   rv   rz   c                  C   s   t jdrttt jd  S ttjddd} t	t
dr"t
  tt
dd}t|r:| |s:t|ddd} ntjdrLt| sLtd	rLd	} tt|  S )
z,Get the configured JupyterLab app directory.JUPYTERLAB_DIRsharejupyterro   getuserbase	USER_BASENz/usrz/usr/local/share/jupyter/lab)rq   rr   rs   strr   resolverl   rX   prefixhasattrsiter~   getattrr$   
startswithri   exists)app_diruserbaserK   rK   rL   get_app_dir   s    

r   c                 C   sJ   t dtdddddg| |d dk}|r#t dtg| |d}|  d	S d	S )
a>  `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
    nodedlxzyarn-berry-deduplicatez-sfewerHighestz--failr0   r<   r   N)r-   r%   re   )pathr<   	had_dupes	yarn_procrK   rK   rL   dedupe_yarn   s(   		r   c                 C   sZ   t |}tdtddg| |d}| }|dkr)t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.
    r   z--immutablez--immutable-cacher   r   )r;   r-   r%   re   r   	REPO_ROOT)r0   r<   r   retrK   rK   rL   ensure_node_modules   s   
r   c                 C   sJ   t | } ttd}tt| st|s#tdtdgt| d}|	  dS dS )z)Ensure that the dev assets are available.staticr   buildr   N)
r;   rl   DEV_DIRr   r   ri   r   r-   r%   re   )r<   targetr   rK   rK   rL   
ensure_dev   s   
r   c                 C   sV   t td}t| } t tdd}t|s)t||  tdtdg|| d}|  dS dS )z*Ensure that the core assets are available.stagingr   
index.htmlr   r   r   N)	rl   r$   r;   ri   r   r   r-   r%   re   )r<   r   r   r   rK   rK   rL   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)ri   r   rl   )r   msgsrK   rK   rL   
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.
    packagesmetapackagez/.* Found 0 errors\. Watching for file changes\.r   runwatchr0   r<   startup_regex)r;   r   r   ri   rj   r`   r   r%   )r<   ts_dirts_regexts_procrK   rK   rL   watch_packages  s   
r   c                 C   s4   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.
    r   r   r   r   )r;   r   r   r%   r   WEBPACK_EXPECT)r<   package_procswp_procrK   rK   rL   	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eddd Z  ZS ) 
AppOptionszOptions object for build systemNc                    sP   |d ur||d< |d ur||d< d|v r|d s| d t jdi | d S )Ncore_configr<   r   rK   )popsuperrM   )rH   r<   r   kwargs	__class__rK   rL   rM   G  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 datarK   zEvent for aborting call)rk   r   z7The paths to look in for prebuilt JupyterLab extensionszNPM packages registry URLFz*Splice source packages into app directory.zIf true, perform only a quick check that the lab build is up to date. If false, perform a thorough check, which verifies extension contents.r<   c                 C   s
   t dS )N
jupyterlablogging	getLoggerrH   rK   rK   rL   _default_loggerp     
zAppOptions._default_loggerr   c                 C      t  S N)r   r   rK   rK   rL   _default_app_dirv     zAppOptions._default_app_dirr   c                 C   r   r   r"   r   rK   rK   rL   _default_core_configz  r   zAppOptions._default_core_configregistryc                 C   s   t | jd }|dtS )Nyarn configr   )_yarn_configr<   rs   YARN_DEFAULT_REGISTRYrH   configrK   rK   rL   _default_registry~  s   zAppOptions._default_registryNN)rf   rg   rh   __doc__rM   r   r   r   use_sys_dirr   r   Loggerr<   r#   r   r   rI   r   labextensions_pathr   splice_sourceskip_full_build_checkr    r   r   r   r   __classcell__rK   rK   r   rL   r   D  s8    




r   c                 C   s,   | du rt  S t| jt r| S t di | S )z-Helper to use deprecated kwargs for AppOptionNrK   )r   
issubclassr   )optionsrK   rK   rL   _ensure_options  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   rK   rK   rL   r     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   rK   rK   rL   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   rK   rK   rL   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   r   r   r   rK   rK   rL   r     s   

r   c                    s  t    j} j}|d| |ttdkrd}t||ttdkr*d}t|t ddr<|d| t|| n.g d	} fd
d|D }|D ]}t||}t	
|rc|d| t|| qK|d| qK|d t dds{t ddr|d dS 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 rK   )r   ).0tr   rK   rL   
<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   inforl   r$   r9   r   _rmtree_starri   r   _rmtree)r   r<   r   rJ   possible_targetstargetsr   r   rK   r   rL   clean  s2   


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   rI   r   r   r   r   r   rK   rK   rL   r     s   
r   c                 C   s   t | }|  |jS )z.Get a dictionary of information about the app.)r   _ensure_disabled_infor   r   r   rK   rK   rL   get_app_info  s   r   
sys_prefixc                 C      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   rK   rK   rL   enable_extension     r  c                 C   r   )zfDisable a JupyterLab package.

    Returns `True` if a rebuild is recommended, `False` otherwise.
    Tr   r   r   rK   rK   rL   disable_extension  r  r  c                 C   s   t |}|| |S )z7Check if a JupyterLab extension is enabled or disabled.)r   check_extension)r   	installedr   r   rK   rK   rL   r       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   rK   rK   rL   r  $  s   
r  c                 C   s   t | }| S )zList the extensions.)r   list_extensionsr   rK   rK   rL   r  /  s   r  c                 C      t |}|| S )zuLink a package against the JupyterLab build.

    Returns `True` if a rebuild is recommended, `False` otherwise.
    )r   link_package)r   r   r   rK   rK   rL   r
  5     
r
  c                 C   r	  )zzUnlink a package from JupyterLab by path or name.

    Returns `True` if a rebuild is recommended, `False` otherwise.
    )r   unlink_package)packager   r   rK   rK   rL   r  >  r  r  c                 C   s   t | }|jd S )zGet the application version.r   )r   r   r   rK   rK   rL   get_app_versionG     
r  c                 C   r	  )z8Get the latest compatible version of a list of packages.)r   "latest_compatible_package_versions)namesr   r   rK   rK   rL   &get_latest_compatible_package_versionsM  r  r  c                 C   sL   t | d}|d}t| d}dd | D |d< |  |S )z0Read 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)r   lenr   frK   rK   rL   r   X  s    z read_package.<locals>.<listcomp>jupyterlab_extracted_files)	tarfileopenextractfilejsonloadsreaddecode
getmembersclose)r   tarr  datarK   rK   rL   read_packageS  s   
r$  c                   @   sr  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%dYdKdLZ&dYdMdNZ'dOdP Z(dQdR Z)dSdT Z*dUdV Z+dS )]r   c                 C   sn   t |}|| _|j| _|jrt n| j| _|j| _t|jj	| _
|j| _|j| _|j| _|j| _|  | _dS )zCreate a new _AppHandler objectN)r   _optionsr   r   r   sys_dirr<   r   r   _data	core_datar   rI   r   r   _get_app_infor   )rH   r   rK   rK   rL   rM   c  s   z_AppHandler.__init__Nc                 C   s&  t |}| jd }|| jd v r8|  }|dg }||v r6| jd|  || ||d< | | dS dS |   t }| j	|||d}W d   n1 sRw   Y  |d	 }	|d
 rt|  }|
di }
|d |
|	< | | |	|v r||	 }|d |d kr|d dkrt|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sourcer   locationapp)_normalize_pathr   _read_build_configrs   r<   remove_write_build_config_ensure_app_dirsr   _install_extension
setdefaultrq   )rH   r   existingr   r   r   uninstalledtempdirr   r   localotherrK   rK   rL   r   t  s6   



z_AppHandler.install_extensionFTc                 C   sH  |du r| j d p| j d  }|sd}| jjr(tt| jd | jdtdgtd |r,d	nd
g}|r:||r7dnd | j dd	| d | j
}| j||||d t|d}	| jdtdg|	d}
|
dkrrd}| j| t|t|	| j d|r}dnd |rdnd }| jdtd|g|	d}
|
dkrd}| j| t|dS )zBuild the application.Nlinked_packagesr-  Fr<   r   zbuild:packagesr0   r   development	minimizedznot minimizedzBuilding jupyterlab assets (z, ))r   r   r   r   r   installr   z"npm dependencies failed to installzbuild:prodr   z	:minimizer.   r   zJupyterLab failed to build)r   r%  r   r   r   r<   _runr%   r^   r`   r   _populate_stagingrl   r?   RuntimeErrorr   )rH   r   r   r   r   r   r   r   r   r   r   rJ   commandrK   rK   rL   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   r   rC  r?  r   r   )r0   r   r<   )	rl   r   rF  rE  r%   r   r<   r   r   )rH   r   rD   rK   rK   rL   r     s   

z_AppHandler.watchc                    sJ  |    | j| j}d|d   |d s|d r!|  |d< |d r)|   |d r>d | |d | |d |d	 }|r]d
 t|D ]}d| d||   qM|d }|rd t|D ]}|| d }d| d|  ql|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|	  qg }
| jd D ]}| jd | d }| jd | d }t||ds|
	| q|
r
d fddt|
D  | j
dd}|r#d fd d|D  d!S d!S )"z"Print an output of the extensions.zJupyterLab v%sr   federated_extensionsr   compat_errorsz+Other labextensions (built into JupyterLab)r0  rX   r-  z
   local extensions:        : r=  z
   linked packages:r.  uninstalled_corez
Uninstalled core extensions:c                       g | ]	}  d | qS     %sr   r   itemr>  rK   rL   r     r   z/_AppHandler.list_extensions.<locals>.<listcomp>r*  c                    s"   g | ]}| d d  v r|qS ):r   )	partition)r   i)all_extsrK   rL   r     s   " disabledz
Disabled extensions:z (all plugins)rP  shadowed_extsTzO
The following source extensions are overshadowed by older prebuilt extensions:c                    rN  rO  rQ  )r   r   r>  rK   rL   r   )  r   )fastz3
Build recommended, please run `jupyter lab build`:c                    rN  rO  rQ  rR  r>  rK   rL   r   .  r   N)r   r<   r   _get_extension_compat_list_federated_extensions_list_extensionssortedr7   r(   r^   r  )rH   r   r;  r   r=  keyr.  rM  rX  rS  improper_shadowedext_namesource_versionprebuilt_versionmessagesrK   )rW  r<   rL   r    sr   









z_AppHandler.list_extensionsc                 C   sV  |du r| j }| j}| jd }| jd }g }t|dd}t|s$dgS | jd }|d }|d	i }	|d
d}
|
dsS|d
 }t|
t|krSd}||
|f gS | jd }| j	|d}|d }|d	i }dD ]4}|| D ]}||v rwqp||| vr|
d|  qp|| D ]}||v rq||| vr|
d|  qqjttd}| D ]2\}}|	|d|rq||	vrq||v s||v rq|	| |krd}|
|||	| || f  q| D ]\}}|s||v rqt|d}| |||r|
d|  q| D ]&\}}|s||v rqt|dd}| ||d |r'|
d|  q|S )z[Determine whether JupyterLab should be built.

        Returns a list of messages.
        Nr-  r=  r   package.jsonzNo built applicationstatic_datar   dependenciesr   r.   -splicedz*Version mismatch: %s (built), %s (current)rY  )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.  )r   r   r   rl   ri   r   rs   endswithr   _get_package_templater^   r   itemsr   _check_local)rH   rZ  r   r;  linkedrd  pkg_pathrf  old_jlabold_depsstatic_versioncore_versionrJ   rY  new_packagenew_jlabnew_depsext_typeextsrc_pkg_dirpkgdepr   r.  dnamerS  rK   rK   rL   r  0  s~   







z_AppHandler.build_checkc                 C   s^  | j }| j}||d v r4|d | di ddr+|d|d | d d   dS |d|  dS ||d v ra|  }|d	g }||vr_| d
|  || ||d	< | | dS dS |d }|d  D ]:\}}|d }	||krd| dt	|	 }
| |
 t
|	 ||v r|  }|di }||= | |  dS qk|d|  dS )zpUninstall an extension by name.

        Returns `True` if a rebuild is recommended, `False` otherwise.
        rI  rC  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   r   zUninstalling z from $No labextension named "%s" installed)r   r<   rs   errorr2  r^   r4  rm  ri   dirnamerq   r3  r7  warning)rH   r   r   r<   r   r9  r;  extnamer#  r   rJ   rK   rK   rL   r     sZ   
	




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   rm  r   )rH   should_rebuildr  rd   r9  rK   rK   rL   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   rm  _update_extension)rH   r  r  rd   updatedrK   rK   rL   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   r  F)r   r<   r  r  )rH   r   rK   rK   rL   r     s   
z_AppHandler.update_extensionc                 C   s   | j d | }|d r| jd|  dS z| |}W n
 ty&   Y dS w |du r7| jd| d dS ||d krG| j d	|  dS | j d
| d|  | | d| S )r  r   alias_package_sourcez(Skipping updating pinned extension '%s'.FNz No compatible version found for !r   zExtension %r already up to datez	Updating z to version @)r   r<   r  "_latest_compatible_package_versionr   r   )rH   r   r#  latestrK   rK   rL   r    s"   z_AppHandler._update_extensionc                    s   t |}t|rt|sd}t|| t } ||}W d   n1 s*w   Y  t|d }|s< |S  j	
d|  fdd|D    }|di }|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<   r  )r   mr   rK   rL   r   	  s    z,_AppHandler.link_package.<locals>.<listcomp>r=  r.  r   T)r1  ri   r   isdirr9   r   _extract_package_validate_extensionr   r<   r  r2  r7  r4  )rH   r   rJ   r:  r   rd  r   ro  rK   r   rL   r
    s&   

z_AppHandler.link_packagec                 C   s   t |}|  }|di }d}| D ]\}}||ks ||kr"|}q|r)||= n,|di }| D ]\}}||ks?||krA|}q3|rU||= | jd | d }t| |s]t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   r   zNo linked package for %sT)	r1  r2  r7  rm  r   rq   r3  r9   r4  )rH   r   r   ro  foundr   r.  r;  rK   rK   rL   r    s.   

z_AppHandler.unlink_packager   c           	      C   s   t | jd}t|| j|d}|di }d}||d}|r(|s(d||< d}n
|s2|r2d||< 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   )ri   r`   r   r   r<   rs   r   )	rH   r   valuer   r  page_configrX  did_somethingis_disabledrK   rK   rL   r   5  s"   z_AppHandler.toggle_extensionc                 C   s\   |    | j}||d v r| |||S ||d v r'| j| dt  dS | |||S )z/Check if a lab extension is enabled or disabledr*  r=  rT  T)r   r   _check_core_extensionr<   r   _check_common_extension)rH   r   check_installed_onlyr   rK   rK   rL   r  O  s   z_AppHandler.check_extensionc                 C   s   ||d v r| j | dt  dS |r"| j | dt  dS ||d v r5| j | dt  dS | j | dt  dS )z0Check if a core extension is enabled or disabledrM  rT  FrL  Tdisabled_core)r<   r   r   r   r   r   )rH   r   r   r  rK   rK   rL   r  ]  s   z!_AppHandler._check_core_extensionc                 C   s   ||d vr| j | dt  dS |  | }|r)| j | dt d dS |r8| j | dt  dS t||d rL| j | dt  dS | j | dt  dS )z=Check if a common (non-core) extension is enabled or disabledr   rT  Fz (compatibility errors)rL  TrX  )r<   r   r   r[  r   _is_disabledr   r   )rH   r   r   r  errorsrK   rK   rL   r  k  s   z#_AppHandler._check_common_extensionc                    s0  i  | j   d< }| |  d< }|   d< |   d< g   d< }g   d< }| D ]\}}| d v |d< |d d	krF|| 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=  app_extensionssys_extensionsis_localr/  r0  rM  rf  r   r   	staticUrlr.   r&  r   r*  rI  c                    s   g | ]
}| d  v r|qS )rI  rK   )r   ry  rQ  rK   rL   r     s    z-_AppHandler._get_app_info.<locals>.<listcomp>rY  )r(  _get_extensions_get_local_extensions_get_linked_packagesrm  r^    _get_uninstalled_core_extensions_get_static_datar   rs   r&  _get_core_extensionsr   r   )rH   r(  r   r0  rX   r   r#  app_datarK   rQ  rL   r)    s2   



z_AppHandler._get_app_infoc                 C   s   | j }d|v r	d S | j}t| jd}t||| jd}|di }t|t	r-dd |D }||d< g }|d D ]}||d v rD|
| q7||d< d S )	NrX  r   )r  r<   r  c                 S      i | ]}|d qS )TrK   )r   r   rK   rK   rL   
<dictcomp>      z5_AppHandler._ensure_disabled_info.<locals>.<dictcomp>r*  r  )r   r   ri   r`   r   r   r<   rs   r6   r7   r^   )rH   r   r   r  r  rX  r  r_  rK   rK   rL   r     s$   

z!_AppHandler._ensure_disabled_infoc           !   
   C   sl  | j }t|d}|rt|r| jd| t|| j |   |s+| jd d d }| jj	}|r>| j
d t}td }nttd}t|d}	t|	r{t|	}
t|
}W d	   n1 saw   Y  |d dd
|kr{t|| j t| dD ]}t||}tt||| q}dD ]}t||}tttd|| qt|d}t|rt|| j ztt|d| W n' tjy } zdt|vodt|v}|st|sڂ W Y d	}~nd	}~ww t|d}t|rt|| j t| | jd }d}| jd  D ]0\}}||vr'|  }|di }||= | | d}qt|d}| ||||| d q|rC|  | jd< | jd }| D ]\}}t|d}| ||d ||d qL|  }|d }|rq||d< |rx||d< |r||d< |rt tt!dddD ]:}t"t#|}t$t%|j&dd}|d }||d v r||d |< ||d |< ||d v r||d |< qt#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w   Y  t|d(}ttdd(} t|s4t| | t*|t+j,t+j-B  d	S d	S ))z+Set up the assets in the staging directory.r   zCleaning %sr(  r   r   z)Splicing dev packages into app directory.rh  re  Nr.   )index.jszbootstrap.jszpublicpath.jszwebpack.config.jszwebpack.prod.config.jszwebpack.prod.minimize.config.js)z.yarnrc.ymlzyarn.js	templatesz
[Errno 22]z	[Errno 5]r=  r   Fr-  Tr.  r   r  r   *r/   )r5   rg  linkedPackagesresolutionsbuilderdevDependenciesz@jupyterlab/buildernode_modulesz@jupyterlab)ignore_errorsw   indentz	yarn.lock).r   rl   ri   r   r<   r   r   r5  r%  r   r?   r   r!   r$   r  r  loadrs   rq   makedirsshutilcopycopytreeErrorr   rm  r2  r7  r4  _update_localr  rl  r   r   r  rj   r  r   	read_textr`   rmtreedumpchmodstatS_IWRITES_IREAD)!rH   r   r   r   r   r   r   r   
source_dirrp  fidr#  fnamer   r  r  
real_error
linked_dirr   removedr_  r.  r   r}  ro  rS  jlabr   
local_pathpkg_datar  	lock_pathlock_templaterK   rK   rL   rF    s   























z_AppHandler._populate_stagingc                    s$   j }t jd } jd } jd } jd } jd }|d } fdd}	i |d	< | D ]\}
}|
|v r9q0||d	 |
< d
 jd |
 d  |d |
< q0| D ]/\}
}|
|v r\qSt jdd}t||d }|	||d |
< |d |d	 |
< |	||d |
< qSi |d d<   }| D ]H\}
}||
 }|r|st||
|d | q|	|d |d |
< |d }dD ]!}||d}|sq|du rd}|||d  |
< ||d d |
< qq jd D ]0}||d v r|d d 	| n||d v r|d d 	| ||d v r|d 	| q|S )z3Get the template the for staging package.json file.r(  r-  r=  r   rY  r   c              
      sH   t | t t t jd} d| tjd } tj	dkr"| 
 } | S )Nr   file:rQ   nt)ri   relpathrj   realpathrl   r   replacerq   sepr   lower)r   r   rK   rL   format_pathX  s
    
z6_AppHandler._get_package_template.<locals>.format_pathr  r  r   r  r   filenamerg  r.  extensionMetadatar   )r   mimeExtensionFTr.   srM  rj  )
r<   r   r   rm  rl   r   r[  _log_single_compat_errorsrs   r   )rH   ri  r<   r#  r;  ro  r   rY  r  r  r_  r.  rS  r   rJ  r  r  	jlab_datary  rK   r   rL   rl  M  sd   



 z!_AppHandler._get_package_templatec                 C   sP   t  }| ||}t||d }t| W  d   S 1 s!w   Y  dS )zwCheck if a local package has changed.

        `dname` is the directory name of existing package tar archives.
        r  N)r   r  rl   ri   r   )rH   r   r.  r}  r:  r   r   rK   rK   rL   rn    s
   
$z_AppHandler._check_localc           	      C   s   |d }t t||sd}t *}| ||}|d |kr'|W  d   S t|d t||d  W d   n1 s>w   Y  |rMtt|| |d |d< t|d |d |d< |d S )z5Update a local dependency.  Return `True` if changed.r  r.   Nr   tar_dir)	ri   r   rl   r   r  r  moverq   r3  )	rH   r   r.  r}  r#  dtyper8  r:  r   rK   rK   rL   r    s   
z_AppHandler._update_localc                 C   sf   | j }i }t| jd}t| j d}| | j|}t|d}||ks&t|s(|S || || |S )z'Get the extensions for the application.r   )r   rl   r&  _get_extensions_in_dirri   r   update)rH   r(  r   r   sys_pathapp_pathrK   rK   rL   r    s   
z_AppHandler._get_extensionsc                 C   s   i }|| j kr	dnd}tt|ddD ]X}t|}|di }|d }|di }	t|}
t|}|t	rD|t
t	t
d  }nd	}t|}|d
d|
t|
||d |r\|nd	|	|t|
|d
||pj|< q|S )z(Get the extensions in a given directory.r0  rX   r   *.tgzrg  r   r   .tgzNdescriptionr.   r   )
r  r   r  urlr   r  r   rg  r  r/  )r   r   rl   r$  rs   ri   rj   basenamer   
PIN_PREFIXr  r   r  )rH   r}  r(  r   r/  r   r#  depsr   r  r   r  aliasr  rK   rK   rL   r    s2   




z"_AppHandler._get_extensions_in_dirc                 C   s   i }| j d }t }| j d  D ]\}}|d }t|||||< || q| j d  D ]\}}||v r7q.|d }t|||||< q.|S )z%Get the extension compatibility info.r(  rI  rg  r   )r   setrm  _validate_compatibilityrG   )rH   compatr(  seenr   r#  r  rK   rK   rL   r[    s   
z!_AppHandler._get_extension_compatc                 C   s
   |  dS )z%Get the locally installed extensions.r-  )_get_local_datar   rK   rK   rL   r    r   z!_AppHandler._get_local_extensionsc                 C   s   |  d}t| jdd}| D ]\}}|d|d||< qt|s$|S tt|dD ]:}t|}t|}|d }||vrL| j	
d|  t| q+|| }t||d< ||d	< |d
 |d
< ||d< q+|S )zGet the linked packages.r=  r   r.   )r.  r  r  r  r   z#Removing orphaned linked package %sr  r   r   r#  )r  rl   r   rm  ri   r   r   rj   r$  r<   r  rq   r3  r  )rH   r   r}  r   r.  r   r#  rS  rK   rK   rL   r    s(   




z _AppHandler._get_linked_packagesc                 C   s   |   }|dg S )z$Get the uninstalled core extensions.r+  )r2  rs   r   rK   rK   rL   r     r  z,_AppHandler._get_uninstalled_core_extensionsc                 C   sn   g d}|D ].}t | j|}t|s4zt| W q ty3 } z|jtjkr) W Y d}~qd}~ww qdS )z-Ensure that the application directories exist)r   r   r   schemasthemesN)	rl   r   ri   r   rq   r  OSErrorerrnoEEXIST)rH   dirsr}  r   erK   rK   rL   r5  %  s   
z_AppHandler._ensure_app_dirsc              
   C   sN  |    | j}|d|  }|sdS |d|  }i }|d| d|  t|D ]r}||d v r1q(|d | }|d }	|d	 | }
d
}t||d rQ|dt 7 }n|dt 7 }|
r`|dt 7 }n|dt 7 }|d rn|d7 }|d }|r|d| d| d|	 |  n|d| d|	 |  |
r|	|
f||< q(t	|| |d
 dS )z$List the extensions of a given type.z%s_extensionsNz%s_dirz   z dir: rI  r   r   rJ  r.   rX   %sr  r  r  rK    v)
r   r<   r   r^  r  r   r   r   r   _log_multiple_compat_errors)rH   r   rx  r<   r  r}  error_accumulatorr   r#  r   r  extrar  rK   rK   rL   r]  1  s@   "
z_AppHandler._list_extensionsc              	   C   sf  |    | j}| j}i }dd | jD }|d  D ]}d||d < q| D ]\}}|s.q'|| |d D ]n}|d | }	|	d |krFq7|	d }
|d | }d}t||d	 r`|d
t 7 }n|d
t 7 }|ro|d
t	 7 }n|d
t
 7 }|	d r}|d7 }|	d}|r|d|d |d 7 }|d| d|
 |  |r|
|f||< q7|d q't|| d S )Nc                 S   r  FrK   )r   prK   rK   rL   r  e  r  z:_AppHandler._list_federated_extensions.<locals>.<dictcomp>rI  Text_dirr   rJ  r.   rX  r  r  r  rC  z	 ({}, {})packageManagerpackageNamerK  r  )r   r   r<   r   valuesrm  r  r   r   r   r   rs   formatr  )rH   r   r<   r  ext_dirsr  r  has_extsr   r#  r   r  r   rC  rK   rK   rL   r\  ^  sF   

z&_AppHandler._list_federated_extensionsc                 C   sR   t | jdd}t|si S t|}t|W  d   S 1 s"w   Y  dS )z*Get the build config data for the app dir.r   build_config.jsonN)rl   r   ri   r   r  r  r  )rH   r   r  rK   rK   rL   r2    s   

$z_AppHandler._read_build_configc                 C   sV   |    t| jdd}t|d}tj||dd W d   dS 1 s$w   Y  dS )z&Write the build config to the app dir.r   r
  r  r  r  N)r5  rl   r   r  r  r  )rH   r   r   r  rK   rK   rL   r4    s
   "z_AppHandler._write_build_configc                 C   s   |   }||i }g }| D ]\}}t|s|| q|D ]}|dd}d| d| d}| j| ||= q!|rC| 	| |S )z5Get the local data for extensions or linked packages.rd   r  z**Note: Removing dead z "")
r2  r7  rm  ri   r   r^   r  r<   r  r4  )rH   r.  r   r#  deadr   	link_typerJ   rK   rK   rL   r    s   


z_AppHandler._get_local_datac                 C   s  | j |||d}|d }d|dd vo|d  }|d }t|}|rHd}	|	|d	|f }	|rDz| |}
W n tyC   t|	dw t|	|d
i }t||| j}|rt	|d |d |}	|rz| |}
W n tyv   t|	dw |
r|r| j
d| | j
d|
 t }| | d|
 |W  d   S 1 sw   Y  d	|	 dd }d| |d|f}	t|	t| jd|d }t|rt| t|d | ||d< |S )zBInstall an extension with validation and return the name and path.r   r#  r     Nr,  r   z!"%s" is not a valid extension:
%srT   rg  r   zIncompatible extension:
%szFound compatible version: %s   r.   z

r   r  r   )r  r  r`   r  r   r9   rs   r  r(  _format_compatibility_errorsr<   r?   r   r6  
splitlines%_format_no_compatible_package_versionrl   r   ri   r   rq   r3  r  r  )rH   r   r:  r   r   r#  allow_fallbackr   rd  rJ   r   r  r  tempdir2	conflictsr   rK   rK   rL   r6    sP   

 

z_AppHandler._install_extensionc                 C   sF  t |o	t |}|rt t|ds| jdtdg|d ||d}| jtdd|g|d}|dkr;d	}t|| tt|d
d }t	||d< |rgt
| |d< }	|dd|	 }
t||
 |
|d< n||d< |r|d }tt |t | d}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.
        r  r   rC  r?  )r.  r,  npmpackr   "%s" is not a valid npm packager  r#  shar  z-%s.tgzr   r  r   r   )ri   r   r  rl   rE  r%   r   r9   r   r$  _tarsumr  r  r  r  r  r  )rH   r.  r:  r   r,  r   r   rJ   r   r  r   old_pathnew_pathrK   rK   rL   r    s2   

z_AppHandler._extract_packagec              	   C   s   | j d }z
t| j|| j}W n
 ty   Y dS w |di }dd }t| |ddD ]N\}}|di }t|||}	|	s{d	|v rP| j	d
| d|  q-t
 }
| | d| |
}W d   n1 siw   Y  t|d rw dS |  S q-dS ).Get the latest compatible version of a packager(  Nversionsc                 S      t | d ddS Nr   T)prerelease_first_semver_key	key_valuerK   rK   rL   sort_key     z@_AppHandler._latest_compatible_package_version.<locals>.sort_keyTr_  reverserg  
deprecatedz@Disregarding compatible version of package as it is deprecated: r  r#  )r   _fetch_package_metadatar   r<   r   rs   r^  rm  r  r?   r   r  r  )rH   r   r(  metadatar  r&  r   r#  r  r  r:  r   rK   rK   rL   r    s2   
z._AppHandler._latest_compatible_package_versionc              	   C   sz  | j d }g }|D ]M}z
t| j|| j}W n	 ty   Y q	w |di }dd }t| |ddD ]#\}}	d|	v r;q2|	di }
t||
|}|sU|	| d	|   nq2q	i }|s]|S t
 S}| jtd
dg||d}|dkrzd}t|| |D ].}|d d	d|dd d	ddd d }tt||}	t|	s|	d ||	d < q|W d   |S 1 sw   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   r  r   r"  r$  rK   rK   rL   r&  D  r'  z@_AppHandler.latest_compatible_package_versions.<locals>.sort_keyTr(  r*  rg  r  r  r  r?  r   r  r.   r  NrN   rQ   r  r   r   )r   r+  r   r<   r   rs   r^  rm  r  r^   r   rE  r   r9   r  r$  ri   r`   r  )rH   r  r(  keysr   r,  r  r&  r   r#  r  r  r:  r   rJ   r_  r  rK   rK   rL   r  3  sP   
.
z._AppHandler.latest_compatible_package_versionsc                 C   s  | j d }d}d}z
t| j|| j}W n	 ty   Y nLw |di }dd }tt| |dd}|d d	 d
i }	|d }
|d d }|	 D ]\}}||v rgt	|
| |dd}|p`|dk }|pf|dk}qJ|rnd| S dg}|rx|
d d|j|dS )r  r(  Fr  c                 S   r  r   r"  r$  rK   rK   rL   r&  w  r'  zC_AppHandler._format_no_compatible_package_version.<locals>.sort_keyTr(  r   r  rg  r  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   rs   r8   r^  rm  _compare_rangesextendr`   r  )rH   r   r(  lab_newer_than_latestlatest_newer_than_labr,  r  r&  storelatest_deps	core_deps
singletonsr_  r  cpartsrK   rK   rL   r  g  s@   
z1_AppHandler._format_no_compatible_package_versionc                 K   sB   | j  rd}t|| 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<   rI   )rI   r:   r9   r<   r-   re   )rH   r>   r   rJ   rD   rK   rK   rL   rE    s   


z_AppHandler._runr   )NNNFTTr   )r   r  )NNNF),rf   rg   rh   rM   r   r   r   r  r  r   r   r   r   r  r
  r  r   r  r  r  r)  r   rF  rl  rn  r  r  r  r[  r  r  r  r5  r]  r\  r2  r4  r  r6  r  r  r  r  rE  rK   rK   rK   rL   r   b  sb    
0
3
GS8

"
$
 
K --	

;'!47r   c                 C   sf   t d}ztj|dgtd}| |d W dS  ty2   t j}|d d }d| }t	|dw )z;Check for the existence of nodejs with the correct version.r   znode-version-check.jsr?  r/   enginesztPlease install nodejs %s before continuing. nodejs may be installed using conda or directly from the nodejs website.N)
r   rA   check_outputr$   r?   r  	Exceptionr#   r'  r9   )r<   r   outputr#  verrJ   rK   rK   rL   r     s   
r   c                 C   s^  i i d}zt d}W n ty   | d | Y S w zStj|tddgtjtd}|d}t	|
 }z)|D ]$}t|}|d d	kr\|d
 }tt|}	|	d dkr\|	d
 ||< q8W n	 tyg   Y nw | d W |S  tjy }
 z| d|
jd|
jd W Y d}
~
|S d}
~
w ty }
 z| d|
 W Y d}
~
|S d}
~
ww )zGet the yarn configuration.

    Returns
    -------
    {"yarn config": dict, "npm config": dict} if unsuccessfull the subdictionary are empty
    )r   z
npm configr   z9NodeJS was not found. Yarn user configuration is ignored.r   z--json)r2   r0   r/   typer   r#  inspectzYarn configuration loaded.z(Fail to get yarn configuration. {!s}{!s}Nz Fail to get yarn configuration. )r   r9   r?   rA   r=  r%   rC   r$   r  iterr  r  r  rZ   StopIterationCalledProcessErrorr  r  r2   r?  r>  )r<   configurationr   output_binaryr?  linesliner   r_  rB  r  rK   rK   rL   r     sR   




r   c                 C   s   | pt dS )zEnsure that we have a loggerr   r   r>  rK   rK   rL   r;     s   r;   c                 C   s"   t | } t | rt | } | S )z,Normalize a given extension if it is a path.)ri   
expanduserr   rj   r1  rK   rK   rL   r1    s   


r1  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?   rK  r>  rK   rL   onerror  s   z_rmtree.<locals>.onerror)rM  N)r  r  )r   r<   rM  rK   r>  rL   r     s   r   c                 C   s8   zt |  W dS  ty   |jdt d Y dS w )zRemove a file, logging errorszError in os.unlinkrK  N)rq   unlinkr>  r?   rX   rL  )r   r<   rK   rK   rL   _unlink  s
   rO  c                 C   sT   t | D ]"}t| |}t|st|rt|| qt|r't|| qdS )z3Remove all files/trees within a dir, logging errorsN)	rq   listdirri   r`   isfileislinkrO  r  r   )r   r<   r  	file_pathrK   rK   rL   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 }|s8|s8|d ||krCd}|| | d }|  dd}|dsV|d7 }|du r]|}n|rh|dsh|d7 }|du ro|}n|rz|dsz|d7 }|r||vr|d|  |r||vr|d|  rt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  	themePathr.   	schemaDirz-No `extension` or `mimeExtension` key presentz?`mimeExtension` and `extension` must point to different modulesr  mainr  z.jsTzMissing extension module "%s"z!Missing mimeExtension module "%s"c                 3   "    | ]}| tt V  qd S r   r   r   r   r  )
theme_pathrK   rL   	<genexpr><       z&_validate_extension.<locals>.<genexpr>zthemePath is empty: "%s"c                 3   rW  r   rX  r  )
schema_dirrK   rL   rZ  ?  r[  zschemaDir is empty: "%s")rs   r6   dictr^   rk  any)r#  r  r   mime_extensionrd  rJ   filesrV  rK   )r\  rY  rL   r    sH   



r  c                 C   sf   t | d}d}td}|D ]}| sq||}||}|r.|| ||}|s"q| S )z6
    Compute the recursive sha sum of a tar file.
    r  i  sha1)	r  r  hashlibnewrQ  r  r  r  	hexdigest)
input_filer"  
chunk_sizehmemberr  r#  rK   rK   rL   r  E  s   




r  c                 C   sP   t | dd}t|r&t|}t|W  d   S 1 sw   Y  dS dS )z$Get the data for the app static dir.r   re  N)rl   ri   r   r  r  r  )r   r   r  rK   rK   rL   r  X  s   

$r  c           	      C   sd   |d }|d d }g }|  D ]\}}||v r/t|| |dd}|du r/|||| |f q|S )z+Validate the compatibility of an extension.r  r   r.  Tr/  F)rm  _test_overlapr^   )	r   r  r(  r8  r9  r  r_  r  overlaprK   rK   rL   r  b  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
    )r0  drop_prerelease2Nr   r2  )spec1spec2r0  rk  cmprK   rK   rL   ri  u  s   ri  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rH|rH|d}|d j}|d j}|	ds\|	dr]q|	|
krct
nt}||krkt
nt}|	|
krstnt}|	|
kr{tnt}dd	 }|	|
kr|	d
r|}||kr|	d
r|}t|	|dr||	|ds||
|dr||
|dst||	dr|||
ds|||	dr|||
dr dS t||
dr|du rd}n|dkrd}qt|	|dr|du rd}n|dkrd}qd}t||du rd}|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 )NTrK   )xyzrK   rK   rL   noop  s   z_compare_ranges.<locals>.noop>r  z(Unexpected case comparing version ranges)r&   rangerU   productr  semver
prereleaseincoperatorr   r*   r)   r(   r'   AssertionError)rm  rn  r0  rk  r1r2return_valuer1setr2setx1x2y1y2o1o2lxlygxgyrv  rJ   rK   rK   rL   r2    sz   
	


















r2  c                 C   sP   |pi }|  D ]\}}|du rq| |kr dS t|| dur% dS qdS )z%Test whether the package is disabled.FTN)rm  recompilematch)r   rX  patternr  rK   rK   rL   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 }
qX|
S )
z*Format a message for compatibility errors.
   Tr  z6
"%s@%s" is not compatible with the current JupyterLabz
Conflicting Dependencies:

JupyterLab	ExtensionzPackage
rT   )r   r&   r^   maxr  ljust)r   r   r  r   l0l1r  r{  r  ry  rJ   rK   rK   rL   r    s&   
"r  c           
      C   s   g }g }|  D ]\}\}}t|}|dkr|| q|| q|r1| ddg|d |D ]}|| \}}t|||}	| |	 d q3dS )z8Log compatibility errors for multiple extensions at oncer   z	
        z*
   The following extensions are outdated:zD
   Consider checking if an update is available for these packages.
rT   N)rm  _compat_error_ager^   r  r`   r  )
r<   
errors_mapoutdatedothersr   rd   r  ager   rJ   rK   rK   rL   r  	  s.   
r  c                 C   s@   t |}|dkr| d| dS t|||}| | d dS )z/Log compatability errors for a single extensionr   z The extension "%s" is outdated.
rT   N)r  r  r  )r<   r   r   r  r  rJ   rK   rK   rL   r  &	  s
   r  c                 C   sZ   d}d}| D ]\}}}t ||dd}|p|dk }|p|dk}q|r%|s%dS |r+|s+dS dS )zCompare all incompatibilities 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  rp  rl  )r  	any_older	any_newerrd   r  ry  r:  rK   rK   rL   r  1	  s   r  c                 C   s    | d }t |d t |d  S )zGet the core extensions.r   r   rj  )r7   )r(  r#  rK   rK   rL   r  K	  s   r  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.
    r.   N)r6   int)r{  entryrK   rK   rL   _semver_prerelease_keyQ	  s   

r  c                 C   st   t | d}|r|jrdndnd}g ||j|j|jR }|s,|jr*g |dR nd}|jr8|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  rK   r   )r+   r{  majorminorrq  r8   r  )r   r!  vr_  rK   rK   rL   r#  i	  s   
r#  c              
   C   s   t t| t|ddddid}z
|d|j  W n ty+   |d|   Y nw z%tt	|}t
| dW  d   W S 1 sJw   Y  W dS  tye } z|d	||  d}~ww )
z6Fetch the metadata for a package from the npm registryr  )safeAcceptzHapplication/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*)headerszFetching URL: %sr/   Nz+Failed to fetch package metadata for %r: %r)r   r
   r	   r?   full_urlAttributeErrorget_full_url
contextlibclosingr   r  r  r  r  r   r  )r   r   r<   reqresponseexcrK   rK   rL   r+  	  s&   (r+  __main__r   r   )NNF)NFNN)NNNNFNTT)Nr   )FN)FFr  )r   r  r  rb  rU   r  r   rq   os.pathr   ri   r  r  r   r  rA   rX   r  r  r   r   pathlibr   tempfiler   	threadingr   urllib.errorr   urllib.requestr   r	   r
   r   jupyter_core.pathsr   (jupyter_server.extension.serverextensionr   r   r   r   jupyterlab_server.configr   r   r   r   r   jupyterlab_server.processr   r   r   r   packaging.versionr   	traitletsr   r   r   r   r   r    jupyterlab._versionr!   jupyterlab.coreconfigr#   jupyterlab.jlpmappr$   r%   jupyterlab.semverr&   r'   r(   r)   r*   r+   r  r   rj   r`   r   r   r  r   r-   rl   ru   rz   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  r$  r   r   r   r;   r1  r   rO  r   r  r  r  r  ri  r2  r  r  r  r  r  r  r  r#  r+  rf   rK   rK   rK   rL   <module>   s      
A
 




@





#



	
	



	
	
          U
+	
5



]

