
    VhS]                         d dl mZmZmZ eZdZdZ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mZ ddddddZdZd	Zd
Zd Zd ZddZd Zd Zd Zd Zd Zd Zedk(  r e        yy)    )absolute_importdivisionprint_functiona
  
module: sorcery
short_description: Package manager for Source Mage GNU/Linux
description:
  - Manages "spells" on Source Mage GNU/Linux using I(sorcery) toolchain.
author: "Vlad Glagolev (@vaygr)"
notes:
  - When all three components are selected, the update goes by the sequence -- Sorcery -> Grimoire(s) -> Spell(s); you cannot
    override it.
  - Grimoire handling is supported since community.general 7.3.0.
requirements:
  - bash
extends_documentation_fragment:
  - community.general.attributes
attributes:
  check_mode:
    support: full
  diff_mode:
    support: none
options:
  name:
    description:
      - Name of the spell or grimoire.
      - Multiple names can be given, separated by commas.
      - Special value V(*) in conjunction with states V(latest) or V(rebuild) will update or rebuild the whole system respectively.
      - The alias O(grimoire) was added in community.general 7.3.0.
    aliases: ["spell", "grimoire"]
    type: list
    elements: str

  repository:
    description:
      - Repository location.
      - If specified, O(name) represents grimoire(s) instead of spell(s).
      - Special value V(*) will pull grimoire from the official location.
      - Only single item in O(name) in conjunction with V(*) can be used.
      - O(state=absent) must be used with a special value V(*).
    type: str
    version_added: 7.3.0

  state:
    description:
      - Whether to cast, dispel or rebuild a package.
      - State V(cast) is an equivalent of V(present), not V(latest).
      - State V(rebuild) implies cast of all specified spells, not only those existed before.
    choices: ["present", "latest", "absent", "cast", "dispelled", "rebuild"]
    default: "present"
    type: str

  depends:
    description:
      - Comma-separated list of _optional_ dependencies to build a spell (or make sure it is built) with; use V(+)/V(-) in
        front of dependency to turn it on/off (V(+) is optional though).
      - This option is ignored if O(name) parameter is equal to V(*) or contains more than one spell.
      - Providers must be supplied in the form recognized by Sorcery, for example 'V(openssl(SSL\))'.
    type: str

  update:
    description:
      - Whether or not to update sorcery scripts at the very first stage.
    type: bool
    default: false

  update_cache:
    description:
      - Whether or not to update grimoire collection before casting spells.
    type: bool
    default: false
    aliases: ["update_codex"]

  cache_valid_time:
    description:
      - Time in seconds to invalidate grimoire collection on update.
      - Especially useful for SCM and rsync grimoires.
      - Makes sense only in pair with O(update_cache).
    type: int
    default: 0
ax	  
- name: Make sure spell foo is installed
  community.general.sorcery:
    spell: foo
    state: present

- name: Make sure spells foo, bar and baz are removed
  community.general.sorcery:
    spell: foo,bar,baz
    state: absent

- name: Make sure spell foo with dependencies bar and baz is installed
  community.general.sorcery:
    spell: foo
    depends: bar,baz
    state: present

- name: Make sure spell foo with bar and without baz dependencies is installed
  community.general.sorcery:
    spell: foo
    depends: +bar,-baz
    state: present

- name: Make sure spell foo with libressl (providing SSL) dependency is installed
  community.general.sorcery:
    spell: foo
    depends: libressl(SSL)
    state: present

- name: Make sure spells with/without required dependencies (if any) are installed
  community.general.sorcery:
    name: "{{ item.spell }}"
    depends: "{{ item.depends | default(None) }}"
    state: present
  loop:
    - {spell: 'vifm', depends: '+file,-gtk+2'}
    - {spell: 'fwknop', depends: 'gpgme'}
    - {spell: 'pv,tnftp,tor'}

- name: Install the latest version of spell foo using regular glossary
  community.general.sorcery:
    name: foo
    state: latest

- name: Rebuild spell foo
  community.general.sorcery:
    spell: foo
    state: rebuild

- name: Rebuild the whole system, but update Sorcery and Codex first
  community.general.sorcery:
    spell: '*'
    state: rebuild
    update: true
    update_cache: true

