1 |
commit: 6faf8d5ab5dc16f193acc1d344bf473e1eaa4808 |
2 |
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com> |
3 |
AuthorDate: Mon Jul 1 20:14:03 2013 +0000 |
4 |
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com> |
5 |
CommitDate: Mon Jul 1 20:14:03 2013 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=6faf8d5a |
7 |
|
8 |
g_sorcery/fileutils: file utilities moved to separate module |
9 |
|
10 |
--- |
11 |
g_sorcery/fileutils.py | 72 ++++++++++++++++++++++++++++ |
12 |
g_sorcery/package_db.py | 64 ++----------------------- |
13 |
tests/test_fileutils.py | 121 +++++++++++++++++++++++++++++++++++++++++++++++ |
14 |
tests/test_package_db.py | 100 --------------------------------------- |
15 |
4 files changed, 198 insertions(+), 159 deletions(-) |
16 |
|
17 |
diff --git a/g_sorcery/fileutils.py b/g_sorcery/fileutils.py |
18 |
new file mode 100644 |
19 |
index 0000000..1920495 |
20 |
--- /dev/null |
21 |
+++ b/g_sorcery/fileutils.py |
22 |
@@ -0,0 +1,72 @@ |
23 |
+#!/usr/bin/env python |
24 |
+# -*- coding: utf-8 -*- |
25 |
+ |
26 |
+""" |
27 |
+ fileutils.py |
28 |
+ ~~~~~~~~~~~~ |
29 |
+ |
30 |
+ file utilities |
31 |
+ |
32 |
+ :copyright: (c) 2013 by Jauhien Piatlicki |
33 |
+ :license: GPL-2, see LICENSE for more details. |
34 |
+""" |
35 |
+ |
36 |
+import json, os, shutil |
37 |
+ |
38 |
+from .exceptions import FileJSONError |
39 |
+ |
40 |
+class FileJSON: |
41 |
+ def __init__(self, directory, name, mandatories): |
42 |
+ """ |
43 |
+ Initialize |
44 |
+ |
45 |
+ mandatories -- list of mandatory keys |
46 |
+ """ |
47 |
+ self.directory = os.path.abspath(directory) |
48 |
+ self.name = name |
49 |
+ self.path = os.path.join(directory, name) |
50 |
+ self.mandatories = mandatories |
51 |
+ |
52 |
+ def read(self): |
53 |
+ if not os.path.exists(self.directory): |
54 |
+ os.makedirs(self.directory) |
55 |
+ content = {} |
56 |
+ if not os.path.isfile(self.path): |
57 |
+ for key in self.mandatories: |
58 |
+ content[key] = "" |
59 |
+ with open(self.path, 'w') as f: |
60 |
+ json.dump(content, f, indent=2, sort_keys=True) |
61 |
+ else: |
62 |
+ with open(self.path, 'r') as f: |
63 |
+ content = json.load(f) |
64 |
+ for key in self.mandatories: |
65 |
+ if not key in content: |
66 |
+ raise FileJSONError('lack of mandatory key: ' + key) |
67 |
+ return content |
68 |
+ |
69 |
+ def write(self, content): |
70 |
+ for key in self.mandatories: |
71 |
+ if not key in content: |
72 |
+ raise FileJSONError('lack of mandatory key: ' + key) |
73 |
+ if not os.path.exists(self.directory): |
74 |
+ os.makedirs(self.directory) |
75 |
+ with open(self.path, 'w') as f: |
76 |
+ json.dump(content, f, indent=2, sort_keys=True) |
77 |
+ |
78 |
+ |
79 |
+def hash_file(name, hasher, blocksize=65536): |
80 |
+ with open(name, 'rb') as f: |
81 |
+ buf = f.read(blocksize) |
82 |
+ while len(buf) > 0: |
83 |
+ hasher.update(buf) |
84 |
+ buf = f.read(blocksize) |
85 |
+ return hasher.hexdigest() |
86 |
+ |
87 |
+def copy_all(src, dst): |
88 |
+ for f_name in os.listdir(src): |
89 |
+ src_name = os.path.join(src, f_name) |
90 |
+ dst_name = os.path.join(dst, f_name) |
91 |
+ if os.path.isdir(src_name): |
92 |
+ shutil.copytree(src_name, dst_name) |
93 |
+ else: |
94 |
+ shutil.copy2(src_name, dst_name) |
95 |
|
96 |
diff --git a/g_sorcery/package_db.py b/g_sorcery/package_db.py |
97 |
index 561129d..fc59878 100644 |
98 |
--- a/g_sorcery/package_db.py |
99 |
+++ b/g_sorcery/package_db.py |
100 |
@@ -11,70 +11,16 @@ |
101 |
:license: GPL-2, see LICENSE for more details. |
102 |
""" |
103 |
|
104 |
-from .exceptions import DBStructureError, FileJSONError, IntegrityError, \ |
105 |
+from .exceptions import DBStructureError, IntegrityError, \ |
106 |
InvalidKeyError, SyncError |
107 |
|
108 |
-import portage |
109 |
- |
110 |
-import collections, glob, hashlib, json, os, shutil, tarfile, tempfile |
111 |
+from .fileutils import FileJSON, hash_file, copy_all |
112 |
|
113 |
-Package = collections.namedtuple("Package", "category name version") |
114 |
+import portage |
115 |
|
116 |
-class FileJSON: |
117 |
- def __init__(self, directory, name, mandatories): |
118 |
- """ |
119 |
- Initialize |
120 |
+import collections, glob, hashlib, os, shutil, tarfile, tempfile |
121 |
|
122 |
- mandatories -- list of mandatory keys |
123 |
- """ |
124 |
- self.directory = os.path.abspath(directory) |
125 |
- self.name = name |
126 |
- self.path = os.path.join(directory, name) |
127 |
- self.mandatories = mandatories |
128 |
- |
129 |
- def read(self): |
130 |
- if not os.path.exists(self.directory): |
131 |
- os.makedirs(self.directory) |
132 |
- content = {} |
133 |
- if not os.path.isfile(self.path): |
134 |
- for key in self.mandatories: |
135 |
- content[key] = "" |
136 |
- with open(self.path, 'w') as f: |
137 |
- json.dump(content, f, indent=2, sort_keys=True) |
138 |
- else: |
139 |
- with open(self.path, 'r') as f: |
140 |
- content = json.load(f) |
141 |
- for key in self.mandatories: |
142 |
- if not key in content: |
143 |
- raise FileJSONError('lack of mandatory key: ' + key) |
144 |
- return content |
145 |
- |
146 |
- def write(self, content): |
147 |
- for key in self.mandatories: |
148 |
- if not key in content: |
149 |
- raise FileJSONError('lack of mandatory key: ' + key) |
150 |
- if not os.path.exists(self.directory): |
151 |
- os.makedirs(self.directory) |
152 |
- with open(self.path, 'w') as f: |
153 |
- json.dump(content, f, indent=2, sort_keys=True) |
154 |
- |
155 |
- |
156 |
-def hash_file(name, hasher, blocksize=65536): |
157 |
- with open(name, 'rb') as f: |
158 |
- buf = f.read(blocksize) |
159 |
- while len(buf) > 0: |
160 |
- hasher.update(buf) |
161 |
- buf = f.read(blocksize) |
162 |
- return hasher.hexdigest() |
163 |
- |
164 |
-def copy_all(src, dst): |
165 |
- for f_name in os.listdir(src): |
166 |
- src_name = os.path.join(src, f_name) |
167 |
- dst_name = os.path.join(dst, f_name) |
168 |
- if os.path.isdir(src_name): |
169 |
- shutil.copytree(src_name, dst_name) |
170 |
- else: |
171 |
- shutil.copy2(src_name, dst_name) |
172 |
+Package = collections.namedtuple("Package", "category name version") |
173 |
|
174 |
class PackageDB: |
175 |
def __init__(self, directory, repo_uri="", db_uri=""): |
176 |
|
177 |
diff --git a/tests/test_fileutils.py b/tests/test_fileutils.py |
178 |
new file mode 100644 |
179 |
index 0000000..1760444 |
180 |
--- /dev/null |
181 |
+++ b/tests/test_fileutils.py |
182 |
@@ -0,0 +1,121 @@ |
183 |
+#!/usr/bin/env python |
184 |
+# -*- coding: utf-8 -*- |
185 |
+ |
186 |
+""" |
187 |
+ fileutils.py |
188 |
+ ~~~~~~~~~~~~ |
189 |
+ |
190 |
+ file utilities test suite |
191 |
+ |
192 |
+ :copyright: (c) 2013 by Jauhien Piatlicki |
193 |
+ :license: GPL-2, see LICENSE for more details. |
194 |
+""" |
195 |
+ |
196 |
+import json, os, shutil, tempfile, unittest |
197 |
+ |
198 |
+from g_sorcery import exceptions, fileutils |
199 |
+ |
200 |
+ |
201 |
+class TestFileJSON(unittest.TestCase): |
202 |
+ |
203 |
+ def setUp(self): |
204 |
+ self.tempdir = tempfile.TemporaryDirectory() |
205 |
+ self.path = os.path.join(self.tempdir.name, 'tst') |
206 |
+ self.name = 'tst.json' |
207 |
+ |
208 |
+ def tearDown(self): |
209 |
+ del self.tempdir |
210 |
+ |
211 |
+ def do_test_read_ok(self, mandatories, value_suffix=""): |
212 |
+ f = fileutils.FileJSON(self.path, self.name, mandatories) |
213 |
+ content = f.read() |
214 |
+ for key in mandatories: |
215 |
+ self.assertTrue(key in content) |
216 |
+ if value_suffix: |
217 |
+ value = key + value_suffix |
218 |
+ else: |
219 |
+ value = "" |
220 |
+ self.assertEqual(content[key], value) |
221 |
+ self.assertTrue(os.path.isfile(os.path.join(self.path, self.name))) |
222 |
+ with open(os.path.join(self.path, self.name), 'r') as f: |
223 |
+ content_f = json.load(f) |
224 |
+ self.assertEqual(content, content_f) |
225 |
+ |
226 |
+ def test_read_dir_does_not_exist(self): |
227 |
+ mandatories = ['tst1', 'tst2', 'tst3'] |
228 |
+ self.do_test_read_ok(mandatories) |
229 |
+ |
230 |
+ def test_read_file_does_not_exist(self): |
231 |
+ os.makedirs(self.path) |
232 |
+ mandatories = ['tst1', 'tst2', 'tst3'] |
233 |
+ self.do_test_read_ok(mandatories) |
234 |
+ |
235 |
+ def test_read_all_keys(self): |
236 |
+ os.makedirs(self.path) |
237 |
+ mandatories = ['tst1', 'tst2', 'tst3'] |
238 |
+ content = {} |
239 |
+ for key in mandatories: |
240 |
+ content[key] = key + "_v" |
241 |
+ with open(os.path.join(self.path, self.name), 'w') as f: |
242 |
+ json.dump(content, f) |
243 |
+ self.do_test_read_ok(mandatories, "_v") |
244 |
+ |
245 |
+ def test_read_missing_keys(self): |
246 |
+ os.makedirs(self.path) |
247 |
+ mandatories = ['tst1', 'tst2', 'tst3'] |
248 |
+ content = {} |
249 |
+ for key in mandatories: |
250 |
+ content[key] = key + "_v" |
251 |
+ with open(os.path.join(self.path, self.name), 'w') as f: |
252 |
+ json.dump(content, f) |
253 |
+ f = fileutils.FileJSON(self.path, self.name, mandatories) |
254 |
+ mandatories.append("tst4") |
255 |
+ self.assertRaises(exceptions.FileJSONError, f.read) |
256 |
+ |
257 |
+ def do_test_write_ok(self): |
258 |
+ mandatories = ['tst1', 'tst2', 'tst3'] |
259 |
+ content = {} |
260 |
+ for key in mandatories: |
261 |
+ content[key] = key + '_v' |
262 |
+ f = fileutils.FileJSON(self.path, self.name, mandatories) |
263 |
+ f.write(content) |
264 |
+ self.assertTrue(os.path.isfile(os.path.join(self.path, self.name))) |
265 |
+ with open(os.path.join(self.path, self.name), 'r') as f: |
266 |
+ content_f = json.load(f) |
267 |
+ self.assertEqual(content, content_f) |
268 |
+ |
269 |
+ def test_write_missing_keys(self): |
270 |
+ content = {'tst1' : '', 'tst2' : ''} |
271 |
+ mandatories = ['tst1', 'tst2', 'tst3'] |
272 |
+ f = fileutils.FileJSON(self.path, self.name, mandatories) |
273 |
+ self.assertRaises(exceptions.FileJSONError, f.write, content) |
274 |
+ |
275 |
+ def test_write_dir_does_not_exist(self): |
276 |
+ self.do_test_write_ok() |
277 |
+ |
278 |
+ def test_write_file_does_not_exist(self): |
279 |
+ os.makedirs(self.path) |
280 |
+ self.do_test_write_ok() |
281 |
+ |
282 |
+ def test_write_all_keys(self): |
283 |
+ os.makedirs(self.path) |
284 |
+ mandatories = ['tst11', 'tst12'] |
285 |
+ content = {} |
286 |
+ for key in mandatories: |
287 |
+ content[key] = key + "_v" |
288 |
+ with open(os.path.join(self.path, self.name), 'w') as f: |
289 |
+ json.dump(content, f) |
290 |
+ self.do_test_write_ok() |
291 |
+ |
292 |
+ |
293 |
+def suite(): |
294 |
+ suite = unittest.TestSuite() |
295 |
+ suite.addTest(TestFileJSON('test_read_dir_does_not_exist')) |
296 |
+ suite.addTest(TestFileJSON('test_read_file_does_not_exist')) |
297 |
+ suite.addTest(TestFileJSON('test_read_all_keys')) |
298 |
+ suite.addTest(TestFileJSON('test_read_missing_keys')) |
299 |
+ suite.addTest(TestFileJSON('test_write_missing_keys')) |
300 |
+ suite.addTest(TestFileJSON('test_write_dir_does_not_exist')) |
301 |
+ suite.addTest(TestFileJSON('test_write_file_does_not_exist')) |
302 |
+ suite.addTest(TestFileJSON('test_write_all_keys')) |
303 |
+ return suite |
304 |
|
305 |
diff --git a/tests/test_package_db.py b/tests/test_package_db.py |
306 |
index c5d7074..2994157 100644 |
307 |
--- a/tests/test_package_db.py |
308 |
+++ b/tests/test_package_db.py |
309 |
@@ -30,98 +30,6 @@ class Server(threading.Thread): |
310 |
self.httpd.shutdown() |
311 |
|
312 |
|
313 |
-class TestFileJSON(unittest.TestCase): |
314 |
- |
315 |
- def setUp(self): |
316 |
- self.tempdir = tempfile.TemporaryDirectory() |
317 |
- self.path = os.path.join(self.tempdir.name, 'tst') |
318 |
- self.name = 'tst.json' |
319 |
- |
320 |
- def tearDown(self): |
321 |
- del self.tempdir |
322 |
- |
323 |
- def do_test_read_ok(self, mandatories, value_suffix=""): |
324 |
- f = package_db.FileJSON(self.path, self.name, mandatories) |
325 |
- content = f.read() |
326 |
- for key in mandatories: |
327 |
- self.assertTrue(key in content) |
328 |
- if value_suffix: |
329 |
- value = key + value_suffix |
330 |
- else: |
331 |
- value = "" |
332 |
- self.assertEqual(content[key], value) |
333 |
- self.assertTrue(os.path.isfile(os.path.join(self.path, self.name))) |
334 |
- with open(os.path.join(self.path, self.name), 'r') as f: |
335 |
- content_f = json.load(f) |
336 |
- self.assertEqual(content, content_f) |
337 |
- |
338 |
- def test_read_dir_does_not_exist(self): |
339 |
- mandatories = ['tst1', 'tst2', 'tst3'] |
340 |
- self.do_test_read_ok(mandatories) |
341 |
- |
342 |
- def test_read_file_does_not_exist(self): |
343 |
- os.makedirs(self.path) |
344 |
- mandatories = ['tst1', 'tst2', 'tst3'] |
345 |
- self.do_test_read_ok(mandatories) |
346 |
- |
347 |
- def test_read_all_keys(self): |
348 |
- os.makedirs(self.path) |
349 |
- mandatories = ['tst1', 'tst2', 'tst3'] |
350 |
- content = {} |
351 |
- for key in mandatories: |
352 |
- content[key] = key + "_v" |
353 |
- with open(os.path.join(self.path, self.name), 'w') as f: |
354 |
- json.dump(content, f) |
355 |
- self.do_test_read_ok(mandatories, "_v") |
356 |
- |
357 |
- def test_read_missing_keys(self): |
358 |
- os.makedirs(self.path) |
359 |
- mandatories = ['tst1', 'tst2', 'tst3'] |
360 |
- content = {} |
361 |
- for key in mandatories: |
362 |
- content[key] = key + "_v" |
363 |
- with open(os.path.join(self.path, self.name), 'w') as f: |
364 |
- json.dump(content, f) |
365 |
- f = package_db.FileJSON(self.path, self.name, mandatories) |
366 |
- mandatories.append("tst4") |
367 |
- self.assertRaises(exceptions.FileJSONError, f.read) |
368 |
- |
369 |
- def do_test_write_ok(self): |
370 |
- mandatories = ['tst1', 'tst2', 'tst3'] |
371 |
- content = {} |
372 |
- for key in mandatories: |
373 |
- content[key] = key + '_v' |
374 |
- f = package_db.FileJSON(self.path, self.name, mandatories) |
375 |
- f.write(content) |
376 |
- self.assertTrue(os.path.isfile(os.path.join(self.path, self.name))) |
377 |
- with open(os.path.join(self.path, self.name), 'r') as f: |
378 |
- content_f = json.load(f) |
379 |
- self.assertEqual(content, content_f) |
380 |
- |
381 |
- def test_write_missing_keys(self): |
382 |
- content = {'tst1' : '', 'tst2' : ''} |
383 |
- mandatories = ['tst1', 'tst2', 'tst3'] |
384 |
- f = package_db.FileJSON(self.path, self.name, mandatories) |
385 |
- self.assertRaises(exceptions.FileJSONError, f.write, content) |
386 |
- |
387 |
- def test_write_dir_does_not_exist(self): |
388 |
- self.do_test_write_ok() |
389 |
- |
390 |
- def test_write_file_does_not_exist(self): |
391 |
- os.makedirs(self.path) |
392 |
- self.do_test_write_ok() |
393 |
- |
394 |
- def test_write_all_keys(self): |
395 |
- os.makedirs(self.path) |
396 |
- mandatories = ['tst11', 'tst12'] |
397 |
- content = {} |
398 |
- for key in mandatories: |
399 |
- content[key] = key + "_v" |
400 |
- with open(os.path.join(self.path, self.name), 'w') as f: |
401 |
- json.dump(content, f) |
402 |
- self.do_test_write_ok() |
403 |
- |
404 |
- |
405 |
class DummyDB(package_db.PackageDB): |
406 |
def __init__(self, directory, packages): |
407 |
super().__init__(directory) |
408 |
@@ -227,14 +135,6 @@ class TestDummyDB(unittest.TestCase): |
409 |
|
410 |
def suite(): |
411 |
suite = unittest.TestSuite() |
412 |
- suite.addTest(TestFileJSON('test_read_dir_does_not_exist')) |
413 |
- suite.addTest(TestFileJSON('test_read_file_does_not_exist')) |
414 |
- suite.addTest(TestFileJSON('test_read_all_keys')) |
415 |
- suite.addTest(TestFileJSON('test_read_missing_keys')) |
416 |
- suite.addTest(TestFileJSON('test_write_missing_keys')) |
417 |
- suite.addTest(TestFileJSON('test_write_dir_does_not_exist')) |
418 |
- suite.addTest(TestFileJSON('test_write_file_does_not_exist')) |
419 |
- suite.addTest(TestFileJSON('test_write_all_keys')) |
420 |
suite.addTest(TestDummyDB('test_manifest')) |
421 |
suite.addTest(TestDummyDB('test_read')) |
422 |
suite.addTest(TestDummyDB('test_list_categories')) |