Commit 78569137d203163f459e5f965f27ee9e404e151c

Authored by Göran Krampe
1 parent 9eb8665e

Added directory expansion for cwd, home and gitroot. Fixes #5

Showing 1 changed file with 61 additions and 28 deletions
blimp.nim
... ... @@ -16,6 +16,7 @@ import md5, os, osproc, parseopt2, strutils, parsecfg, streams, lapp, subexes
16 16 # <homedir>/blimpStore/<originalfilename>-<md5sum>
17 17 #
18 18 # Configuration is in these locations in order:
  19 +#
19 20 # ./.blimp.conf
20 21 # <gitroot>/.blimp.conf
21 22 # ~/blimpstore/.blimp.conf
... ... @@ -29,23 +30,57 @@ const
29 30  
30 31 var
31 32 blimpStore, remoteBlimpStore, uploadCommandFormat, downloadCommandFormat, deleteCommandFormat, rsyncPassword: string = nil
  33 + homeDir, currentDir, gitRootDir: string
32 34 verbose: bool
33 35  
34 36 let
35 37 defaultConfig = """
36 38 [rsync]
37   -# Set this to your remote rsync daemon area
  39 +# Set your local blimpstore directory.
  40 +# Example:
  41 +# # Place it inside the git clone
  42 +# blimpstore = "%gitroot%/.git/blimpstore"
  43 +# # Place it in current working directory (not very useful)
  44 +# blimpstore = "%cwd%/blimpstore"
  45 +#
  46 +# Default:
  47 +# # Place it in the users home directory
  48 +# blimpstore = "%home%/blimpstore"
  49 +
  50 +# Set this to your remote rsync location
38 51 remote = "blimpuser@some-rsync-server.com::blimpstore"
  52 +# Set this to your rsync password
39 53 password = "some-good-rsync-password-for-blimpuser"
40 54  
41 55 # The following three formats should not need editing
42   -# $1 is filename, $2 is remote and $3 is the local blimpstore
  56 +# $1 is the blimp filename, $2 is remote location and $3 is
  57 +# the local blimpstore directory.
  58 +# NOTE: The password-file will be created by blimp on every command.
43 59 upload = "rsync --password-file $3/.blimp.pass -avzP $3/$1 $2/"
44 60 download = "rsync --password-file $3/.blimp.pass -avzP $2/$1 $3/"
45   -# This deletes a single file from destination, that is already deleted in source
  61 +# This deletes a single file from destination, that is already deleted in source. Yeah... insane! But it works.
46 62 delete = "rsync --password-file $3/.blimp.pass -dv --delete --existing --ignore-existing --include '$1' --exclude '*' $3/ $2"
47 63 """
48 64  
  65 +# Find git root dir or nil
  66 +proc gitRoot(): string =
  67 + try:
  68 + let tup = execCmdEx("git rev-parse --show-toplevel")
  69 + if tup[1] == 0:
  70 + result = strip(tup[0])
  71 + else:
  72 + result = nil
  73 + except:
  74 + result = nil
  75 +
  76 +# Simple expansion of %home%, %cwd% and %gitroot%
  77 +proc expandDirs(templ: string): string =
  78 + result = templ.replace("%home%", homeDir)
  79 + result = result.replace("%cwd%", currentDir)
  80 + if result.contains("%gitroot%"):
  81 + if gitRootDir.isNil: quit("Not in a git clone, can not expand %gitroot% in '" & templ & "'")
  82 + result = result.replace("%gitroot%", gitRootDir)
  83 +
49 84 # Load a blimp.conf file
50 85 proc parseConfFile(filename: string) =
51 86 var f = newFileStream(filename, fmRead)
... ... @@ -64,17 +99,17 @@ proc parseConfFile(filename: string) =
64 99 of cfgKeyValuePair:
65 100 case e.key
66 101 of "blimpstore":
67   - if blimpStore.isNil: blimpStore = e.value
  102 + if blimpStore.isNil: blimpStore = expandDirs(e.value)
68 103 of "remote":
69   - if remoteBlimpStore.isNil: remoteBlimpStore = e.value
  104 + if remoteBlimpStore.isNil: remoteBlimpStore = expandDirs(e.value)
70 105 of "password":
71 106 if rsyncPassword.isNil: rsyncPassword = e.value
72 107 of "upload":
73   - if uploadCommandFormat.isNil: uploadCommandFormat = e.value
  108 + if uploadCommandFormat.isNil: uploadCommandFormat = expandDirs(e.value)
74 109 of "download":
75   - if downloadCommandFormat.isNil: downloadCommandFormat = e.value
  110 + if downloadCommandFormat.isNil: downloadCommandFormat = expandDirs(e.value)
