Commit e914743a56027342c159eb2158cbd593e2542f5e

Authored by Göran Krampe
1 parent 19f977a4

Added remove command that unblimps a file.

Showing 2 changed files with 95 additions and 27 deletions
blimp.nim
... ... @@ -20,17 +20,22 @@ import md5, os, osproc, parseopt2, strutils, parsecfg, streams, lapp, subexes
20 20 # ~/blimpstore/.blimp.conf
21 21  
22 22 var
23   - blimpStore, uploadCommandFormat, downloadCommandFormat: string
  23 + blimpStore, uploadCommandFormat, downloadCommandFormat, deleteCommandFormat: string
24 24 remoteBlimpStore: string = nil
25 25 verbose: bool
26 26  
27 27 let
28 28 defaultConfig = """
29 29 [rsync]
  30 +# Set this to your remote rsync daemon area
30 31 remote = "blimp@some-rsync-server.com::blimpstore"
  32 +
  33 +# The following three formats should not need editing
31 34 # $1 is filename, $2 is remote and $3 is the local blimpstore
32 35 upload = "rsync --password-file ~/blimp.pass -avzP $3/$1 $2/"
33   -download = "rsync -avzP $2/$1 $3/"
  36 +download = "rsync --password-file ~/blimp.pass -avzP $2/$1 $3/"
  37 +# This deletes a single file from destination, that is already deleted in source
  38 +delete = "rsync --password-file ~/blimp.pass -dv --delete --existing --ignore-existing --include '$1' --exclude '*' $3/ $2"
34 39 """
35 40  
36 41 # Load blimp.conf file, overkill for now but...
... ... @@ -54,6 +59,8 @@ proc parseConfFile(filename: string) =
54 59 uploadCommandFormat = e.value
55 60 of "download":
56 61 downloadCommandFormat = e.value
  62 + of "delete":
  63 + deleteCommandFormat = e.value
57 64 else:
58 65 quit("Unknown configuration: " & e.key)
59 66 of cfgOption:
... ... @@ -70,7 +77,7 @@ proc run(cmd: string): auto =
70 77 # Upload a file to the remote master blimpStore
71 78 proc uploadFile(blimpFilename: string) =
72 79 if remoteBlimpStore.isNil:
73   - echo("Remote blimpstore not set in configuration file, not uploading content:\n\t" & blimpFilename)
  80 + echo("Remote blimpstore not set in configuration file, skipping uploading content:\n\t" & blimpFilename)
74 81 return
75 82 let errorCode = run(format(uploadCommandFormat, blimpFilename, remoteBlimpStore, blimpStore))
76 83 if errorCode != 0:
... ... @@ -84,6 +91,13 @@ proc downloadFile(blimpFilename: string) =
84 91 if errorCode != 0:
85 92 quit("Something went wrong downloading " & blimpFilename & " from " & remoteBlimpStore, 3)
86 93  
  94 +# Delete a file from the remote master blimpStore
  95 +proc remoteDeleteFile(blimpFilename: string) =
  96 + if remoteBlimpStore.isNil:
  97 + return
  98 + let errorCode = run(format(deleteCommandFormat, blimpFilename, remoteBlimpStore, blimpStore))
  99 + if errorCode != 0:
  100 + quit("Something went wrong deleting " & blimpFilename & " from " & remoteBlimpStore, 3)
87 101  
88 102 # Copy content to blimpStore, no upload yet.
89 103 proc copyToBlimpStore(filename, blimpFilename: string) =
... ... @@ -92,40 +106,71 @@ proc copyToBlimpStore(filename, blimpFilename: string) =
92 106 uploadFile(blimpFilename)
93 107  
94 108 # Copy content from blimpStore, and downloading first if needed
95   -proc copyFromblimpStore(blimpFilename, filename: string) =
  109 +proc copyFromBlimpStore(blimpFilename, filename: string) =
96 110 if not existsFile(blimpStore / blimpFilename):
97 111 downloadFile(blimpFilename)
98 112 copyFile(blimpStore / blimpFilename, filename)
99 113  
100   -
  114 +# Delete from blimpStore and remote.
  115 +proc deleteFromBlimpStore(blimpFilename, filename: string) =
  116 + if existsFile(blimpStore / blimpFilename):
  117 + removeFile(blimpStore / blimpFilename)
  118 + remoteDeleteFile(blimpFilename)
  119 +
  120 +# Pick out blimpFilename (filename & "-" & hash)
  121 +proc blimpFileName(filename: string): string=
  122 + var hashfile: File
  123 + if not open(hashfile, filename):
  124 + quit("Failed opening file: " & filename, 4)
  125 + let hashline = split(string(readLine(hashfile)), {':'})
  126 + if hashline[0] == "hash":
  127 + result = hashline[1]
  128 + else:
  129 + result = nil
  130 +
  131 +# Get hash and compute blimpFilename
  132 +proc computeBlimpFilename(filename: string): string =
  133 + result = blimpFilename(filename)
  134 + if result.isNil:
  135 + var content: string
  136 + try:
  137 + content = readFile(filename)
  138 + except:
  139 + quit("Failed opening file: " & filename, 1)
  140 + let hash = getMD5(content)
  141 + result = filename & "-" & hash
  142 +
