1""" 2Subversion SCM 3""" 4 5import re 6 7import salt.utils.args 8import salt.utils.path 9from salt.exceptions import CommandExecutionError 10 11_INI_RE = re.compile(r"^([^:]+):\s+(\S.*)$", re.M) 12 13 14def __virtual__(): 15 """ 16 Only load if svn is installed 17 """ 18 if salt.utils.path.which("svn") is None: 19 return (False, "The svn execution module cannot be loaded: svn unavailable.") 20 else: 21 return True 22 23 24def _run_svn(cmd, cwd, user, username, password, opts, **kwargs): 25 """ 26 Execute svn 27 return the output of the command 28 29 cmd 30 The command to run. 31 32 cwd 33 The path to the Subversion repository 34 35 user 36 Run svn as a user other than what the minion runs as 37 38 username 39 Connect to the Subversion server as another user 40 41 password 42 Connect to the Subversion server with this password 43 44 .. versionadded:: 0.17.0 45 46 opts 47 Any additional options to add to the command line 48 49 kwargs 50 Additional options to pass to the run-cmd 51 """ 52 cmd = ["svn", "--non-interactive", cmd] 53 54 options = list(opts) 55 if username: 56 options.extend(["--username", username]) 57 if password: 58 options.extend(["--password", password]) 59 cmd.extend(options) 60 61 result = __salt__["cmd.run_all"]( 62 cmd, python_shell=False, cwd=cwd, runas=user, **kwargs 63 ) 64 65 retcode = result["retcode"] 66 67 if retcode == 0: 68 return result["stdout"] 69 raise CommandExecutionError(result["stderr"] + "\n\n" + " ".join(cmd)) 70 71 72def info(cwd, targets=None, user=None, username=None, password=None, fmt="str"): 73 """ 74 Display the Subversion information from the checkout. 75 76 cwd 77 The path to the Subversion repository 78 79 targets : None 80 files, directories, and URLs to pass to the command as arguments 81 svn uses '.' by default 82 83 user : None 84 Run svn as a user other than what the minion runs as 85 86 username : None 87 Connect to the Subversion server as another user 88 89 password : None 90 Connect to the Subversion server with this password 91 92 .. versionadded:: 0.17.0 93 94 fmt : str 95 How to fmt the output from info. 96 (str, xml, list, dict) 97 98 CLI Example: 99 100 .. code-block:: bash 101 102 salt '*' svn.info /path/to/svn/repo 103 """ 104 opts = list() 105 if fmt == "xml": 106 opts.append("--xml") 107 if targets: 108 opts += salt.utils.args.shlex_split(targets) 109 infos = _run_svn("info", cwd, user, username, password, opts) 110 111 if fmt in ("str", "xml"): 112 return infos 113 114 info_list = [] 115 for infosplit in infos.split("\n\n"): 116 info_list.append(_INI_RE.findall(infosplit)) 117 118 if fmt == "list": 119 return info_list 120 if fmt == "dict": 121 return [dict(tmp) for tmp in info_list] 122 123 124def checkout(cwd, remote, target=None, user=None, username=None, password=None, *opts): 125 """ 126 Download a working copy of the remote Subversion repository 127 directory or file 128 129 cwd 130 The path to the Subversion repository 131 132 remote : None 133 URL to checkout 134 135 target : None 136 The name to give the file or directory working copy 137 Default: svn uses the remote basename 138 139 user : None 140 Run svn as a user other than what the minion runs as 141 142 username : None 143 Connect to the Subversion server as another user 144 145 password : None 146 Connect to the Subversion server with this password 147 148 .. versionadded:: 0.17.0 149 150 CLI Example: 151 152 .. code-block:: bash 153 154 salt '*' svn.checkout /path/to/repo svn://remote/repo 155 """ 156 opts += (remote,) 157 if target: 158 opts += (target,) 159 return _run_svn("checkout", cwd, user, username, password, opts) 160 161 162def switch(cwd, remote, target=None, user=None, username=None, password=None, *opts): 163 """ 164 .. versionadded:: 2014.1.0 165 166 Switch a working copy of a remote Subversion repository 167 directory 168 169 cwd 170 The path to the Subversion repository 171 172 remote : None 173 URL to switch 174 175 target : None 176 The name to give the file or directory working copy 177 Default: svn uses the remote basename 178 179 user : None 180 Run svn as a user other than what the minion runs as 181 182 username : None 183 Connect to the Subversion server as another user 184 185 password : None 186 Connect to the Subversion server with this password 187 188 CLI Example: 189 190 .. code-block:: bash 191 192 salt '*' svn.switch /path/to/repo svn://remote/repo 193 """ 194 opts += (remote,) 195 if target: 196 opts += (target,) 197 return _run_svn("switch", cwd, user, username, password, opts) 198 199 200def update(cwd, targets=None, user=None, username=None, password=None, *opts): 201 """ 202 Update the current directory, files, or directories from 203 the remote Subversion repository 204 205 cwd 206 The path to the Subversion repository 207 208 targets : None 209 files and directories to pass to the command as arguments 210 Default: svn uses '.' 211 212 user : None 213 Run svn as a user other than what the minion runs as 214 215 password : None 216 Connect to the Subversion server with this password 217 218 .. versionadded:: 0.17.0 219 220 username : None 221 Connect to the Subversion server as another user 222 223 CLI Example: 224 225 .. code-block:: bash 226 227 salt '*' svn.update /path/to/repo 228 """ 229 if targets: 230 opts += tuple(salt.utils.args.shlex_split(targets)) 231 return _run_svn("update", cwd, user, username, password, opts) 232 233 234def diff(cwd, targets=None, user=None, username=None, password=None, *opts): 235 """ 236 Return the diff of the current directory, files, or directories from 237 the remote Subversion repository 238 239 cwd 240 The path to the Subversion repository 241 242 targets : None 243 files and directories to pass to the command as arguments 244 Default: svn uses '.' 245 246 user : None 247 Run svn as a user other than what the minion runs as 248 249 username : None 250 Connect to the Subversion server as another user 251 252 password : None 253 Connect to the Subversion server with this password 254 255 .. versionadded:: 0.17.0 256 257 CLI Example: 258 259 .. code-block:: bash 260 261 salt '*' svn.diff /path/to/repo 262 """ 263 if targets: 264 opts += tuple(salt.utils.args.shlex_split(targets)) 265 return _run_svn("diff", cwd, user, username, password, opts) 266 267 268def commit(cwd, targets=None, msg=None, user=None, username=None, password=None, *opts): 269 """ 270 Commit the current directory, files, or directories to 271 the remote Subversion repository 272 273 cwd 274 The path to the Subversion repository 275 276 targets : None 277 files and directories to pass to the command as arguments 278 Default: svn uses '.' 279 280 msg : None 281 Message to attach to the commit log 282 283 user : None 284 Run svn as a user other than what the minion runs as 285 286 username : None 287 Connect to the Subversion server as another user 288 289 password : None 290 Connect to the Subversion server with this password 291 292 .. versionadded:: 0.17.0 293 294 CLI Example: 295 296 .. code-block:: bash 297 298 salt '*' svn.commit /path/to/repo 299 """ 300 if msg: 301 opts += ("-m", msg) 302 if targets: 303 opts += tuple(salt.utils.args.shlex_split(targets)) 304 return _run_svn("commit", cwd, user, username, password, opts) 305 306 307def add(cwd, targets, user=None, username=None, password=None, *opts): 308 """ 309 Add files to be tracked by the Subversion working-copy checkout 310 311 cwd 312 The path to the Subversion repository 313 314 targets : None 315 files and directories to pass to the command as arguments 316 317 user : None 318 Run svn as a user other than what the minion runs as 319 320 username : None 321 Connect to the Subversion server as another user 322 323 password : None 324 Connect to the Subversion server with this password 325 326 .. versionadded:: 0.17.0 327 328 CLI Example: 329 330 .. code-block:: bash 331 332 salt '*' svn.add /path/to/repo /path/to/new/file 333 """ 334 if targets: 335 opts += tuple(salt.utils.args.shlex_split(targets)) 336 return _run_svn("add", cwd, user, username, password, opts) 337 338 339def remove(cwd, targets, msg=None, user=None, username=None, password=None, *opts): 340 """ 341 Remove files and directories from the Subversion repository 342 343 cwd 344 The path to the Subversion repository 345 346 targets : None 347 files, directories, and URLs to pass to the command as arguments 348 349 msg : None 350 Message to attach to the commit log 351 352 user : None 353 Run svn as a user other than what the minion runs as 354 355 username : None 356 Connect to the Subversion server as another user 357 358 password : None 359 Connect to the Subversion server with this password 360 361 .. versionadded:: 0.17.0 362 363 CLI Example: 364 365 .. code-block:: bash 366 367 salt '*' svn.remove /path/to/repo /path/to/repo/remove 368 """ 369 if msg: 370 opts += ("-m", msg) 371 if targets: 372 opts += tuple(salt.utils.args.shlex_split(targets)) 373 return _run_svn("remove", cwd, user, username, password, opts) 374 375 376def status(cwd, targets=None, user=None, username=None, password=None, *opts): 377 """ 378 Display the status of the current directory, files, or 379 directories in the Subversion repository 380 381 cwd 382 The path to the Subversion repository 383 384 targets : None 385 files, directories, and URLs to pass to the command as arguments 386 Default: svn uses '.' 387 388 user : None 389 Run svn as a user other than what the minion runs as 390 391 username : None 392 Connect to the Subversion server as another user 393 394 password : None 395 Connect to the Subversion server with this password 396 397 .. versionadded:: 0.17.0 398 399 CLI Example: 400 401 .. code-block:: bash 402 403 salt '*' svn.status /path/to/repo 404 """ 405 if targets: 406 opts += tuple(salt.utils.args.shlex_split(targets)) 407 return _run_svn("status", cwd, user, username, password, opts) 408 409 410def export( 411 cwd, 412 remote, 413 target=None, 414 user=None, 415 username=None, 416 password=None, 417 revision="HEAD", 418 *opts 419): 420 """ 421 Create an unversioned copy of a tree. 422 423 cwd 424 The path to the Subversion repository 425 426 remote : None 427 URL and path to file or directory checkout 428 429 target : None 430 The name to give the file or directory working copy 431 Default: svn uses the remote basename 432 433 user : None 434 Run svn as a user other than what the minion runs as 435 436 username : None 437 Connect to the Subversion server as another user 438 439 password : None 440 Connect to the Subversion server with this password 441 442 .. versionadded:: 0.17.0 443 444 CLI Example: 445 446 .. code-block:: bash 447 448 salt '*' svn.export /path/to/repo svn://remote/repo 449 """ 450 opts += (remote,) 451 if target: 452 opts += (target,) 453 revision_args = "-r" 454 opts += ( 455 revision_args, 456 str(revision), 457 ) 458 return _run_svn("export", cwd, user, username, password, opts) 459