Commit 3e2f4c1467d355cce492bde32a2de9ad48564114
1 parent
ec7d9613
Added upload command, made file specifications use a set.
Showing
1 changed file
with
49 additions
and
48 deletions
blimp.nim
| 1 | -import md5, os, osproc, parseopt2, strutils, parsecfg, streams, lapp, subexes, tables | |
| 1 | +import md5, os, osproc, parseopt2, strutils, parsecfg, streams, lapp, subexes, tables, sets | |
| 2 | 2 | |
| 3 | 3 | # blimp is a little utility program for handling large files |
| 4 | 4 | # in git repositories. Its inspired by git-fat and s3annex |
| 5 | 5 | # but doesn't rely on S3 for storage - it uses rsync like git-fat. |
| 6 | 6 | # It is a single binary without any dependencies. |
| 7 | 7 | # |
| 8 | -# Manual use: | |
| 9 | -# | |
| 10 | -# Use "blimp d mybigfile" to deflate it before commit. | |
| 11 | -# Use "blimp i mybigfile" to inflate it back to original size. | |
| 12 | -# | |
| 13 | -# When deflated the file only has: | |
| 14 | -# "blimphash:" <filename> + <an md5sum> | |
| 15 | -# ...inside it. | |
| 16 | -# | |
| 17 | -# The file is copied over to a local dir: | |
| 18 | -# <blimpstore>/<filename>-<md5sum> | |
| 19 | -# | |
| 20 | -# Configuration is in these locations in order: | |
| 21 | -# | |
| 22 | -# ./.blimp.conf | |
| 23 | -# <gitroot>/.blimp.conf | |
| 24 | -# ~/<blimpstore>/.blimp.conf | |
| 25 | -# ~/.blimp.conf | |
| 26 | -# | |
| 27 | -# This way you can have settings per directory, per git clone, | |
| 28 | -# per store and per user. A default blimpstore with a commented .blimp.conf | |
| 29 | -# is created in ~/blimpstore if you run blimp and no .blimp.conf is found. | |
| 8 | +# Just run blimp --help for detailed help. | |
| 30 | 9 | |
| 31 | 10 | const |
| 32 | 11 | versionMajor* = 0 |
| ... | ... | @@ -189,7 +168,7 @@ proc remoteDeleteFile(blimpFilename: string) = |
| 189 | 168 | if errorCode != 0: |
| 190 | 169 | quit("Something went wrong deleting " & blimpFilename & " from " & remoteBlimpStore, 3) |
| 191 | 170 | |
| 192 | -# Copy content to blimpStore, no upload yet. | |
| 171 | +# Copy content to blimpStore and upload if it was a new file or upload == true. | |
| 193 | 172 | proc copyToBlimpStore(filename, blimpFilename: string) = |
| 194 | 173 | if not existsFile(blimpStore / blimpFilename): |
| 195 | 174 | if stdio: |
| ... | ... | @@ -200,6 +179,7 @@ proc copyToBlimpStore(filename, blimpFilename: string) = |
| 200 | 179 | else: |
| 201 | 180 | copyFile(filename, blimpStore / blimpFilename) |
| 202 | 181 | uploadFile(blimpFilename) |
| 182 | + | |
| 203 | 183 | |
| 204 | 184 | # Copy content from blimpStore, and downloading first if needed |
| 205 | 185 | proc copyFromBlimpStore(blimpFilename, filename: string) = |
| ... | ... | @@ -227,7 +207,7 @@ proc blimpFileNameFromString(line: string): string = |
| 227 | 207 | else: |
| 228 | 208 | result = nil |
| 229 | 209 | |
| 230 | -# Pick out blimpFilename (filename & "-" & hash) | |
| 210 | +# Pick out blimpFilename (filename & "-" & hash) or nil | |
| 231 | 211 | proc blimpFileName(filename: string): string = |
| 232 | 212 | if stdio: |
| 233 | 213 | blimpFileNameFromString(stdinContent) |
| ... | ... | @@ -299,6 +279,19 @@ proc remove(filename: string) = |
| 299 | 279 | echo("\t" & filename & " content removed from blimpstore locally and remotely.") |
| 300 | 280 | |
| 301 | 281 | |
| 282 | +# Copy original file to blimpStore and replace with hash stub in git. | |
| 283 | +proc upload(filename: string) = | |
| 284 | + if verbose: echo "Uploading " & filename | |
| 285 | + var blimpFilename = blimpFilename(filename) | |
| 286 | + if blimpFilename.isNil: | |
| 287 | + blimpFilename = computeBlimpFilename(filename) | |
| 288 | + if existsFile(blimpStore / blimpFilename): | |
| 289 | + uploadFile(blimpFilename) | |
| 290 | + if verbose: echo("\t" & filename & " uploaded.") | |
| 291 | + else: | |
| 292 | + if verbose: echo("\t" & filename & " is not in blimpstore, skipping.") | |
| 293 | + | |
| 294 | + | |
| 302 | 295 | proc setupBlimpStore() = |
| 303 | 296 | try: |
| 304 | 297 | if not existsDir(blimpStore): |
| ... | ... | @@ -333,7 +326,7 @@ let synopsis = """ |
| 333 | 326 | -v,--verbose Verbosity, only works without -s |
| 334 | 327 | -i,--init Set blimp filter in git config |
| 335 | 328 | ---------- |
| 336 | - <command> (string) (d)eflate, (i)nflate, remove | |
| 329 | + <command> (string) (d)eflate, (i)nflate, remove, upload | |
| 337 | 330 | -a,--all Operate on all deflated files in clone |
| 338 | 331 | -f,--filter Operate on all files matching blimp filter |
| 339 | 332 | ---------- |
| ... | ... | @@ -341,6 +334,7 @@ let synopsis = """ |
| 341 | 334 | <filenames> (string...) One or more filepaths to inflate/deflate |
| 342 | 335 | """ |
| 343 | 336 | let help = """ |
| 337 | + | |
| 344 | 338 | blimp is a little utility program for handling large files |
| 345 | 339 | in git repositories. Its inspired by git-fat and s3annex |
| 346 | 340 | but doesn't rely on S3 for storage - it uses rsync like git-fat. |
| ... | ... | @@ -352,9 +346,9 @@ let help = """ |
| 352 | 346 | Use "blimp d mybigfile" to deflate a file, typically before commit. |
| 353 | 347 | Use "blimp i mybigfile" to inflate it back to original content. |
| 354 | 348 | |
| 355 | - When deflated the file only has: | |
| 349 | + When deflated the file only has this content: | |
| 350 | + | |
| 356 | 351 | "blimphash:" <filename> "-" <md5sum> |
| 357 | - ...inside it. | |
| 358 | 352 | |
| 359 | 353 | Deflate also copies the real content to your local blimpstore: |
| 360 | 354 | |
| ... | ... | @@ -391,6 +385,10 @@ let help = """ |
| 391 | 385 | the current content version, not older versions. The file itself is first |
| 392 | 386 | inflated, if needed, and not deleted. This only "unblimps" the file. |
| 393 | 387 | |
| 388 | + The upload command (no single character shortcut) will upload the given file | |
| 389 | + from the local blimpstore to the remote. This is normally done automatically, | |
| 390 | + but this way you can make sure they are up on the remote. | |
| 391 | + | |
| 394 | 392 | In order to have blimp work automatically you can: |
| 395 | 393 | |
| 396 | 394 | * Create a .gitattributes file with lines like: |
| ... | ... | @@ -408,7 +406,7 @@ let help = """ |
| 408 | 406 | This means that if you clone a git repository that already has a .gitattributes |
| 409 | 407 | file in it that uses the blimp filter, then you should do: |
| 410 | 408 | |
| 411 | - blimp --init inflate --all | |
| 409 | + blimp --init inflate --filter | |
| 412 | 410 | |
| 413 | 411 | This will configure the blimp filter and also find and inflate all deflated |
| 414 | 412 | files throughout the clone. |
| ... | ... | @@ -469,9 +467,19 @@ if args["init"].asBool: |
| 469 | 467 | if verbose: echo("Installed blimp filter") |
| 470 | 468 | |
| 471 | 469 | let command = args["command"].asString |
| 472 | -var filenames: seq[PValue] | |
| 470 | +var filenames = initSet[string]() | |
| 471 | + | |
| 472 | +# Add upp all files to operate on in a Set | |
| 473 | 473 | if args.hasKey("filenames"): |
| 474 | - filenames = args["filenames"].asSeq | |
| 474 | + for f in args["filenames"].asSeq: | |
| 475 | + if f.asString != "": | |
| 476 | + filenames.incl(f.asString) | |
| 477 | +if onAllDeflated: | |
| 478 | + for fn in allDeflated(): | |
| 479 | + filenames.incl(fn) | |
| 480 | +if onAllFiltered: | |
| 481 | + for fn in allFiltered(): | |
| 482 | + filenames.incl(fn) | |
| 475 | 483 | |
| 476 | 484 | # Make sure the local blimpstore is setup. |
| 477 | 485 | setupBlimpStore() |
| ... | ... | @@ -479,27 +487,20 @@ setupBlimpStore() |
| 479 | 487 | # Do the deed |
| 480 | 488 | if command != "": |
| 481 | 489 | if command == "d" or command == "deflate": |
| 482 | - if onAllFiltered: | |
| 483 | - for fn in allFiltered(): | |
| 484 | - deflate(fn) | |
| 485 | - else: | |
| 486 | - for fn in filenames: | |
| 487 | - deflate(fn.asString) | |
| 490 | + for fn in filenames: | |
| 491 | + deflate(fn) | |
| 488 | 492 | elif command == "i" or command == "inflate": |
| 489 | - if onAllDeflated: | |
| 490 | - for fn in allDeflated(): | |
| 491 | - inflate(fn) | |
| 492 | - elif onAllFiltered: | |
| 493 | - for fn in allFiltered(): | |
| 494 | - inflate(fn) | |
| 495 | - else: | |
| 496 | - for fn in filenames: | |
| 497 | - inflate(fn.asString) | |
| 493 | + for fn in filenames: | |
| 494 | + inflate(fn) | |
| 498 | 495 | elif command == "remove": |
| 499 | 496 | for fn in filenames: |
| 500 | - remove(fn.asString) | |
| 497 | + remove(fn) | |
| 498 | + elif command == "upload": | |
| 499 | + echo repr(filenames) | |
| 500 | + for fn in filenames.items: | |
| 501 | + upload(fn) | |
| 501 | 502 | else: |
| 502 | - quit("Unknown command, only (d)eflate, (i)inflate or remove are valid.", 6) | |
| 503 | + quit("Unknown command: \"" & command & "\", only (d)eflate, (i)inflate, remove or upload are valid.", 6) | |
| 503 | 504 | |
| 504 | 505 | # All good |
| 505 | 506 | quit(0) | ... | ... |