- name: Refresh the grimoire collection if it is 1 day old using native sorcerous alias
  community.general.sorcery:
    update_codex: true
    cache_valid_time: 86400

- name: Make sure stable grimoire is present
  community.general.sorcery:
    name: stable
    repository: '*'
    state: present

- name: Make sure binary and stable-rc grimoires are removed
  community.general.sorcery:
    grimoire: binary,stable-rc
    repository: '*'
    state: absent

- name: Make sure games grimoire is pulled from rsync
  community.general.sorcery:
    grimoire: games
    repository: "rsync://download.sourcemage.org::codex/games"
    state: present

- name: Make sure a specific branch of stable grimoire is pulled from git
  community.general.sorcery:
    grimoire: stable.git
    repository: "git://download.sourcemage.org/smgl/grimoire.git:stable.git:stable-0.62"
    state: present

- name: Update only Sorcery itself
  community.general.sorcery:
    update: true

N)AnsibleModule)sorceryscribecastdispelgazez/var/log/sorceryz/var/state/sorceryzN/Ac                     dt         d   z  }| j                  |      \  }}}|dk7  s|s| j                  d       |j                         S )z Get Sorcery version. z%s --versionr   r   zunable to get Sorcery versionmsg)SORCERYrun_command	fail_jsonstrip)modulecmd_sorceryrcstdoutstderrs        m/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/modules/sorcery.pyget_sorcery_verr      sQ     !79#55K++K8B	Qwf<=<<>    c                    |j                   d   syt        j                  |j                   d         }| D ]  }t        j                  j                  t        |dz         }	 t        j                  |      j                  }t        j                  j                  |      }||z   t        j                  j                         k  s y y# t        $ r Y  yw xY w)z/ Check if grimoire collection is fresh enough. cache_valid_timeF)secondsz.lastupdateT)paramsdatetime	timedeltaospathjoinSORCERY_STATE_DIRstatst_mtime	Exceptionfromtimestampnow)codexr   r!   grimoirelastupdate_pathmtimelastupdate_tss          r   codex_freshr0      s     ==+,""6==9K+LMI '',,'8'/-'?A	GGO,55E !))77> 9$x'8'8'<'<'>>   		s   !C	CCc                    | j                   }i }dt        d   z  }| j                  |      \  }}}|dk7  r| j                  d       t	        j
                  d      }|j                         dd D ]9  }	|j                  |	      }
|
s|
j                  d	      ||
j                  d
      <   ; |d   r)|s'|d   D ci c]  }||j                  |t               }}|s| j                  d       |S c c}w )z! List valid grimoire collection. z%s indexr	   r   z2unable to list grimoire collection, fix your Codexr   zL^\s*\[\d+\] : (?P<grim>[\w\-+.]+) : [\w\-+./]+(?: : (?P<ver>[\w\-+.]+))?\s*$   vergrim
repositorynamez,no grimoires to operate on; add at least one)r   r   r   r   recompile
splitlinesmatchgroupgetNA)r   skip_newr   r+   
cmd_scriber   r   r   rexliner;   xs               r   
codex_listrD      s     ]]FEgh//J++J7B	QwQR
**d
eC !!#Ab) <		$).U);E%++f%&	< lH.4Vn=EIIa$$==KLL >s   9C/c                     d}| j                   ryt        |       }dt        d   z  }| j                  |      \  }}}|dk7  r| j	                  d|z          |t        |       k7  rd}|d	fS )
z Update sorcery scripts.

    This runs 'sorcery update' ('sorcery -u'). Check mode always returns a
    positive change value.

    F)Tzwould have updated Sorcery	%s updater   r   zunable to update Sorcery: r   Tzsuccessfully updated Sorcery)
check_moder   r   r   r   )r   changedsorcery_verr   r   r   r   s          r   update_sorceryrJ     s     G3%f-!GI$66#//<FF7!=!FG/&11G788r   c                    | j                   }d}t        |       }t        ||       }| j                  r|sd}|dfS |s| j                  j                  t        d             dt        d   z  }|d   r%|d	d
j                  |j                               z  z  }| j                  |      \  }}}|dk7  r| j                  d|z          |t        |       k7  rd}|dfS )z Update grimoire collections.

    This runs 'scribe update'. Check mode always returns a positive change
    value when 'cache_valid_time' is used.

    FTzwould have updated Codex1SILENTrF   r	   r6   z %s r   zunable to update Codex: r   zsuccessfully updated Codex)r   rD   r0   rG   run_command_environ_updateupdatedictr   r$   keysr   r   )	r   r   rH   r+   freshr@   r   r   r   s	            r   update_codexrU   9  s     ]]FGvEv&EG344--44T5EF$wx'88Jl#echhuzz|&<<<
