_pkg.bash.in
1 #! /usr/bin/env bash 2 ###################################################################### 3 # # 4 # Copyright (c) 2013, Niamkik <niamkik@gmail.com> # 5 # All rights reserved. # 6 # # 7 # Redistribution and use in source and binary forms, with or without # 8 # modification, are permitted provided that the following conditions # 9 # are met: # 10 # # 11 # 1. Redistributions of source code must retain the above copyright # 12 # notice, this list of conditions and the following disclaimer. # 13 # # 14 # 2. Redistributions in binary form must reproduce the above # 15 # copyright notice, this list of conditions and the following # 16 # disclaimer in the documentation and/or other materials provided # 17 # with the distribution. # 18 # # 19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND # 20 # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # 21 # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # 22 # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # 23 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS # 24 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # 25 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED # 26 # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # 27 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON # 28 # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR # 29 # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF # 30 # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # 31 # SUCH DAMAGE. # 32 # # 33 # The views and conclusions contained in the software and # 34 # documentation are those of the authors and should not be # 35 # interpreted as representing official policies, either expressed or # 36 # implied, of the FreeBSD Project. # 37 # # 38 # ================================================================== # 39 # # 40 # Usage: put "source _pkg.bash" into ~/.bashrc or /etc/bash.bashrc. # 41 # # 42 ###################################################################### 43 44 ###################################################################### 45 # Global function (generate dynamic package list e.g.) # 46 ###################################################################### 47 48 _pkg_installed () { 49 %prefix%/sbin/pkg query "%n-%v" 50 } 51 52 _pkg_available_name () { 53 %prefix%/sbin/pkg rquery "%n" 54 } 55 56 _pkg_available () { 57 %prefix%/sbin/pkg rquery "%n-%v" 58 } 59 60 ###################################################################### 61 # pkgng subfunction for pkg subcommand. # 62 ###################################################################### 63 64 _pkgng_add () { 65 local cur prev opts lopts 66 COMPREPLY=() 67 68 opts=() 69 lopts=() 70 71 small_info="Registers a package and installs it on the system" 72 large_info="" 73 } 74 75 _pkgng_audit () { 76 local cur prev opts lopts 77 COMPREPLY=() 78 79 opts=('-F' '-q') 80 lopts=() 81 82 small_info="Reports vulnerable packages" 83 large_info="" 84 } 85 86 _pkgng_autoremove () { 87 local cur prev opts lopts 88 COMPREPLY=() 89 90 opts=() 91 lopts=() 92 small_info="Removes orphan packages" 93 large_info="" 94 } 95 96 _pkgng_check () { 97 local cur prev opts lopts 98 COMPREPLY=() 99 100 opts=('-B' '-d' '-r' '-s' '-v' '-g' '-x' '-X' '-a') 101 lopts=() 102 small_info="Checks for missing dependencies and database consistency" 103 large_info="" 104 } 105 106 _pkgng_clean () { 107 local cur prev opts lopts 108 COMPREPLY=() 109 110 opts=() 111 lopts=() 112 small_info="Cleans old packages from the cache" 113 large_info="" 114 } 115 116 _pkgng_create () { 117 local cur prev opts lopts 118 COMPREPLY=() 119 120 opts=('-r' '-m' '-f' '-l' '-o' '-g' '-x' '-X' '-a') 121 lopts=() 122 small_info="Creates software package distributions" 123 large_info="" 124 } 125 126 _pkgng_delete () { 127 local cur prev opts lopts 128 COMPREPLY=() 129 130 opts=('-y' '-n' '-f' '-g' '-x' '-X' '-a') 131 lopts=() 132 small_info="Deletes packages from the database and the system" 133 large_info="" 134 } 135 136 _pkgng_fetch () { 137 local cur prev opts lopts 138 COMPREPLY=() 139 140 opts=('-y' '-L' '-q' '-g' '-x' '-X' '-a') 141 lopts=() 142 small_info="Fetches packages from a remote repository" 143 large_info="" 144 } 145 146 _pkgng_help () { 147 local cur prev opts lopts 148 COMPREPLY=() 149 150 opts=() 151 lopts=() 152 small_info="Displays help information" 153 large_info="" 154 } 155 156 _pkgng_info () { 157 local cur prev opts lopts 158 COMPREPLY=() 159 160 opts=('-e' '-d' '-r' '-l' '-o' '-p' '-D' 161 '-f' '-q' '-g' '-x' '-X' '-F' '-a') 162 lopts=() 163 small_info="Displays information about installed packages" 164 large_info="" 165 } 166 167 _pkgng_install () { 168 local cur prev opts lopts 169 COMPREPLY=() 170 171 opts=('-y' '-n' '-f' '-R' '-L' '-x' '-X' '-g') 172 lopts=() 173 small_info="Installs packages from remote package repositories" 174 large_info="" 175 } 176 177 _pkgng_query () { 178 local cur prev opts lopts 179 COMPREPLY=() 180 181 opts=('-g' '-x' '-X' '-F' '-e' '-a') 182 lopts=() 183 small_info="Queries information about installed packages" 184 large_info="" 185 } 186 187 _pkgng_register () { 188 local cur prev opts lopts 189 COMPREPLY=() 190 191 opts=('-l' '-d' '-f' '-m' '-a' '-i') 192 lopts=() 193 small_info="Registers a package into the local database" 194 large_info="" 195 } 196 197 _pkgng_remove () { 198 local cur prev opts lopts 199 COMPREPLY=() 200 201 opts=() 202 lopts=() 203 small_info="Deletes packages from the database and the system" 204 large_info="" 205 } 206 207 _pkgng_repo () { 208 local cur prev opts lopts 209 COMPREPLY=() 210 211 opts=() 212 lopts=() 213 small_info="Creates a package repository catalogue" 214 large_info="" 215 } 216 217 _pkgng_rquery () { 218 local cur prev opts lopts 219 COMPREPLY=() 220 221 opts=('-g' '-x' '-X' '-e' '-a') 222 lopts=() 223 small_info="Queries information in repository catalogues" 224 large_info="" 225 } 226 227 _pkgng_search () { 228 local cur prev opts lopts 229 COMPREPLY=() 230 231 opts=('-x' '-X' '-g') 232 lopts=() 233 small_info="Performs a search of package repository catalogues" 234 large_info="" 235 } 236 237 _pkgng_set () { 238 local cur prev opts lopts 239 COMPREPLY=() 240 241 opts=('-o' '-A' '-y' '-g' '-x' '-X' '-a') 242 lopts=('(-o)-A[Mark as automatic or not]' 243 '(-A)-o[Change the origin]' 244 '-y[Assume yes when asked for confirmation]' 245 '(-g -x -X)-a[Process all packages]' 246 '(-x -X -a)-g[Process packages that match the glob pattern]' 247 '(-g -X -a)-x[Process packages that match the regex pattern]' 248 '(-g -x -a)-X[Process packages that match the extended regex pattern]') 249 250 small_info="Modifies information about packages in the local database" 251 large_info="" 252 } 253 254 _pkgng_shell () { 255 local cur prev opts lopts 256 COMPREPLY=() 257 258 opts=() 259 lopts=('-q[Be quiet]' 260 '(-l)-r[Display stats only for the local package database]' 261 '(-r)-l[Display stats only for the remote package database(s)]') 262 263 small_info="Opens a debug shell" 264 large_info="" 265 } 266 267 _pkgng_shlib () { 268 local cur prev opts lopts 269 COMPREPLY=() 270 271 opts=() 272 lopts=('-f[Force updating]' 273 '-q[Be quiet]') 274 275 small_info="Displays which packages link against a specific shared library" 276 large_info="" 277 } 278 279 _pkgng_stats () { 280 local cur prev opts lopts 281 COMPREPLY=() 282 283 opts=() 284 lopts=() 285 small_info="Displays package database statistics" 286 large_info="" 287 } 288 289 _pkgng_update () { 290 local cur prev opts lopts 291 COMPREPLY=() 292 293 opts=() 294 lopts=() 295 small_info="Updates package repository catalogues" 296 large_info="" 297 } 298 299 _pkgng_updating () { 300 local cur prev opts lopts 301 COMPREPLY=() 302 303 opts=() 304 lopts=() 305 small_info="Displays UPDATING information for a package" 306 large_info="" 307 } 308 309 _pkgng_upgrade () { 310 local cur prev opts lopts 311 COMPREPLY=() 312 313 opts=() 314 lopts=() 315 small_info="Performs upgrades of packaged software distributions" 316 large_info="" 317 } 318 319 _pkgng_version () { 320 local cur prev opts lopts 321 COMPREPLY=() 322 323 opts=() 324 lopts=('(-P -R)-I[Use INDEX file]' 325 '(-R -I)-P[Force checking against the ports tree]' 326 '(-I -P)-R[Use remote repository]' 327 '-o[Display package origin, instead of package name]' 328 '-q[Be quiet]' 329 '-v[Be verbose]' 330 '(-L)-l[Display only the packages for given status flag]' 331 '(-l)-L[Display only the packages without given status flag]') 332 333 small_info="Displays the versions of installed packages" 334 large_info="" 335 } 336 337 _pkgng_which () { 338 local cur prev opts lopts 339 COMPREPLY=() 340 341 opts=() 342 lopts=() 343 small_info="Displays which package installed a specific file" 344 large_info="" 345 } 346 347 ###################################################################### 348 # Main function for completion, only for "pkg" command. Other # 349 # subcommand use function like _pkgng_[subfunction]. # 350 ###################################################################### 351 352 _pkg () { 353 354 local cur prev opts lopts 355 COMPREPLY=() 356 357 # get command name 358 cur="${COMP_WORDS[COMP_CWORD]}" 359 360 # get first arguments 361 prev="${COMP_WORDS[COMP_CWORD-1]}" 362 363 # init opts for first completion 364 opts='add audit autoremove check clean create delete 365 fetch help info install query rquery search set shell 366 shlib stats update updating upgrade version which' 367 368 # init lopts for second completion with details 369 lopts=( 'add[Registers a package and installs it on the system]' 370 'audit[Reports vulnerable packages]' 371 'autoremove[Removes orphan packages]' 372 'check[Checks for missing dependencies and database consistency]' 373 'clean[Cleans old packages from the cache]' 374 'convert[Convert database from/to pkgng]' 375 'create[Creates software package distributions]' 376 'delete[Deletes packages from the database and the system]' 377 'fetch[Fetches packages from a remote repository]' 378 'help[Displays help information]' 379 'info[Displays information about installed packages]' 380 'install[Installs packages from remote package repositories]' 381 'query[Queries information about installed packages]' 382 'register[Registers a package into the local database]' 383 'remove[Deletes packages from the database and the system]' 384 'repo[Creates a package repository catalogue]' 385 'rquery[Queries information in repository catalogues]' 386 'search[Performs a search of package repository catalogues]' 387 'set[Modifies information about packages in the local database]' 388 'shell[Opens a debug shell]' 389 'shlib[Displays which packages link against a specific shared library]' 390 'stats[Displays package database statistics]' 391 'update[Updates package repository catalogues]' 392 'updating[Displays UPDATING information for a package]' 393 'upgrade[Performs upgrades of packaged software distributions]' 394 'version[Displays the versions of installed packages]' 395 'which[Displays which package installed a specific file]' ) 396 397 # switch on second arguments 398 case "${prev}" in 399 400 add) 401 COMPREPLY=( $(compgen -A file *.t?z ) ) && \ 402 return 0 403 ;; 404 405 audit) 406 COMPREPLY=( 407 '-F[Fetch the database before checking.]' 408 '-q[Quiet]' 409 $(compgen -F _pkg_installed) 410 ) 411 return 0 412 ;; 413 414 autoremove) 415 COMPREPLY=( $(compgen) ) && \ 416 return 0 ;; 417 418 check) 419 COMPREPLY=( 420 '-B[reanalyse the shared libraries]' 421 '-d[check for and install missing dependencies]' 422 '-r[recompute sizes and checksums of installed]' 423 '-s[find invalid checksums]' 424 '-v[Be verbose]' 425 '(-g -x -X)-a[Process all packages]' 426 '(-x -X -a)-g[Process packages that match the glob pattern]' 427 '(-g -X -a)-x[Process packages that match the regex pattern]' 428 '(-g -x -a)-X[Process packages that match the extended regex pattern]' 429 ) 430 return 0 431 ;; 432 433 clean) 434 return 0 ;; 435 436 convert) 437 # _arguments -s \ 438 # '-r[Revert conversion]' \ 439 # return 0 440 return 0;; 441 442 create) 443 COMPREPLY=( 444 '-r[Root directory] -/' 445 '-m[Manifest directory] -/' 446 '-f[format]' 447 '-o[Ouput directory] -/' 448 '(-g -x -X)-a[Process all packages]' 449 '(-x -X -a)-g[Process packages that match the glob pattern]' 450 '(-g -X -a)-x[Process packages that match the regex pattern]' 451 '(-g -x -a)-X[Process packages that match the extended regex pattern]' 452 '*:Package:_pkg_installed' 453 ) 454 return 0 455 ;; 456 457 delete|remove) 458 COMPREPLY=( 459 '(-y)-n[Assume yes when asked for confirmation]' 460 '(-n)-y[Assume no (dry run) when asked for confirmation]' 461 '-f[Force the package(s) to be removed]' 462 '(-g -x -X)-a[Process all packages]' 463 '(-x -X -a)-g[Process packages that match the glob pattern]' 464 '(-g -X -a)-x[Process packages that match the regex pattern]' 465 '(-g -x -a)-X[Process packages that match the extended regex pattern]' 466 '*:Package:_pkg_installed' 467 ) 468 return 0 469 ;; 470 471 fetch) 472 COMPREPLY=( 473 '-y[Assume yes when asked for confirmation]' 474 '-L[Do not try to update the repository metadata]' 475 '-q[Be quiet]' 476 '(-g -x -X)-a[Process all packages]' 477 '(-x -X -a)-g[Process packages that match the glob pattern]' 478 '(-g -X -a)-x[Process packages that match the regex pattern]' 479 '(-g -x -a)-X[Process packages that match the extended regex pattern]' 480 '*:Available packages:_pkg_available' 481 ) 482 return 0 483 ;; 484 485 help) 486 COMPREPLY=() && \ 487 return 0 ;; 488 489 info) 490 COMPREPLY=( 491 '(-e -d -r -l -o -p -D)-f[Displays full information]' 492 '(-f -d -r -l -o -p -D)-e[Returns 0 if <pkg-name> is installed]' 493 '(-e -f -r -l -o -p -D)-d[Displays the dependencies]' 494 '(-e -d -f -l -o -p -D)-r[Displays the reverse dependencies]' 495 '(-e -d -r -f -o -p -D)-l[Displays all files]' 496 '(-e -d -r -l -f -p -D)-o[Displays origin]' 497 '(-e -d -r -l -o -f -D)-p[Displays prefix]' 498 '(-e -d -r -l -o -p -f)-D[Displays message]' 499 '-q[Be quiet]' 500 '(-g -x -X -F)-a[Process all packages]' 501 '(-x -X -a -F)-g[Process packages that match the glob pattern]' 502 '(-g -X -a -F)-x[Process packages that match the regex pattern]' 503 '(-g -x -a -F)-X[Process packages that match the extended regex pattern]' 504 '(-g -x -X -a)-F[Process the specified package]' 505 '*:Package:_pkg_installed' 506 ) 507 return 0 508 ;; 509 510 install) 511 COMPREPLY=( 512 '(-y)-n[Assume yes when asked for confirmation]' 513 '(-n)-y[Assume no (dry run) when asked for confirmation]' 514 '-f[Force reinstallation if needed]' 515 '-R[Reinstall every package depending on matching expressions]' 516 '-L[Do not try to update the repository metadata]' 517 '(-x -X)-g[Process packages that match the glob pattern]' 518 '(-g -X)-x[Process packages that match the regex pattern]' 519 '(-g -x)-X[Process packages that match the extended regex pattern]' 520 '*:Available packages:_pkg_available' 521 ) 522 return 0 523 ;; 524 525 query) 526 COMPREPLY=( 527 '(-g -x -X -F -e)-a[Process all packages]' 528 '(-x -X -a -F -e)-g[Process packages that match the glob pattern]' 529 '(-g -X -a -F -e)-x[Process packages that match the regex pattern]' 530 '(-g -x -a -F -e)-X[Process packages that match the extended regex pattern]' 531 '(-g -x -X -a -F)-e[Process packages that match the evaluation]' 532 '(-g -x -X -a -e)-F[Process the specified package]' 533 ':Ouput format:' 534 ) 535 return 0 536 ;; 537 538 register) 539 COMPREPLY=( 540 '-l[register as a legacy format]' 541 '-d[mark the package as an automatic dependency]' 542 '-f[packing list file]' 543 '-m[metadata directory]' 544 '-a[ABI]' 545 '-i[input path (aka root directory)]' 546 ) 547 return 0 ;; 548 549 repo) 550 COMPREPLY=() && \ 551 return 0 ;; 552 553 rquery) 554 COMPREPLY=( 555 '(-g -x -X -e)-a[Process all packages]' 556 '(-x -X -a -e)-g[Process packages that match the glob pattern]' 557 '(-g -X -a -e)-x[Process packages that match the regex pattern]' 558 '(-g -x -a -e)-X[Process packages that match the extended regex pattern]' 559 '(-g -x -X -a)-e[Process packages that match the evaluation]' 560 ) 561 return 0 ;; 562 563 search) 564 COMPREPLY=( 565 '(-x -X)-g[Process packages that match the glob pattern]' 566 '(-g -X)-x[Process packages that match the regex pattern]' 567 '(-g -x)-X[Process packages that match the extended regex pattern]' 568 ) 569 return 0 ;; 570 571 set) 572 COMPREPLY=( 573 '(-o)-A[Mark as automatic or not]' 574 '(-A)-o[Change the origin]' 575 '-y[Assume yes when asked for confirmation]' 576 '(-g -x -X)-a[Process all packages]' 577 '(-x -X -a)-g[Process packages that match the glob pattern]' 578 '(-g -X -a)-x[Process packages that match the regex pattern]' 579 '(-g -x -a)-X[Process packages that match the extended regex pattern]' 580 ) 581 return 0 ;; 582 583 shell) 584 COMPREPLY=() && \ 585 return 0 ;; 586 587 shlib) 588 COMPREPLY=() && \ 589 return 0 ;; 590 591 stats) 592 COMPREPLY=( 593 '-q[Be quiet]' 594 '(-l)-r[Display stats only for the local package database]' 595 '(-r)-l[Display stats only for the remote package database(s)]' 596 ) 597 return 0 ;; 598 599 update) 600 COMPREPLY=( 601 '-f[Force update]' 602 '-q[Be quiet]' 603 ) 604 return 0 ;; 605 606 updating) 607 COMPREPLY=( 608 '-d[Only entries newer than date are shown]' 609 '-f[Defines a alternative location of the UPDATING file]' 610 ) 611 return 0 612 ;; 613 614 upgrade) 615 COMPREPLY=( 616 '(-y)-n[Assume no (dry run) when asked for confirmation]' 617 '(-n)-y[Assume yes when asked for confirmation]' 618 '-f[Upgrade/Reinstall everything]' 619 '-L[Do not try to update the repository metadata]' 620 ) 621 return 0 622 ;; 623 624 version) 625 COMPREPLY=( 626 '(-P -R)-I[Use INDEX file]' 627 '(-R -I)-P[Force checking against the ports tree]' 628 '(-I -P)-R[Use remote repository]' 629 '-o[Display package origin, instead of package name]' 630 '-q[Be quiet]' 631 '-v[Be verbose]' 632 '(-L)-l[Display only the packages for given status flag]' 633 '(-l)-L[Display only the packages without given status flag]' 634 ) 635 return 0 636 ;; 637 638 which) 639 COMPREPLY=( $(compgen -W "$(compgen -A file)") ) && \ 640 return 0 641 ;; 642 esac 643 644 # if doesn't exist, return opts 645 COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) 646 } 647 648 complete -F _pkg pkg