ó
AqzRc           @   sv   d  Z  d d l Z d d l Z d d l Z d d l Z d d l m Z d e f d „  ƒ  YZ d e	 f d „  ƒ  YZ
 d S(   s   Handle Patches and Patch SeriesiÿÿÿÿN(   t   GbpErrort   Patchc           B   sŒ   e  Z d  Z d d g Z d d d „ Z d „  Z d „  Z d „  Z d d „ Z	 e
 d „  ƒ Z e
 d	 „  ƒ Z e
 d
 „  ƒ Z e
 d „  ƒ Z RS(   sÆ  
    A patch in a L{PatchSeries}

    @ivar path: path to the patch
    @type path: string
    @ivar topic: the topic of the patch (the directory component)
    @type topic: string
    @ivar strip: path components to strip (think patch -p<strip>)
    @type strip: integer
    @ivar info: Information retrieved from a RFC822 style patch header
    @type info: C{dict} with C{str} keys and values
    @ivar long_desc: the long description of the patch
    t   difft   patchc         C   s1   | |  _  | |  _ | |  _ d  |  _ d  |  _ d  S(   N(   t   patht   topict   stript   Nonet   infot	   long_desc(   t   selfR   R   R   (    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyt   __init__)   s
    				c         C   s[   d |  j  } |  j r* | d |  j 7} n  |  j d  k rM | d |  j 7} n  | d 7} | S(   Ns"   <gbp.patch_series.Patch path='%s' s   topic='%s' s	   strip=%d t   >(   R   R   R   R   (   R
   t   repr(    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyt   __repr__0   s    	
c         C   s=  i  |  _  t j d d ƒ } t j d | j |  j f d t d t j ƒj	 } xX | D]P } d | k rS | j
 d d ƒ \ } } | d	  j ƒ  } | j ƒ  |  j  | <qS qS Wzf y3 d
 j g  | D] } | ^ qº ƒ |  _ | j ƒ  Wn, t k
 r} t d |  j | f ƒ ‚ n XWd t j j | j ƒ r8t j | j ƒ n  Xd S(   s^   
        Read patch information into a structured form

        using I{git mailinfo}
        t   prefixt   gbp_s.   git mailinfo '%s' /dev/null 2>/dev/null < '%s't   shellt   stdoutt   :t    i   iÿÿÿÿt    s'   Failed to read patch header of '%s': %sN(   R   t   tempfilet   NamedTemporaryFilet
   subprocesst   Popent   nameR   t   Truet   PIPER   t   splitt   lowerR   t   joinR	   t   closet   IOErrorR    R   t   ost   existst   unlink(   R
   t   bodyt   pipet   linet
   rfc_headert   valuet   headert   msg(    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyt
   _read_info9   s(    		 %c         C   sa   t  j j |  j ƒ } y4 | j d d ƒ \ } } | |  j k rH | } n  Wn t k
 r\ n X| S(   sý  
        Determine the patch's subject based on the it's filename

        >>> p = Patch('debian/patches/foo.patch')
        >>> p._get_subject_from_filename()
        'foo'
        >>> Patch('foo.patch')._get_subject_from_filename()
        'foo'
        >>> Patch('debian/patches/foo.bar')._get_subject_from_filename()
        'foo.bar'
        >>> p = Patch('debian/patches/foo')
        >>> p._get_subject_from_filename()
        'foo'

        @return: the patch's subject
        @rtype: C{str}
        t   .i   (   R"   R   t   basenamet   rsplitt
   patch_extst
   ValueError(   R
   t   subjectt   baset   ext(    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyt   _get_subject_from_filenameT   s    c         C   sN   |  j  d k r |  j ƒ  n  |  j  j | ƒ r9 |  j  | S| rF | ƒ  Sd Sd S(   s8  
        Return the key I{key} from the info C{dict}
        or use val if I{key} is not a valid key.

        Fill self.info if not already done.

        @param key: key to fetch
        @type key: C{str}
        @param get_val: alternate value if key is not in info dict
        @type get_val: C{str}
        N(   R   R   R,   t   has_key(   R
   t   keyt   get_val(    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyt   _get_info_fieldp   s
    c         C   s   |  j  d |  j ƒ S(   sY   
        The patch's subject, either from the patch header or from the filename.
        R2   (   R9   R5   (   R
   (    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyR2   …   s    c         C   s   |  j  d ƒ S(   s   The patch's authort   author(   R9   (   R
   (    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyR:   Œ   s    c         C   s   |  j  d ƒ S(   s    The patch author's email addresst   email(   R9   (   R
   (    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyR;   ‘   s    c         C   s   |  j  d ƒ S(   s   The patch's modification timet   date(   R9   (   R
   (    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyR<   –   s    N(   t   __name__t
   __module__t   __doc__R0   R   R   R   R,   R5   R9   t   propertyR2   R:   R;   R<   (    (    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyR      s   				t   PatchSeriesc           B   sY   e  Z d  Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z	 RS(   sC   
    A series of L{Patch}es as read from a quilt series file).
    c         C   s~   t  j j | ƒ } t  j j | ƒ s( g  Sy t | ƒ } Wn# t k
 r] } t d | ƒ ‚ n X|  j | | ƒ } | j ƒ  | S(   s(   Read a series file into L{Patch} objectss   Cannot open series file: %s(	   R"   R   t   dirnameR#   t   opent	   ExceptionR    t   _read_seriesR    (   t   klasst
   seriesfilet	   patch_dirt   st   errt   queue(    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyt   read_series_file¡   s    
c         C   sh   t  ƒ  } xX | D]P } y | d d k r/ w n  Wn t k
 rF q n X| j |  j | | ƒ ƒ q W| S(   sÅ  
        Read patch series

        >>> PatchSeries._read_series(['a/b',                             'a -p1',                             'a/b -p2'], '.') # doctest:+NORMALIZE_WHITESPACE
        [<gbp.patch_series.Patch path='./a/b' topic='a' >,
         <gbp.patch_series.Patch path='./a' strip=1 >,
         <gbp.patch_series.Patch path='./a/b' topic='a' strip=2 >]

        >>> PatchSeries._read_series(['# foo', 'a/b', '', '# bar'], '.')
        [<gbp.patch_series.Patch path='./a/b' topic='a' >]

        @param series: series of patches in quilt format
        @type series: iterable of strings
        @param patch_dir: path prefix to prepend to each patch path
        @type patch_dir: string
        i    s   
t   #(   s   
RM   (   RA   t
   IndexErrort   appendt   _parse_line(   RF   t   seriesRH   RK   R'   (    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyRE   ²   s    	
c         C   s+   t  j j |  ƒ } | d k r' d } n  | S(   sÅ   
        Get the topic from the patch's path

        >>> PatchSeries._get_topic("a/b c")
        'a'
        >>> PatchSeries._get_topic("asdf")
        >>> PatchSeries._get_topic("/asdf")
        R   t   /(   R   RR   N(   R"   R   RB   R   (   R'   R   (    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyt
   _get_topicÑ   s    
	c         C   s{   |  } d } |  j d d ƒ } t | ƒ d k rq t j d | d ƒ } | rq | d } t | j d ƒ ƒ } qq n  | | f S(   s'  
        Separate the -p<num> option from the patch name

        >>> PatchSeries._split_strip("asdf -p1")
        ('asdf', 1)
        >>> PatchSeries._split_strip("a/nice/patch")
        ('a/nice/patch', None)
        >>> PatchSeries._split_strip("asdf foo")
        ('asdf foo', None)
        i   s   -p(?P<level>[0-9]+)i    t   levelN(   R   R/   t   lent   ret   matcht   intt   group(   R'   R   R   R   t   m(    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyt   _split_stripà   s    
c         C   sO   | j  ƒ  } |  j | ƒ } |  j | ƒ \ } } t t j j | | ƒ | | ƒ S(   s-  
        Parse a single line from a series file

        >>> PatchSeries._parse_line("a/b -p1", '/tmp/patches')
        <gbp.patch_series.Patch path='/tmp/patches/a/b' topic='a' strip=1 >
        >>> PatchSeries._parse_line("a/b", '.')
        <gbp.patch_series.Patch path='./a/b' topic='a' >
        (   t   rstripRS   R[   R   R"   R   R   (   RF   R'   RH   R   R   R   (    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyRP   ø   s    
(
   R=   R>   R?   t   classmethodRL   RE   t   staticmethodRS   R[   RP   (    (    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyRA   œ   s   (   R?   R"   RV   R   R   t
   gbp.errorsR    t   objectR   t   listRA   (    (    (    s4   /usr/lib/python2.7/dist-packages/gbp/patch_series.pyt   <module>   s   ƒ