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 | # blimp is a little utility program for handling large files | 3 | # blimp is a little utility program for handling large files |
4 | # in git repositories. Its inspired by git-fat and s3annex | 4 | # in git repositories. Its inspired by git-fat and s3annex |
5 | # but doesn't rely on S3 for storage - it uses rsync like git-fat. | 5 | # but doesn't rely on S3 for storage - it uses rsync like git-fat. |
6 | # It is a single binary without any dependencies. | 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 | const | 10 | const |
32 | versionMajor* = 0 | 11 | versionMajor* = 0 |
@@ -189,7 +168,7 @@ proc remoteDeleteFile(blimpFilename: string) = | @@ -189,7 +168,7 @@ proc remoteDeleteFile(blimpFilename: string) = | ||
189 | if errorCode != 0: | 168 | if errorCode != 0: |
190 | quit("Something went wrong deleting " & blimpFilename & " from " & remoteBlimpStore, 3) | 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 | proc copyToBlimpStore(filename, blimpFilename: string) = | 172 | proc copyToBlimpStore(filename, blimpFilename: string) = |
194 | if not existsFile(blimpStore / blimpFilename): | 173 | if not existsFile(blimpStore / blimpFilename): |
195 | if stdio: | 174 | if stdio: |
@@ -200,6 +179,7 @@ proc copyToBlimpStore(filename, blimpFilename: string) = | @@ -200,6 +179,7 @@ proc copyToBlimpStore(filename, blimpFilename: string) = | ||
200 | else: | 179 | else: |
201 | copyFile(filename, blimpStore / blimpFilename) | 180 | copyFile(filename, blimpStore / blimpFilename) |
202 | uploadFile(blimpFilename) | 181 | uploadFile(blimpFilename) |
182 | + | ||
203 | 183 | ||
204 | # Copy content from blimpStore, and downloading first if needed | 184 | # Copy content from blimpStore, and downloading first if needed |
205 | proc copyFromBlimpStore(blimpFilename, filename: string) = | 185 | proc copyFromBlimpStore(blimpFilename, filename: string) = |
@@ -227,7 +207,7 @@ proc blimpFileNameFromString(line: string): string = | @@ -227,7 +207,7 @@ proc blimpFileNameFromString(line: string): string = | ||
227 | else: | 207 | else: |
228 | result = nil | 208 | result = nil |
229 | 209 | ||
230 | -# Pick out blimpFilename (filename & "-" & hash) | 210 | +# Pick out blimpFilename (filename & "-" & hash) or nil |
231 | proc blimpFileName(filename: string): string = | 211 | proc blimpFileName(filename: string): string = |
232 | if stdio: | 212 | if stdio: |
233 | blimpFileNameFromString(stdinContent) | 213 | blimpFileNameFromString(stdinContent) |
@@ -299,6 +279,19 @@ proc remove(filename: string) = | @@ -299,6 +279,19 @@ proc remove(filename: string) = | ||
299 | echo("\t" & filename & " content removed from blimpstore locally and remotely.") | 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 | proc setupBlimpStore() = | 295 | proc setupBlimpStore() = |
303 | try: | 296 | try: |
304 | if not existsDir(blimpStore): | 297 | if not existsDir(blimpStore): |
@@ -333,7 +326,7 @@ let synopsis = """ | @@ -333,7 +326,7 @@ let synopsis = """ | ||
333 | -v,--verbose Verbosity, only works without -s | 326 | -v,--verbose Verbosity, only works without -s |
334 | -i,--init Set blimp filter in git config | 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 | -a,--all Operate on all deflated files in clone | 330 | -a,--all Operate on all deflated files in clone |
338 | -f,--filter Operate on all files matching blimp filter | 331 | -f,--filter Operate on all files matching blimp filter |
339 | ---------- | 332 | ---------- |
@@ -341,6 +334,7 @@ let synopsis = """ | @@ -341,6 +334,7 @@ let synopsis = """ | ||
341 | <filenames> (string...) One or more filepaths to inflate/deflate | 334 | <filenames> (string...) One or more filepaths to inflate/deflate |
342 | """ | 335 | """ |
343 | let help = """ | 336 | let help = """ |
337 | + | ||
344 | blimp is a little utility program for handling large files | 338 | blimp is a little utility program for handling large files |
345 | in git repositories. Its inspired by git-fat and s3annex | 339 | in git repositories. Its inspired by git-fat and s3annex |
346 | but doesn't rely on S3 for storage - it uses rsync like git-fat. | 340 | but doesn't rely on S3 for storage - it uses rsync like git-fat. |
@@ -352,9 +346,9 @@ let help = """ | @@ -352,9 +346,9 @@ let help = """ | ||
352 | Use "blimp d mybigfile" to deflate a file, typically before commit. | 346 | Use "blimp d mybigfile" to deflate a file, typically before commit. |
353 | Use "blimp i mybigfile" to inflate it back to original content. | 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 | "blimphash:" <filename> "-" <md5sum> | 351 | "blimphash:" <filename> "-" <md5sum> |
357 | - ...inside it. | ||
358 | 352 | ||
359 | Deflate also copies the real content to your local blimpstore: | 353 | Deflate also copies the real content to your local blimpstore: |
360 | 354 | ||
@@ -391,6 +385,10 @@ let help = """ | @@ -391,6 +385,10 @@ let help = """ | ||
391 | the current content version, not older versions. The file itself is first | 385 | the current content version, not older versions. The file itself is first |
392 | inflated, if needed, and not deleted. This only "unblimps" the file. | 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 | In order to have blimp work automatically you can: | 392 | In order to have blimp work automatically you can: |
395 | 393 | ||
396 | * Create a .gitattributes file with lines like: | 394 | * Create a .gitattributes file with lines like: |
@@ -408,7 +406,7 @@ let help = """ | @@ -408,7 +406,7 @@ let help = """ | ||
408 | This means that if you clone a git repository that already has a .gitattributes | 406 | This means that if you clone a git repository that already has a .gitattributes |
409 | file in it that uses the blimp filter, then you should do: | 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 | This will configure the blimp filter and also find and inflate all deflated | 411 | This will configure the blimp filter and also find and inflate all deflated |
414 | files throughout the clone. | 412 | files throughout the clone. |
@@ -469,9 +467,19 @@ if args["init"].asBool: | @@ -469,9 +467,19 @@ if args["init"].asBool: | ||
469 | if verbose: echo("Installed blimp filter") | 467 | if verbose: echo("Installed blimp filter") |
470 | 468 | ||
471 | let command = args["command"].asString | 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 | if args.hasKey("filenames"): | 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 | # Make sure the local blimpstore is setup. | 484 | # Make sure the local blimpstore is setup. |
477 | setupBlimpStore() | 485 | setupBlimpStore() |
@@ -479,27 +487,20 @@ setupBlimpStore() | @@ -479,27 +487,20 @@ setupBlimpStore() | ||
479 | # Do the deed | 487 | # Do the deed |
480 | if command != "": | 488 | if command != "": |
481 | if command == "d" or command == "deflate": | 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 | elif command == "i" or command == "inflate": | 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 | elif command == "remove": | 495 | elif command == "remove": |
499 | for fn in filenames: | 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 | else: | 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 | # All good | 505 | # All good |
505 | quit(0) | 506 | quit(0) |