o
    fiUa                    @   s  g 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	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mZmZmZmZmZmZmZmZmZmZ ddl m!Z! d	" Z#e#Z$d
" Z%d" Z&dZ'dZ(dZ)dZ*dZ+edZ,G dd deZ-G dd deZ.G dd deZ/G dd deZ0d>de1dee1e/f deee1  de1fddZ2	 	!	dd"e1d#ee d$ee3 d%e4d&ee5 dee3e1f fd'd(Z6ed)d*e1fd+e1fd,eee1ee3 f  fd-ee1 fd.ee1 fd/ee3 fgZ7dee1e/f d0ee1 d1e4d2e4d3e4d4ee1 dee7 fd5d6Z8d7ee, d8e,de,fd9d:Z9d7e1d;e1de1fd<d=Z:dd?e,d@ee, dAee de4fdBdCZ;dee3 fdDdEZ<dFee3 de1fdGdHZ=dIee. dJee de.fdKdLZ>dJee dee. fdMdNZ?d>dOe1dPee dQee1 dee fdRdSZ@G dTdU dUZAeG dVdW dWZBe-jCfdXe1dYe-ddfdZd[ZDddeBd\deBfdOe1d]eeg eeB f  d^eeg eeB f  d_eBd`eeeB  daee1geBf deBfdbdcZE						dd+e1ddee1 deee3 dfee3 dgee3 d/ee3 dheeee1e3f   de1fdidjZF		dd+e1dkeeee1e3f   dheeee1e3f   de1fdldmZGd>d+e1dheeee1e3f   de1fdndoZHdd+e1dre3dse3de1fdtduZIdve1dejfdwdxZJdve1dejfdydzZKe(fdve1d{e1dejfd|d}ZLeEd~M ZNdS ))	bump_versioncheck_versionget_versionserialize_pep440serialize_pvpserialize_semverStyleVcsVersion    N)OrderedDict)Enum)total_ordering)Path)AnyCallableListMapping
NamedTupleOptionalSequenceSetTupleTypeVarUnion)ElementTreeaG  
    (?x)                                                        (?# ignore whitespace)
    ^v((?P<epoch>\d+)!)?(?P<base>\d+(\.\d+)*)                   (?# v1.2.3 or v1!2000.1.2)
    ([-._]?((?P<stage>[a-zA-Z]+)[-._]?(?P<revision>\d+)?))?     (?# b0)
    (\+(?P<tagged_metadata>.+))?$                               (?# +linux)
z
    (?x)
    ^(\d+!)?
    \d+(\.\d+)*
    ((a|b|rc)\d+)?
    (\.post\d+)?
    (\.dev\d+)?
    (\+([a-zA-Z0-9]|[a-zA-Z0-9]{2}|[a-zA-Z0-9][a-zA-Z0-9.]+[a-zA-Z0-9]))?$
zt
    (?x)
    ^\d+\.\d+\.\d+
    (\-[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]+)*)?
    (\+[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]+)*)?$
z^\d+(\.\d+)*(-[a-zA-Z0-9]+)*$z%Y-%m-%dT%H:%M:%S.%f%zz%Y-%m-%d %H:%M:%S.%f%zz%Y-%m-%dT%H:%M:%S%zz%Y-%m-%d %H:%M:%S %z_Tc                   @   s    e Zd ZdZdZ	 dZ	 dZdS )r   z4
    Standard styles for serializing a version.
    pep440semverpvpN)__name__
__module____qualname____doc__Pep440SemVerPvp r&   r&   D/home/ubuntu/.local/lib/python3.10/site-packages/dunamai/__init__.pyr   M   s    r   c                   @   s>   e Zd ZdZdZ	 dZ	 dZ	 dZ	 dZ	 dZ		 dZ
	 d	Zd
S )r   z"
    Version control systems.
    anygit	mercurialdarcs
subversionbazaarfossilpijulN)r   r    r!   r"   r   Git	MercurialDarcs
SubversionBazaarFossilPijulr&   r&   r&   r'   r   Z   s$    r   c                   @   s\   e Zd ZdZdZ	 dZ	 ddee defddZe	dd	e
ed f dee defd
dZdS )Patternz=
    Regular expressions used to parse tags as versions.
    defaultzdefault-unprefixedNprefixreturnc                 C   s>   t jtt jtdddi}||  }|r|dd|d}|S )z
        Get the regular expression for this preset pattern.

        :param prefix: Insert this after the pattern's start anchor (`^`).
        :returns: Regular expression.
        z^vz^v?   ^^{})r7   DefaultVERSION_SOURCE_PATTERNDefaultUnprefixedreplaceformat)selfr9   variantsoutr&   r&   r'   regex{   s   zPattern.regexpatternc                 C   sl   t | trd| v r|r| dd|dS | S zt| } W n ty0   ttdtjj| w | 	|S )a  
        Parse a pattern string into a regular expression.

        If the pattern contains the capture group `?P<base>`, then it is
        returned as-is. Otherwise, it is interpreted as a variant of the
        `Pattern` enum.

        :param pattern: Pattern to parse.
        :param prefix: Insert this after the pattern's start anchor (`^`).
        :returns: Regular expression.
        z?P<base>r<   r=   r;   z]The pattern does not contain the capture group '?P<base>' and is not a known preset like '{}')

isinstancestrrA   rB   r7   
ValueError_pattern_errorr>   valuerF   )rG   r9   r&   r&   r'   parse   s    


zPattern.parseN)r   r    r!   r"   r>   r@   r   rI   rF   staticmethodr   rM   r&   r&   r&   r'   r7   q   s    *r7   c                   @   s$   e Zd ZdZdZ	 defddZdS )ConcernzC
    A concern/warning discovered while producing the version.
    zshallow-repositoryr:   c                 C   s   | t jkrdS dS )zn
        Produce a human-readable description of the concern.

        :returns: Concern description.
        zMThis is a shallow repository, so Dunamai may not produce the correct version. )rP   ShallowRepositoryrC   r&   r&   r'   message   s   
zConcern.messageN)r   r    r!   r"   rR   rI   rT   r&   r&   r&   r'   rP      s
    rP   primaryrG   tagsr:   c                 C   s0   | d |g}|d ur|d | d|S )NzPattern:
{}zTags:
{}z

)rB   appendjoin)rU   rG   rV   partsr&   r&   r'   rK      s   
rK   r
   Fcommandwherecodesshellenvc                 C   sj   t jt| t jt j|d urt|nd ||d}|j 	 }|r0|j
|vr0td| |j
||j
|fS )N)stdoutstderrcwdr^   r_   z-The command '{}' returned code {}. Output:
{})
subprocessrunshlexsplitPIPESTDOUTrI   r`   decodestrip
returncodeRuntimeErrorrB   )r[   r\   r]   r^   r_   resultoutputr&   r&   r'   _run_cmd   s   
ro   _MatchedVersionPatternmatched_tagbasestage_revision
newer_tagstagged_metadataepochsourceslatest_sourcehighest_sourcestrictpattern_prefixc                 C   sL  d}d}d}g }	d}
d}t | |} |r|dd }n4|rMd}d}|D ]}t|| }z|du s4||kr8|}|}W q# tyB   Y q#w |durJ|gng }n|}|D ]N}zt| |}W n tjyx } zttd|j	| |j
|jd}~ww |du r|	| qQz|d}|durW  nW qQ ty   ttd| w |du s|du r|rttd|d | ||rttd| |dS | d	}| d
}| d}
| d}|durz||du rdnt|f}W n ty   td|w |durzt|}W n ty   td|w t||||	|
|S )z
    :returns: Tuple of:
        * matched tag
        * base segment
        * tuple of:
          * stage
          * revision
        * any newer unmatched tags
        * tagged_metadata matched section
    Nr;   z0The pattern is an invalid regular expression: {}rr   z9The pattern did not include required capture group 'base'z-The pattern did not match the latest tag '{}'r
   z"The pattern did not match any tagsstagerevisionru   rv   z#Revision '{}' is not a valid numberz Epoch '{}' is not a valid number)r7   rM   r	   	ExceptionresearcherrorrK   rB   msgrG   posrW   group