!'!3!3J!?BQw  %?&%H I
6**566r   c           
         | j                   }|d   }i }d}t        |      dkD  s|d   s|S |d   }| j                  r`t        j                  j                  t        d      }t        j                  j                  t        d      }	 t        j                  ||       n$t        j                  j                  t        d      }t        j                  d	      }|d   j                  d
      D ]h  }	|j                  |	      }
|
s| j                  d|z         |
j                  d      r|
j                  d      dk(  rd}nd}|||
j                  d      <   j |D cg c]  }|j                  d      d    }}t         d   ddj                  |      }| j#                  |      \  }}}|dk7  r| j                  d|z         t%        j&                  |d      }	 	 |D ](  }|j)                  |dz         rd}
|D ]  }	|	j+                  d      }|dk(  rd}nt        j,                  |	|d       }t        j                  t        j,                  |      dt        j,                  |	      d|d      }|j                  |      }
|
s|
j                  d      ||	   k(  r$d||	<   t.        j0                  j3                  |        n |
rt.        j0                  j3                  |       
t.        j0                  j3                  |       + 	 |j5                          |D cg c]
  }||   s	| }}|r=	 t7        |d       5 }|D ]  }|j3                  |d|d||   d!       ! 	 ddd       d"}| j                  r	 t        j8                  |       |S |S # t        $ r | j                  d       Y w xY wc c}w # t        $ r | j                  d       Y w xY w# |j5                          w xY wc c}w # 1 sw Y   xY w# t        $ r | j                  d       Y w xY w# t        $ r | j                  d#       Y |S w xY w)$a   Check for matching dependencies.

    This inspects spell's dependencies with the desired states and returns
    'False' if a recast is needed to match them. It also adds required lines
    to the system-wide depends file for proper recast procedure.

    r7   T   dependsr   zdepends.checkz!failed to copy depends.check filer   zS^(?P<status>\+?|\-){1}(?P<depend>[a-z0-9]+[a-z0-9_\-\+\.]*(\([A-Z0-9_\-\+\.]+\))*)$,z!wrong depends line for spell '%s'status+onoffdepend(r    -q version rO   z!wrong dependencies for spell '%s')inplace:Nr3    z:(?:|z):(?P<lstatus>on|off):optional:lstatuszI/O error on the depends fileaz:optional::
Fz&failed to clean up depends.backup file)r   lenrG   r"   r#   r$   r%   shutilcopy2IOErrorr   r8   r9   splitr;   r<   r   r   	fileinputinput
startswithfindescapesysr   writecloseopenremove)r   r   spellsrX   
depends_okspellsorcery_depends_origsorcery_dependsrA   dr;   rZ   sdepends_listcmd_gazer   r   r   firB   d_offsetd_pvdepends_newflks                             r   match_dependsr   b  s    ]]FF^FGJ
6{QfY/1IE!ww||,=yI'',,'8/J	FLL-? '',,'8)D
**k
lCI$$S) 0		!!Du!LM {{8$H(=(DFF)/H%&0 .55AGGCLO5L5%,V_chh|6LMH++H5B	Qw@5HI	$	7B+(	B %+??53;/ E$ " $%66#;#r>"$C"$))AhiL"9C !jj*,))E*:BIIaL#*O P !$		$ !  %{{95C-1
 #

 0 0 6
 "9"< !

((.JJ$$T*K%+R 	
%414K4	Bos+ Or$ OAHHq'!*MNOO 
	KIIo& :A  	F!DE	F, 6f  	B!@A	B 	
4O O  	B!@A	B  	K!IJ	Ks   N N5B)N: A N: AN: O 
O0(O01P =%O5#P :P" N21N2:OO OO O-5O>:P PP"Q Qc                 V   | j                   }|d   }|d   }t        | d      }|dk(  r|d   dv r|d   dk(  rd}t        |      t        |      z  }nd	}t        |      t        |      z
  }|s
d
d|dd z  fS | j                  r
dd|dd z  fS t        d   d|ddj                  |      }| j                  |      \  }}	}
|dk7  r| j                  d|d|	       dd|dd z  fS | j                  d       y|d   dv rt        |      dkD  r| j                  d       |d   }||v rd
d|z  fS | j                  r
dd|d|fS t        d   d|d|}| j                  |      \  }}	}
|dk7  r| j                  d|d|d|	       dd |d|fS | j                  d!       y)"z Add or remove grimoires. r7   r6   T*state)presentlatestabsentr   ru   addFz all grimoire(s) are already %sedN   zwould have %sed grimoire(s)r	   rO   r   z
failed to z one or more grimoire(s): r   z)successfully %sed one or more grimoire(s)z-unsupported operation on '*' repository value)r   r   rW   z/using multiple items with repository is invalidzgrimoire %s already existszwould have added grimoire z from z add zfailed to add grimoire : zsuccessfully added grimoire z)unsupported operation on repository value)	r   rD   setrG   r   r$   r   r   rg   )r   r   	grimoiresurlr+   actiontodor@   r   r   r   r,   s               r   manage_grimoiresr     s    ]]FvI

Cvt$E
cz'?==g(*!9~E
29~E
2AF2AJNOO  ;fRajHII'.x'8&#((4.QJ!'!3!3J!?BQw  SY[a%b cErPQ
RSS!PQ'?339~!  %V W |H5 ;hFGG  RUVWW070A8SQJ!'!3!3J!?BQw  PXZ]_e%f ghPSTUU!LMr   c                    | j                   }|d   }t        j                  j                  t        d      }|dk(  ri|d   dk(  r	 t        j
                  ||dz          | j                  j                  t        d	
             dt        d   z  }| j                  |      \  }}}|dk7  r| j                  d       	 t        j                  |      j                  }dk7  r`| j                   r	 t        j
                  |dz   |       ydt        d   z  }	| j                  |	      \  }}}|dk7  r| j                  d       yy|d   dk(  rI| j                   rydt        d   z  }| j                  |      \  }}}|dk7  r| j                  d|z          y| j                  d       y8|d   dv rBt        d   dd j                  |      }
