o
    ;i:                     @   sn   d Z ddlZddlZddlZddlmZmZ edZG dd dej	Z
G dd dZd	ed
ee fddZdS )a  Pattern matching library ported from https://github.com/moby/patternmatcher.

This is the same pattern-matching logic used by Docker, except it is written in
Python rather than Go. Also, the original Go library has a couple deprecated
functions that we don't implement in this port.

The main way to use this library is by constructing a `FilePatternMatcher` object,
then asking it whether file paths match any of its patterns.
    N)OptionalTextIOz.+()|{}$c                   @   s    e Zd ZdZdZdZdZdZdS )	MatchTyper               N)__name__
__module____qualname__UNKNOWNEXACTPREFIXSUFFIXREGEXP r   r   N/home/ubuntu/.local/lib/python3.10/site-packages/modal/_utils/pattern_utils.pyr      s    r   c                   @   sL   e Zd ZdZdddZdefddZdeddfd	d
ZdedefddZ	dS )Patternz9Defines a single regex pattern used to filter file paths.returnNc                 C   s$   t j| _d| _g | _d| _d| _dS )z"Initialize a new Pattern instance. NF)r   r   
match_typecleaned_patterndirsregexp	exclusionselfr   r   r   __init__   s
   
zPattern.__init__c                 C   s   | j S )z8Return the cleaned pattern as the string representation.)r   r   r   r   r   __str__'   s   zPattern.__str__	separatorc           	   
   C   s6  d}| j }|}|dkrd}tj| _d}t|}||k r|| }|dkr|d |k rv||d  dkrv|d7 }|d |k rG||d  |krG|d7 }|d |kra| jtjkrXtj| _n|d7 }tj| _n|d| d	7 }tj| _|dkrutj| _nm|d
| d7 }tj| _n`|dkr|d
| d7 }tj| _nO|tv r|d| 7 }nD|dkr|dkr||7 }|d7 }q|d |k r|d||d   7 }|d7 }tj| _n|d7 }n|dks|dkr||7 }tj| _n||7 }|d7 }||k s| jtjkrdS |d7 }zt	
|| _tj| _W dS  t	jy } ztd| |d}~ww )zCompile the pattern into a regular expression.

        Args:
            separator (str): The path separator (e.g., '/' or '\').

        Raises:
            ValueError: If the pattern is invalid.
        ^\z\\r   *r   z.*z(.*z)?z[^z]*?][N$zBad pattern: )r   r   r   r   lenr   r   r   escape_charsrecompiler   error
ValueError)	r   r   reg_strpatternesc_separatoripattern_lengthcher   r   r   r*   +   st   	






4zPattern.compilepathc                 C   s   | j tjkr| tjj | j tjkr|| jkS | j tj	kr(|
| jdd S | j tjkrP| jdd }||r<dS |d tjjkrN||dd krNdS dS | j tjkr^| j|duS dS )z&Check if the path matches the pattern.Nr   Tr   r   F)r   r   r   r*   osr4   sepr   r   r   
startswithr   endswithr   r   match)r   r4   suffixr   r   r   r:   }   s    

 zPattern.match)r   N)
r	   r
   r   __doc__r   strr   r*   boolr:   r   r   r   r   r      s    
Rr   readerr   c                 C   s   | du rg S g }| D ]V}| d}|drq
| }|dkr q
|d dk}|r0|dd  }t|dkrUtj|}|tjd}t|dkrU|d dkrU|dd }|r[d| }|	| q
|S )	a  Read an ignore file from a reader and return the list of file patterns to
    ignore, applying the following rules:

    - An UTF8 BOM header (if present) is stripped. (Python does this already)
    - Lines starting with "#" are considered comments and are skipped.

    For remaining lines:

    - Leading and trailing whitespace is removed from each ignore pattern.
    - It uses `os.path.normpath` to get the shortest/cleanest path for ignore
      patterns.
    - Leading forward-slashes ("/") are removed from ignore patterns, so
      "/some/path" and "some/path" are considered equivalent.

    Args:
        reader (file-like object): The input stream to read from.

    Returns:
        list: A list of patterns to ignore.
    Nz
#r   r   !r   /)
rstripr8   stripr'   r6   r4   normpathreplacer7   append)r?   excludesliner.   invertr   r   r   read_ignorefile   s,   

rK   )r<   enumr6   r)   typingr   r   	frozensetr(   IntEnumr   r   listr=   rK   r   r   r   r   <module>   s   
{