IndexErrorrJ   	groupdictgetintrp   )rG   rw   rx   ry   rz   r{   pattern_matchrr   rs   newer_unmatched_tagsru   rv   relevant_sourcesselected_sourceselected_parsedsourceparseder|   r}   r&   r&   r'   _match_version_pattern   s   
	



r   rL   r8   c                 C   s   | d ur| S |S rN   r&   )rL   r8   r&   r&   r'   _blankP  s   r   replacementc                 C   s   t d|| S )Nz[^a-zA-Z0-9])r   sub)rL   r   r&   r&   r'   _escape_branchT     r   rN   xyunsetc                 C   s   ||v rdS | |kS )NTr&   )r   r   r   r&   r&   r'   _equal_if_setX  s   r   c                  C   sJ   t dd d\} }td| }|d ur#|dd}dd |D S g S )Nzgit version)r\   zgit version (\d+(\.\d+)*)r;   .c                 S      g | ]}t |qS r&   r   .0r   r&   r&   r'   
<listcomp>c      z$_get_git_version.<locals>.<listcomp>)ro   r   r   rj   r   rf   )_r   rm   rY   r&   r&   r'   _get_git_version^  s   r   git_versionc                 C   s   | ddgk rdS dS )N   
   zgit logz"git -c log.showsignature=false logr&   )r   r&   r&   r'   _git_logg  s   r   expected_vcspathc              	   C   s  t tjdftjdftjdftjdftjdftjdftjdfg}d}d	}| rb||  }|	 d
 }t