76 111 of "delete":
77   - if deleteCommandFormat.isNil: deleteCommandFormat = e.value
  112 + if deleteCommandFormat.isNil: deleteCommandFormat = expandDirs(e.value)
78 113 else:
79 114 quit("Unknown configuration: " & e.key)
80 115 of cfgOption:
... ... @@ -90,9 +125,10 @@ proc run(cmd: string): auto =
90 125  
91 126 # Every rsync command, make sure we have a password file
92 127 proc rsyncRun(cmd: string): auto =
93   - writeFile(blimpStore / ".blimp.pass", rsyncPassword)
94   - if execCmd("chmod 600 " & blimpStore / ".blimp.pass") != 0:
95   - quit("Failed to chmod 600 " & blimpStore / ".blimp.pass")
  128 + if not rsyncPassword.isNil:
  129 + writeFile(blimpStore / ".blimp.pass", rsyncPassword)
  130 + if execCmd("chmod 600 " & blimpStore / ".blimp.pass") != 0:
  131 + quit("Failed to chmod 600 " & blimpStore / ".blimp.pass")
96 132 run(cmd)
97 133  
98 134 # Upload a file to the remote master blimpStore
... ... @@ -192,16 +228,6 @@ proc remove(filename: string) =
192 228 deleteFromBlimpStore(blimpfilename, filename)
193 229 echo("\t" & filename & " content removed from blimpstore locally and remotely.")
194 230  
195   -# Find git root dir or nil
196   -proc gitRoot(): string =
197   - try:
198   - let tup = execCmdEx("git rev-parse --show-toplevel")
199   - if tup[1] == 0:
200   - result = strip(tup[0])
201   - else:
202   - result = nil
203   - except:
204   - result = nil
205 231  
206 232 proc setupBlimpStore() =
207 233 try:
... ... @@ -216,6 +242,9 @@ proc setupBlimpStore() =
216 242 except:
217 243 quit("Could not create .blimp.conf config file in " & blimpStore & " directory.", 1)
218 244  
  245 +proc `$`(x: string): string =
  246 + if x.isNil: "nil" else: x
  247 +
219 248 proc dumpConfig() =
220 249 echo "\nDump of configuration:"
221 250 echo "\tblimpStore: " & blimpStore
... ... @@ -223,7 +252,7 @@ proc dumpConfig() =
223 252 echo "\tuploadCommandFormat: " & uploadCommandFormat
224 253 echo "\tdownloadCommandFormat: " & downloadCommandFormat
225 254 echo "\tdeleteCommandFormat: " & deleteCommandFormat
226   - echo "\trsyncPassword: " & rsyncPassword
  255 + echo "\trsyncPassword: " & $rsyncPassword
227 256 echo "\n"
228 257  
229 258 let help = """
... ... @@ -254,23 +283,28 @@ let help = &quot;&quot;&quot;
254 283 """
255 284  
256 285 ################################ main #####################################
  286 +# Set some dirs
  287 +homeDir = getHomeDir()
  288 +homeDir = homeDir[0.. -2] # Not sure why it keeps a trailing "/" on Linux
  289 +currentDir = getCurrentDir()
  290 +gitRootDir = gitRoot()
257 291  
258 292 # Using lapp to get args, on parsing failure this will show usage automatically
259 293 var args = parse(help)
260 294 verbose = args["verbose"].asBool
261 295  
262 296 # Parse configuration files, may shadow and override each other
263   -parseConfFile(getCurrentDir() / ".blimp.conf")
264   -if not gitRoot().isNil:
265   - parseConfFile(gitRoot() / ".blimp.conf")
  297 +parseConfFile(currentDir / ".blimp.conf")
  298 +if not gitRootDir.isNil:
  299 + parseConfFile(gitRootDir / ".blimp.conf")
266 300  
267 301 # If we haven't gotten a blimpstore yet, we set a default one
268 302 if blimpStore.isNil:
269   - blimpStore = getHomeDir() / "blimpstore"
  303 + blimpStore = homeDir / "blimpstore"
270 304  
271 305 if existsDir(blimpStore):
272 306 parseConfFile(blimpStore / ".blimp.conf")
273   -parseConfFile(getHomeDir() / ".blimp.conf")
  307 +parseConfFile(homeDir / ".blimp.conf")
274 308  
275 309 if verbose: dumpConfig()
276 310  
... ... @@ -285,7 +319,6 @@ let filenames = args[&quot;filenames&quot;].asSeq
285 319 setupBlimpStore()
286 320  
287 321  
288   -
289 322 # Do the deed
290 323 if command == "d" or command == "deflate":
291 324 for fn in filenames:
... ...