_borg 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. #compdef borg
  2. # -------
  3. #
  4. # To Install:
  5. #
  6. # Copy this file to /usr/[local]/share/zsh/site-functions/
  7. #
  8. # -------
  9. # borgbackup ZSH completion
  10. # Kevin Gravier 2017 <kevin@mrkmg.com>
  11. #
  12. # The MIT License (MIT)
  13. # Copyright (c) 2017 Kevin
  14. # Permission is hereby granted, free of charge, to any person obtaining a copy
  15. # of this software and associated documentation files (the "Software"), to deal
  16. # in the Software without restriction, including without limitation the rights
  17. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  18. # copies of the Software, and to permit persons to whom the Software is
  19. # furnished to do so, subject to the following conditions:
  20. # The above copyright notice and this permission notice shall be included in all
  21. # copies or substantial portions of the Software.
  22. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  23. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  24. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  25. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  26. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  27. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  28. # SOFTWARE.
  29. _borg() {
  30. typeset -A opt_args
  31. local -a borg_possible_commands borg_possible_key_commands commands keyCommands borg_common_options
  32. local command keyCommand item subItem
  33. borg_common_options=({-h,--help}'[show this help message and exit]'
  34. --critical'[work on log level CRITICAL]'
  35. --error'[work on log level ERROR]'
  36. --warning'[work on log level WARNING (default)]'
  37. {--info,-v,--verbose}'[work on log level INFO]'
  38. --debug'[work on log level DEBUG]'
  39. --default-topic'[enable TOPIC debugging (can be specified multiple times).]:TOPIC'
  40. {-p,--progress}'[show progress information]'
  41. --log-json'[Output one JSON object per log line instead of formatted text.]'
  42. --lock-wait'[wait at most SECONDS for acquiring a repository/cache lock (default: 1).]:SECONDS'
  43. --show-version'[show/log the borg version]'
  44. --show-rc'[show/log the return code (rc)]'
  45. --umask'[set umask to M (local and remote, default: 0077)]:umask'
  46. --remote-path'[set remote path to executable (default: "borg")]:_files'
  47. --remote-ratelimit'[set remote network upload rate limit in kiByte/s (default: 0=unlimited)]:RATE'
  48. --consider-part-files'[treat part files like normal files (e.g. to list/extract them)]'
  49. --debug-profile'[write execution profile in Borg format into FILE.]:_files'
  50. --rsh'[use COMMAND instead of ssh]:COMMAND')
  51. borg_possible_commands=(init create extract check rename list diff delete prune compact info mount umount key upgrade recreate export-tar serve config with-lock break-lock benchmark help)
  52. borg_possible_key_commands=(change-passphrase import export)
  53. command=""
  54. keyCommand=""
  55. for item in $words; do
  56. (( ${borg_possible_commands[(I)$item]} )) && command=$item
  57. (( ${borg_possible_key_commands[(I)$item]} )) && keyCommand=$item
  58. done
  59. case $command in
  60. (init)
  61. _arguments \
  62. '2:repo:_files'\
  63. {-e,--encryption}'[select encryption key mode]:mode:(none keyfile keyfile-blake2 repokey repokey-blake2 authenticated authenticated-blake2)'\
  64. --append-only'[only allow appending to repository segment files]'\
  65. --storage-quota'[Override storage quota of the repository]:QUOTA'\
  66. --make-parent-dirs'[create parent directories]'\
  67. $borg_common_options
  68. ;;
  69. (create)
  70. _arguments \
  71. '2:archives:__borg_archive'\
  72. '3:path:_files'\
  73. {-n,--dry-run}'[do not create a backup archive]'\
  74. {-s,--stats}'[print statistics for the created archive]'\
  75. --list'[output verbose list of items (files, dirs, ...)]'\
  76. --filter'[only display items with the given status characters]:STATUSCHARS'\
  77. --json'[output stats as JSON. Implies --stats.]'\
  78. --no-cache-sync'[experimental: do not synchronize the cache. Implies not using the files cache.]'\
  79. --stdin-name'[use NAME in archive for stdin data]:NAME'\
  80. {-e,--exclude}'[exclude paths matching PATTERN]:PATTERN'\
  81. --exclude-from'[read exclude patterns from EXCLUDEFILE, one per line]:_files'\
  82. --pattern'[experimental: include/exclude paths matching PATTERN]:PATTERN'\
  83. --patterns-from'[experimental: read include/exclude patterns from PATTERNFILE, one per line]:_files'\
  84. --exclude-caches'[exclude directories that contain a CACHEDIR.TAG file ]'\
  85. --exclude-if-present'[exclude directories that are tagged by containing a filesystem object with the given NAME]:NAME'\
  86. --keep-exclude-tags'[if tag objects are specified with --exclude-if-present, don’t omit the tag objects themselves]'\
  87. {-x,--one-file-system}'[stay in the same file system ]'\
  88. --numeric-owner'[only store numeric user and group identifiers]'\
  89. --noatime'[do not store atime into archive]'\
  90. --nobirthtime'[do not store birthtime (creation date) into archive]'\
  91. --nobsdflags'[do not read and store bsdflags (e.g. NODUMP, IMMUTABLE) into archive]'\
  92. --noflags'[do not read and store flags (e.g. NODUMP, IMMUTABLE) into archive]'\
  93. --files-cache'[operate files cache in MODE. default: ctime,size,inode]:mode:(ctime,size,inode mtime,size,inode ctime,size mtime,size rechunk,ctime rechunk,mtime disabled)'\
  94. --read-special'[open and read block and char device files as well as FIFOs as if they were regular files.]'\
  95. --comment'[add a comment text to the archive]:COMMENT'\
  96. --timestamp'[manually specify the archive creation date/time]:TIMESTAMP'\
  97. --timestamp'[manually specify the archive creation date/time by a reference file/directory]:_files'\
  98. {-c,--checkpoint-interval}'[write checkpoint every SECONDS seconds]:SECONDS'\
  99. --chunker-params'[specify the chunker parameters]:PARAMS'\
  100. {-C,--compression}'[select compression algorithm]:COMPRESSION'\
  101. $borg_common_options
  102. ;;
  103. (extract)
  104. _arguments \
  105. '2:archives:__borg_archive'\
  106. '3:path:_files'\
  107. --list'[output verbose list of items (files, dirs, ...)]'\
  108. {-n,--dry-run}'[do not actually change any files]'\
  109. --numeric-owner'[only obey numeric user and group identifiers]'\
  110. --nobsdflags'[do not extract/set bsdflags (e.g. NODUMP, IMMUTABLE)]'\
  111. --noflags'[do not extract/set flags (e.g. NODUMP, IMMUTABLE)]'\
  112. --stdout'[write all extracted data to stdout]'\
  113. --sparse'[create holes in output sparse file from all-zero chunks]'\
  114. {-e,--exclude}'[exclude paths matching PATTERN]:PATTERN'\
  115. --exclude-from'[read exclude patterns from EXCLUDEFILE, one per line]:_files'\
  116. --pattern'[experimental: include/exclude paths matching PATTERN]:PATTERN'\
  117. --patterns-from'[experimental: read include/exclude patterns from PATTERNFILE, one per line]:_files'\
  118. --strip-components'[Remove the specified number of leading path elements. Paths with fewer elements will be silently skipped.]:NUMBER'\
  119. $borg_common_options
  120. ;;
  121. (check)
  122. _arguments \
  123. '2:archives:__borg_archive'\
  124. --repository-only'[only perform repository checks]'\
  125. --archives-only'[only perform archives checks]'\
  126. --verify-data'[perform cryptographic archive data integrity verification]'\
  127. --repair'[attempt to repair any inconsistencies found]'\
  128. --save-space'[work slower, but using less space]'\
  129. --max-duration'[partial repo check for max. SECONDS]:SECONDS'\
  130. {-P,--prefix}'[only consider archive names starting with this prefix.]:PREFIX'\
  131. {-a,--glob-archives}'[only consider archive names matching the glob]:GLOB'\
  132. --sort-by'[Comma-separated list of sorting keys]:keys:(timestamp name id)'\
  133. --first'[consider first N archives after other filters were applied]:N'\
  134. --last'[consider last N archives after other filters were applied]:N'\
  135. $borg_common_options
  136. ;;
  137. (rename)
  138. _arguments \
  139. '2:archives:__borg_archive'\
  140. '3:name:NAME'\
  141. $borg_common_options
  142. ;;
  143. (list)
  144. _arguments \
  145. '2:archives:__borg_archive'\
  146. '*:path:_files'\
  147. --short'[only print file/directory names, nothing else]'\
  148. --format'[specify format for file listing]:FORMAT'\
  149. --json'[Only valid for listing repository contents. Format output as JSON.]'\
  150. --json-lines'[Only valid for listing archive contents. Format output as JSON Lines. ]'\
  151. {-P,--prefix}'[only consider archive names starting with this prefix.]:PREFIX'\
  152. {-a,--glob-archives}'[only consider archive names matching the glob]:GLOB'\
  153. --sort-by'[Comma-separated list of sorting keys]:keys:(timestamp name id)'\
  154. --first'[consider first N archives after other filters were applied]:N'\
  155. --last'[consider last N archives after other filters were applied]:N'\
  156. {-e,--exclude}'[exclude paths matching PATTERN]:PATTERN'\
  157. --exclude-from'[read exclude patterns from EXCLUDEFILE, one per line]:_files'\
  158. --pattern'[experimental: include/exclude paths matching PATTERN]:PATTERN'\
  159. --patterns-from'[experimental: read include/exclude patterns from PATTERNFILE, one per line]:_files'\
  160. $borg_common_options
  161. ;;
  162. (diff)
  163. _arguments \
  164. '2:archives:__borg_archive'\
  165. '3:archives:__borg_archive2'\
  166. '*:path:_files'\
  167. --numeric-owner'[only obey numeric user and group identifiers]'\
  168. --same-chunker-params'[override check of chunker parameters.]'\
  169. --sort'[sort the output lines by file path.]'\
  170. {-e,--exclude}'[exclude paths matching PATTERN]:PATTERN'\
  171. --exclude-from'[read exclude patterns from EXCLUDEFILE, one per line]:_files'\
  172. --pattern'[experimental: include/exclude paths matching PATTERN]:PATTERN'\
  173. --patterns-from'[experimental: read include/exclude patterns from PATTERNFILE, one per line]:_files'\
  174. $borg_common_options
  175. ;;
  176. (delete)
  177. _arguments \
  178. '2:archives:__borg_archive'\
  179. '*:archives:archives'\
  180. --dry-run'[do not change the repository]'\
  181. {-s,--stats}'[print statistics for the deleted archive]'\
  182. --cache-only'[delete only the local cache for the given repository]'\
  183. --force'[force deletion of corrupted archives, use --force --force in case --force does not work.]'\
  184. --save-space'[work slower, but using less space]'\
  185. {-P,--prefix}'[only consider archive names starting with this prefix.]:PREFIX'\
  186. {-a,--glob-archives}'[only consider archive names matching the glob]:GLOB'\
  187. --sort-by'[Comma-separated list of sorting keys]:keys:(timestamp name id)'\
  188. --first'[consider first N archives after other filters were applied]:N'\
  189. --last'[consider last N archives after other filters were applied]:N'\
  190. $borg_common_options
  191. ;;
  192. (prune)
  193. _arguments \
  194. '2:archives:__borg_archive'\
  195. {-n,--dry-run}'[do not change repository]'\
  196. --force'[force pruning of corrupted archives]'\
  197. {-s,--stats}'[print statistics for the deleted archive]'\
  198. --list'[output verbose list of archives it keeps/prunes]'\
  199. --keep-within'[keep all archives within this time interval]:INTERVAL'\
  200. {--keep-last,--keep-secondly}'[number of secondly archives to keep]:N'\
  201. --keep-minutely'[number of minutely archives to keep]:N'\
  202. {-H,--keep-hourly}'[number of hourly archives to keep]:N'\
  203. {-d,--keep-daily}'[number of daily archives to keep]:N'\
  204. {-w,--keep-weekly}'[number of weekly archives to keep]:N'\
  205. {-m,--keep-monthly}'[number of monthly archives to keep]:N'\
  206. {-y,--keep-yearly}'[number of yearly archives to keep]:N'\
  207. --save-space'[work slower, but using less space]'\
  208. {-P,--prefix}'[only consider archive names starting with this prefix.]:PREFIX'\
  209. {-a,--glob-archives}'[only consider archive names matching the glob]:GLOB'\
  210. $borg_common_options
  211. ;;
  212. (compact)
  213. _arguments \
  214. '2:archives:__borg_archive'\
  215. --cleanup-commits'[cleanup commit-only 17-byte segment files]'\
  216. $borg_common_options
  217. ;;
  218. (info)
  219. _arguments \
  220. '2:archives:__borg_archive'\
  221. --json'[format output as JSON]'\
  222. {-P,--prefix}'[only consider archive names starting with this prefix.]:PREFIX'\
  223. {-a,--glob-archives}'[only consider archive names matching the glob]:GLOB'\
  224. --sort-by'[Comma-separated list of sorting keys]:keys:(timestamp name id)'\
  225. --first'[consider first N archives after other filters were applied]:N'\
  226. --last'[consider last N archives after other filters were applied]:N'\
  227. $borg_common_options
  228. ;;
  229. (mount)
  230. _arguments \
  231. '2:archives:__borg_archive'\
  232. '3:mountpoint:_files'\
  233. {-f,--foreground}'[stay in foreground, do not daemonize]'\
  234. -o'[Extra mount options]:options:(ac_attr_timeout= allow_damaged_files allow_other allow_root attr_timeout= auto auto_cache auto_unmount default_permissions entry_timeout= gid= group_id= kernel_cache max_read= negative_timeout= noauto noforget remember= remount rootmode= uid= umask= user user_id= versions)'\
  235. {-P,--prefix}'[only consider archive names starting with this prefix.]:PREFIX'\
  236. {-a,--glob-archives}'[only consider archive names matching the glob]:GLOB'\
  237. --sort-by'[Comma-separated list of sorting keys]:keys:(timestamp name id)'\
  238. --first'[consider first N archives after other filters were applied]:N'\
  239. --last'[consider last N archives after other filters were applied]:N'\
  240. {-e,--exclude}'[exclude paths matching PATTERN]:PATTERN'\
  241. --exclude-from'[read exclude patterns from EXCLUDEFILE, one per line]:_files'\
  242. --pattern'[experimental: include/exclude paths matching PATTERN]:PATTERN'\
  243. --patterns-from'[experimental: read include/exclude patterns from PATTERNFILE, one per line]:_files'\
  244. --strip-components'[Remove the specified number of leading path elements. Paths with fewer elements will be silently skipped.]:NUMBER'\
  245. $borg_common_options
  246. ;;
  247. (umount)
  248. _arguments \
  249. '2:mountpoint:_files'\
  250. $borg_common_options
  251. ;;
  252. (key)
  253. case $keyCommand in
  254. (change-passphrase)
  255. _arguments \
  256. '2:subCommand:(change-passphrase import export)'\
  257. '3:archives:__borg_archive'\
  258. $borg_common_options
  259. ;;
  260. (export)
  261. _arguments \
  262. '2:subCommand:(change-passphrase import export)'\
  263. '3:archives:__borg_archive'\
  264. '4:path:_files'\
  265. --paper'[Create an export suitable for printing and later type-in]'\
  266. --qr-html'[Create an html file suitable for printing and later type-in or qr scan]'\
  267. $borg_common_options
  268. ;;
  269. (import)
  270. _arguments \
  271. '2:subCommand:(change-passphrase import export)'\
  272. '3:archives:__borg_archive'\
  273. '4:path:_files'\
  274. --paper'[interactively import from a backup done with --paper]'\
  275. $borg_common_options
  276. ;;
  277. *)
  278. _arguments \
  279. '2:subCommand:(change-passphrase import export)'\
  280. $borg_common_options
  281. ;;
  282. esac
  283. ;;
  284. (upgrade)
  285. _arguments \
  286. '2:archives:__borg_archive'\
  287. {-n,--dry-run}'[do not change repository]'\
  288. --inplace'[rewrite repository in place, with no chance of going back to older versions of the repository.]'\
  289. --force'[Force upgrade]'\
  290. --tam'[Enable manifest authentication (in key and cache).]'\
  291. --disable-tam'[Disable manifest authentication (in key and cache).]'\
  292. $borg_common_options
  293. ;;
  294. (recreate)
  295. _arguments \
  296. '2:archives:__borg_archive'\
  297. '3:path:_files'\
  298. --list'[output verbose list of items (files, dirs, ...)]'\
  299. --filter'[only display items with the given status characters]:STATUSCHARS'\
  300. {-n,--dry-run}'[do not create a backup archive]'\
  301. {-s,--stats}'[print statistics at end]'\
  302. {-e,--exclude}'[exclude paths matching PATTERN]:PATTERN'\
  303. --exclude-from'[read exclude patterns from EXCLUDEFILE, one per line]:_files'\
  304. --pattern'[experimental: include/exclude paths matching PATTERN]:PATTERN'\
  305. --patterns-from'[experimental: read include/exclude patterns from PATTERNFILE, one per line]:_files'\
  306. --exclude-caches'[exclude directories that contain a CACHEDIR.TAG file ]'\
  307. --exclude-if-present'[exclude directories that are tagged by containing a filesystem object with the given NAME]:NAME'\
  308. --keep-exclude-tags'[if tag objects are specified with --exclude-if-present, don’t omit the tag objects themselves]'\
  309. --target'[create a new archive with the name ARCHIVE]:ARCHIVE'\
  310. {-c,--checkpoint-interval}'[write checkpoint every SECONDS seconds]:SECONDS'\
  311. --comment'[add a comment text to the archive]:COMMENT'\
  312. --timestamp'[manually specify the archive creation date/time]:TIMESTAMP'\
  313. {-C,--compression}'[select compression algorithm]:COMPRESSION'\
  314. --recompress'[recompress data chunks according to --compression if if-different]:params:(if-different always)'\
  315. --chunker-params'[pecify the chunker parameters]:PARAMS'\
  316. $borg_common_options
  317. ;;
  318. (export-tar)
  319. _arguments \
  320. '2:archives:__borg_archive'\
  321. '3:tar:_files'\
  322. '4:path:_files'\
  323. --tar-filter'[filter program to pipe data through]'\
  324. --list'[output verbose list of items (files, dirs, ...)]'\
  325. {-e,--exclude}'[exclude paths matching PATTERN]:PATTERN'\
  326. --exclude-from'[read exclude patterns from EXCLUDEFILE, one per line]:_files'\
  327. --pattern'[experimental: include/exclude paths matching PATTERN]:PATTERN'\
  328. --patterns-from'[experimental: read include/exclude patterns from PATTERNFILE, one per line]:_files'\
  329. --strip-components'[Remove the specified number of leading path elements. Paths with fewer elements will be silently skipped.]:NUMBER'\
  330. $borg_common_options
  331. ;;
  332. (serve)
  333. _arguments \
  334. --restrict-to-path'[restrict repository access to PATH]:_files'\
  335. --restrict-to-repository'[restrict repository access]:_files'\
  336. --append-only'[only allow appending to repository segment files]'\
  337. --storage-quota'[Override storage quota of the repository]:QUOTA'\
  338. $borg_common_options
  339. ;;
  340. (config)
  341. _arguments \
  342. '2:archives:__borg_archive'\
  343. '3:name:NAME'\
  344. '4:value:VALUE'\
  345. {-c,--cache}'[get and set values from the repo cache]'\
  346. {-d,--delete}'[delete the key from the config]'\
  347. --list'[list the configuration of the repo]'\
  348. $borg_common_options
  349. ;;
  350. (with-lock)
  351. _arguments \
  352. '(-)2:archives:__borg_archive'\
  353. $borg_common_options
  354. #'3:command:_command_names -e'\
  355. #'4:arguments:_normal'
  356. #TODO Debug this, getting "_tags:comptags:36: nesting level too deep" error
  357. ;;
  358. (break-lock)
  359. _arguments \
  360. '2:archives:__borg_archive'\
  361. $borg_common_options
  362. ;;
  363. (benchmark)
  364. _arguments \
  365. '2:type:(crud)'\
  366. '3:repo:_files'\
  367. '4:path:_files'\
  368. $borg_common_options
  369. ;;
  370. (help)
  371. _arguments \
  372. '2:type:(patterns placeholders compression )'\
  373. $borg_common_options
  374. ;;
  375. *)
  376. commands=(
  377. 'init:initialize empty repository'
  378. 'create:create backup'
  379. 'extract:extract archive contents'
  380. 'check:verify repository'
  381. 'rename:rename archive'
  382. 'list:list archive or repository contents'
  383. 'diff:find differences in archive contents'
  384. 'delete:delete archive'
  385. 'prune:prune archives'
  386. 'compact:free repository space'
  387. 'info:show repository or archive information'
  388. 'mount:mount repository'
  389. 'umount:umount repository'
  390. 'key:manage repository key'
  391. 'upgrade:upgrade repository format'
  392. 'recreate:recreate contents of existing archives'
  393. 'export-tar:create tarball from archive'
  394. 'serve:start repository server process'
  395. 'config:get/set options in repo/cache config'
  396. 'with-lock:run user command with lock held'
  397. 'break-lock:break repository and cache locks'
  398. 'benchmark:benchmark command'
  399. 'help:miscellaneous help'
  400. )
  401. _describe 'values' commands
  402. _arguments $borg_common_options
  403. ;;
  404. esac
  405. }
  406. __borg_archive() {
  407. __borg_list_archives 1
  408. }
  409. __borg_archive2() {
  410. __borg_list_archives 2
  411. }
  412. __borg_list_archives() {
  413. local -a items
  414. local cpath
  415. cpath=`expr match "${words}" "\(.*\)::"`
  416. cpath=${cpath##* }
  417. if (( $1 == 1 )); then
  418. # To achieve "repository::archive" listing:
  419. prefix_repo="${cpath}::"
  420. fi
  421. if (( $1 == 2 )); then
  422. # To achieve only "archive" listing:
  423. prefix_repo=
  424. fi
  425. items=("${(@f)$(borg list --format=$prefix_repo\{archive\}\{NEWLINE\} $cpath 2>/dev/null)}")
  426. if [[ $items[1] == "" ]]; then
  427. _files -/
  428. else
  429. _wanted archives expl 'archive' compadd $items
  430. fi
  431. }