|s<td|t||g d\}}|d
kr`| tjkrV||v rVt|td| j | S g }	g }
| D ]8\}}t
|	 d
 rt||g d\}}|d
kr|  S |tjkr||v rt||	|j qj|
|j qjdg}|	r|dd|	 |
r|dd|
 td|)Nz
git statusz	hg statusz	darcs logzsvn log
bzr statuszfossil statusz	pijul logzdetected dubious ownershipz@Detected Git repository, but failed because of dubious ownershipr
   zUnable to find '{}' programr]   z'This does not appear to be a {} projectz(Unable to detect version control system.zChecked: {}., zNot installed: {}. )r   r   r0   r1   r2   r3   r4   r5   r6   rf   shutilwhichrl   rB   ro   rL   titleitemsrW   namerX   )r   r   checksdubious_ownership_flagdubious_ownership_errorr[   programcoder   	disprovenunavailablevcserror_partsr&   r&   r'   _detect_vcsn  sP   
r   c                 C   sJ   t d| d}|d ur|d}d|vrtjS t d| d}|d ur#tjS d S )N.git_archival.json.gitutf8$Format:.hg_archival.txt.hg)_find_higher_file	read_textr   r0   r1   )r   archivalcontentr&   r&   r'   _detect_vcs_from_archival  s   
r   r   startlimitc                 C   sX   |du rt  }|g|jD ]}||   r||    S |dur)||  r) dS qdS )z
    :param name: Bare name of a file we'd like to find.
    :param limit: Give up if we find a file/folder with this name.
    :param start: Begin recursing from this folder (default: `.`).
    N)r   rb   parentsis_fileexists)r   r   r   levelr&   r&   r'   r     s   r   c                   @   s   e Zd ZdZdededededef
ddZd	eeef d
d fddZe	ded
e
ej fddZdd Zd
e
ej fddZd
efddZd
eee
ej f fddZd
efddZe	ded
efddZe	dedee de
e d
eeef fdd Zd!S )"_GitRefInfoz 
    This assumes Git 2.7+.
    refcommitcreatordatecommitterdate
taggerdatec                 C   s:   || _ || _| || _| || _| || _i | _d S rN   )fullrefr   normalize_git_dtr   r   r   tag_topo_lookup)rC   r   r   r   r   r   r&   r&   r'   __init__  s   
z_GitRefInfo.__init__lookupr:   c                 C   s
   || _ | S rN   )r   )rC   r   r&   r&   r'   with_tag_topo_lookup  s   z _GitRefInfo.with_tag_topo_lookup	timestampc                 C   s   | dkrd S t | S )NrQ   )_parse_git_timestamp_iso_strict)r   r&   r&   r'   r     s   z_GitRefInfo.normalize_git_dtc                 C   s   d | j| j| j| j| jS )NzY_GitRefInfo(ref={!r}, commit={!r}, creatordate={!r}, committerdate={!r}, taggerdate={!r}))rB   r   commit_offsetr   r   r   rS   r&   r&   r'   __repr__  s   z_GitRefInfo.__repr__c                 C   s&   | j d ur| j S | jd ur| jS | jS rN   )r   r   r   rS   r&   r&   r'   	best_date  s
   

z_GitRefInfo.best_datec                 C   s(   z| j | j W S  ty   tj Y S w rN   )r   r   KeyErrorsysmaxsizerS   r&   r&   r'   r     s
   
z_GitRefInfo.commit_offsetc                 C   s   |    |  fS rN   )r   r   rS   r&   r&   r'   sort_key  s   z_GitRefInfo.sort_keyc                 C   s   | j ddS )N
refs/tags/rQ   )r   rA   rS   r&   r&   r'   r     r   z_GitRefInfo.refc                 C   s   |  dr| S d| S )Nr   zrefs/tags/{})
startswithrB   r   r&   r&   r'   normalize_tag_ref  s   

z_GitRefInfo.normalize_tag_ref
tag_branchr   r   c                 C   s   d t|| }|ddgkr|d7 }t||\}}dd | jddD }i }t|D ]9\}}	|	d	\}
}}|
 }
|re|d d
 }dd |dD }dd |D }dd |D }|D ]}|||< q^q,|S )NzK{} --simplify-by-decoration --topo-order --decorate=full {} "--format=%H%d"r      z --decorate-refs=refs/tags/c                 S   s    g | ]}d |vsd|v r|qS )z (tag: r&   r   r&   r&   r'   r           z7_GitRefInfo.from_git_tag_topo_order.<locals>.<listcomp>F)keepends(c                 S   s"   g | ]}|  d r|  qS )r   )rj   r   r   tagr&   r&   r'   r     s   " r   c                 S   s   g | ]}|  d  qS )r   rf   r   r&   r&   r'   r         c                 S   s   g | ]}t |qS r&   )r   r   r   r&   r&   r'   r         )rB   r   ro   rj   
splitlines	enumerate	partitionrf   )r   r   r   cmdr   logmsgfiltered_lines
tag_lookup
tag_offsetliner   r   rV   taglistr   r&   r&   r'   from_git_tag_topo_order  s(   
z#_GitRefInfo.from_git_tag_topo_orderN)r   r    r!   r"   rI   r   r   r   r   rO   r   dtdatetimer   r   r   r   r   r   r   r   r   r   r   r&   r&   r&   r'   r     s    0r   c                   @   s  e Zd ZdZdddddddddejd
dedeeeee	 f  de	dee d	ee
 d
ee dee	 dee deej deee  deddfddZdefddZdefddZdede
fddZdd de
fddZdede
fddZ								dSdee
 d	e
d eeeed gef f  d!ee d"e
d
e
d#ee d$ee defd%d&Zeejfd'ed(eeef dd fd)d*ZdTd-e	d.e	d/e
dd fd0d1Zedddddddddejd
d2e
deeeee	 f  de	dee d	ee
 d
ee dee	 dee deej deee  defd3d4Zeejdddddddddf
d(eeef d5e
d6ee d7e
d2e
d8ee d9ee d:e
d;ee	 d<e
dd fd=d>Z eejdddddddfd(eeef d5e
d7e
d2e
d8ee d9ee d;ee	 d<e
dd fd?d@Z!eejddddddfd(eeef d5e
d2e
d8ee d9ee d;ee	 d<e
dd fdAdBZ"eejddCdddddfd(eeef d5e
dDed2e
d8ee d9ee d;ee	 d<e
dd fdEdFZ#eejddddddfd(eeef d5e
d2e
d8ee d9ee d;ee	 d<e
dd fdGdHZ$eejddddddfd(eeef d5e
d2e
d8ee d9ee d;ee	 d<e
dd fdIdJZ%eejddddddfd(eeef d5e
d2e
d8ee d9ee d;ee	 d<e
dd fdKdLZ&eejddCddddddddfd(eeef d5e
dDed6ee d7e
d2e
d8ee d9ee d:e
d;ee	 d<e
dd fdMdNZ'eejddCddddddddfded(eeef d5e
dDed6ee d7e
d2e
d8ee d9ee d:e
d;ee	 d<e
dd fdOdPZ(e				dUded(eeef d5e
dDed6ee d7e
d2e
d8ee d9ee d:e
d;ee	 d<e
dd fdQdRZ)dS )Vr	   a8  
    A dynamic version.

    :ivar base: Release segment.
    :vartype base: str
    :ivar stage: Alphabetical part of prerelease segment.
    :vartype stage: Optional[str]
    :ivar revision: Numerical part of prerelease segment.
    :vartype revision: Optional[int]
    :ivar distance: Number of commits since the last tag.
    :vartype distance: int
    :ivar commit: Commit ID.
    :vartype commit: Optional[str]
    :ivar dirty: Whether there are uncommitted changes.
    :vartype dirty: Optional[bool]
    :ivar tagged_metadata: Any metadata segment from the tag itself.
    :vartype tagged_metadata: Optional[str]
    :ivar epoch: Optional PEP 440 epoch.
    :vartype epoch: Optional[int]
    :ivar branch: Name of the current branch.
    :vartype branch: Optional[str]
    :ivar timestamp: Timestamp of the current commit.
    :vartype timestamp: Optional[dt.datetime]
    :ivar concerns: Any concerns regarding the version.
    :vartype concerns: Optional[Set[Concern]]
    :ivar vcs: Version control system from which the version was detected.
    :vartype vcs: Vcs
    Nr
   
r|   distancer   dirtyru   rv   branchr   concernsr   rr   r|   r  r   r  ru   rv   r  r   r  r   r:   c       
         C   s   || _ d| _d| _|dur|\| _| _|| _|| _|| _|| _|| _|| _z|	r/|		t
jjnd| _W n ty?   |	| _Y nw |
pDt | _|| _d| _d| _d| _dS )aM  
        :param base: Release segment, such as 0.1.0.
        :param stage: Pair of release stage (e.g., "a", "alpha", "b", "rc")
            and an optional revision number.
        :param distance: Number of commits since the last tag.
        :param commit: Commit hash/identifier.
        :param dirty: True if the working directory does not match the commit.
        :param epoch: Optional PEP 440 epoch.
        :param branch: Name of the current branch.
        :param timestamp: Timestamp of the current commit.
        :param concerns: Any concerns regarding the version.
        NF)rr   r|   r}   r  r   r  ru   rv   r  
astimezoner   timezoneutcr   rJ   setr  r   _matched_tag_newer_unmatched_tags_smart_bumped)rC   rr   r|   r  r   r  ru   rv   r  r   r  r   r&   r&   r'   r   2  s*   

zVersion.__init__c                 C      |   S rN   )	serializerS   r&   r&   r'   __str__f  s   zVersion.__str__c                 C   s0   d | j| j| j| j| j| j| j| j| j	| j

S )NzVersion(base={!r}, stage={!r}, revision={!r}, distance={!r}, commit={!r}, dirty={!r}, tagged_metadata={!r}, epoch={!r}, branch={!r}, timestamp={!r}))rB   rr   r|   r}   r  r   r  ru   rv   r  r   rS   r&   r&   r'   r   i  s   zVersion.__repr__otherc                 C   s   t |tstd|jj| j|jkoI| j|jkoI| j|jkoI| j	|j	koI| j
|j
koI| j|jkoI| j|jkoI| j|jkoI| j|jkoI| j|jkS )N#Cannot compare Version with type {})rH   r	   	TypeErrorrB   	__class__r!   rr   r|   r}   r  r   r  ru   rv   r  r   rC   r  r&   r&   r'   __eq__z  s*   









	zVersion.__eq__c                 C   s   t | j|joIt | j|joIt | j|joIt | j|jddgdoIt | j|joIt | j|joIt | j|joIt | j|joIt | j	|j	oIt | j
|j
S )a  
        Compare this version to another version, but ignore None values in the other version.
        Distance is also ignored when `other.distance == 0`.

        :param other: The version to compare to.
        :returns: True if this version equals the other version.
        Nr
   )r   )r   rr   r|   r}   r  r   r  ru   rv   r  r   r  r&   r&   r'   _matches_partial  s&   		zVersion._matches_partialc           
      C   s  t |tstd|jjdd lm} d}z"|| jdd}||jdd}||k r0W dS ||kr7W dS W n t	yC   d}Y nw t
| jdt
|jdft
| jdt
|jdft| jt|jft
| jdt
|jdft
| jdt
|jdft
| jtddddddt
|jtddddddfg}|r|}n0t
| jdt
|jdf|| j||jft
| jdt
|jdft
| jdt
|jdfg|}|D ]\}}	||	k r dS ||	kr dS qdS )Nr  r
   TFmetadatarQ   r;   )rH   r	   r  rB   r  r!   packaging.versionversionr  r~   r   r  r   boolr  ru   r  r   r   r   rv   rr   r|   r}   )
rC   r  pvparsableusthemcommon_pairspairsabr&   r&   r'   __lt__  sP   
zVersion.__lt__Fr  rB   stylebumpcommit_prefixescape_withc	                 C   s  | j }	| j}
|r| jdd}|j }	|j}
| j}|dur%|dur%d||}|durt|r=t| }|	|_ |
|_||}nzi|	d}|j|	t	| j
dt	|
dt	| jdt	|dt	| jd| jrbdndt	| jdt	| jdtt	| jd|pvd| jr| jd	ndt|d
kr|d
 ndt|dkr|d ndt|dkr|d ndd}W n% ty } ztd|d}~w ty } ztd|d}~ww |durt|| |S |du rtj}d}g }|dur|r| jr|| j |s| jd
kr|dur|| |r| jr|d g }| j
dur*|| j
 |
dur*|t|
 | jd
krF||s9| jr;dnd |t| j |tjkr| j
}d}d}|dkr]d}|
}n	|dkrfd}|
}| jd
kr|ss| jr|du r|| j}n$|| j7 }n|du r|du r| j}d
}n|du r| j}n|| j7 }t|	||
|||| jd}n|tjkrt|	||d}n|tjkrt |	g ||d}t|| |S )a	  
        Create a string from the version info.

        :param metadata: Metadata (commit ID, dirty flag) is normally included
            in the metadata/local version part only if the distance is nonzero.
            Set this to True to always include metadata even with no distance,
            or set it to False to always exclude it.
            This is ignored when `format` is used.
        :param dirty: Set this to True to include a dirty flag in the
            metadata if applicable. Inert when metadata=False.
            This is ignored when `format` is used.
        :param format: Custom output format. It is either a formatted string or a
            callback. In the string you can use substitutions, such as "v{base}"
            to get "v0.1.0". Available substitutions:

            * {base}
            * {stage}
            * {revision}
            * {distance}
            * {commit}
            * {dirty} which expands to either "dirty" or "clean"
            * {tagged_metadata}
            * {epoch}
            * {branch}
            * {branch_escaped} which omits any non-letter/number characters (or replaces via `escape_with`)
            * {timestamp} which expands to YYYYmmddHHMMSS as UTC
            * {major} (first part of `base` split on `.`, or 0)
            * {minor} (second part of `base` split on `.`, or 0)
            * {patch} (third part of `base` split on `.`, or 0)
        :param style: Built-in output formats. Will default to PEP 440 if not
            set and no custom format given. If you specify both a style and a
            custom format, then the format will be validated against the
            style's rules.
        :param bump: If true, increment the last part of the `base` by 1,
            unless `stage` is set, in which case either increment `revision`
            by 1 or set it to a default of 2 if there was no revision.
            Does nothing when on a commit with a version tag.
        :param tagged_metadata: If true, insert the `tagged_metadata` in the
            version as the first part of the metadata segment.
            This is ignored when `format` is used.
        :param commit_prefix: Add this prefix to the commit ID.
            This can be helpful when an all-numeric commit would be misinterpreted.
            For example, "g" is a common prefix for Git commits.
        :param escape_with: When escaping, replace with this substitution.
            The default is simply to remove invalid characters.
        :returns: Serialized version.
        T)smartNz{}{}r   rQ   r  cleanz%Y%m%d%H%M%Sr
   0r;   r   )rr   r|   r}   r  r   ru   r  rv   r  branch_escapedr   majorminorpatchz'Format contains invalid placeholder: {}zFormat is invalid: {}Fprepostdev)r|   r}   r0  r1  r  rv   )r/  r  r  )!rr   r}   r%  r   rB   callablecopydeepcopyrf   r   r|   r  ru   r  rv   r  r   r   strftimelenr   rJ   r   r   r#   rW   rI   r  r   r$   r   r%   r   )rC   r  r  rB   r$  r%  ru   r&  r'  rr   r}   bumpedr   new_versionrE   
base_partsr   
meta_parts	pre_partsr|   r0  r1  r&   r&   r'   r    s   :



















	
zVersion.serializer  rG   c              	   C   s  |}| ds|ttjfv rd|}d}zt||gddddd}W n ty-   d}Y nw |s4|du rRtjdd|d	d
}||krNt	
||}|j|krN|S | |S |j}|j}	d}
d}d}|j}|j}|rg }|d}t|D ]P\}}|du r|dkrd}|| qq|dkrd}|| qq|
du rtd|}|rt|d	}
|| qq|du rtd|}|r|d	}|| qqqqtt|D ]}|| qd|}|
du rd}
|dur| dkrd}|	dur|	d dkr|	d	 dur|
|	d	 7 }
d}	| ||	|
||||dS )a  
        Attempt to parse a string into a Version instance.

        This uses inexact heuristics, so its output may vary slightly between
        releases. Consider this a "best effort" conversion.

        :param version: Full version, such as 0.3.0a3+d7.gb6a9020.dirty.
        :param pattern: Regular expression matched against the version.
            Refer to `from_any_vcs` for more info.
        :returns: Parsed version.
        vzv{}FTN)rz   r{   z(\.post(\d+)\.dev\d+)z.dev\2r;   )countr   r  r)  zd?(\d+)zg?([\da-z]+)r
   rQ   r1  )r|   r  r   r  ru   rv   )r   r?   r7   r>   rB   r   rJ   r   r   r	   rM   rr   rs   ru   rv   rf   r   rW   matchr   r   reversedsortedpoprX   rj   )clsr  rG   
normalizedfailedmatched_patternreplacedaltrr   r|   r  r   r  ru   rv   rA  rY   irL   r>  r&   r&   r'   rM   v  s   









 zVersion.parser   r;   index	incrementr(  c                 C   sf   t | }|r|jdkr|S d|_|jdu r t|j|||_|S |jdu r*d|_|S | j|7  _|S )a1  
        Increment the version.

        The base is bumped unless there is a stage defined, in which case,
        the revision is bumped instead.

        :param index: Numerical position to increment in the base.
            This follows Python indexing rules, so positive numbers start from
            the left side and count up from 0, while negative numbers start from
            the right side and count down from -1.
            Only has an effect when the base is bumped.
        :param increment: By how much to increment the relevant position.
        :param smart: If true, only bump when distance is not 0.
            This will also make `Version.serialize()` use pre-release formatting automatically,
            like calling `Version.serialize(bump=True)`.
        :returns: Bumped version.
        r
   TNr   )r3  r4  r  r  r|   r   rr   r}   )rC   rI  rJ  r(  r7  r&   r&   r'   r%    s   



zVersion.bumprz   c       
         C   s*   |rt d| d||||||||	|
|dS )Nz7No tags available and fallbacks disabled by strict mode0.0.0r   )rl   )rB  rz   r|   r  r   r  ru   rv   r  r   r  r   r&   r&   r'   	_fallback  s   zVersion._fallback
latest_tagr   full_commitr   r{   ignore_untrackedcommit_lengthhighest_tagc           *      C   s  t j}|p|	du}dd tj D }td|d}|dur|d}d|vrt|}|r3|	d}n|	d	}|durB|d|	 }d}|	d
}|rOt
|}d}|	d}|rl|d}t|dkrl|d dd }d}d}d}|	d}|r|drd}|dd }nd}|dd}|d }t|dkrt|d }|du r| j|||||||dS t||g||
||}|du r| j|||||||dS |\}}}}}}| ||||||||||d
} || _|| _| S t|| t }!|du rd}t }"|"ddgk rtd|}#|#r|!tj ntd||d\}$}%|% dkr$|!tj |r6|!r6tdd d! |!D td"|dd#g|d$\}$}%|$d#krJd}n|%}td%t|"|rWd&nd'|dd#g|d$\}$}%|$d#krs| j|dd||!|d(S |%d|	 }d}|"ddgk rtd)t|"||d\}$}%t |%}ntd*t|"||d\}$}%t
|%}td+||d\}$}%|%d}|s|std,||d\}$}%|% d-krd}|"dd.gk rtd/||d\}$}%|%s	ztd0||d\}$}%t|%}W n t!y   d}Y nw | j|||||||!|d1S d2d3 |%" D }&t||&||
||}n|td4|d5 ||d\}$}%|%sVztd0||d\}$}%t|%}W n t!yH   d}Y nw | j|||||||!|d1S g }'t#$||"|}(|% " D ]})|)d6}t|d7kruqe|'%t#| &|( qed8d3 t'|'d9d: dd;D }&t||&||
||}|du rztd0||d\}$}%t|%}W n t!y   d}Y nw | j|||||||!|d1S |\}}}}}}td<|||d\}$}%t|%}| ||||||||||!|d=} || _|| _| S )>a  
        Determine a version based on Git tags.

        :param pattern: Regular expression matched against the version source.
            Refer to `from_any_vcs` for more info.
        :param latest_tag: If true, only inspect the latest tag on the latest
            tagged commit for a pattern match. If false, keep looking at tags
            until there is a match.
        :param tag_branch: Branch on which to find tags, if different than the
            current branch.
        :param full_commit: Get the full commit hash instead of the short form.
        :param strict: Elevate warnings to errors.
            When there are no tags, fail instead of falling back to 0.0.0.
        :param path: Directory to inspect, if not the current working directory.
        :param pattern_prefix: Insert this after the pattern's start anchor (`^`).
        :param ignore_untracked:
            Ignore untracked files when determining whether the repository is dirty.
        :param commit_length:
            Use this many characters from the start of the full commit hash.
        :param highest_tag:
            Only inspect the numerically highest tag across all tagged commits for a pattern match.
        :returns: Detected version.
        Nc                 S   s    i | ]\}}| d s||qS )	GIT_TRACE)r   r   kr<  r&   r&   r'   
<dictcomp>>  r   z$Version.from_git.<locals>.<dictcomp>r   r   r   r   z	hash-fullz
hash-shortr   refsz -> r   r;   r   r
   describez-dirtyTiF-r  r   r  r  r   r   	r|   r  r   r  ru   rv   r  r   r   HEAD   z.git/shallowz%git rev-parse --is-shallow-repository)r_   true
c                 s   s    | ]}|  V  qd S rN   rT   r   r&   r&   r'   	<genexpr>      z#Version.from_git.<locals>.<genexpr>zgit symbolic-ref --short HEAD   )r]   r_   z{} -n 1 --format="format:{}"z%Hz%h)r  r  r  r  r   z{} -n 1 --pretty=format:"%ci"z{} -n 1 --pretty=format:"%cI"zgit describe --always --dirtyzgit status --porcelainrQ      zIgit for-each-ref "refs/tags/**" --format "%(refname)" --sort -creatordatezgit rev-list --count HEAD)r  r   r  r  r   r  r   c                 S   s   g | ]}| d dqS )r   rQ   )rA   r   r   r&   r&   r'   r     r   z$Version.from_git.<locals>.<listcomp>z+git for-each-ref "refs/tags/**" --merged {}zx --format "%(refname)@{%(objectname)@{%(creatordate:iso-strict)@{%(*committerdate:iso-strict)@{%(taggerdate:iso-strict)"z@{   c                 S   s   g | ]}|  qS r&   r   r   tr&   r&   r'   r     r   c                 S   r  rN   )r   r   r&   r&   r'   <lambda>      z"Version.from_git.<locals>.<lambda>keyreversez'git rev-list --count refs/tags/{}..HEADr   )(r   r0   osenvironr   r   r   jsonloadsr   r   rf   r6  endswithrsplitr   rL  r   r	  r
  r   r  r   addrP   rR   ro   rj   rl   rX   rB   r   _parse_git_timestamp_isor~   r   r   r   rW   r   r@  )*rB  rG   rM  r   rN  rz   r   r{   rO  rP  rQ  r   r_   r   r   datar   r   raw_timestampr  rV  rY   r   r  r  rW  rE  rr   r|   	unmatchedru   rv   r  r  r   	flag_filer   r   rV   detailed_tagsr   r   r&   r&   r'   from_git  s  %








	













zVersion.from_gitc	           "      C   sp  t j}	|p|du}td|d}
|
dur|
d}i }| D ]}|dd}t|dkr-q|d  ||d  < q|d	}t	|d
dd }|d}|durX|d| }|d}|du se|dkro| j
|||||	dS td|d}|du r}|g}n$g }|d}t| D ]}|dd}t|dkrq||d  qt||||||}|du r| j
|||||	dS |\}}}}}}| ||||||||	d}||_||_|S t|	| td|\}}d| v}td|\}}|}td|rdnd|\}}t|dhkr|d| nd}td|\}}|dkrt|nd} td|dur,d|nd|\}}|s^ztd|\}}t	|d }W n tyQ   d}Y nw | j
|||||| |	dS dd  d!d  | D D }!t||!||||}|du r| j
|||||| |	dS |\}}}}}}td"|||\}}tt|d d}| ||||||||| |	d#
}||_||_|S )$a  
        Determine a version based on Mercurial tags.

        :param pattern: Regular expression matched against the version source.
            Refer to `from_any_vcs` for more info.
        :param latest_tag: If true, only inspect the latest tag on the latest
            tagged commit for a pattern match. If false, keep looking at tags
            until there is a match.
        :param full_commit: Get the full commit hash instead of the short form.
        :param strict: Elevate warnings to errors.
            When there are no tags, fail instead of falling back to 0.0.0.
        :param path: Directory to inspect, if not the current working directory.
        :param pattern_prefix: Insert this after the pattern's start anchor (`^`).
        :param commit_length:
            Use this many characters from the start of the full commit hash.
        :param highest_tag:
            Only inspect the numerically highest tag across all tagged commits for a pattern match.
        :returns: Detected version.
        Nr   r   r   :r;   r   r
   	latesttaglatesttagdistancenoder  null)r  r   r  r   z.hgtagsr   )r|   r  r   ru   rv   r  r   z
hg summaryzcommit: (clean)z	hg branchzhg id --template "{}"z{id}z
{id|short}r*  z0hg log --limit 1 --template "{date|rfc3339date}"rQ   zBhg log -r "sort(tag(){}, -rev)" --template "{{join(tags, ':')}}\n"z and ancestors({})zhg id --num --rev tiprY  c                 S   s   g | ]	}|D ]}|qqS r&   r&   )r   rV   r   r&   r&   r'   r     s    z*Version.from_mercurial.<locals>.<listcomp>c                 S   s   g | ]}| d qS )r|  r   rd  r&   r&   r'   r     r   z)hg log -r "{0}::{1} - {0}" --template "."rZ  )r   r1   r   r   r   rf   r6  rj   r   r   rL  r?  rW   r   r	  r
  r   ro   rB   r  r   r~   max)"rB  rG   rM  rN  rz   r   r{   rP  rQ  r   r   r   rv  r   rY   r   r  r   r  all_tags_fileall_tagsall_tags_contentrE  rr   r|   rx  ru   rv   r  r   r   r  r   rV   r&   r&   r'   from_mercurial+  s   






 	
	zVersion.from_mercurialc                 C   s  t j}t|| td|ddgd\}	}
|
dk}td|\}	}
t|
}t|dkr.d}d}n|d jd }|dur?|d| }tj	
|d jd	 d
 d}td|\}	}
|
szztd|\}	}
t|
}W n tyn   d}Y nw | j||||||dS |
 }t||||||}|du r| j||||||dS |\}}}}}}td||\}	}
t|
d }| |||||||||d	}||_||_|S )a  
        Determine a version based on Darcs tags.

        :param pattern: Regular expression matched against the version source.
            Refer to `from_any_vcs` for more info.
        :param latest_tag: If true, only inspect the latest tag on the latest
            tagged commit for a pattern match. If false, keep looking at tags
            until there is a match.
        :param strict: Elevate warnings to errors.
            When there are no tags, fail instead of falling back to 0.0.0.
        :param path: Directory to inspect, if not the current working directory.
        :param pattern_prefix: Insert this after the pattern's start anchor (`^`).
        :param commit_length:
            Use this many characters from the start of the full commit hash.
        :param highest_tag:
            Only inspect the numerically highest tag across all tagged commits for a pattern match.
        :returns: Detected version.
        zdarcs statusr
   r;   r   zNo changes!zdarcs log --last 1 --xml-outputNhashdate+0000z%Y%m%d%H%M%S%zzdarcs show tagszdarcs log --countr  r   r  r   r   zdarcs log --from-tag {} --countr|   r  r   r  ru   rv   r   r   )r   r2   r   ro   r   
fromstringr6  attribr   r   strptimer   r~   rL  r   r   rB   r	  r
  )rB  rG   rM  rz   r   r{   rP  rQ  r   r   r   r  rootr   r   r  rV   rE  r   rr   r|   rx  ru   rv   r  r&   r&   r'   
from_darcs  sd   

zVersion.from_darcsrV   tag_dirc	                     s4  t j}	t|	| |d}td|\}
}t|}td|\}
}|d}td|\}
}|r1|dkr4d}n|d| }d}|rItd|\}
}t|}|sV| j|d||||	d	S td
||||\}
}dd |	 dd D }dd |D }|szt
|}W n ty   d}Y nw | j||||||	d	S i  | D ]0\}}td||||\}
}|	 D ]}td|||}|rt
|d}||f |< qqt  fdddd}t||||||}|du r| j||||||	d	S |\}}}}}} | \}}t
|d | }| |||||||||	d	}||_||_|S )a  
        Determine a version based on Subversion tags.

        :param pattern: Regular expression matched against the version source.
            Refer to `from_any_vcs` for more info.
        :param latest_tag: If true, only inspect the latest tag on the latest
            tagged commit for a pattern match. If false, keep looking at tags
            until there is a match.
        :param tag_dir: Location of tags relative to the root.
        :param strict: Elevate warnings to errors.
            When there are no tags, fail instead of falling back to 0.0.0.
        :param path: Directory to inspect, if not the current working directory.
        :param pattern_prefix: Insert this after the pattern's start anchor (`^`).
        :param commit_length:
            Use this many characters from the start of the full commit hash.
        :param highest_tag:
            Only inspect the numerically highest tag across all tagged commits for a pattern match.
        :returns: Detected version.
        /z
svn statusz#svn info --show-item repos-root-urlzsvn info --show-item revisionr*  Nz&svn info --show-item last-changed-dater
   r  zsvn ls -v -r {} "{}/{}"c                 S   s   g | ]}|j d dqS )re  maxsplitr   rd  r&   r&   r'   r   \  r   z+Version.from_subversion.<locals>.<listcomp>r;   c                 S   s$   i | ]}|d   dt|d qS )r   r  r
   )rj   r   rd  r&   r&   r'   rU  ]  s   $ z+Version.from_subversion.<locals>.<dictcomp>z$svn log -v "{}/{}/{}" --stop-on-copyzA /{}/{} \(from .+?:(\d+)\)c                    s    |  S rN   r&   rh  tags_to_sources_revsr&   r'   ri  l  rj  z)Version.from_subversion.<locals>.<lambda>Trk  r  )r   r3   r   rj   ro   r  _parse_timestamprL  rB   r   r   r~   r   r   r   r   r@  r   r	  r
  ) rB  rG   rM  r  rz   r   r{   rP  rQ  r   r   r   r  urlr   r   linestags_to_revsr  r   revr   r>  r   rV   rE  rr   r|   rx  ru   rv   r  r&   r  r'   from_subversion$  s   


zVersion.from_subversionc                 C   s  t j}t|| td|\}	}
|
dk}td|\}	}
d}d}d}|
 D ]>}|jddd}t|dkr;|d d| }|jd	dd}t|dkrL|d }|jd
dd}t|dkrbtj	|d d}q$td|\}	}
|
rn|sz|durwt
|nd}W n ty   d}Y nw | j|||||||dS dd |
 D }dd tdd | D ddD }t||||||}|du r| j|||||||dS |\}}}}}}t
|||  }| ||||||||||d
}||_||_|S )a  
        Determine a version based on Bazaar tags.

        :param pattern: Regular expression matched against the version source.
            Refer to `from_any_vcs` for more info.
        :param latest_tag: If true, only inspect the latest tag on the latest
            tagged commit for a pattern match. If false, keep looking at tags
            until there is a match.
        :param strict: Elevate warnings to errors.
            When there are no tags, fail instead of falling back to 0.0.0.
        :param path: Directory to inspect, if not the current working directory.
        :param pattern_prefix: Insert this after the pattern's start anchor (`^`).
        :param commit_length:
            Use this many characters from the start of the full commit hash.
        :param highest_tag:
            Only inspect the numerically highest tag across all tagged commits for a pattern match.
        :returns: Detected version.
        r   rQ   zbzr log --limit 1Nzrevno: r;   r  r   zbranch nick: ztimestamp: z%a %Y-%m-%d %H:%M:%S %zzbzr tagsr
   rY  c                 S   s6   i | ]}|  d  dkr|  d t|  d  qS )r;   ?r
   )rf   r   rd  r&   r&   r'   rU    s   6 z'Version.from_bazaar.<locals>.<dictcomp>c                 S      g | ]}|d  qS )r;   r&   r   r&   r&   r'   r     r   z'Version.from_bazaar.<locals>.<listcomp>c                 S   s   g | ]\}}||fqS r&   r&   rS  r&   r&   r'   r     r   T)rm  rZ  )r   r4   r   ro   r   rf   r6  r   r   r  r   r~   rL  r@  r   r   r	  r
  )rB  rG   rM  rz   r   r{   rP  rQ  r   r   r   r  r   r  r   r   infor  r  rV   rE  r   rr   r|   rx  ru   rv   r  r&   r&   r'   from_bazaar  s   
	$	zVersion.from_bazaarc                 C   s  t j}t|| td|\}	}
t|
}td|\}	}
|
}td|\}	}
|
dd| }td|\}	}
tj|
dd d}td	|\}	}
t	|
d
 }|dkr\| j
|d|||||dS d}tdd| |\}	}
|
szt	|}W n ty   d}Y nw | j
|||||||dS dd |
 D }t|dd |D ||||}|du r| j
|||||||dS |\}}}}}}t|| }| ||||||||||d
}||_||_|S )a  
        Determine a version based on Fossil tags.

        :param pattern: Regular expression matched against the version source.
            Refer to `from_any_vcs` for more info.
        :param latest_tag: If true, only inspect the latest tag for a pattern
            match. If false, keep looking at tags until there is a match.
        :param strict: Elevate warnings to errors.
            When there are no tags, fail instead of falling back to 0.0.0.
        :param path: Directory to inspect, if not the current working directory.
        :param pattern_prefix: Insert this after the pattern's start anchor (`^`).
        :param commit_length:
            Use this many characters from the start of the full commit hash.
        :param highest_tag:
            Only inspect the numerically highest tag across all tagged commits for a pattern match.
        :returns: Detected version.
        zfossil changes --differzfossil branch currentzHfossil sql "SELECT value FROM vvar WHERE name = 'checkout-hash' LIMIT 1"'Nzfossil sql "SELECT DATETIME(mtime) FROM event JOIN blob ON event.objid=blob.rid WHERE type = 'ci' AND uuid = (SELECT value FROM vvar WHERE name = 'checkout-hash' LIMIT 1) LIMIT 1"r  z%Y-%m-%d %H:%M:%S%zz8fossil sql "SELECT count() FROM event WHERE type = 'ci'"r;   r
   rY  a  
            CREATE TEMP TABLE IF NOT EXISTS
                dunamai_ancestor(
                    rid INTEGER UNIQUE NOT NULL,
                    generation INTEGER PRIMARY KEY
                );
            DELETE FROM dunamai_ancestor;
            WITH RECURSIVE g(x, i)
                AS (
                    VALUES((SELECT value FROM vvar WHERE name = 'checkout' LIMIT 1), 1)
                    UNION ALL
                    SELECT plink.pid, g.i + 1 FROM plink, g
                    WHERE plink.cid = g.x AND plink.isprim
                )
                INSERT INTO dunamai_ancestor(rid, generation) SELECT x, i FROM g;
            SELECT tag.tagname, dunamai_ancestor.generation
                FROM tag
                JOIN tagxref ON tag.tagid = tagxref.tagid
                JOIN event ON tagxref.origid = event.objid
                JOIN dunamai_ancestor ON tagxref.origid = dunamai_ancestor.rid
                WHERE tagxref.tagtype = 1
                ORDER BY event.mtime DESC, tagxref.mtime DESC;
        zfossil sql "{}"r   c                 S   s<   g | ]}| d dd dd t| d dd d fqS ),r;   r
   re  r   )rs  r   rd  r&   r&   r'   r   Y  s    0z'Version.from_fossil.<locals>.<listcomp>c                 S   s   g | ]\}}|qS r&   r&   )r   rg  dr&   r&   r'   r   ^  r   rZ  )r   r5   r   ro   r  rj   r   r   r  r   rL  rB   rX   r   r~   r   dictr	  r
  )rB  rG   rM  rz   r   r{   rP  rQ  r   r   r   r  r  r   r   total_commitsqueryr  tags_to_distancerE  r   rr   r|   rx  ru   rv   r  r&   r&   r'   from_fossil  s   

	zVersion.from_fossilc           %      C   sF  t j}t|| td|\}	}
|
 dk}td|\}	}
d}|
 D ]}|dr3|ddd } nq"td|\}	}
t	|
}t
|dkrO| j||||d	S |d d
 d| }t|d d }td|\}	}
t	|
}td|\}	}
|
st
|d }| j|||||||dS g }d}tj }d}d}|
 D ]^}|s|dr|ddd }q|drt|ddd ddtd}q|dr||dd 7 }d}q|dr|||| d |ddd }tj }d}d}q||7 }q|r|||| d i }|D ]}|d |vs |d ||d  d kr&|||d < q
dd t| dd dd D }t||||||}|du rR| j|||||||dS |\}}}}} }!|| d! }"td"|"|ddgd# td$|"|\}	}
|
 dkrg }#nt	|
}#t
|t
|# }| |||||| |!|||d%
}$||$_||$_|$S )&a  
        Determine a version based on Pijul tags.

        :param pattern: Regular expression matched against the version source.
            Refer to `from_any_vcs` for more info.
        :param latest_tag: If true, only inspect the latest tag on the latest
            tagged commit for a pattern match. If false, keep looking at tags
            until there is a match.
        :param strict: Elevate warnings to errors.
            When there are no tags, fail instead of falling back to 0.0.0.
        :param path: Directory to inspect, if not the current working directory.
        :param pattern_prefix: Insert this after the pattern's start anchor (`^`).
        :param commit_length:
            Use this many characters from the start of the full commit hash.
        :param highest_tag:
            Only inspect the numerically highest tag across all tagged commits for a pattern match.
        :returns: Detected version.
        zpijul diff --shortrQ   zpijul channelmainz* r;   z(pijul log --limit 1 --output-format jsonr
   )r  r  r   r  Nr   zpijul log --output-format jsonz	pijul tagrY  FzState zDate:zDate: z UTCZ)rB   z       T)stater   rT   rT   c                 S   r  r_  r&   rf  r&   r&   r'   r     r   z&Version.from_pijul.<locals>.<listcomp>c                 S   s   | d S )Nr   r&   rh  r&   r&   r'   ri    rj  z$Version.from_pijul.<locals>.<lambda>rk  r  zpijul tag checkout {}r   z+pijul log --output-format json --channel {}rZ  )r   r6   r   ro   rj   r   r   rf   rp  rq  r6  rL  r  r   r   nowrA   _TIMESTAMP_GENERIC_SPACErW   r@  valuesr   rB   r	  r
  )%rB  rG   rM  rz   r   r{   rP  rQ  r   r   r   r  r  r   limited_commitsr   r   channel_commitsr  tag_meta	tag_statetag_timestamptag_messagetag_after_headertag_meta_by_msgmetarV   rE  r   rr   r|   rx  ru   rv   tag_idtag_commitsr  r&   r&   r'   
from_pijul~  s   











 
	
zVersion.from_pijulc                 C   s8   t |}|du rtd|}| ||||||||||	|
S )a  
        Determine a version based on a detected version control system.

        :param pattern: Regular expression matched against the version source.
            This must contain one capture group named `base` corresponding to
            the release segment of the source. Optionally, it may contain another
            two groups named `stage` and `revision` corresponding to a prerelease
            type (such as 'alpha' or 'rc') and number (such as in 'alpha-2' or 'rc3').
            It may also contain a group named `tagged_metadata` corresponding to extra
            metadata after the main part of the version (typically after a plus sign).
            There may also be a group named `epoch` for the PEP 440 concept.

            If the `base` group is not included, then this will be interpreted
            as the name of a variant of the `Pattern` enum. For example, passing
            `"default"` is the same as passing `Pattern.Default`.
        :param latest_tag: If true, only inspect the latest tag on the latest
            tagged commit for a pattern match. If false, keep looking at tags
            until there is a match.
        :param tag_dir: Location of tags relative to the root.
            This is only used for Subversion.
        :param tag_branch: Branch on which to find tags, if different than the
            current branch. This is only used for Git currently.
        :param full_commit: Get the full commit hash instead of the short form.
            This is only used for Git and Mercurial.
        :param strict: Elevate warnings to errors.
            When there are no tags, fail instead of falling back to 0.0.0.
        :param path: Directory to inspect, if not the current working directory.
        :param pattern_prefix: Insert this after the pattern's start anchor (`^`).
        :param ignore_untracked:
            Ignore untracked files when determining whether the repository is dirty.
            This is only used for Git currently.
        :param commit_length:
            Use this many characters from the start of the full commit hash.
        :param highest_tag:
            Only inspect the numerically highest tag across all tagged commits for a pattern match.
        :returns: Detected version.
        N)r   r   _do_vcs_callback)rB  rG   rM  r  r   rN  rz   r   r{   rO  rP  rQ  r   r&   r&   r'   from_any_vcs  s    4
zVersion.from_any_vcsc                 C   s    |  |||||||||	|
||S )a  
        Determine a version based on a specific VCS setting.

        This is primarily intended for other tools that want to generically
        use some VCS setting based on user configuration, without having to
        maintain a mapping from the VCS name to the appropriate function.

        :param pattern: Regular expression matched against the version source.
            Refer to `from_any_vcs` for more info.
        :param latest_tag: If true, only inspect the latest tag on the latest
            tagged commit for a pattern match. If false, keep looking at tags
            until there is a match.
        :param tag_dir: Location of tags relative to the root.
            This is only used for Subversion.
        :param tag_branch: Branch on which to find tags, if different than the
            current branch. This is only used for Git currently.
        :param full_commit: Get the full commit hash instead of the short form.
            This is only used for Git and Mercurial.
        :param strict: Elevate warnings to errors.
            When there are no tags, fail instead of falling back to 0.0.0.
        :param path: Directory to inspect, if not the current working directory.
        :param pattern_prefix: Insert this after the pattern's start anchor (`^`).
        :param ignore_untracked:
            Ignore untracked files when determining whether the repository is dirty.
            This is only used for Git currently.
        :param commit_length:
            Use this many characters from the start of the full commit hash.
        :param highest_tag:
            Only inspect the numerically highest tag across all tagged commits for a pattern match.
        :returns: Detected version.
        )r  )rB  r   rG   rM  r  r   rN  rz   r   r{   rO  rP  rQ  r&   r&   r'   from_vcsZ  s   /zVersion.from_vcsc                 C   s   t j| jt j| jt j| jt j| jt j	| j
t j| jt j| jt j| ji}i }|| }d|fd|fd|fd|fd|fd|fd|fd|	fd	|
fd
|fd|ffD ]\}}|t|jv r[|||< qK|di |S )NrG   rM  r  r   rN  rz   r   r{   rO  rP  rQ  r&   )r   r   r  r0   r{  r1   r  r2   r  r3   r  r4   r  r5   r  r6   r  inspectgetfullargspecargs)rB  r   rG   rM  r  r   rN  rz   r   r{   rO  rP  rQ  mappingkwargscallbackkwargrL   r&   r&   r'   r    s6   
zVersion._do_vcs_callback)NFNNFFNN)r   r;   F)NFNF)*r   r    r!   r"   r   r   rI   r   r   r   r  r   r   r   rP   r   r  r   r  r  r#  r   r   r   r  classmethodr7   r>   rM   r%  rL  r   r{  r  r  r  r  r  r  r  r  r  r&   r&   r&   r'   r	     s4   !	


42	

 (&\"	

!
	
  
	
 "
	V
	
h
	d
	 
	 
	
D
	
=
	
r	   r  r$  c                 C   s   t jdtft jdtft jdtfi| \}}d| |}t	|| s%t
||t jkrCtd| ddd }td	d
 |D rEt
|dS dS )z
    Check if a version is valid for a style.

    :param version: Version to check.
    :param style: Style against which to check.
    :raises ValueError: If the version is invalid.
    zPEP 440zSemantic VersioningPVPz-Version '{}' does not conform to the {} stylez[.-]+r;   r
   c                 s   s    | ]	}t d |V  qdS )z	^0[0-9]+$N)r   r   r   r&   r&   r'   r`    s    z check_version.<locals>.<genexpr>N)r   r#   _VALID_PEP440r$   _VALID_SEMVERr%   