101 143 # Copy original file to blimpStore and replace with hash stub in git.
102 144 proc deflate(filename: string) =
103   - var content: string
104   - try:
105   - content = readFile(filename)
106   - except:
107   - quit("Failed opening file: " & filename, 1)
108   - if content[0..4] == "hash:":
109   - quit("File is already deflated, ignored.", 5)
110   - let hash = getMD5(content)
111   - let blimpFilename = filename & "-" & hash
  145 + let blimpFilename = computeBlimpFilename(filename)
112 146 copyToBlimpStore(filename, blimpFilename)
113 147 writeFile(filename, "hash:" & blimpFilename)
114 148 echo("\t" & filename & " deflated.")
  149 +
  150 +proc isInBlimpStore(filename: string): bool =
  151 + let blimpFilename = blimpFilename(filename)
  152 + if not blimpFilename.isNil:
  153 + return true
115 154  
116 155 # Parse out hash from hash stub and copy back original content from blimpStore.
117 156 proc inflate(filename: string) =
118   - var hashfile: File
119   - if not open(hashfile, filename):
120   - quit("Failed opening file: " & filename, 4)
121   - let hashline = split(string(readLine(hashfile)), {':'})
122   - if hashline[0] == "hash":
123   - let blimpfilename = hashline[1]
124   - #removeFile(filename)
125   - copyFromblimpStore(blimpfilename, filename)
  157 + let blimpFilename = blimpFilename(filename)
  158 + if blimpFilename.isNil:
  159 + echo("\t" & filename & " is not deflated, skipping.", 5)
  160 + else:
  161 + copyFromBlimpStore(blimpfilename, filename)
  162 + echo("\t" & filename & " inflated.")
  163 +
  164 +# Inflates file first (if deflated) and then removes current content for it,
  165 +# both locally and in remote.
  166 +proc remove(filename: string) =
  167 + var blimpFilename = blimpFilename(filename)
  168 + if not blimpFilename.isNil:
  169 + copyFromBlimpStore(blimpfilename, filename)
126 170 else:
127   - quit("\t" & filename & " is not deflated.", 5)
128   - echo("\t" & filename & " inflated.")
  171 + blimpFilename = computeBlimpFilename(filename)
  172 + deleteFromBlimpStore(blimpfilename, filename)
  173 + echo("\t" & filename & " content removed from blimpstore locally and remotely.")
129 174  
130 175 # Find git root dir or fall back on current dir
131 176 proc gitRoot(): string =
... ... @@ -141,8 +186,26 @@ proc gitRoot(): string =
141 186 let help = """
142 187 blimp [options] <command> <filenames...>
143 188 -v,--verbose Verbosity
144   - <command> (string) (i)nflate or (d)eflate
  189 + <command> (string) (d)eflate, (i)nflate, delete, (c)heck, (r)ecover
145 190 <filenames> (string...) One or more filepaths to inflate/deflate
  191 +
  192 + Edit ~/blimpstore/.blimp.conf or <gitroot>/.blimp.conf and set a proper
  193 + remote and also create ~/blimp.pass with the proper rsync password to use.
  194 +
  195 + Deflate is run before you add the big file to the index for committing.
  196 + Deflate will replace the file contents with a hash, and copy the
  197 + real content to ~/blimpstore, and if configured also upload it to
  198 + remote, using rsync.
  199 +
  200 + Inflate will bring back the original content by copying from
  201 + ~/blimpstore, and if its not there, first downloading from the remote.
  202 + Use this whenever you need to work/edit the big file - in order to get
  203 + its real content.
  204 +
  205 + Remove (no single character shortcut) will remove the file(s) content
  206 + both from the local ~/blimpstore and from the remote. This only removes
  207 + the current content version, not older versions. The file itself is first
  208 + inflated, if needed, and not deleted. This only "unblimps" the file.
146 209 """
147 210  
148 211 ################################ main #####################################
... ... @@ -161,8 +224,10 @@ except:
161 224  
162 225  
163 226 # Parse configuration files if they exist
164   -parseConfFile(gitRoot() / ".blimp.conf")
  227 +# The one in gitroot overrides settings from the store.
165 228 parseConfFile(blimpStore / ".blimp.conf")
  229 +parseConfFile(gitRoot() / ".blimp.conf")
  230 +
166 231  
167 232 # Using lapp to get args
168 233 let args = parse(help)
... ... @@ -177,6 +242,9 @@ if command == &quot;d&quot; or command == &quot;deflate&quot;:
177 242 elif command == "i" or command == "inflate":
178 243 for fn in filenames:
179 244 inflate(fn.asString)
  245 +elif command == "remove":
  246 + for fn in filenames:
  247 + remove(fn.asString)
180 248 else:
181 249 quit("Unknown command, only (d)eflate or (i)inflate are valid.", 6)
182 250  
... ...
blimp.nimble
1 1 [Package]
2 2 name = "blimp"
3   -version = "0.1"
  3 +version = "0.2"
4 4 author = "Göran Krampe"
5 5 description = "Utility that helps with big files in git, very similar to git-fat, s3annnex etc."
6 6 license = "MIT"
... ...