| j                  |
      \  }}}|dk7  r$| j                  d!d"j                  |      z         g }g }t#        j$                  d#      }|j'                         d$d% D ]  }|j)                  |      }d&}|d   d'k(  r0|j+                  d(      d)k(  rt-        |        d*}nt-        |       sd*}n|d   dk(  r?|j+                  d+      |j+                  d(      k7  rt-        |        d*}nMt-        |       sBd*}n?|d   dk(  rd*}n4|j+                  d(      d)k7  r |j/                  |j+                  d,             |s|j/                  |j+                  d,              |rZ| j                   ry-t        d   d.d j                  |      }	| j                  |	      \  }}}|dk7  r| j                  d/|z          y0|d   d1k7  ry2|rZ| j                   ry3t        d4   d d j                  |      }| j                  |      \  }}}|dk7  r| j                  d5|z          y6y7y8# t        $ r | j                  d       Y w xY w# t        $ r | j                  d       Y Uw xY w# t        $ r | j                  d       Y yw xY w)9z Cast or dispel spells.

    This manages the whole system ('*'), list or a single spell. Command 'cast'
    is used to install or rebuild spells, while 'dispel' takes care of theirs
    removal from the system.

    r7   zqueue/installr   r   r   z.backupz!failed to backup the update queuer   rL   rM   z%s queuer   r   z#failed to generate the update queuezfailed to read the update queuez"failed to restore the update queue)Tzwould have updated the systemz
%s --queuer
   zfailed to update the system)Tzsuccessfully updated the system)Fz the system is already up to daterebuild)Tzwould have rebuilt the systemz
