
    dgL                     L    S r SSKrSSKrSSKrSSKJr  SSKJr   " S S5      rg)a  State snapshots to facilitate debugging and fixing apt-listchanges bugs

Sometimes apt-listchanges malfunctions in ways that are highly dependent on the
environment in which it's running and the specific packages it's looking for
changes in. We've implemented this snapshot functionality to facilitate finding
and fixing those bugs quickly when there is active development of the program
ongoing and therefore odds are higher that bugs will be introduced.

When snapshots are enabled (more on that below), each time the program runs, it
makes copies of several significant files and also saves some data to disk, in
a snapshot folder which is, at the end of the run, turned into a .tar.xz file.
The last seven .tar.xz files are saved. If a user who has snapshots enabled
reports a bug, we can ask them to send us the relevant snapshot to assist us in
troubleshooting.

Any user can enable snapshots at any time by adding the configuration settings
`capture_snapshots=true` and `snapshot_dir=[directory-path]` to the
apt-listchanges config fragment file for a particular profile. However, these
settings are undocumented and generally not expected to be added by hand.
Instead, when debconf_helper.py is configured to enable snapshots, it adds
`capture_snapshots=auto` and `snapshot_dir` settings to the configuration of
the `apt` profile.

Setting `capture_snapshots=auto` is equivalent to setting it to `true`, but it
means that in a subsequent release when we change debconf_helper.py to no
longer enable snapshots, it's allowed to automatically remove the
`capture_snapshots` and `snapshot_dir` options and delete any snapshots that
are still around. In this way we can transition easily from experimental to
non-experimental packages and snapshots get disabled and cleaned up
automatically.

The build checks to make sure that debconf_helper.py doesn't have snapshots
enabled unless the changelog says we're doing an experimental release. We never
want to release apt-listchanges past experimental with snapshots enabled.

    N)	ALCConfig)debugc                       \ rS rSrSrSrS\SS4S jrS rS	 r	S
 r
SS\S\S-  SS4S jjrS\\-  S\SS4S jrS rS rSrg)Snapshot.   zBuild a snapshot of what happened during the apt-listchanges run
This is designed to _never cause an exception_. If something goes wrong it
just gives up. The goal here is to make a best effort and never interfere
with the proper operation of the program.   configreturnNc                    S U l         UR                  (       d  SU l        g UR                  (       d  SU l        g UR                  U l        [        R
                  R                  U R                  5      (       dt  [        R
                  R                  [        R
                  R                  U R                  5      5      (       d  SU l        g  [        R                  " U R                  5        [        R                  R                  5       R                  SS9R                  5       U l        [        R
                  R!                  U R                  U R                  5      U l         [        R                  " U R"                  5        SU l        g ! [         a,  n[        SU R                   SU 35        SU l         S nAg S nAff = f! [         a,  n[        SU R"                   SU 35        SU l         S nAg S nAff = f)NFzmkdir(z
) failed, r   )microsecondT)archivecapture_snapshots	capturingsnapshot_dirospathexistsdirnamemkdir	Exceptionr   datetimenowreplace	isoformatsnapshot_subdirjoinsnapshot_path)selfr	   exs      :/usr/lib/python3/dist-packages/apt_listchanges/snapshot.py__init__Snapshot.__init__5   s   ''"DN"""DN"//ww~~d//0077>>"''//$2C2C"DEE
 "'**+
  (00446>>1>MIK 	WW\\t335	HHT''(
   t001B4@A!&  	F4--.j=>"DN	s0    F % G 
G"F>>G
G<"G77G<c                     U $ N r   s    r    	__enter__Snapshot.__enter__X   s        c                 $    U R                  5         g)NF)commit)r   	_exc_type
_exc_value_exc_tracebacks       r    __exit__Snapshot.__exit__[   s    r)   c                 r    SU l          [        R                  " U R                  SS9  g ! [         a     g f = f)NFTignore_errors)r   shutilrmtreer   r   r&   s    r    abortSnapshot.abort_   s4    	MM$,,DA 		s   ) 
66r   namec                    U R                   (       d  gU(       d  [        R                  R                  U5      n[        R                  R	                  U5      (       d  U R                  SU S35        g [        R                  " U[        R                  R                  U R                  U5      5        g! [         a    U R                  5          gf = f)zXAdd a file to the snapshot
If name is not specified the the basename of the file is usedN z.missing)r   r   r   basenamer   add_datar4   copyr   r   r   r6   )r   r   r8   s      r    add_fileSnapshot.add_filef   s     ~~77##D)Dww~~d##MM"h/0	KKbggll4+=+=tDE 	JJL	s   4?B4 4CCdatac                 l   U R                   (       d  g [        U[        5      (       a  SnSS0nOSn0 n [        R                  R                  U R                  U5      n[        XS40 UD6 nUR                  U5        S S S 5        g ! , (       d  f       g = f! [         a    U R                  5          g f = f)Nwtencodingzutf-8wb)r   
isinstancestrr   r   r   r   openwriter   r6   )r   r@   r8   moderC   targetfs          r    r<   Snapshot.add_datau   s    ~~dC  D"G,HDH	WW\\$"4"4d;Ff/h/1 0// 	JJL	s/   6B *B<B 
BB B B32B3c                 p   U R                   (       d  g  [        R                  " U R                  SU R                  U R
                  5      U l        SU l          [        R                  " U R                  SS9  U R                  5         g ! [         a    U R                  5          g f = f! [         a     g f = f)NxztarFTr2   )r   r4   make_archiver   r   r   r   r   r6   r5   pruner&   s    r    r+   Snapshot.commit   s    ~~	!..""GT->->$$&DL 	MM$,,DA 	

  	JJL	  		s#   <B B( B%$B%(
B54B5c                 ~    [        S [        R                  " U R                  5       5       SS9U R                  S nU HD  n[        R
                  R                  U R                  U5      n [        R                  " U5        MF     g! [         a    [        R                  " USS9   Mk  f = f! [         a     gf = f)z+Prune old snapshots or snapshot directoriesc              3   8   #    U  H  oR                   v   M     g 7fr$   )r8   ).0des     r    	<genexpr>!Snapshot.prune.<locals>.<genexpr>   s     A#@R#@s   T)reverseNr2   )sortedr   scandirr   SAVED_SNAPSHOTSr   r   remover   r4   r5   )r   	snapshotssnapshotr   s       r    rP   Snapshot.prune   s    	A2::d.?.?#@A"2235I &ww||D$5$5x@<IIdO & ! <MM$d;< 		s6   A+B/ .B	B/ 	B,(B/ +B,,B/ /
B<;B<)r   r   r   r   r   r$   )__name__
__module____qualname____firstlineno____doc__r[   r   r!   r'   r/   r6   rF   r>   bytesr<   r+   rP   __static_attributes__r%   r)   r    r   r   .   sw    1 O!y !T !FS d
 d S5[   ""r)   r   )	rd   r   r   r4   apt_listchanges.ALCConfigr   apt_listchanges.ALCLogr   r   r%   r)   r    <module>ri      s(   #J  	  / (v vr)   