_VALID_PVPrB   r   r   rJ   rf   r(   )r  r$  r   rG   failure_messagerY   r&   r&   r'   r     s   
	


r   rK  first_choicethird_choicefallbackignoreparserc                    s   |du rg }|r|   rt  fdd|D s S zddlm} W n ty/   ddl}Y nw z||| t fdd|D sFW S W n
 |jyQ   Y nw |rf| rft fdd|D sfS |S )aH  
    Check importlib-metadata info or a fallback function to determine the version.
    This is intended as a convenient default for setting your `__version__` if
    you do not want to include a generated version statically during packaging.

    :param name: Installed package name.
    :param first_choice: Callback to determine a version before checking
        to see if the named package is installed.
    :param third_choice: Callback to determine a version if the installed
        package cannot be found by name.
    :param fallback: If no other matches found, use this version.
    :param ignore: Ignore a found version if it is part of this list. When
        comparing the found version to an ignored one, fields with None in the ignored
        version are not taken into account. If the ignored version has distance=0,
        then that field is also ignored.
    :param parser: Callback to convert a string into a Version instance.
        This will be used for the second choice.
        For example, you can pass `Version.parse` here.
    :returns: First available version.
    Nc                 3       | ]}  |V  qd S rN   r  r   r<  )	first_verr&   r'   r`        zget_version.<locals>.<genexpr>r
   c                 3   r  rN   r  r  )ilm_versionr&   r'   r`  	  r  c                 3   r  rN   r  r  )	third_verr&   r'   r`  	  r  )r(   importlib.metadatar  ImportErrorimportlib_metadatar  PackageNotFoundError)r   r  r  r  r  r  ilmr&   )r  r  r  r'   r     s0   r   r|   r}   r0  r1  r  c           
      C   s   g }|dur| |dg ||  |dur:dddddd}||| |  |du r5|d n|| |durE| d|g |durP| d	|g |durgt|dkrg| d
dtt|g dtt|}	t|	t	j
 |	S )aA  
    Serialize a version based on PEP 440.
    Use this instead of `Version.serialize()` if you want more control
    over how the version is mapped.

    :param base: Release segment, such as 0.1.0.
    :param stage: Pre-release stage ("a", "b", or "rc").
    :param revision: Pre-release revision (e.g., 1 as in "rc1").
        This is ignored when `stage` is None.
    :param post: Post-release number.
    :param dev: Developmental release number.
    :param epoch: Epoch number.
    :param metadata: Any local version label segments.
    :returns: Serialized version.
    N!r!  r"  rc)alphabetacr/  previewr
   z.postz.devr  r   rQ   )extendrW   r   lowerr6  rX   maprI   r   r   r#   )
rr   r|   r}   r0  r1  rv   r  rE   alternative_stages
serializedr&   r&   r'   r   	  s&   

r   r/  c                 C   s   | g}|durt |dkr|ddtt|g |dur1t |dkr1|ddtt|g ddd |D }t|tj |S )	aQ  
    Serialize a version based on Semantic Versioning.
    Use this instead of `Version.serialize()` if you want more control
    over how the version is mapped.

    :param base: Version core, such as 0.1.0.
    :param pre: Pre-release identifiers.
    :param metadata: Build metadata identifiers.
    :returns: Serialized version.
    Nr
   rX  r   r  rQ   c                 s       | ]}t |V  qd S rN   rI   r   r&   r&   r'   r`  `	  ra  z#serialize_semver.<locals>.<genexpr>)r6  r  rX   r  rI   r   r   r$   )rr   r/  r  rE   r  r&   r&   r'   r   I	  s   r   c                 C   sT   | g}|durt |dkr|ddtt|g dtt|}t|tj |S )a4  
    Serialize a version based on the Haskell Package Versioning Policy.
    Use this instead of `Version.serialize()` if you want more control
    over how the version is mapped.

    :param base: Version core, such as 0.1.0.
    :param metadata: Version tag metadata.
    :returns: Serialized version.
    Nr
   rX  rQ   )r6  r  rX   r  rI   r   r   r%   )rr   r  rE   r  r&   r&   r'   r   e	  s   
r   r   r;   rI  rJ  c                 C   st   dd |  dD }||  |7  < |dk rdnt|}|d }||k r0d||< |d7 }||k s$ddd |D S )a  
    Increment one of the numerical positions of a version.

    :param base: Version core, such as 0.1.0.
        Do not include pre-release identifiers.
    :param index: Numerical position to increment.
        This follows Python indexing rules, so positive numbers start from
        the left side and count up from 0, while negative numbers start from
        the right side and count down from -1.
    :param increment: By how much the `index` needs to increment.
    :returns: Bumped version.
    c                 S   r   r&   r   r   r&   r&   r'   r   	  r   z bump_version.<locals>.<listcomp>r   r
   r;   c                 s   r  rN   r  r   r&   r&   r'   r`  	  ra  zbump_version.<locals>.<genexpr>)rf   r6  rX   )rr   rI  rJ  basesr   rH  r&   r&   r'   r   y	  s   r   rawc                 C      t dd| }t|tS )Nz(.*T.*[-+]\d+):(\d+)\1\2)r   r   r  _TIMESTAMP_GIT_ISO_STRICTr  compatr&   r&   r'   r   	     
r   c                 C   r  )Nz(.* .* [-+]\d+):(\d+)r  )r   r   r  _TIMESTAMP_GIT_ISOr  r&   r&   r'   ru  	  r  ru  rB   c                 C   s*   t dd| }t dd|}tj||S )NzZ$r  z\.(\d{6})\d+\+0000z.\g<1>+0000)r   r   r   r   r  )r  rB   rC  r&   r&   r'   r  	  s   r  dunamai)rZ   FN)rN   )NNNNNN)NN)r   r;   )O__all__r3  r   r   r  rp  rn  r   re   r   rc   r   collectionsr   enumr   	functoolsr   pathlibr   typingr   r   r   r   r   r   r   r   r   r   r   	xml.etreer   rj   r?   _VERSION_PATTERNr  r  r  _TIMESTAMP_GENERICr  r  r  r   r   r   r7   rP   rI   rK   r   r  r  ro   rp   r   r   r   r   r   r   r   r   r   r   r	   r#   r   r   r   r   r   r   r   ru  r  r  __version__r&   r&   r&   r'   <module>   sH   4	>,






a$	1(U             ?

9
8
(	