%s rebuildzfailed to rebuild the system: )Tzsuccessfully rebuilt the systemz'unsupported operation on '*' name value)r   r   r   r   r   r`   rO   z*failed to locate spell(s) in the list (%s)z, zH[^|]+\|[^|]+\|(?P<spell>[^|]+)\|(?P<grim_ver>[^|]+)\|(?P<inst_ver>[^$]+)   r3   Fr   inst_ver-Tgrim_verrx   )Tzwould have cast spell(s)z -c zfailed to cast spell(s): )Tzsuccessfully cast spell(s)r   )Fzspell(s) are already cast)Tzwould have dispelled spell(s)r   zfailed to dispel spell(s): )Tzsuccessfully dispelled spell(s))Fzspell(s) are already dispelledN)r   r"   r#   r$   SORCERY_LOG_DIRrenamerj   r   rP   rQ   rR   r   r   r&   st_sizer(   rG   r8   r9   r:   r;   r<   r   append)r   r   rv   sorcery_queuer   r   r   r   
queue_sizecmd_castr~   
cast_queuedispel_queuerA   rB   r;   r
   
cmd_dispels                     r   manage_spellsr     s    ]]FF^FGGLL/BM}'?h&J		-)BC
 --44T5EF$wy'99K!'!3!3K!@BQw  %J KHWW]3;;
 Q$$S		-)";]K C''&/9%+%7%7%A"FF7$$)F$G@BG_	)  >&);;K!'!3!3K!@BQw  %E%N O<!JK'?HH-4V_chhv>NOH!'!3!3H!=B Qw  %Q!%6!2&3  4 JL**hiC ))+Ab1 %<		$'?i/{{:.#5%f-#  -V4#'DG_0{{:.%++j2II%f-#  -V4#'DG_	1D {{:.#5$++EKK,@A%%ekk'&:;K%<N $$=)0#((::NO%+%7%7%A"FF7$$)Dv)M$N;H,;$$B(/(9388L;QR
%+%7%7
%C"FF7$$)F)O$P@@i Ii  J  %H IJ  H  %F GH # S((-Q(RBSs6   O0 <P -P4 0PPP10P14QQc                     t        t        t        d ddgdd      t        d d      t        dg d	      t        d 
      t        dd      t        ddgd      t        dd            g dgd      } t        j                         dk7  r| j	                  d       t
        D ]  }| j                  |d      t
        |<    t        dd      | _        | j                  }|d   dv rd|d<   n|d   dv rd|d<   dt        fdt        fdt        fdt        fd}|d   rt        |       |d<   |d    r|d!   rt        |       |d"<   |d#   rt        |       |d$<   |d    r|d!   st        |       |d%<   t        d& |j                         D              rd'}d}nd(}d}| j!                  ||d)z   d*j#                  d+ |j                         D              z   ,       y )-Nrx   r,   liststr)defaultaliasestypeelements)r   r   r   )r   r   r   r
   	dispelledr   )r   choices)r   FboolrU   )r   r   r   r   int)r7   r6   r   rX   rQ   update_cacher   )r7   rQ   r   T)argument_specrequired_one_ofsupports_check_modez/root privileges are required for this operationr   0)PROMPT_DELAYVOYEURr   )r   r
   )r   r   r   )r   r   r+   rv   rQ   r   r7   r6   r   r   r+   rv   c              3   &   K   | ]	  }|d      yw)r   N .0rC   s     r   	<genexpr>zmain.<locals>.<genexpr>  s     
*A1Q4
*   zstate changedzno change in stater   z; c              3   &   K   | ]	  }|d      yw)rW   Nr   r   s     r   r   zmain.<locals>.<genexpr>  s     LlVWQqTLlr   )rH   r   )r   rR   r"   geteuidr   r   get_bin_pathrP   r   r>   rJ   r   rU   r   anyvalues	exit_jsonr$   )r   cr   rH   	state_msgstate_changeds         r   mainr     s   dWj,AY^_Du5y 3] ^&F3en5EFS!!%8	
 << F 
zz|qNO 2((D1
2 )-#c(JF%]]F g--#w	3	3"w 2;R["+	G h+F3	f~&./7n'/f~f\2)&1

*)
**#	(	
]	D0@499Ll[b[i[i[kLlCl0lmr   __main__)F)
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESRETURNr    rl   r"   r8   rh   rq   ansible.module_utils.basicr   r   r   r%   r>   r   r0   rD   rJ   rU   r   r   r   r   __name__r   r   r   <module>r      s    A @M`Xv
   	 	  
 4
  %( 

4B98&7R{|8Nv[A|;n| zF r   