74272cdb
Göran Krampe
First commit
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
import md5, os, osproc, parseopt2, strutils, parsecfg, streams
# This is a little utility program for handling large files
# in git repositories. Its inspired by git-fat and s3annex
# but doesn't rely on S3 for storage.
#
# Use "fat d mybigfile" to deflate it before commit.
# Use "fat i mybigfile" to inflate it back to original size.
#
# When deflated the file only has an md5sum string inside it.
#
# The file is copied over into:
# <homedir>/fatstore/<originalfilename>-<md5sum>
var fatstore, remoteFatstore: string
# Load fatstore.conf file, overkill for now but...
proc parseConfFile(filename: string) =
echo filename
var f = newFileStream(filename, fmRead)
if f != nil:
var p: CfgParser
open(p, f, filename)
while true:
var e = next(p)
case e.kind
of cfgEof:
break
of cfgSectionStart:
continue # Ignore
of cfgKeyValuePair:
if e.key == "remote":
remoteFatstore = e.value
else:
quit("Unknown configuration: " & e.key)
of cfgOption:
quit("Unknown configuration: " & e.key)
of cfgError:
quit("Parsing " & filename & ": " & e.msg)
close(p)
# Upload a file to the remote master fatstore
proc uploadFile(fatfilename: string) =
if remoteFatstore.isNil:
echo("Remote fatstore not set in configuration file, not uploading content:\n\t" & fatfilename)
return
let errorCode = execCmd("rsync -a " & fatstore / fatfilename & " " & remoteFatstore)
if errorCode != 0: quit("Something went wrong uploading content to " & remoteFatstore, 2)
# Download a file to the remote master fatstore
proc downloadFile(fatfilename: string) =
if remoteFatstore.isNil:
quit("Remote fatstore not set in configuration file, can not download content:\n\t" & fatfilename)
let errorCode = execCmd("rsync -a " & remoteFatstore / fatfilename & " " & fatstore / "")
if errorCode != 0: quit("Something went wrong downloading " & fatfilename & " from " & remoteFatstore, 3)
# Copy content to fatstore, no upload yet.
proc copyToFatstore(filename, fatfilename: string) =
if not existsFile(fatstore / fatfilename):
copyFile(filename, fatstore / fatfilename)
uploadFile(fatfilename)
# Copy content from fatstore, and downloading first if needed
proc copyFromFatstore(fatfilename, filename: string) =
if not existsFile(fatstore / fatfilename):
downloadFile(fatfilename)
copyFile(fatstore / fatfilename, filename)
# Copy original file to fatstore and replace with hash stub in git.
proc deflate(filename: string) =
let content = readFile(filename)
if content[0..4] == "hash:":
quit("File is already deflated, ignored.", 5)
let hash = getMD5(content)
let fatfilename = filename & "-" & hash
copyToFatstore(filename, fatfilename)
writeFile(filename, "hash:" & fatfilename)
# Parse out hash from hash stub and copy back original content from fatstore.
proc inflate(filename: string) =
var hashfile: File
if not open(hashfile, filename):
quit("Could not open file: " & filename, 4)
let hashline = split(string(readLine(hashfile)), {':'})
if hashline[0] == "hash":
let fatfilename = hashline[1]
#removeFile(filename)
copyFromFatstore(fatfilename, filename)
else:
quit("File is not a fat file.", 5)
################################ main #####################################
# Hardwired to "fatstore" directory in home dir.
fatstore = getHomeDir() / "fatstore"
# Make sure we have the dir, or create it.
try:
if not existsDir(fatstore): createDir(fatstore)
except:
quit("Could not create " & fatstore & " directory.", 1)
# Parse configuration if it exists
parseConfFile(fatstore / "fatstore.conf")
# Only a command and a path as argument
let argv = commandLineParams()
let command = argv[0]
let filename = argv[1]
# Do the deed
if command == "d" or command == "deflate":
deflate(filename)
elif command == "i" or command == "inflate":
inflate(filename)
else:
quit("Unknown command, only (d)eflate or (i)inflate are valid.", 6)
# All good
quit(0)
|