* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-06-20 23:21 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-06-20 23:21 UTC (permalink / raw
To: gentoo-commits
commit: 707603adc020c074d473fad77bd8163bc4abdefe
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Thu Jun 20 23:07:48 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Thu Jun 20 23:07:48 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=707603ad
g_sorcery/package_db.py: list_package_names
---
g_sorcery/package_db.py | 5 +++++
tests/test_package_db.py | 12 +++++++++++-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/g_sorcery/package_db.py b/g_sorcery/package_db.py
index a925af4..aae3abc 100644
--- a/g_sorcery/package_db.py
+++ b/g_sorcery/package_db.py
@@ -263,3 +263,8 @@ class PackageDB:
def list_categories(self):
return list(self.db['categories'].keys())
+
+ def list_package_names(self, category):
+ if not category in self.db['packages']:
+ raise Exception('No such category: ' + category)
+ return list(self.db['packages'][category].keys())
diff --git a/tests/test_package_db.py b/tests/test_package_db.py
index 1b3600b..9977d8c 100644
--- a/tests/test_package_db.py
+++ b/tests/test_package_db.py
@@ -152,7 +152,16 @@ class TestDummyDB(unittest.TestCase):
db.generate()
categories = list(set([x.category for x in self.packages]))
self.assertEqual(categories, db.list_categories())
-
+
+ def test_list_package_names(self):
+ db = DummyDB(self.tempdir.name, self.packages)
+ db.generate()
+ categories = list(set([x.category for x in self.packages]))
+ for category in categories:
+ package_names = list(set([x.name for x in self.packages if x.category == category]))
+ self.assertEqual(package_names, db.list_package_names(category))
+ self.assertRaises(Exception, db.list_package_names, 'no_such_category')
+
def suite():
suite = unittest.TestSuite()
@@ -167,4 +176,5 @@ def suite():
suite.addTest(TestDummyDB('test_manifest'))
suite.addTest(TestDummyDB('test_read'))
suite.addTest(TestDummyDB('test_list_categories'))
+ suite.addTest(TestDummyDB('test_list_package_names'))
return suite
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2015-04-22 7:35 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2015-04-22 7:35 UTC (permalink / raw
To: gentoo-commits
commit: 15e264af65e08505ec85d8cb0dd53170ac044985
Author: Jauhien Piatlicki <jauhien <AT> gentoo <DOT> org>
AuthorDate: Fri Apr 17 09:31:25 2015 +0000
Commit: Jauhien Piatlicki <jauhien <AT> gentoo <DOT> org>
CommitDate: Fri Apr 17 17:10:08 2015 +0000
URL: https://gitweb.gentoo.org/proj/g-sorcery.git/commit/?id=15e264af
[g_sorcery/package_db] add category common data setter and getter to DB API
g_sorcery/package_db.py | 38 ++++++++++++++++++++++++++++++++++++++
tests/test_PackageDB.py | 17 +++++++++++++----
2 files changed, 51 insertions(+), 4 deletions(-)
diff --git a/g_sorcery/package_db.py b/g_sorcery/package_db.py
index ec2d45f..5374ae5 100644
--- a/g_sorcery/package_db.py
+++ b/g_sorcery/package_db.py
@@ -105,6 +105,7 @@ class PackageDB(object):
self.pkg_name, self.pkg_data = next(self.pkgs_iter)
self.vers_iter = iter(self.pkg_data.items())
+ ebuild_data = dict(ebuild_data)
ebuild_data.update(self.cat_data['common_data'])
return (Package(self.cat_name, self.pkg_name, ver), ebuild_data)
@@ -129,6 +130,7 @@ class PackageDB(object):
self.pkg_name, self.pkg_data = next(self.pkgs_iter)
self.vers_iter = iter(self.pkg_data.items())
+ ebuild_data = dict(ebuild_data)
ebuild_data.update(self.cat_data['common_data'])
return (Package(self.cat_name, self.pkg_name, ver), ebuild_data)
@@ -275,6 +277,42 @@ class PackageDB(object):
self.categories[category] = description
+ def set_common_data(self, category, common_data):
+ """
+ Set common data for a category.
+
+ Args:
+ category: Category name.
+ common_data: Category common data.
+ """
+ if not category in self.categories:
+ raise InvalidKeyError('Non-existent category: ' + category)
+
+ if not category in self.database:
+ self.database[category] = {'common_data': common_data, 'packages': {}}
+ else:
+ self.database[category]['common_data'] = common_data
+
+
+ def get_common_data(self, category):
+ """
+ Get common data for a category.
+
+ Args:
+ category: Category name.
+
+ Returns:
+ Dictionary with category common data.
+ """
+ if not category in self.categories:
+ raise InvalidKeyError('Non-existent category: ' + category)
+
+ if not category in self.database:
+ return {}
+ else:
+ return self.database[category]['common_data']
+
+
def add_package(self, package, ebuild_data=None):
"""
Add a package.
diff --git a/tests/test_PackageDB.py b/tests/test_PackageDB.py
index f73f006..2a67385 100644
--- a/tests/test_PackageDB.py
+++ b/tests/test_PackageDB.py
@@ -38,11 +38,15 @@ class TestPackageDB(BaseTest):
orig_db = PackageDB(orig_path)
orig_db.add_category("app-test1")
orig_db.add_category("app-test2")
- ebuild_data = {"test1": "test1", "test2": "test2"}
+ ebuild_data = {"test1": "tst1", "test2": "tst2"}
+ common_data = {"common1": "cmn1", "common2": "cmn2"}
packages = [Package("app-test1", "test", "1"), Package("app-test1", "test", "2"),
Package("app-test1", "test1", "1"), Package("app-test2", "test2", "1")]
for package in packages:
orig_db.add_package(package, ebuild_data)
+ orig_db.set_common_data("app-test1", common_data)
+ full_data = dict(ebuild_data)
+ full_data.update(common_data)
orig_db.write()
os.system("cd " + orig_tempdir.name + " && tar cvzf good.tar.gz db")
@@ -61,6 +65,8 @@ class TestPackageDB(BaseTest):
srv.join()
test_db.read()
self.assertEqual(orig_db.database, test_db.database)
+ self.assertEqual(orig_db.get_common_data("app-test1"), test_db.get_common_data("app-test1"))
+ self.assertEqual(orig_db.get_common_data("app-test2"), test_db.get_common_data("app-test2"))
self.assertEqual(set(test_db.list_categories()), set(["app-test1", "app-test2"]))
self.assertTrue(test_db.in_category("app-test1", "test"))
self.assertFalse(test_db.in_category("app-test2", "test"))
@@ -71,7 +77,7 @@ class TestPackageDB(BaseTest):
self.assertRaises(InvalidKeyError, test_db.list_package_versions, "app-test1", "invalid")
self.assertEqual(set(test_db.list_package_versions("app-test1", "test")), set(['1', '2']))
self.assertEqual(set(test_db.list_all_packages()), set(packages))
- self.assertEqual(test_db.get_package_description(packages[0]), ebuild_data)
+ self.assertEqual(test_db.get_package_description(packages[0]), full_data)
self.assertRaises(KeyError, test_db.get_package_description, Package("invalid", "invalid", "1"))
self.assertEqual(test_db.get_max_version("app-test1", "test"), "2")
self.assertEqual(test_db.get_max_version("app-test1", "test1"), "1")
@@ -79,10 +85,13 @@ class TestPackageDB(BaseTest):
pkg_set = set(packages)
for package, data in test_db:
self.assertTrue(package in pkg_set)
- self.assertEqual(data, ebuild_data)
+ if package.category == "app-test1":
+ self.assertEqual(data, full_data)
+ else:
+ self.assertEqual(data, ebuild_data)
pkg_set.remove(package)
self.assertTrue(not pkg_set)
-
+ self.assertEqual(orig_db.database, test_db.database)
def suite():
suite = unittest.TestSuite()
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-07-04 20:24 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-07-04 20:24 UTC (permalink / raw
To: gentoo-commits
commit: 976ba56c16c4035f81bacae5db057778863732d5
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Thu Jul 4 20:23:03 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Thu Jul 4 20:23:03 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=976ba56c
g_sorcery/ebuild: substitute_list
---
g_sorcery/ebuild.py | 43 +++++++++++++++++++++++++++++++++++++++++++
g_sorcery/exceptions.py | 3 +++
tests/test_ebuild.py | 16 ++++++++++++++--
3 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/g_sorcery/ebuild.py b/g_sorcery/ebuild.py
index 9529220..83fcb13 100644
--- a/g_sorcery/ebuild.py
+++ b/g_sorcery/ebuild.py
@@ -11,8 +11,51 @@
:license: GPL-2, see LICENSE for more details.
"""
+import copy
+import re
import string
+from .exceptions import DescriptionError
+
+def substitute_list(text, values):
+ """
+ Performs the template substitution. Variables are
+ substituted by lists.
+
+ Variable format.
+ ~~~~~~~~~~~~~~~~
+
+ #[n ]#name#
+ 'n': Separate list entries with '\n'.
+ ' ': Separate list entries with ' '.
+ name: Key in values dict.
+
+ Args:
+ text: List with template strings.
+ values: Dictionary with values.
+ """
+ result = copy.deepcopy(text)
+ regex = re.compile('#[n ]#\w+#')
+ for idx, line in enumerate(result):
+ match = regex.search(line)
+ if not match:
+ continue
+ group = match.group()
+ new_line = (group[1] == 'n')
+ key = group[3:-1]
+ if not key in values:
+ error = "missing key: " + key
+ raise DescriptionError(error)
+ lst = values[key]
+ if new_line:
+ sep = '\n'
+ else:
+ sep = ' '
+ repl = sep.join(lst)
+ result[idx] = regex.sub(repl, line)
+ return result
+
+
class EbuildGenerator(object):
"""
Ebuild generator.
diff --git a/g_sorcery/exceptions.py b/g_sorcery/exceptions.py
index 38a80b2..a05cfa5 100644
--- a/g_sorcery/exceptions.py
+++ b/g_sorcery/exceptions.py
@@ -34,3 +34,6 @@ class FileJSONError(GSorceryError):
class XMLGeneratorError(GSorceryError):
pass
+
+class DescriptionError(GSorceryError):
+ pass
diff --git a/tests/test_ebuild.py b/tests/test_ebuild.py
index 69222e8..6a97249 100644
--- a/tests/test_ebuild.py
+++ b/tests/test_ebuild.py
@@ -13,7 +13,7 @@
import os, tempfile, unittest
-from g_sorcery import ebuild, package_db
+from g_sorcery import ebuild, package_db, exceptions
from tests.base import BaseTest
@@ -81,10 +81,22 @@ var: $$var""")
self.assertEqual(ebuild, ['test', 'author: jauhien',
'homepage: 127.0.0.1', 'var: $var'])
-
+
+class TestSubstituteList(BaseTest):
+
+ def test_substitute_list(self):
+ text = ['a', 'test', 'DEPEND="#n#depend#"', 'IUSE="# #iuse#"']
+ desc = {'depend' : ['app-test/test1', 'app-test/test2'],
+ 'iuse' : ['test', 'check']}
+ result = ['a', 'test', 'DEPEND="app-test/test1\napp-test/test2"', 'IUSE="test check"']
+ self.assertEqual(ebuild.substitute_list(text, desc), result)
+ self.assertRaises(exceptions.DescriptionError, ebuild.substitute_list, text, {})
+
+
def suite():
suite = unittest.TestSuite()
suite.addTest(TestEbuildGenerator('test_process'))
suite.addTest(TestEbuildGenerator('test_generate'))
suite.addTest(TestEbuildGeneratorFromFile('test_generate'))
+ suite.addTest(TestSubstituteList('test_substitute_list'))
return suite
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-07-03 22:54 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-07-03 22:54 UTC (permalink / raw
To: gentoo-commits
commit: 1cc214be6a43cf6c68353650bf6938756366b05e
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Wed Jul 3 22:36:49 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Wed Jul 3 22:36:49 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=1cc214be
g_sorcery/package_db: hiding pylint swearing
---
g_sorcery/package_db.py | 210 +++++++++++++++++++++++++++++++++++++++++------
tests/test_package_db.py | 4 +-
2 files changed, 188 insertions(+), 26 deletions(-)
diff --git a/g_sorcery/package_db.py b/g_sorcery/package_db.py
index 12577ad..bb3b6e2 100644
--- a/g_sorcery/package_db.py
+++ b/g_sorcery/package_db.py
@@ -25,7 +25,37 @@ import collections, glob, hashlib, os, shutil, tarfile
Package = collections.namedtuple("Package", "category name version")
class PackageDB(object):
+ """
+ Package database.
+ Database is a directory and related data structure.
+
+ Directory layout.
+ ~~~~~~~~~~~~~~~~~
+ db dir
+ manifest.json: database manifest
+ uri.json: URIes
+ info.json: information about database
+ categories.json: information about categories
+ category1
+ packages.json: list of packages
+ package1
+ versions.json: list of versions
+ version1.json: description of a package
+ version2.json: description of a package
+ ...
+ package2
+ ...
+ category2
+ ...
+
+ """
def __init__(self, directory, repo_uri="", db_uri=""):
+ """
+ Args:
+ directory: database directory.
+ repo_uri: Repository URI.
+ db_uri: URI for synchronization with remote database.
+ """
self.URI_NAME = 'uri.json'
self.INFO_NAME = 'info.json'
self.CATEGORIES_NAME = 'categories.json'
@@ -36,6 +66,13 @@ class PackageDB(object):
self.reset_db()
def reset_uri(self, repo_uri="", db_uri=""):
+ """
+ Reset URI information.
+
+ Args:
+ repo_uri: Repository URI.
+ db_uri: URI for synchronization with remote database.
+ """
uri_f = FileJSON(self.directory, self.URI_NAME, ['repo_uri', 'db_uri'])
uri = uri_f.read()
if not repo_uri:
@@ -51,16 +88,19 @@ class PackageDB(object):
uri_f.write(uri)
def reset_db(self):
- self.db = {}
+ """
+ Reset database.
+ """
+ self.database = {}
self.info = {}
self.categories = {}
- self.db = {}
def generate(self, repo_uri=""):
"""
- Generates a new package database
+ Generate new package database
- repo_uri -- repository uri
+ Args:
+ repo_uri: Repository URI
"""
if repo_uri:
self.repo_uri = repo_uri
@@ -78,6 +118,12 @@ class PackageDB(object):
pass
def sync(self, db_uri=""):
+ """
+ Synchronize local database with remote database.
+
+ Args:
+ db_uri: URI for synchronization with remote database.
+ """
if db_uri:
self.db_uri = db_uri
self.clean()
@@ -116,9 +162,19 @@ class PackageDB(object):
self.read()
def get_real_db_uri(self):
+ """
+ Convert self.db_uri to URI where remote database can be
+ fetched from.
+
+ Returns:
+ URI of remote database file.
+ """
return self.db_uri
def manifest(self):
+ """
+ Generate database manifest.
+ """
categories = FileJSON(self.directory, self.CATEGORIES_NAME, [])
categories = categories.read()
manifest = {}
@@ -134,12 +190,19 @@ class PackageDB(object):
for f in files:
manifest[os.path.join(root[len(self.directory)+1:], f)] = \
hash_file(os.path.join(root, f), hashlib.md5())
- m = FileJSON(self.directory, 'manifest.json', [])
- m.write(manifest)
+ m_f = FileJSON(self.directory, 'manifest.json', [])
+ m_f.write(manifest)
def check_manifest(self):
- m = FileJSON(self.directory, 'manifest.json', [])
- manifest = m.read()
+ """
+ Check database manifest.
+
+ Returns:
+ Tuple with first element containing result of manifest check
+ as boolean and second element containing list of files with errors.
+ """
+ m_f = FileJSON(self.directory, 'manifest.json', [])
+ manifest = m_f.read()
result = True
errors = []
@@ -158,17 +221,23 @@ class PackageDB(object):
return (result, errors)
def clean(self):
+ """
+ Clean database.
+ """
shutil.rmtree(self.directory)
self.reset_uri(self.repo_uri, self.db_uri)
self.reset_db()
def write(self):
+ """
+ Write database.
+ """
info_f = FileJSON(self.directory, self.INFO_NAME, [])
categories_f = FileJSON(self.directory, self.CATEGORIES_NAME, [])
info_f.write(self.info)
categories_f.write(self.categories)
- for pkgname, versions in self.db.items():
+ for pkgname, versions in self.database.items():
category, name = pkgname.split('/')
if not category or (not category in self.categories):
raise DBStructureError('Non existent: ' + category)
@@ -195,18 +264,33 @@ class PackageDB(object):
self.additional_write()
def additional_write_version(self, category, package, version):
+ """
+ Hook to be overrided.
+ """
pass
def additional_write_package(self, category, package):
+ """
+ Hook to be overrided.
+ """
pass
def additional_write_category(self, category):
+ """
+ Hook to be overrided.
+ """
pass
def additional_write(self):
+ """
+ Hook to be overrided.
+ """
pass
def read(self):
+ """
+ Read database.
+ """
sane, errors = self.check_manifest()
if not sane:
raise IntegrityError('Manifest error: ' + str(errors))
@@ -227,42 +311,70 @@ class PackageDB(object):
for name in packages:
package_path = os.path.join(category_path, name)
if not os.path.isdir(category_path):
- raise DBStructureError('Empty package: ' + category + '/' + name)
+ error_msg = 'Empty package: ' + category + '/' + name
+ raise DBStructureError(error_msg)
f = FileJSON(package_path, self.VERSIONS_NAME, [])
versions = f.read()
if not versions:
- raise DBStructureError('Empty package: ' + category + '/' + name)
+ error_msg = 'Empty package: ' + category + '/' + name
+ raise DBStructureError(error_msg)
pkgname = category + '/' + name
- self.db[pkgname] = {}
+ self.database[pkgname] = {}
for version in versions:
f = FileJSON(package_path, version + '.json', [])
description = f.read()
- self.db[pkgname][version] = description
+ self.database[pkgname][version] = description
self.additional_read_version(category, name, version)
self.additional_read_package(category, name)
self.additional_read_category(category)
self.additional_read()
def additional_read_version(self, category, package, version):
+ """
+ Hook to be overrided.
+ """
pass
def additional_read_package(self, category, package):
+ """
+ Hook to be overrided.
+ """
pass
def additional_read_category(self, category):
+ """
+ Hook to be overrided.
+ """
pass
def additional_read(self):
+ """
+ Hook to be overrided.
+ """
pass
def add_category(self, category, description=None):
+ """
+ Add a category.
+
+ Args:
+ category: Category name.
+ description: Category description.
+ """
if not description:
description = {}
- self.categories[category] = description;
+ self.categories[category] = description
def add_package(self, package, description=None):
+ """
+ Add a package.
+
+ Args:
+ package: package_db.Package instance.
+ description: Dictionary with package description.
+ """
if not description:
description = {}
category = package.category
@@ -271,44 +383,94 @@ class PackageDB(object):
pkgname = category + '/' + name
if category and not category in self.categories:
raise InvalidKeyError('Non-existent category: ' + category)
- if pkgname and not pkgname in self.db:
- self.db[pkgname] = {}
- self.db[pkgname][version] = description
+ if pkgname and not pkgname in self.database:
+ self.database[pkgname] = {}
+ self.database[pkgname][version] = description
def list_categories(self):
+ """
+ List all categories.
+
+ Returns:
+ List with category names.
+ """
return list(self.categories)
def list_package_names(self, category):
+ """
+ List package names in a category.
+
+ Args:
+ category: Category name.
+
+ Returns:
+ List of package names.
+ """
if not category or (not category in self.categories):
raise InvalidKeyError('No such category: ' + category)
- res = [x.split('/')[1] for x in self.db if x.split('/')[0] == category]
+ res = [x.split('/')[1] for x in self.database if x.split('/')[0] == category]
return res
def list_package_versions(self, category, name):
+ """
+ List package versions.
+
+ Args:
+ category: Category name.
+ name: package name.
+
+ Returns:
+ List of package versions.
+ """
if not category or (not category in self.categories):
raise InvalidKeyError('No such category: ' + category)
pkgname = category + '/' + name
- if not pkgname in self.db:
+ if not pkgname in self.database:
raise InvalidKeyError('No such package: ' + pkgname)
- return list(self.db[pkgname])
+ return list(self.database[pkgname])
def list_all_packages(self):
+ """
+ List all packages in a database.
+
+ Returns:
+ List of package_db.Package instances.
+ """
result = []
- for pkgname, versions in self.db.items():
+ for pkgname, versions in self.database.items():
for version in versions:
category, name = pkgname.split('/')
result.append(Package(category, name, version))
return result
def get_package_description(self, package):
+ """
+ Get package description.
+
+ Args:
+ package: package_db.Package instance.
+
+ Returns:
+ Dictionary with package description.
+ """
#a possible exception should be catched in the caller
- return self.db[package.category + '/' + package.name][package.version]
+ return self.database[package.category + '/' + package.name][package.version]
def get_max_version(self, category, name):
+ """
+ Get the recent available version of a package.
+
+ Args:
+ category: Category name.
+ name: package name.
+
+ Returns:
+ The recent version of a package.
+ """
pkgname = category + '/' + name
- if not pkgname in self.db:
+ if not pkgname in self.database:
raise InvalidKeyError('No such package: ' + pkgname)
- versions = list(self.db[pkgname])
+ versions = list(self.database[pkgname])
max_ver = versions[0]
for version in versions[1:]:
if portage.pkgcmp(portage.pkgsplit(pkgname + '-' + version),
diff --git a/tests/test_package_db.py b/tests/test_package_db.py
index 0f82129..d491152 100644
--- a/tests/test_package_db.py
+++ b/tests/test_package_db.py
@@ -58,7 +58,7 @@ class TestDummyDB(BaseTest):
db.generate()
db2 = DummyDB(self.tempdir.name, self.packages)
db2.read()
- self.assertEqual(db.db, db2.db)
+ self.assertEqual(db.database, db2.database)
def test_list_categories(self):
db = DummyDB(self.tempdir.name, self.packages)
@@ -107,7 +107,7 @@ class TestDummyDB(BaseTest):
os.chdir(prev)
- self.assertEqual(src_db.db, db.db)
+ self.assertEqual(src_db.database, db.database)
def test_sync_fail(self):
db = DummyDB(os.path.join(self.tempdir.name, 'testdb'), self.packages)
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-07-02 14:48 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-07-02 14:48 UTC (permalink / raw
To: gentoo-commits
commit: 72ebc34dc4ff6fa2c56a3629f267b74c32723951
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Tue Jul 2 13:55:50 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Tue Jul 2 13:55:50 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=72ebc34d
py2: encoding unicode -> utf-8 (in xml.etree.ElementTree.tostring)
---
g_sorcery/metadata.py | 2 +-
tests/test_metadata.py | 13 ++++++++-----
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/g_sorcery/metadata.py b/g_sorcery/metadata.py
index da4d291..1ce8fdc 100644
--- a/g_sorcery/metadata.py
+++ b/g_sorcery/metadata.py
@@ -17,7 +17,7 @@ import xml.etree.ElementTree as ET
import xml.dom.minidom as minidom
def prettify(tree):
- rough_str = ET.tostring(tree, 'unicode')
+ rough_str = ET.tostring(tree, "utf-8").decode("utf-8")
reparsed = minidom.parseString(rough_str)
return reparsed.toprettyxml(encoding="utf-8").decode("utf-8")
diff --git a/tests/test_metadata.py b/tests/test_metadata.py
index 39155fb..288d8b1 100644
--- a/tests/test_metadata.py
+++ b/tests/test_metadata.py
@@ -19,6 +19,9 @@ from g_sorcery import exceptions, metadata, package_db
from tests.base import BaseTest
+def tostring(element):
+ return ET.tostring(element, encoding='utf-8').decode('utf-8')
+
class TestXMLGenerator(BaseTest):
def test_generate(self):
@@ -52,22 +55,22 @@ class TestXMLGenerator(BaseTest):
xg = metadata.XMLGenerator('test_ext', schema)
self.assertRaises(exceptions.XMLGeneratorError, xg.generate, {})
tree = xg.generate({'desc' : 'test xml'})
- self.assertEqual(ET.tostring(tree, encoding='unicode'),
+ self.assertEqual(tostring(tree),
'<test_ext><desc>test xml</desc></test_ext>')
tree = xg.generate({'desc' : 'test xml',
'contact' : {'email' : 'test@example.com',
'phone' : '00-0'}})
- self.assertEqual(ET.tostring(tree, encoding='unicode'),
+ self.assertEqual(tostring(tree),
'<test_ext><desc>test xml</desc><contact><email>test@example.com\
</email><phone>00-0</phone></contact></test_ext>')
tree = xg.generate({'desc' : 'test xml',
'multiple' : ['test1', 'test2', 'test3']})
- self.assertEqual(ET.tostring(tree, encoding='unicode'),
+ self.assertEqual(tostring(tree),
'<test_ext><desc>test xml</desc><multiple>test1</multiple>\
<multiple>test2</multiple><multiple>test3</multiple></test_ext>')
tree = xg.generate({'desc' : 'test xml',
'flag' : [('flag1', 'test1'), ('flag2', 'test2')]})
- self.assertEqual(ET.tostring(tree, encoding='unicode'),
+ self.assertEqual(tostring(tree),
'<test_ext><desc>test xml</desc><flag name="flag1">test1</flag>\
<flag name="flag2">test2</flag></test_ext>')
@@ -109,7 +112,7 @@ class TestMetadataGenerator(BaseTest):
def test_process(self):
mg = DummyMetadataGenerator(None)
- self.assertEqual(ET.tostring(mg.process(None, description), encoding='unicode'),
+ self.assertEqual(tostring(mg.process(None, description)),
'<pkgmetadata><herd>test</herd><maintainer><email>test@example.com</email>\
<name>testor</name></maintainer><longdescription>test metadata</longdescription><use>\
<flag name="flag1">test flag1</flag><flag name="flag2">test flag2</flag></use>\
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-07-02 12:25 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-07-02 12:25 UTC (permalink / raw
To: gentoo-commits
commit: 7c3f2ef461e92ef610ea835997c21921a8b4d05f
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Tue Jul 2 12:26:25 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Tue Jul 2 12:26:25 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=7c3f2ef4
base class for tests and initial commit for py2 compatibility module
---
g_sorcery/compatibility.py | 21 +++++++++++++++++++++
tests/base.py | 24 ++++++++++++++++++++++++
tests/test_backend.py | 10 +++-------
tests/test_dummy.py | 7 +++----
tests/test_ebuild.py | 18 ++++--------------
tests/test_elpa_db.py | 7 ++-----
tests/test_fileutils.py | 8 +++-----
tests/test_g_sorcery.py | 16 +++++-----------
tests/test_metadata.py | 14 +++-----------
tests/test_package_db.py | 8 +++++---
10 files changed, 73 insertions(+), 60 deletions(-)
diff --git a/g_sorcery/compatibility.py b/g_sorcery/compatibility.py
new file mode 100644
index 0000000..ea6f3bf
--- /dev/null
+++ b/g_sorcery/compatibility.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+ compatibility.py
+ ~~~~~~~~~~~~~~~~
+
+ utilities for py2 compatibility
+
+ :copyright: (c) 2013 by Jauhien Piatlicki
+ :license: GPL-2, see LICENSE for more details.
+"""
+
+import sys
+
+py2k = sys.version_info < (3, 0)
+
+if py2k:
+ pass
+else:
+ from tempfile import TemporaryDirectory
diff --git a/tests/base.py b/tests/base.py
new file mode 100644
index 0000000..0c3270a
--- /dev/null
+++ b/tests/base.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+ base.py
+ ~~~~~~~
+
+ base class for tests
+
+ :copyright: (c) 2013 by Jauhien Piatlicki
+ :license: GPL-2, see LICENSE for more details.
+"""
+
+import unittest
+
+from g_sorcery.compatibility import TemporaryDirectory
+
+class BaseTest(unittest.TestCase):
+
+ def setUp(self):
+ self.tempdir = TemporaryDirectory()
+
+ def tearDown(self):
+ del self.tempdir
diff --git a/tests/test_backend.py b/tests/test_backend.py
index 65e136d..2c28f79 100644
--- a/tests/test_backend.py
+++ b/tests/test_backend.py
@@ -17,6 +17,8 @@ from g_sorcery import backend, ebuild, metadata, package_db
from tests import test_ebuild, test_metadata
+from tests.base import BaseTest
+
class DummyBackend(backend.Backend):
def __init__(self, PackageDB, EbuildGenrator, MetadataGenerator, directory,
sync_db=True, eclass_dir=""):
@@ -24,14 +26,8 @@ class DummyBackend(backend.Backend):
sync_db=sync_db, eclass_dir=eclass_dir)
-class TestBackend(unittest.TestCase):
+class TestBackend(BaseTest):
- def setUp(self):
- self.tempdir = tempfile.TemporaryDirectory()
-
- def tearDown(self):
- del self.tempdir
-
def test_list_eclasses(self):
backend = DummyBackend(package_db.PackageDB, ebuild.EbuildGenerator,
metadata.MetadataGenerator,
diff --git a/tests/test_dummy.py b/tests/test_dummy.py
index dfa9700..58df716 100644
--- a/tests/test_dummy.py
+++ b/tests/test_dummy.py
@@ -13,10 +13,9 @@
import unittest
-class TestDummy(unittest.TestCase):
-
- def setUp(self):
- pass
+from tests.base import BaseTest
+
+class TestDummy(BaseTest):
def test_dummy(self):
self.assertEqual('works', 'works')
diff --git a/tests/test_ebuild.py b/tests/test_ebuild.py
index 52c34f5..8e7aca4 100644
--- a/tests/test_ebuild.py
+++ b/tests/test_ebuild.py
@@ -15,6 +15,8 @@ import os, tempfile, unittest
from g_sorcery import ebuild, package_db
+from tests.base import BaseTest
+
package = package_db.Package("app-test", "test", "0.1")
package2 = package_db.Package("app-test", "tst", "1")
@@ -36,13 +38,7 @@ class DummyEbuildGenerator(ebuild.EbuildGenerator):
return tmpl
-class TestEbuildGenerator(unittest.TestCase):
-
- def setUp(self):
- self.tempdir = tempfile.TemporaryDirectory()
-
- def tearDown(self):
- del self.tempdir
+class TestEbuildGenerator(BaseTest):
def test_process(self):
eg = DummyEbuildGenerator(None)
@@ -69,13 +65,7 @@ class DummyEbuildGeneratorFromFile(ebuild.EbuildGeneratorFromFile):
return self.path
-class TestEbuildGeneratorFromFile(unittest.TestCase):
-
- def setUp(self):
- self.tempdir = tempfile.TemporaryDirectory()
-
- def tearDown(self):
- del self.tempdir
+class TestEbuildGeneratorFromFile(BaseTest):
def test_generate(self):
db = DummyDB(os.path.join(self.tempdir.name, 'tstdb'))
diff --git a/tests/test_elpa_db.py b/tests/test_elpa_db.py
index 97ce4e2..874ee96 100644
--- a/tests/test_elpa_db.py
+++ b/tests/test_elpa_db.py
@@ -19,12 +19,9 @@ from g_sorcery import exceptions, package_db
from tests.server import Server
-class TestElpaDB(unittest.TestCase):
- def setUp(self):
- self.tempdir = tempfile.TemporaryDirectory()
+from tests.base import BaseTest
- def tearDown(self):
- del self.tempdir
+class TestElpaDB(BaseTest):
def test_generate(self):
prev = os.getcwd()
diff --git a/tests/test_fileutils.py b/tests/test_fileutils.py
index 1760444..1e3ab1f 100644
--- a/tests/test_fileutils.py
+++ b/tests/test_fileutils.py
@@ -15,17 +15,15 @@ import json, os, shutil, tempfile, unittest
from g_sorcery import exceptions, fileutils
+from tests.base import BaseTest
-class TestFileJSON(unittest.TestCase):
+class TestFileJSON(BaseTest):
def setUp(self):
- self.tempdir = tempfile.TemporaryDirectory()
+ super().setUp()
self.path = os.path.join(self.tempdir.name, 'tst')
self.name = 'tst.json'
- def tearDown(self):
- del self.tempdir
-
def do_test_read_ok(self, mandatories, value_suffix=""):
f = fileutils.FileJSON(self.path, self.name, mandatories)
content = f.read()
diff --git a/tests/test_g_sorcery.py b/tests/test_g_sorcery.py
index 4b18474..bc91e97 100644
--- a/tests/test_g_sorcery.py
+++ b/tests/test_g_sorcery.py
@@ -17,17 +17,16 @@ from g_sorcery import g_sorcery
from tests.dummy_backend import backend as dummyBackend
-class TestBin(unittest.TestCase):
+from tests.base import BaseTest
+
+class TestBin(BaseTest):
def setUp(self):
- self.tempdir = tempfile.TemporaryDirectory()
+ super().setUp()
binpath = os.path.join(os.path.dirname(
os.path.dirname(os.path.realpath(__file__))), 'bin')
self.binary = os.path.join(binpath, 'g-sorcery')
- def tearDown(self):
- del self.tempdir
-
def test_g_sorcery(self):
self.assertEqual(subprocess.check_output(self.binary), b'g-sorcery\n')
@@ -55,12 +54,7 @@ class TestBin(unittest.TestCase):
dummyBackend.instance.test())
os.chdir(prev)
-class TestGSorcery(unittest.TestCase):
- def setUp(self):
- self.tempdir = tempfile.TemporaryDirectory()
-
- def tearDown(self):
- del self.tempdir
+class TestGSorcery(BaseTest):
def test_get_backend(self):
self.assertEqual(g_sorcery.get_backend('nonexistent_backend'), None)
diff --git a/tests/test_metadata.py b/tests/test_metadata.py
index 9bb1f43..4906541 100644
--- a/tests/test_metadata.py
+++ b/tests/test_metadata.py
@@ -17,12 +17,9 @@ import tempfile, unittest
from g_sorcery import exceptions, metadata, package_db
-class TestXMLGenerator(unittest.TestCase):
- def setUp(self):
- pass
+from tests.base import BaseTest
- def tearDown(self):
- pass
+class TestXMLGenerator(BaseTest):
def test_generate(self):
schema = [{'name' : 'desc',
@@ -108,12 +105,7 @@ class DummyDB(package_db.PackageDB):
self.add_package(package, description)
-class TestMetadataGenerator(unittest.TestCase):
- def setUp(self):
- self.tempdir = tempfile.TemporaryDirectory()
-
- def tearDown(self):
- del self.tempdir
+class TestMetadataGenerator(BaseTest):
def test_process(self):
mg = DummyMetadataGenerator(None)
diff --git a/tests/test_package_db.py b/tests/test_package_db.py
index 1433eb7..6b1004e 100644
--- a/tests/test_package_db.py
+++ b/tests/test_package_db.py
@@ -17,6 +17,8 @@ from g_sorcery import package_db, exceptions
from tests.server import Server
+from tests.base import BaseTest
+
class DummyDB(package_db.PackageDB):
def __init__(self, directory, packages):
super().__init__(directory)
@@ -33,10 +35,10 @@ class DummyDB(package_db.PackageDB):
return self.db_uri + '/dummy.tar.gz'
-class TestDummyDB(unittest.TestCase):
+class TestDummyDB(BaseTest):
def setUp(self):
- self.tempdir = tempfile.TemporaryDirectory()
+ super().setUp()
category1 = 'app-test'
category2 = 'dev-test'
self.packages = [package_db.Package(category1, 'test', '0.2'),
@@ -47,7 +49,7 @@ class TestDummyDB(unittest.TestCase):
package_db.Package(category2, 'tst', '0.1')]
def tearDown(self):
- del self.tempdir
+ super().tearDown()
def test_manifest(self):
db = DummyDB(self.tempdir.name, self.packages)
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-07-01 20:51 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-07-01 20:51 UTC (permalink / raw
To: gentoo-commits
commit: 32e17174a95099bbbbcce8cdb83bb4573308753e
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Mon Jul 1 20:52:46 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Mon Jul 1 20:52:46 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=32e17174
g_sorcery/g_sorcery: backend config, initial commit
---
g_sorcery/g_sorcery.py | 29 +++++++++++++++++++++++++++--
tests/test_g_sorcery.py | 25 +++++++++++++++++++++----
2 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/g_sorcery/g_sorcery.py b/g_sorcery/g_sorcery.py
index dd90c96..4b1784a 100644
--- a/g_sorcery/g_sorcery.py
+++ b/g_sorcery/g_sorcery.py
@@ -11,10 +11,35 @@
:license: GPL-2, see LICENSE for more details.
"""
-import sys
+import os, sys
+
+from .fileutils import FileJSON
+
+from .exceptions import FileJSONError
def main():
- print('it works')
+ name = os.path.basename(sys.argv[0])
+ if name == 'g-sorcery':
+ print(name)
+ return 0
+ else:
+ cfg = name + '.json'
+ cfg_path = None
+ for path in '.', '/etc/g-sorcery', '~':
+ current = os.path.join(path, cfg)
+ if (os.path.isfile(current)):
+ cfg_path = path
+ break
+ if not cfg_path:
+ sys.stderr.write('g-sorcery error: no config file for ' + name + ' backend\n')
+ return -1
+ cfg_f = FileJSON(cfg_path, cfg, ['package'])
+ try:
+ config = cfg_f.read()
+ except FileJSONError as e:
+ sys.stderr.write('g-sorcery error in config file for ' + name + ': ' + str(e) + '\n')
+ return -1
+ pass
if __name__ == "__main__":
sys.exit(main())
diff --git a/tests/test_g_sorcery.py b/tests/test_g_sorcery.py
index 7241b19..7ff9992 100644
--- a/tests/test_g_sorcery.py
+++ b/tests/test_g_sorcery.py
@@ -16,18 +16,35 @@ import os, subprocess, tempfile, unittest
class TestBin(unittest.TestCase):
def setUp(self):
self.tempdir = tempfile.TemporaryDirectory()
+
+ binpath = os.path.join(os.path.dirname(
+ os.path.dirname(os.path.realpath(__file__))), 'bin')
+ self.binary = os.path.join(binpath, 'g-sorcery')
def tearDown(self):
del self.tempdir
def test_g_sorcery(self):
- binpath = os.path.join(os.path.split(
- os.path.dirname(os.path.realpath(__file__)))[0], 'bin')
- binary = os.path.join(binpath, 'g-sorcery')
- self.assertEqual(subprocess.check_output(binary), b'it works\n')
+ self.assertEqual(subprocess.check_output(self.binary), b'g-sorcery\n')
+ def test_nonexistent_backend(self):
+ prev = os.getcwd()
+ os.chdir(self.tempdir.name)
+ os.system('ln -s ' + self.binary + ' g-nonexistent')
+ self.assertRaises(subprocess.CalledProcessError, subprocess.check_output, './g-nonexistent')
+ os.chdir(prev)
+
+ def test_empty_config(self):
+ prev = os.getcwd()
+ os.chdir(self.tempdir.name)
+ os.system('ln -s ' + self.binary + ' g-empty')
+ os.system('echo {} > ./g-empty.json')
+ self.assertRaises(subprocess.CalledProcessError, subprocess.check_output, './g-empty')
+ os.chdir(prev)
def suite():
suite = unittest.TestSuite()
suite.addTest(TestBin('test_g_sorcery'))
+ suite.addTest(TestBin('test_nonexistent_backend'))
+ suite.addTest(TestBin('test_empty_config'))
return suite
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-07-01 20:51 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-07-01 20:51 UTC (permalink / raw
To: gentoo-commits
commit: 6faf8d5ab5dc16f193acc1d344bf473e1eaa4808
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Mon Jul 1 20:14:03 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Mon Jul 1 20:14:03 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=6faf8d5a
g_sorcery/fileutils: file utilities moved to separate module
---
g_sorcery/fileutils.py | 72 ++++++++++++++++++++++++++++
g_sorcery/package_db.py | 64 ++-----------------------
tests/test_fileutils.py | 121 +++++++++++++++++++++++++++++++++++++++++++++++
tests/test_package_db.py | 100 ---------------------------------------
4 files changed, 198 insertions(+), 159 deletions(-)
diff --git a/g_sorcery/fileutils.py b/g_sorcery/fileutils.py
new file mode 100644
index 0000000..1920495
--- /dev/null
+++ b/g_sorcery/fileutils.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+ fileutils.py
+ ~~~~~~~~~~~~
+
+ file utilities
+
+ :copyright: (c) 2013 by Jauhien Piatlicki
+ :license: GPL-2, see LICENSE for more details.
+"""
+
+import json, os, shutil
+
+from .exceptions import FileJSONError
+
+class FileJSON:
+ def __init__(self, directory, name, mandatories):
+ """
+ Initialize
+
+ mandatories -- list of mandatory keys
+ """
+ self.directory = os.path.abspath(directory)
+ self.name = name
+ self.path = os.path.join(directory, name)
+ self.mandatories = mandatories
+
+ def read(self):
+ if not os.path.exists(self.directory):
+ os.makedirs(self.directory)
+ content = {}
+ if not os.path.isfile(self.path):
+ for key in self.mandatories:
+ content[key] = ""
+ with open(self.path, 'w') as f:
+ json.dump(content, f, indent=2, sort_keys=True)
+ else:
+ with open(self.path, 'r') as f:
+ content = json.load(f)
+ for key in self.mandatories:
+ if not key in content:
+ raise FileJSONError('lack of mandatory key: ' + key)
+ return content
+
+ def write(self, content):
+ for key in self.mandatories:
+ if not key in content:
+ raise FileJSONError('lack of mandatory key: ' + key)
+ if not os.path.exists(self.directory):
+ os.makedirs(self.directory)
+ with open(self.path, 'w') as f:
+ json.dump(content, f, indent=2, sort_keys=True)
+
+
+def hash_file(name, hasher, blocksize=65536):
+ with open(name, 'rb') as f:
+ buf = f.read(blocksize)
+ while len(buf) > 0:
+ hasher.update(buf)
+ buf = f.read(blocksize)
+ return hasher.hexdigest()
+
+def copy_all(src, dst):
+ for f_name in os.listdir(src):
+ src_name = os.path.join(src, f_name)
+ dst_name = os.path.join(dst, f_name)
+ if os.path.isdir(src_name):
+ shutil.copytree(src_name, dst_name)
+ else:
+ shutil.copy2(src_name, dst_name)
diff --git a/g_sorcery/package_db.py b/g_sorcery/package_db.py
index 561129d..fc59878 100644
--- a/g_sorcery/package_db.py
+++ b/g_sorcery/package_db.py
@@ -11,70 +11,16 @@
:license: GPL-2, see LICENSE for more details.
"""
-from .exceptions import DBStructureError, FileJSONError, IntegrityError, \
+from .exceptions import DBStructureError, IntegrityError, \
InvalidKeyError, SyncError
-import portage
-
-import collections, glob, hashlib, json, os, shutil, tarfile, tempfile
+from .fileutils import FileJSON, hash_file, copy_all
-Package = collections.namedtuple("Package", "category name version")
+import portage
-class FileJSON:
- def __init__(self, directory, name, mandatories):
- """
- Initialize
+import collections, glob, hashlib, os, shutil, tarfile, tempfile
- mandatories -- list of mandatory keys
- """
- self.directory = os.path.abspath(directory)
- self.name = name
- self.path = os.path.join(directory, name)
- self.mandatories = mandatories
-
- def read(self):
- if not os.path.exists(self.directory):
- os.makedirs(self.directory)
- content = {}
- if not os.path.isfile(self.path):
- for key in self.mandatories:
- content[key] = ""
- with open(self.path, 'w') as f:
- json.dump(content, f, indent=2, sort_keys=True)
- else:
- with open(self.path, 'r') as f:
- content = json.load(f)
- for key in self.mandatories:
- if not key in content:
- raise FileJSONError('lack of mandatory key: ' + key)
- return content
-
- def write(self, content):
- for key in self.mandatories:
- if not key in content:
- raise FileJSONError('lack of mandatory key: ' + key)
- if not os.path.exists(self.directory):
- os.makedirs(self.directory)
- with open(self.path, 'w') as f:
- json.dump(content, f, indent=2, sort_keys=True)
-
-
-def hash_file(name, hasher, blocksize=65536):
- with open(name, 'rb') as f:
- buf = f.read(blocksize)
- while len(buf) > 0:
- hasher.update(buf)
- buf = f.read(blocksize)
- return hasher.hexdigest()
-
-def copy_all(src, dst):
- for f_name in os.listdir(src):
- src_name = os.path.join(src, f_name)
- dst_name = os.path.join(dst, f_name)
- if os.path.isdir(src_name):
- shutil.copytree(src_name, dst_name)
- else:
- shutil.copy2(src_name, dst_name)
+Package = collections.namedtuple("Package", "category name version")
class PackageDB:
def __init__(self, directory, repo_uri="", db_uri=""):
diff --git a/tests/test_fileutils.py b/tests/test_fileutils.py
new file mode 100644
index 0000000..1760444
--- /dev/null
+++ b/tests/test_fileutils.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+ fileutils.py
+ ~~~~~~~~~~~~
+
+ file utilities test suite
+
+ :copyright: (c) 2013 by Jauhien Piatlicki
+ :license: GPL-2, see LICENSE for more details.
+"""
+
+import json, os, shutil, tempfile, unittest
+
+from g_sorcery import exceptions, fileutils
+
+
+class TestFileJSON(unittest.TestCase):
+
+ def setUp(self):
+ self.tempdir = tempfile.TemporaryDirectory()
+ self.path = os.path.join(self.tempdir.name, 'tst')
+ self.name = 'tst.json'
+
+ def tearDown(self):
+ del self.tempdir
+
+ def do_test_read_ok(self, mandatories, value_suffix=""):
+ f = fileutils.FileJSON(self.path, self.name, mandatories)
+ content = f.read()
+ for key in mandatories:
+ self.assertTrue(key in content)
+ if value_suffix:
+ value = key + value_suffix
+ else:
+ value = ""
+ self.assertEqual(content[key], value)
+ self.assertTrue(os.path.isfile(os.path.join(self.path, self.name)))
+ with open(os.path.join(self.path, self.name), 'r') as f:
+ content_f = json.load(f)
+ self.assertEqual(content, content_f)
+
+ def test_read_dir_does_not_exist(self):
+ mandatories = ['tst1', 'tst2', 'tst3']
+ self.do_test_read_ok(mandatories)
+
+ def test_read_file_does_not_exist(self):
+ os.makedirs(self.path)
+ mandatories = ['tst1', 'tst2', 'tst3']
+ self.do_test_read_ok(mandatories)
+
+ def test_read_all_keys(self):
+ os.makedirs(self.path)
+ mandatories = ['tst1', 'tst2', 'tst3']
+ content = {}
+ for key in mandatories:
+ content[key] = key + "_v"
+ with open(os.path.join(self.path, self.name), 'w') as f:
+ json.dump(content, f)
+ self.do_test_read_ok(mandatories, "_v")
+
+ def test_read_missing_keys(self):
+ os.makedirs(self.path)
+ mandatories = ['tst1', 'tst2', 'tst3']
+ content = {}
+ for key in mandatories:
+ content[key] = key + "_v"
+ with open(os.path.join(self.path, self.name), 'w') as f:
+ json.dump(content, f)
+ f = fileutils.FileJSON(self.path, self.name, mandatories)
+ mandatories.append("tst4")
+ self.assertRaises(exceptions.FileJSONError, f.read)
+
+ def do_test_write_ok(self):
+ mandatories = ['tst1', 'tst2', 'tst3']
+ content = {}
+ for key in mandatories:
+ content[key] = key + '_v'
+ f = fileutils.FileJSON(self.path, self.name, mandatories)
+ f.write(content)
+ self.assertTrue(os.path.isfile(os.path.join(self.path, self.name)))
+ with open(os.path.join(self.path, self.name), 'r') as f:
+ content_f = json.load(f)
+ self.assertEqual(content, content_f)
+
+ def test_write_missing_keys(self):
+ content = {'tst1' : '', 'tst2' : ''}
+ mandatories = ['tst1', 'tst2', 'tst3']
+ f = fileutils.FileJSON(self.path, self.name, mandatories)
+ self.assertRaises(exceptions.FileJSONError, f.write, content)
+
+ def test_write_dir_does_not_exist(self):
+ self.do_test_write_ok()
+
+ def test_write_file_does_not_exist(self):
+ os.makedirs(self.path)
+ self.do_test_write_ok()
+
+ def test_write_all_keys(self):
+ os.makedirs(self.path)
+ mandatories = ['tst11', 'tst12']
+ content = {}
+ for key in mandatories:
+ content[key] = key + "_v"
+ with open(os.path.join(self.path, self.name), 'w') as f:
+ json.dump(content, f)
+ self.do_test_write_ok()
+
+
+def suite():
+ suite = unittest.TestSuite()
+ suite.addTest(TestFileJSON('test_read_dir_does_not_exist'))
+ suite.addTest(TestFileJSON('test_read_file_does_not_exist'))
+ suite.addTest(TestFileJSON('test_read_all_keys'))
+ suite.addTest(TestFileJSON('test_read_missing_keys'))
+ suite.addTest(TestFileJSON('test_write_missing_keys'))
+ suite.addTest(TestFileJSON('test_write_dir_does_not_exist'))
+ suite.addTest(TestFileJSON('test_write_file_does_not_exist'))
+ suite.addTest(TestFileJSON('test_write_all_keys'))
+ return suite
diff --git a/tests/test_package_db.py b/tests/test_package_db.py
index c5d7074..2994157 100644
--- a/tests/test_package_db.py
+++ b/tests/test_package_db.py
@@ -30,98 +30,6 @@ class Server(threading.Thread):
self.httpd.shutdown()
-class TestFileJSON(unittest.TestCase):
-
- def setUp(self):
- self.tempdir = tempfile.TemporaryDirectory()
- self.path = os.path.join(self.tempdir.name, 'tst')
- self.name = 'tst.json'
-
- def tearDown(self):
- del self.tempdir
-
- def do_test_read_ok(self, mandatories, value_suffix=""):
- f = package_db.FileJSON(self.path, self.name, mandatories)
- content = f.read()
- for key in mandatories:
- self.assertTrue(key in content)
- if value_suffix:
- value = key + value_suffix
- else:
- value = ""
- self.assertEqual(content[key], value)
- self.assertTrue(os.path.isfile(os.path.join(self.path, self.name)))
- with open(os.path.join(self.path, self.name), 'r') as f:
- content_f = json.load(f)
- self.assertEqual(content, content_f)
-
- def test_read_dir_does_not_exist(self):
- mandatories = ['tst1', 'tst2', 'tst3']
- self.do_test_read_ok(mandatories)
-
- def test_read_file_does_not_exist(self):
- os.makedirs(self.path)
- mandatories = ['tst1', 'tst2', 'tst3']
- self.do_test_read_ok(mandatories)
-
- def test_read_all_keys(self):
- os.makedirs(self.path)
- mandatories = ['tst1', 'tst2', 'tst3']
- content = {}
- for key in mandatories:
- content[key] = key + "_v"
- with open(os.path.join(self.path, self.name), 'w') as f:
- json.dump(content, f)
- self.do_test_read_ok(mandatories, "_v")
-
- def test_read_missing_keys(self):
- os.makedirs(self.path)
- mandatories = ['tst1', 'tst2', 'tst3']
- content = {}
- for key in mandatories:
- content[key] = key + "_v"
- with open(os.path.join(self.path, self.name), 'w') as f:
- json.dump(content, f)
- f = package_db.FileJSON(self.path, self.name, mandatories)
- mandatories.append("tst4")
- self.assertRaises(exceptions.FileJSONError, f.read)
-
- def do_test_write_ok(self):
- mandatories = ['tst1', 'tst2', 'tst3']
- content = {}
- for key in mandatories:
- content[key] = key + '_v'
- f = package_db.FileJSON(self.path, self.name, mandatories)
- f.write(content)
- self.assertTrue(os.path.isfile(os.path.join(self.path, self.name)))
- with open(os.path.join(self.path, self.name), 'r') as f:
- content_f = json.load(f)
- self.assertEqual(content, content_f)
-
- def test_write_missing_keys(self):
- content = {'tst1' : '', 'tst2' : ''}
- mandatories = ['tst1', 'tst2', 'tst3']
- f = package_db.FileJSON(self.path, self.name, mandatories)
- self.assertRaises(exceptions.FileJSONError, f.write, content)
-
- def test_write_dir_does_not_exist(self):
- self.do_test_write_ok()
-
- def test_write_file_does_not_exist(self):
- os.makedirs(self.path)
- self.do_test_write_ok()
-
- def test_write_all_keys(self):
- os.makedirs(self.path)
- mandatories = ['tst11', 'tst12']
- content = {}
- for key in mandatories:
- content[key] = key + "_v"
- with open(os.path.join(self.path, self.name), 'w') as f:
- json.dump(content, f)
- self.do_test_write_ok()
-
-
class DummyDB(package_db.PackageDB):
def __init__(self, directory, packages):
super().__init__(directory)
@@ -227,14 +135,6 @@ class TestDummyDB(unittest.TestCase):
def suite():
suite = unittest.TestSuite()
- suite.addTest(TestFileJSON('test_read_dir_does_not_exist'))
- suite.addTest(TestFileJSON('test_read_file_does_not_exist'))
- suite.addTest(TestFileJSON('test_read_all_keys'))
- suite.addTest(TestFileJSON('test_read_missing_keys'))
- suite.addTest(TestFileJSON('test_write_missing_keys'))
- suite.addTest(TestFileJSON('test_write_dir_does_not_exist'))
- suite.addTest(TestFileJSON('test_write_file_does_not_exist'))
- suite.addTest(TestFileJSON('test_write_all_keys'))
suite.addTest(TestDummyDB('test_manifest'))
suite.addTest(TestDummyDB('test_read'))
suite.addTest(TestDummyDB('test_list_categories'))
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-07-01 0:05 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-07-01 0:05 UTC (permalink / raw
To: gentoo-commits
commit: e34a7a1d98b0a3b1ff1a8ea35d1a70134989e555
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Mon Jul 1 00:06:52 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Mon Jul 1 00:06:52 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=e34a7a1d
g_sorcery/backend: generate_metadata
---
g_sorcery/backend.py | 9 +++++++--
g_sorcery/package_db.py | 14 ++++++++++++++
tests/test_backend.py | 23 +++++++++++++++++++----
tests/test_metadata.py | 26 ++++++++++++++------------
tests/test_package_db.py | 6 ++++++
5 files changed, 60 insertions(+), 18 deletions(-)
diff --git a/g_sorcery/backend.py b/g_sorcery/backend.py
index 476a8a4..f472a85 100644
--- a/g_sorcery/backend.py
+++ b/g_sorcery/backend.py
@@ -13,8 +13,10 @@
import glob, os
+from .package_db import Package
+
class Backend:
- def __init__(self, PackageDB, EbuildGenrator, directory,
+ def __init__(self, PackageDB, EbuildGenrator, MetadataGenerator, directory,
repo_uri="", db_uri="", sync_db=True, eclass_dir=""):
self.sync_db = sync_db
self.repo_uri = repo_uri
@@ -32,6 +34,7 @@ class Backend:
self.db_uri = self.db.db_uri
self.eg = EbuildGenrator(self.db)
+ self.mg = MetadataGenerator(self.db)
def sync(self):
if self.sync_db and not self.db_uri:
@@ -69,4 +72,6 @@ class Backend:
return eclass
def generate_metadata(self, category, name):
- pass
+ version = self.db.get_max_version(category, name)
+ metadata = self.mg.generate(Package(category, name, version))
+ return metadata
diff --git a/g_sorcery/package_db.py b/g_sorcery/package_db.py
index b4f6193..561129d 100644
--- a/g_sorcery/package_db.py
+++ b/g_sorcery/package_db.py
@@ -14,6 +14,8 @@
from .exceptions import DBStructureError, FileJSONError, IntegrityError, \
InvalidKeyError, SyncError
+import portage
+
import collections, glob, hashlib, json, os, shutil, tarfile, tempfile
Package = collections.namedtuple("Package", "category name version")
@@ -353,3 +355,15 @@ class PackageDB:
def get_package_description(self, package):
#a possible exception should be catched in the caller
return self.db[package.category + '/' + package.name][package.version]
+
+ def get_max_version(self, category, name):
+ pkgname = category + '/' + name
+ if not pkgname in self.db:
+ raise InvalidKeyError('No such package: ' + pkgname)
+ versions = list(self.db[pkgname])
+ max_ver = versions[0]
+ for version in versions[1:]:
+ if portage.pkgcmp(portage.pkgsplit(pkgname + '-' + version),
+ portage.pkgsplit(pkgname + '-' + max_ver)) > 0:
+ max_ver = version
+ return max_ver
diff --git a/tests/test_backend.py b/tests/test_backend.py
index 027f4a8..65e136d 100644
--- a/tests/test_backend.py
+++ b/tests/test_backend.py
@@ -13,14 +13,14 @@
import os, tempfile, unittest
-from g_sorcery import backend, ebuild, package_db
+from g_sorcery import backend, ebuild, metadata, package_db
-from tests import test_ebuild
+from tests import test_ebuild, test_metadata
class DummyBackend(backend.Backend):
- def __init__(self, PackageDB, EbuildGenrator, directory,
+ def __init__(self, PackageDB, EbuildGenrator, MetadataGenerator, directory,
sync_db=True, eclass_dir=""):
- super().__init__(PackageDB, EbuildGenrator, directory,
+ super().__init__(PackageDB, EbuildGenrator, MetadataGenerator, directory,
sync_db=sync_db, eclass_dir=eclass_dir)
@@ -34,6 +34,7 @@ class TestBackend(unittest.TestCase):
def test_list_eclasses(self):
backend = DummyBackend(package_db.PackageDB, ebuild.EbuildGenerator,
+ metadata.MetadataGenerator,
self.tempdir.name, eclass_dir = self.tempdir.name)
self.assertEqual(backend.list_eclasses(), [])
lst = ['test', 'supertest', 'anothertest']
@@ -44,6 +45,7 @@ class TestBackend(unittest.TestCase):
def test_generate_eclass(self):
backend = DummyBackend(package_db.PackageDB, ebuild.EbuildGenerator,
+ metadata.MetadataGenerator,
self.tempdir.name, eclass_dir = self.tempdir.name)
eclass = ["testing eclass", "nothing interesting here"]
eclass_name = "test"
@@ -55,6 +57,7 @@ class TestBackend(unittest.TestCase):
def test_list_ebuilds(self):
backend = DummyBackend(test_ebuild.DummyDB, test_ebuild.DummyEbuildGenerator,
+ metadata.MetadataGenerator,
self.tempdir.name, eclass_dir = self.tempdir.name, sync_db = False)
backend.sync()
ebuilds = backend.list_ebuilds()
@@ -62,16 +65,28 @@ class TestBackend(unittest.TestCase):
def test_generate_ebuild(self):
backend = DummyBackend(test_ebuild.DummyDB, test_ebuild.DummyEbuildGenerator,
+ metadata.MetadataGenerator,
self.tempdir.name, eclass_dir = self.tempdir.name, sync_db = False)
backend.sync()
ebuild = backend.generate_ebuild(test_ebuild.package)
self.assertEqual(ebuild, ['test', 'author: jauhien',
'homepage: 127.0.0.1', 'var: $var'])
+ def test_generate_metadata(self):
+ backend = DummyBackend(test_metadata.DummyDB, ebuild.EbuildGenerator,
+ metadata.MetadataGenerator,
+ self.tempdir.name, eclass_dir = self.tempdir.name, sync_db = False)
+ backend.sync()
+ self.assertEqual(backend.generate_metadata("app-test", "test"),
+ test_metadata.resulting_metadata)
+
+
+
def suite():
suite = unittest.TestSuite()
suite.addTest(TestBackend('test_list_eclasses'))
suite.addTest(TestBackend('test_generate_eclass'))
suite.addTest(TestBackend('test_list_ebuilds'))
suite.addTest(TestBackend('test_generate_ebuild'))
+ suite.addTest(TestBackend('test_generate_metadata'))
return suite
diff --git a/tests/test_metadata.py b/tests/test_metadata.py
index 2398733..9bb1f43 100644
--- a/tests/test_metadata.py
+++ b/tests/test_metadata.py
@@ -87,6 +87,18 @@ description = {'herd' : ['test'],
'use' : {'flag' : [('flag1', 'test flag1'), ('flag2', 'test flag2')]},
'upstream' : {'maintainer' : [{'name' : 'TEST'}], 'remote-id' : '001'}}
+resulting_metadata = ['<?xml version="1.0" encoding="utf-8"?>',
+ '<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">',
+ '<pkgmetadata>', '\t<herd>test</herd>',
+ '\t<maintainer>', '\t\t<email>test@example.com</email>',
+ '\t\t<name>testor</name>', '\t</maintainer>',
+ '\t<longdescription>test metadata</longdescription>',
+ '\t<use>', '\t\t<flag name="flag1">test flag1</flag>',
+ '\t\t<flag name="flag2">test flag2</flag>', '\t</use>',
+ '\t<upstream>', '\t\t<maintainer>', '\t\t\t<name>TEST</name>',
+ '\t\t</maintainer>', '\t\t<remote-id>001</remote-id>',
+ '\t</upstream>', '</pkgmetadata>']
+
class DummyDB(package_db.PackageDB):
def __init__(self, directory, repo_uri="", db_uri=""):
super().__init__(directory, repo_uri, db_uri)
@@ -116,19 +128,9 @@ class TestMetadataGenerator(unittest.TestCase):
db.generate()
mg = DummyMetadataGenerator(db)
metadata = mg.generate(package)
- self.assertEqual(metadata,
- ['<?xml version="1.0" encoding="utf-8"?>',
- '<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">',
- '<pkgmetadata>', '\t<herd>test</herd>',
- '\t<maintainer>', '\t\t<email>test@example.com</email>',
- '\t\t<name>testor</name>', '\t</maintainer>',
- '\t<longdescription>test metadata</longdescription>',
- '\t<use>', '\t\t<flag name="flag1">test flag1</flag>',
- '\t\t<flag name="flag2">test flag2</flag>', '\t</use>',
- '\t<upstream>', '\t\t<maintainer>', '\t\t\t<name>TEST</name>',
- '\t\t</maintainer>', '\t\t<remote-id>001</remote-id>',
- '\t</upstream>', '</pkgmetadata>'])
+ self.assertEqual(metadata, resulting_metadata)
+
def suite():
suite = unittest.TestSuite()
suite.addTest(TestXMLGenerator('test_generate'))
diff --git a/tests/test_package_db.py b/tests/test_package_db.py
index 2b8c482..c5d7074 100644
--- a/tests/test_package_db.py
+++ b/tests/test_package_db.py
@@ -219,6 +219,11 @@ class TestDummyDB(unittest.TestCase):
db = DummyDB(os.path.join(self.tempdir.name, 'testdb'), self.packages)
self.assertRaises(exceptions.SyncError, db.sync, db_uri='127.0.0.1:8080')
+ def test_get_max_version(self):
+ db = DummyDB(os.path.join(self.tempdir.name, 'testdb'), self.packages)
+ db.generate()
+ self.assertEqual(db.get_max_version('dev-test', 'test'), '0.2')
+
def suite():
suite = unittest.TestSuite()
@@ -237,4 +242,5 @@ def suite():
suite.addTest(TestDummyDB('test_list_package_versions'))
suite.addTest(TestDummyDB('test_sync'))
suite.addTest(TestDummyDB('test_sync_fail'))
+ suite.addTest(TestDummyDB('test_get_max_version'))
return suite
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-06-30 23:29 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-06-30 23:29 UTC (permalink / raw
To: gentoo-commits
commit: ad2315d5c047be8696c84d76b64a0cac39aaf2da
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Sun Jun 30 22:19:51 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Sun Jun 30 22:19:51 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=ad2315d5
g_sorcery/metadata: MetadataGenerator, initial commit
---
g_sorcery/metadata.py | 16 ++++++++++++++++
tests/test_metadata.py | 16 ++++++++++++++++
2 files changed, 32 insertions(+)
diff --git a/g_sorcery/metadata.py b/g_sorcery/metadata.py
index ccc344a..c945f70 100644
--- a/g_sorcery/metadata.py
+++ b/g_sorcery/metadata.py
@@ -60,3 +60,19 @@ class XMLGenerator:
else:
child.text = value
+
+class MetadataGenerator:
+ def __init__(self, db):
+ self.db = db
+
+ def generate(self, package):
+ description = self.db.get_package_description(package)
+ metadata = self.process(package, description)
+ metadata = self.postprocess(package, description, metadata)
+ return metadata
+
+ def process(self, package, description):
+ pass
+
+ def postprocess(self, package, description, metadata):
+ return metadata
diff --git a/tests/test_metadata.py b/tests/test_metadata.py
index 91da5bc..8bec86b 100644
--- a/tests/test_metadata.py
+++ b/tests/test_metadata.py
@@ -75,7 +75,23 @@ class TestXMLGenerator(unittest.TestCase):
<flag name="flag2">test2</flag></test_ext>')
+class DummyMetadataGenerator(metadata.MetadataGenerator):
+ def __init__(self, db):
+ super().__init__(db)
+
+class TestMetadataGenerator(unittest.TestCase):
+ def setUp(self):
+ self.tempdir = tempfile.TemporaryDirectory()
+
+ def tearDown(self):
+ del self.tempdir
+
+ def test_process(self):
+ mg = DummyMetadataGenerator(None)
+
+
def suite():
suite = unittest.TestSuite()
suite.addTest(TestXMLGenerator('test_generate'))
+ suite.addTest(TestMetadataGenerator('test_process'))
return suite
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-06-30 23:29 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-06-30 23:29 UTC (permalink / raw
To: gentoo-commits
commit: 5f037f6a973754545e32272abf677a9c48a473e6
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Sun Jun 30 23:07:51 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Sun Jun 30 23:07:51 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=5f037f6a
g_sorcery/metadata: MetadataGenerator, xml generation by description
---
g_sorcery/metadata.py | 3 ++-
tests/test_metadata.py | 11 ++++++++++-
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/g_sorcery/metadata.py b/g_sorcery/metadata.py
index 7ef949a..1ead07a 100644
--- a/g_sorcery/metadata.py
+++ b/g_sorcery/metadata.py
@@ -143,7 +143,8 @@ class MetadataGenerator:
return metadata
def process(self, package, description):
- pass
+ metadata = self.xmlg.generate(description)
+ return metadata
def postprocess(self, package, description, metadata):
return metadata
diff --git a/tests/test_metadata.py b/tests/test_metadata.py
index 8bec86b..aeaac6d 100644
--- a/tests/test_metadata.py
+++ b/tests/test_metadata.py
@@ -88,7 +88,16 @@ class TestMetadataGenerator(unittest.TestCase):
def test_process(self):
mg = DummyMetadataGenerator(None)
-
+ description = {'herd' : ['test'],
+ 'maintainer' : [{'email' : 'test@example.com', 'name' : 'testor'}],
+ 'longdescription' : 'test metadata',
+ 'use' : {'flag' : [('flag1', 'test flag1'), ('flag2', 'test flag2')]},
+ 'upstream' : {'maintainer' : [{'name' : 'TEST'}], 'remote-id' : '001'}}
+ self.assertEqual(ET.tostring(mg.process(None, description), encoding='unicode'),
+ '<pkgmetadata><herd>test</herd><maintainer><email>test@example.com</email>\
+<name>testor</name></maintainer><longdescription>test metadata</longdescription><use>\
+<flag name="flag1">test flag1</flag><flag name="flag2">test flag2</flag></use>\
+<upstream><maintainer><name>TEST</name></maintainer><remote-id>001</remote-id></upstream></pkgmetadata>')
def suite():
suite = unittest.TestSuite()
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-06-30 23:29 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-06-30 23:29 UTC (permalink / raw
To: gentoo-commits
commit: fa7c0ac5f53757d538483c449df7fd5ae233eb7e
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Sun Jun 30 23:30:54 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Sun Jun 30 23:30:54 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=fa7c0ac5
g_sorcery/metadata: MetadataGenerator, generate
---
g_sorcery/metadata.py | 7 ++++++-
tests/test_metadata.py | 43 +++++++++++++++++++++++++++++++++++++------
2 files changed, 43 insertions(+), 7 deletions(-)
diff --git a/g_sorcery/metadata.py b/g_sorcery/metadata.py
index 1ead07a..89d071e 100644
--- a/g_sorcery/metadata.py
+++ b/g_sorcery/metadata.py
@@ -19,7 +19,7 @@ import xml.dom.minidom as minidom
def prettify(tree):
rough_str = ET.tostring(tree, 'unicode')
reparsed = minidom.parseString(rough_str)
- return reparsed.toprettyxml()
+ return reparsed.toprettyxml(encoding="utf-8").decode("utf-8")
class XMLGenerator:
def __init__(self, external, schema):
@@ -140,6 +140,11 @@ class MetadataGenerator:
description = self.db.get_package_description(package)
metadata = self.process(package, description)
metadata = self.postprocess(package, description, metadata)
+ metadata = prettify(metadata)
+ metadata = metadata.split('\n')
+ if metadata[-1] == '':
+ metadata = metadata[:-1]
+ metadata.insert(1, '<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">')
return metadata
def process(self, package, description):
diff --git a/tests/test_metadata.py b/tests/test_metadata.py
index aeaac6d..2398733 100644
--- a/tests/test_metadata.py
+++ b/tests/test_metadata.py
@@ -15,7 +15,7 @@ import xml.etree.ElementTree as ET
import tempfile, unittest
-from g_sorcery import exceptions, metadata
+from g_sorcery import exceptions, metadata, package_db
class TestXMLGenerator(unittest.TestCase):
def setUp(self):
@@ -79,6 +79,23 @@ class DummyMetadataGenerator(metadata.MetadataGenerator):
def __init__(self, db):
super().__init__(db)
+package = package_db.Package("app-test", "test", "0.1")
+
+description = {'herd' : ['test'],
+ 'maintainer' : [{'email' : 'test@example.com', 'name' : 'testor'}],
+ 'longdescription' : 'test metadata',
+ 'use' : {'flag' : [('flag1', 'test flag1'), ('flag2', 'test flag2')]},
+ 'upstream' : {'maintainer' : [{'name' : 'TEST'}], 'remote-id' : '001'}}
+
+class DummyDB(package_db.PackageDB):
+ def __init__(self, directory, repo_uri="", db_uri=""):
+ super().__init__(directory, repo_uri, db_uri)
+
+ def generate_tree(self):
+ self.add_category("app-test")
+ self.add_package(package, description)
+
+
class TestMetadataGenerator(unittest.TestCase):
def setUp(self):
self.tempdir = tempfile.TemporaryDirectory()
@@ -88,19 +105,33 @@ class TestMetadataGenerator(unittest.TestCase):
def test_process(self):
mg = DummyMetadataGenerator(None)
- description = {'herd' : ['test'],
- 'maintainer' : [{'email' : 'test@example.com', 'name' : 'testor'}],
- 'longdescription' : 'test metadata',
- 'use' : {'flag' : [('flag1', 'test flag1'), ('flag2', 'test flag2')]},
- 'upstream' : {'maintainer' : [{'name' : 'TEST'}], 'remote-id' : '001'}}
self.assertEqual(ET.tostring(mg.process(None, description), encoding='unicode'),
'<pkgmetadata><herd>test</herd><maintainer><email>test@example.com</email>\
<name>testor</name></maintainer><longdescription>test metadata</longdescription><use>\
<flag name="flag1">test flag1</flag><flag name="flag2">test flag2</flag></use>\
<upstream><maintainer><name>TEST</name></maintainer><remote-id>001</remote-id></upstream></pkgmetadata>')
+ def test_generate(self):
+ db = DummyDB(self.tempdir.name)
+ db.generate()
+ mg = DummyMetadataGenerator(db)
+ metadata = mg.generate(package)
+ self.assertEqual(metadata,
+ ['<?xml version="1.0" encoding="utf-8"?>',
+ '<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">',
+ '<pkgmetadata>', '\t<herd>test</herd>',
+ '\t<maintainer>', '\t\t<email>test@example.com</email>',
+ '\t\t<name>testor</name>', '\t</maintainer>',
+ '\t<longdescription>test metadata</longdescription>',
+ '\t<use>', '\t\t<flag name="flag1">test flag1</flag>',
+ '\t\t<flag name="flag2">test flag2</flag>', '\t</use>',
+ '\t<upstream>', '\t\t<maintainer>', '\t\t\t<name>TEST</name>',
+ '\t\t</maintainer>', '\t\t<remote-id>001</remote-id>',
+ '\t</upstream>', '</pkgmetadata>'])
+
def suite():
suite = unittest.TestSuite()
suite.addTest(TestXMLGenerator('test_generate'))
suite.addTest(TestMetadataGenerator('test_process'))
+ suite.addTest(TestMetadataGenerator('test_generate'))
return suite
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-06-30 19:55 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-06-30 19:55 UTC (permalink / raw
To: gentoo-commits
commit: e2456139f555f531c6a2a13d002b81725a7c389d
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Sun Jun 30 19:52:17 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Sun Jun 30 19:52:17 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=e2456139
g_sorcery/metadata: XMLGenerator
---
g_sorcery/exceptions.py | 5 ++-
g_sorcery/metadata.py | 62 +++++++++++++++++++++++++++++++++++++
tests/test_metadata.py | 81 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 147 insertions(+), 1 deletion(-)
diff --git a/g_sorcery/exceptions.py b/g_sorcery/exceptions.py
index 857e4ea..38a80b2 100644
--- a/g_sorcery/exceptions.py
+++ b/g_sorcery/exceptions.py
@@ -29,5 +29,8 @@ class IntegrityError(DBError):
class DBStructureError(DBError):
pass
-class FileJSONError(Exception):
+class FileJSONError(GSorceryError):
+ pass
+
+class XMLGeneratorError(GSorceryError):
pass
diff --git a/g_sorcery/metadata.py b/g_sorcery/metadata.py
new file mode 100644
index 0000000..ccc344a
--- /dev/null
+++ b/g_sorcery/metadata.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+ metadata.py
+ ~~~~~~~~~~~
+
+ metadata generation
+
+ :copyright: (c) 2013 by Jauhien Piatlicki
+ :license: GPL-2, see LICENSE for more details.
+"""
+
+from .exceptions import XMLGeneratorError
+
+import xml.etree.ElementTree as ET
+import xml.dom.minidom as minidom
+
+def prettify(tree):
+ rough_str = ET.tostring(tree, 'unicode')
+ reparsed = minidom.parseString(rough_str)
+ return reparsed.toprettyxml()
+
+class XMLGenerator:
+ def __init__(self, external, schema):
+ self.external = external
+ self.schema = schema
+
+ def generate(self, values):
+ root = ET.Element(self.external)
+ for tag in self.schema:
+ self.add_tag(root, tag, values)
+ return root
+
+ def add_tag(self, root, tag, values):
+ name = tag['name']
+ if not name in values:
+ if tag['required']:
+ raise XMLGeneratorError('Required tag not found: ' + name)
+ return
+ value = values[name]
+ multiple, attr = tag['multiple']
+ if multiple:
+ for v in value:
+ self.add_single_tag(root, name, tag, v, attr)
+ else:
+ self.add_single_tag(root, name, tag, value)
+
+ def add_single_tag(self, root, name, tag, value, attr=None):
+ child = ET.SubElement(root, name)
+ if attr:
+ child.set(attr, value[0])
+ value = value[1]
+ subtags = tag['subtags']
+ if subtags:
+ if 'text' in value:
+ child.text = value[text]
+ for child_tag in subtags:
+ self.add_tag(child, child_tag, value)
+ else:
+ child.text = value
+
diff --git a/tests/test_metadata.py b/tests/test_metadata.py
new file mode 100644
index 0000000..91da5bc
--- /dev/null
+++ b/tests/test_metadata.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+ test_metadata.py
+ ~~~~~~~~~~~~~~~~
+
+ metadata generator test suite
+
+ :copyright: (c) 2013 by Jauhien Piatlicki
+ :license: GPL-2, see LICENSE for more details.
+"""
+
+import xml.etree.ElementTree as ET
+
+import tempfile, unittest
+
+from g_sorcery import exceptions, metadata
+
+class TestXMLGenerator(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_generate(self):
+ schema = [{'name' : 'desc',
+ 'subtags' : [],
+ 'multiple' : (False, ""),
+ 'required' : True},
+ {'name' : 'contact',
+ 'multiple' : (False, ""),
+ 'required' : False,
+ 'subtags' : [
+ {'name' : 'email',
+ 'subtags' : [],
+ 'multiple' : (False, ""),
+ 'required' : True},
+
+ {'name' : 'phone',
+ 'subtags' : [],
+ 'multiple' : (False, ""),
+ 'required' : False},
+ ]},
+ {'name' : 'multiple',
+ 'subtags' : [],
+ 'multiple' : (True, ""),
+ 'required' : False},
+ {'name' : 'flag',
+ 'subtags' : [],
+ 'multiple' : (True, "name"),
+ 'required' : False},
+ ]
+ xg = metadata.XMLGenerator('test_ext', schema)
+ self.assertRaises(exceptions.XMLGeneratorError, xg.generate, {})
+ tree = xg.generate({'desc' : 'test xml'})
+ self.assertEqual(ET.tostring(tree, encoding='unicode'),
+ '<test_ext><desc>test xml</desc></test_ext>')
+ tree = xg.generate({'desc' : 'test xml',
+ 'contact' : {'email' : 'test@example.com',
+ 'phone' : '00-0'}})
+ self.assertEqual(ET.tostring(tree, encoding='unicode'),
+ '<test_ext><desc>test xml</desc><contact><email>test@example.com\
+</email><phone>00-0</phone></contact></test_ext>')
+ tree = xg.generate({'desc' : 'test xml',
+ 'multiple' : ['test1', 'test2', 'test3']})
+ self.assertEqual(ET.tostring(tree, encoding='unicode'),
+ '<test_ext><desc>test xml</desc><multiple>test1</multiple>\
+<multiple>test2</multiple><multiple>test3</multiple></test_ext>')
+ tree = xg.generate({'desc' : 'test xml',
+ 'flag' : [('flag1', 'test1'), ('flag2', 'test2')]})
+ self.assertEqual(ET.tostring(tree, encoding='unicode'),
+ '<test_ext><desc>test xml</desc><flag name="flag1">test1</flag>\
+<flag name="flag2">test2</flag></test_ext>')
+
+
+def suite():
+ suite = unittest.TestSuite()
+ suite.addTest(TestXMLGenerator('test_generate'))
+ return suite
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-06-29 12:13 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-06-29 12:13 UTC (permalink / raw
To: gentoo-commits
commit: f56eb9904accf9ab6f9d02ee6c30f2811020c97f
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Sat Jun 29 12:09:08 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Sat Jun 29 12:09:08 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=f56eb990
g_sorcery/package_db: exceptions hierarchy, g_sorcery/exceptions: initial commit
---
g_sorcery/exceptions.py | 33 +++++++++++++++++++++++++++++++++
g_sorcery/package_db.py | 37 ++++++++++++++++++++-----------------
tests/test_package_db.py | 15 ++++++++-------
3 files changed, 61 insertions(+), 24 deletions(-)
diff --git a/g_sorcery/exceptions.py b/g_sorcery/exceptions.py
new file mode 100644
index 0000000..857e4ea
--- /dev/null
+++ b/g_sorcery/exceptions.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+ exceptions.py
+ ~~~~~~~~~~~~~
+
+ Exceptions hierarchy
+
+ :copyright: (c) 2013 by Jauhien Piatlicki
+ :license: GPL-2, see LICENSE for more details.
+"""
+
+class GSorceryError(Exception):
+ pass
+
+class DBError(GSorceryError):
+ pass
+
+class InvalidKeyError(DBError):
+ pass
+
+class SyncError(DBError):
+ pass
+
+class IntegrityError(DBError):
+ pass
+
+class DBStructureError(DBError):
+ pass
+
+class FileJSONError(Exception):
+ pass
diff --git a/g_sorcery/package_db.py b/g_sorcery/package_db.py
index 1fe4b38..e2cd40d 100644
--- a/g_sorcery/package_db.py
+++ b/g_sorcery/package_db.py
@@ -11,6 +11,9 @@
:license: GPL-2, see LICENSE for more details.
"""
+from .exceptions import DBStructureError, FileJSONError, IntegrityError, \
+ InvalidKeyError, SyncError
+
import collections, glob, hashlib, json, os, shutil, tarfile, tempfile
Package = collections.namedtuple("Package", "category name version")
@@ -41,13 +44,13 @@ class FileJSON:
content = json.load(f)
for key in self.mandatories:
if not key in content:
- raise KeyError
+ raise FileJSONError('lack of mandatory key: ' + key)
return content
def write(self, content):
for key in self.mandatories:
if not key in content:
- raise KeyError
+ raise FileJSONError('lack of mandatory key: ' + key)
if not os.path.exists(self.directory):
os.makedirs(self.directory)
with open(self.path, 'w') as f:
@@ -131,7 +134,7 @@ class PackageDB:
real_db_uri = self.get_real_db_uri()
download_dir = tempfile.TemporaryDirectory()
if os.system('wget -P ' + download_dir.name + ' ' + real_db_uri):
- raise Exception('sync failed: ' + real_db_uri)
+ raise SyncError('sync failed: ' + real_db_uri)
temp_dir = tempfile.TemporaryDirectory()
for f_name in glob.iglob(os.path.join(download_dir.name, '*.tar.gz')):
@@ -148,13 +151,13 @@ class PackageDB:
copy_all(current_dir, tempdb_dir.name)
if not tempdb.check_manifest():
- raise Exception('Manifest check failed.')
+ raise IntegrityError('Manifest check failed.')
self.clean()
copy_all(tempdb_dir.name, self.directory)
if not self.check_manifest():
- raise Exception('Manifest check failed, db inconsistent.')
+ raise IntegrityError('Manifest check failed, db inconsistent.')
del download_dir
del temp_dir
@@ -176,7 +179,7 @@ class PackageDB:
for category in categories:
category_path = os.path.join(self.directory, category)
if not os.path.isdir(category_path):
- raise Exception('Empty category: ' + category)
+ raise DBStructureError('Empty category: ' + category)
for root, dirs, files in os.walk(category_path):
for f in files:
manifest[os.path.join(root[len(self.directory)+1:], f)] = \
@@ -194,7 +197,7 @@ class PackageDB:
names = [self.INFO_NAME, self.CATEGORIES_NAME, self.URI_NAME]
for name in names:
if not name in manifest:
- raise Exception('Bad manifest: no ' + name + ' entry')
+ raise DBStructureError('Bad manifest: no ' + name + ' entry')
for name, value in manifest.items():
if hash_file(os.path.join(self.directory, name), hashlib.md5()) != \
@@ -216,7 +219,7 @@ class PackageDB:
categories_f.write(self.db['categories'])
for category in self.db['categories']:
if not category in self.db['packages']:
- raise Exception('Empty category: ' + category)
+ raise DBStructureError('Empty category: ' + category)
for package, versions in self.db['packages'][category].items():
for version, content in versions.items():
f = FileJSON(os.path.join(self.directory, category, package),
@@ -248,7 +251,7 @@ class PackageDB:
def read(self):
sane, errors = self.check_manifest()
if not sane:
- raise Exception('Manifest error: ' + str(errors))
+ raise IntegrityError('Manifest error: ' + str(errors))
info_f = FileJSON(self.directory, self.INFO_NAME, [])
categories_f = FileJSON(self.directory, self.CATEGORIES_NAME, [])
self.db['info'] = info_f.read()
@@ -256,23 +259,23 @@ class PackageDB:
for category in self.db['categories']:
category_path = os.path.join(self.directory, category)
if not os.path.isdir(category_path):
- raise Exception('Empty category: ' + category)
+ raise DBStructureError('Empty category: ' + category)
f = FileJSON(category_path, self.PACKAGES_NAME, [])
packages = f.read()
if not packages:
- raise Exception('Empty category: ' + category)
+ raise DBStructureError('Empty category: ' + category)
self.db['packages'][category] = {}
for name in packages:
package_path = os.path.join(category_path, name)
if not os.path.isdir(category_path):
- raise Exception('Empty package: ' + category + '/' + name)
+ raise DBStructureError('Empty package: ' + category + '/' + name)
f = FileJSON(package_path, self.VERSIONS_NAME, [])
versions = f.read()
if not versions:
- raise Exception('Empty package: ' + category + '/' + name)
+ raise DBStructureError('Empty package: ' + category + '/' + name)
self.db['packages'][category][name] = {}
for version in versions:
@@ -309,7 +312,7 @@ class PackageDB:
name = package.name
version = package.version
if category and not category in self.db['packages']:
- raise Exception('Non-existent category: ' + category)
+ raise InvalidKeyError('Non-existent category: ' + category)
if name and not name in self.db['packages'][category]:
self.db['packages'][category][name] = {}
self.db['packages'][category][name][version] = description
@@ -319,14 +322,14 @@ class PackageDB:
def list_package_names(self, category):
if category and not category in self.db['packages']:
- raise Exception('No such category: ' + category)
+ raise InvalidKeyError('No such category: ' + category)
return list(self.db['packages'][category])
def list_package_versions(self, category, name):
if category and not category in self.db['packages']:
- raise Exception('No such category: ' + category)
+ raise InvalidKeyError('No such category: ' + category)
if name and not name in self.db['packages'][category]:
- raise Exception('No such package: ' + name)
+ raise InvalidKeyError('No such package: ' + name)
return list(self.db['packages'][category][name])
def list_all_packages(self):
diff --git a/tests/test_package_db.py b/tests/test_package_db.py
index 94693d8..2b8c482 100644
--- a/tests/test_package_db.py
+++ b/tests/test_package_db.py
@@ -14,7 +14,7 @@
import json, http.server, os, shutil, tempfile, threading, \
unittest
-from g_sorcery import package_db
+from g_sorcery import package_db, exceptions
class Server(threading.Thread):
@@ -84,7 +84,7 @@ class TestFileJSON(unittest.TestCase):
json.dump(content, f)
f = package_db.FileJSON(self.path, self.name, mandatories)
mandatories.append("tst4")
- self.assertRaises(KeyError, f.read)
+ self.assertRaises(exceptions.FileJSONError, f.read)
def do_test_write_ok(self):
mandatories = ['tst1', 'tst2', 'tst3']
@@ -102,7 +102,7 @@ class TestFileJSON(unittest.TestCase):
content = {'tst1' : '', 'tst2' : ''}
mandatories = ['tst1', 'tst2', 'tst3']
f = package_db.FileJSON(self.path, self.name, mandatories)
- self.assertRaises(KeyError, f.write, content)
+ self.assertRaises(exceptions.FileJSONError, f.write, content)
def test_write_dir_does_not_exist(self):
self.do_test_write_ok()
@@ -179,7 +179,7 @@ class TestDummyDB(unittest.TestCase):
for category in categories:
package_names = list(set([x.name for x in self.packages if x.category == category]))
self.assertEqual(package_names, db.list_package_names(category))
- self.assertRaises(Exception, db.list_package_names, 'no_such_category')
+ self.assertRaises(exceptions.InvalidKeyError, db.list_package_names, 'no_such_category')
def test_list_package_versions(self):
db = DummyDB(self.tempdir.name, self.packages)
@@ -190,8 +190,9 @@ class TestDummyDB(unittest.TestCase):
for name in package_names:
versions = [x.version for x in self.packages if x.category == category and x.name == name]
self.assertEqual(versions, db.list_package_versions(category, name))
- self.assertRaises(Exception, db.list_package_names, 'no_such_category', 'a')
- self.assertRaises(Exception, db.list_package_names, categories[0], 'no_such_package')
+ self.assertRaises(exceptions.InvalidKeyError, db.list_package_versions, 'no_such_category', 'a')
+ self.assertRaises(exceptions.InvalidKeyError, db.list_package_versions,
+ categories[0], 'no_such_package')
def test_sync(self):
src_db = DummyDB(os.path.join(self.tempdir.name, 'src_testdb'), self.packages)
@@ -216,7 +217,7 @@ class TestDummyDB(unittest.TestCase):
def test_sync_fail(self):
db = DummyDB(os.path.join(self.tempdir.name, 'testdb'), self.packages)
- self.assertRaises(Exception, db.sync, db_uri='127.0.0.1:8080')
+ self.assertRaises(exceptions.SyncError, db.sync, db_uri='127.0.0.1:8080')
def suite():
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-06-23 21:39 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-06-23 21:39 UTC (permalink / raw
To: gentoo-commits
commit: b6cf7231ae7425288746e5d28228744288637dbc
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Sun Jun 23 21:40:01 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Sun Jun 23 21:40:01 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=b6cf7231
g_sorcery/backend
---
g_sorcery/backend.py | 58 ++++++++++++++++++++++++++++++++++++-
g_sorcery/package_db.py | 16 ++++++++--
tests/__init__.py | 2 ++
tests/test_backend.py | 77 +++++++++++++++++++++++++++++++++++++++++++++++++
tests/test_ebuild.py | 7 +++--
5 files changed, 155 insertions(+), 5 deletions(-)
diff --git a/g_sorcery/backend.py b/g_sorcery/backend.py
index 0fb194d..476a8a4 100644
--- a/g_sorcery/backend.py
+++ b/g_sorcery/backend.py
@@ -11,6 +11,62 @@
:license: GPL-2, see LICENSE for more details.
"""
+import glob, os
+
class Backend:
- def __init__(self):
+ def __init__(self, PackageDB, EbuildGenrator, directory,
+ repo_uri="", db_uri="", sync_db=True, eclass_dir=""):
+ self.sync_db = sync_db
+ self.repo_uri = repo_uri
+ self.db_uri = db_uri
+ self.eclass_dir = eclass_dir
+
+ self.directory = directory
+ self.backend_data_dir = os.path.join(directory, '.backend_data')
+ os.makedirs(self.backend_data_dir)
+ self.db = PackageDB(os.path.join(self.backend_data_dir, 'db'),
+ repo_uri = self.repo_uri,
+ db_uri = self.db_uri)
+
+ self.repo_uri = self.db.repo_uri
+ self.db_uri = self.db.db_uri
+
+ self.eg = EbuildGenrator(self.db)
+
+ def sync(self):
+ if self.sync_db and not self.db_uri:
+ Exception("No uri for syncing provided.")
+ if not self.sync_db and not self.repo_uri:
+ Exception("No repo uri provided.")
+ if self.sync_db:
+ self.db.sync()
+ else:
+ self.db.generate()
+
+ def list_ebuilds(self):
+ return self.db.list_all_packages()
+
+ def generate_ebuild(self, package):
+ return self.eg.generate(package)
+
+ def list_eclasses(self):
+ result = []
+ if self.eclass_dir:
+ for f_name in glob.iglob(os.path.join(self.eclass_dir, '*.eclass')):
+ result.append(os.path.basename(f_name)[:-7])
+ return result
+
+ def generate_eclass(self, eclass):
+ if not self.eclass_dir:
+ Exception('No eclass dir')
+ f_name = os.path.join(self.eclass_dir, eclass + '.eclass')
+ if not os.path.isfile(f_name):
+ Exception('No eclass ' + eclass)
+ with open(f_name, 'r') as f:
+ eclass = f.read().split('\n')
+ if eclass[-1] == '':
+ eclass = eclass[:-1]
+ return eclass
+
+ def generate_metadata(self, category, name):
pass
diff --git a/g_sorcery/package_db.py b/g_sorcery/package_db.py
index 48101a2..a85a704 100644
--- a/g_sorcery/package_db.py
+++ b/g_sorcery/package_db.py
@@ -86,9 +86,13 @@ class PackageDB:
uri_f = FileJSON(self.directory, self.URI_NAME, ['repo_uri', 'db_uri'])
uri = uri_f.read()
if not repo_uri:
- self.repo_uri = uri['repo_uri']
+ self.repo_uri = uri['repo_uri']
+ else:
+ self.repo_uri = repo_uri
if not db_uri:
- self.db_uri = uri['db_uri']
+ self.db_uri = uri['db_uri']
+ else:
+ self.db_uri = db_uri
uri['repo_uri'] = self.repo_uri
uri['db_uri'] = self.db_uri
uri_f.write(uri)
@@ -321,6 +325,14 @@ class PackageDB:
raise Exception('No such package: ' + name)
return list(self.db['packages'][category][name])
+ def list_all_packages(self):
+ result = []
+ for category in self.db['packages']:
+ for name in self.db['packages'][category]:
+ for version in self.db['packages'][category][name]:
+ result.append(Package(category, name, version))
+ return result
+
def get_package_description(self, package):
#a possible exception should be catched in the caller
return self.db['packages'][package.category][package.name][package.version]
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..faa18be
--- /dev/null
+++ b/tests/__init__.py
@@ -0,0 +1,2 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
diff --git a/tests/test_backend.py b/tests/test_backend.py
new file mode 100644
index 0000000..027f4a8
--- /dev/null
+++ b/tests/test_backend.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+ test_backend.py
+ ~~~~~~~~~~~~~~~
+
+ backend test suite
+
+ :copyright: (c) 2013 by Jauhien Piatlicki
+ :license: GPL-2, see LICENSE for more details.
+"""
+
+import os, tempfile, unittest
+
+from g_sorcery import backend, ebuild, package_db
+
+from tests import test_ebuild
+
+class DummyBackend(backend.Backend):
+ def __init__(self, PackageDB, EbuildGenrator, directory,
+ sync_db=True, eclass_dir=""):
+ super().__init__(PackageDB, EbuildGenrator, directory,
+ sync_db=sync_db, eclass_dir=eclass_dir)
+
+
+class TestBackend(unittest.TestCase):
+
+ def setUp(self):
+ self.tempdir = tempfile.TemporaryDirectory()
+
+ def tearDown(self):
+ del self.tempdir
+
+ def test_list_eclasses(self):
+ backend = DummyBackend(package_db.PackageDB, ebuild.EbuildGenerator,
+ self.tempdir.name, eclass_dir = self.tempdir.name)
+ self.assertEqual(backend.list_eclasses(), [])
+ lst = ['test', 'supertest', 'anothertest']
+ for f_name in lst:
+ with open(os.path.join(self.tempdir.name, f_name + '.eclass'), 'w') as f:
+ f.write("test")
+ self.assertEqual(set(backend.list_eclasses()), set(lst))
+
+ def test_generate_eclass(self):
+ backend = DummyBackend(package_db.PackageDB, ebuild.EbuildGenerator,
+ self.tempdir.name, eclass_dir = self.tempdir.name)
+ eclass = ["testing eclass", "nothing interesting here"]
+ eclass_name = "test"
+ with open(os.path.join(self.tempdir.name, eclass_name + '.eclass'), 'w') as f:
+ for line in eclass:
+ f.write(line + '\n')
+ g_eclass = backend.generate_eclass(eclass_name)
+ self.assertEqual(eclass, g_eclass)
+
+ def test_list_ebuilds(self):
+ backend = DummyBackend(test_ebuild.DummyDB, test_ebuild.DummyEbuildGenerator,
+ self.tempdir.name, eclass_dir = self.tempdir.name, sync_db = False)
+ backend.sync()
+ ebuilds = backend.list_ebuilds()
+ self.assertEqual(set(ebuilds), set([test_ebuild.package, test_ebuild.package2]))
+
+ def test_generate_ebuild(self):
+ backend = DummyBackend(test_ebuild.DummyDB, test_ebuild.DummyEbuildGenerator,
+ self.tempdir.name, eclass_dir = self.tempdir.name, sync_db = False)
+ backend.sync()
+ ebuild = backend.generate_ebuild(test_ebuild.package)
+ self.assertEqual(ebuild, ['test', 'author: jauhien',
+ 'homepage: 127.0.0.1', 'var: $var'])
+
+def suite():
+ suite = unittest.TestSuite()
+ suite.addTest(TestBackend('test_list_eclasses'))
+ suite.addTest(TestBackend('test_generate_eclass'))
+ suite.addTest(TestBackend('test_list_ebuilds'))
+ suite.addTest(TestBackend('test_generate_ebuild'))
+ return suite
diff --git a/tests/test_ebuild.py b/tests/test_ebuild.py
index 03b5d37..52c34f5 100644
--- a/tests/test_ebuild.py
+++ b/tests/test_ebuild.py
@@ -16,15 +16,18 @@ import os, tempfile, unittest
from g_sorcery import ebuild, package_db
package = package_db.Package("app-test", "test", "0.1")
+package2 = package_db.Package("app-test", "tst", "1")
class DummyDB(package_db.PackageDB):
- def __init__(self, directory):
- super().__init__(directory)
+ def __init__(self, directory, repo_uri="", db_uri=""):
+ super().__init__(directory, repo_uri, db_uri)
def generate_tree(self):
self.add_category("app-test")
self.add_package(package,
{"author" : "jauhien", "homepage" : "127.0.0.1"})
+ self.add_package(package2,
+ {"author" : "unknown", "homepage" : "example.com"})
class DummyEbuildGenerator(ebuild.EbuildGenerator):
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-06-23 0:44 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-06-23 0:44 UTC (permalink / raw
To: gentoo-commits
commit: d86e2f7db9b29f2fb38f3d6db223bc4dfaea9e3c
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Sun Jun 23 00:44:55 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Sun Jun 23 00:44:55 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=d86e2f7d
g_sorcery/ebuild: EbuildGeneratorFromFile
---
g_sorcery/ebuild.py | 15 +++++++++++++++
tests/test_ebuild.py | 37 ++++++++++++++++++++++++++++++++++---
2 files changed, 49 insertions(+), 3 deletions(-)
diff --git a/g_sorcery/ebuild.py b/g_sorcery/ebuild.py
index 88e9acd..ea27afe 100644
--- a/g_sorcery/ebuild.py
+++ b/g_sorcery/ebuild.py
@@ -38,3 +38,18 @@ class EbuildGenerator:
def postprocess(self, ebuild, description):
return ebuild
+
+class EbuildGeneratorFromFile(EbuildGenerator):
+ def __init__(self, db):
+ super().__init__(db)
+
+ def get_template(self, package, description):
+ name = self.get_template_file(package, description)
+ with open(name, 'r') as f:
+ ebuild = f.read().split('\n')
+ if ebuild[-1] == '':
+ ebuild = ebuild[:-1]
+ return ebuild
+
+ def get_template_file(self, package, description):
+ return ""
diff --git a/tests/test_ebuild.py b/tests/test_ebuild.py
index 029e2df..03b5d37 100644
--- a/tests/test_ebuild.py
+++ b/tests/test_ebuild.py
@@ -11,7 +11,7 @@
:license: GPL-2, see LICENSE for more details.
"""
-import tempfile, unittest
+import os, tempfile, unittest
from g_sorcery import ebuild, package_db
@@ -37,11 +37,9 @@ class TestEbuildGenerator(unittest.TestCase):
def setUp(self):
self.tempdir = tempfile.TemporaryDirectory()
- pass
def tearDown(self):
del self.tempdir
- pass
def test_process(self):
eg = DummyEbuildGenerator(None)
@@ -58,9 +56,42 @@ class TestEbuildGenerator(unittest.TestCase):
self.assertEqual(ebuild, ['test', 'author: jauhien',
'homepage: 127.0.0.1', 'var: $var'])
+
+class DummyEbuildGeneratorFromFile(ebuild.EbuildGeneratorFromFile):
+ def __init__(self, db, path):
+ super().__init__(db)
+ self.path = path
+
+ def get_template_file(self, package, description):
+ return self.path
+
+
+class TestEbuildGeneratorFromFile(unittest.TestCase):
+
+ def setUp(self):
+ self.tempdir = tempfile.TemporaryDirectory()
+
+ def tearDown(self):
+ del self.tempdir
+
+ def test_generate(self):
+ db = DummyDB(os.path.join(self.tempdir.name, 'tstdb'))
+ db.generate()
+ tmpl = os.path.join(self.tempdir.name, 'tst.tmpl')
+ with open(tmpl, 'w') as f:
+ f.write("""test
+author: $author
+homepage: $homepage
+var: $$var""")
+ eg = DummyEbuildGeneratorFromFile(db, tmpl)
+ ebuild = eg.generate(package)
+ self.assertEqual(ebuild, ['test', 'author: jauhien',
+ 'homepage: 127.0.0.1', 'var: $var'])
+
def suite():
suite = unittest.TestSuite()
suite.addTest(TestEbuildGenerator('test_process'))
suite.addTest(TestEbuildGenerator('test_generate'))
+ suite.addTest(TestEbuildGeneratorFromFile('test_generate'))
return suite
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-06-23 0:44 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-06-23 0:44 UTC (permalink / raw
To: gentoo-commits
commit: a8ec7786e12dab514996b60b4b79f1f57dc58a66
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Sun Jun 23 00:22:27 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Sun Jun 23 00:22:27 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=a8ec7786
g_sorcery/ebuild: EbuildGenerator
---
g_sorcery/ebuild.py | 28 ++++++++++++++++++++++
tests/test_ebuild.py | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 94 insertions(+)
diff --git a/g_sorcery/ebuild.py b/g_sorcery/ebuild.py
index 47c727a..88e9acd 100644
--- a/g_sorcery/ebuild.py
+++ b/g_sorcery/ebuild.py
@@ -10,3 +10,31 @@
:copyright: (c) 2013 by Jauhien Piatlicki
:license: GPL-2, see LICENSE for more details.
"""
+
+import string
+
+class EbuildGenerator:
+ def __init__(self, db):
+ self.db = db
+
+ def generate(self, package):
+ #a possible exception should be catched in the caller
+ description = self.db.get_package_description(package)
+ ebuild = self.get_template(package, description)
+ ebuild = self.process(ebuild, description)
+ ebuild = self.postprocess(ebuild, description)
+ return ebuild
+
+ def process(self, ebuild, description):
+ result = []
+ for line in ebuild:
+ tmpl = string.Template(line)
+ result.append(tmpl.substitute(description))
+ return result
+
+ def get_template(self, package, description):
+ ebuild = []
+ return ebuild
+
+ def postprocess(self, ebuild, description):
+ return ebuild
diff --git a/tests/test_ebuild.py b/tests/test_ebuild.py
new file mode 100644
index 0000000..029e2df
--- /dev/null
+++ b/tests/test_ebuild.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+ test_ebuild.py
+ ~~~~~~~~~~~~~~~~~~
+
+ ebuild generator test suite
+
+ :copyright: (c) 2013 by Jauhien Piatlicki
+ :license: GPL-2, see LICENSE for more details.
+"""
+
+import tempfile, unittest
+
+from g_sorcery import ebuild, package_db
+
+package = package_db.Package("app-test", "test", "0.1")
+
+class DummyDB(package_db.PackageDB):
+ def __init__(self, directory):
+ super().__init__(directory)
+
+ def generate_tree(self):
+ self.add_category("app-test")
+ self.add_package(package,
+ {"author" : "jauhien", "homepage" : "127.0.0.1"})
+
+
+class DummyEbuildGenerator(ebuild.EbuildGenerator):
+ def get_template(self, ebuild, description):
+ tmpl = ["test", "author: $author", "homepage: $homepage", "var: $$var"]
+ return tmpl
+
+
+class TestEbuildGenerator(unittest.TestCase):
+
+ def setUp(self):
+ self.tempdir = tempfile.TemporaryDirectory()
+ pass
+
+ def tearDown(self):
+ del self.tempdir
+ pass
+
+ def test_process(self):
+ eg = DummyEbuildGenerator(None)
+ tst_dict = {"a" : "d", "b" : "e", "c" : "f"}
+ ebuild = ["$a", "$b", "$c"]
+ ebuild = eg.process(ebuild, tst_dict)
+ self.assertEqual(ebuild, ["d", "e", "f"])
+
+ def test_generate(self):
+ db = DummyDB(self.tempdir.name)
+ db.generate()
+ eg = DummyEbuildGenerator(db)
+ ebuild = eg.generate(package)
+ self.assertEqual(ebuild, ['test', 'author: jauhien',
+ 'homepage: 127.0.0.1', 'var: $var'])
+
+
+def suite():
+ suite = unittest.TestSuite()
+ suite.addTest(TestEbuildGenerator('test_process'))
+ suite.addTest(TestEbuildGenerator('test_generate'))
+ return suite
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-06-23 0:44 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-06-23 0:44 UTC (permalink / raw
To: gentoo-commits
commit: 404e62bfbc2b579260a5bbc6a98af112a9237246
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Sat Jun 22 22:22:31 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Sat Jun 22 22:22:31 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=404e62bf
g_sorcery/package_db: sync
---
g_sorcery/package_db.py | 55 ++++++++++++++++++++++++++++++++++++++----------
tests/test_package_db.py | 40 ++++++++++++++++++++++++++++++++++-
2 files changed, 83 insertions(+), 12 deletions(-)
diff --git a/g_sorcery/package_db.py b/g_sorcery/package_db.py
index 9c477f7..b97a688 100644
--- a/g_sorcery/package_db.py
+++ b/g_sorcery/package_db.py
@@ -11,7 +11,7 @@
:license: GPL-2, see LICENSE for more details.
"""
-import collections, hashlib, json, os, shutil
+import collections, glob, hashlib, json, os, shutil, tarfile, tempfile
Package = collections.namedtuple("Package", "category name version")
@@ -61,7 +61,15 @@ def hash_file(name, hasher, blocksize=65536):
hasher.update(buf)
buf = f.read(blocksize)
return hasher.hexdigest()
-
+
+def copy_all(src, dst):
+ for f_name in os.listdir(src):
+ src_name = os.path.join(src, f_name)
+ dst_name = os.path.join(dst, f_name)
+ if os.path.isdir(src_name):
+ shutil.copytree(src_name, dst_name)
+ else:
+ shutil.copy2(src_name, dst_name)
class PackageDB:
def __init__(self, directory, repo_uri="", db_uri=""):
@@ -112,18 +120,43 @@ class PackageDB:
"""
pass
- def sync(self, repo_uri="", db_uri=""):
- if repo_uri:
- self.repo_uri = repo_uri
+ def sync(self, db_uri=""):
if db_uri:
self.db_uri = db_uri
self.clean()
real_db_uri = self.get_real_db_uri()
- """
- TODO
- code that downloads tarball from the real_db_uri
- and unpacks it
- """
+ download_dir = tempfile.TemporaryDirectory()
+ if os.system('wget -P ' + download_dir.name + ' ' + real_db_uri):
+ raise Exception('sync failed: ' + real_db_uri)
+
+ temp_dir = tempfile.TemporaryDirectory()
+ for f_name in glob.iglob(os.path.join(download_dir.name, '*.tar.gz')):
+ with tarfile.open(f_name) as f:
+ f.extractall(temp_dir.name)
+
+ tempdb_dir = tempfile.TemporaryDirectory()
+ tempdb = PackageDB(tempdb_dir.name)
+
+ for d_name in os.listdir(temp_dir.name):
+ current_dir = os.path.join(temp_dir.name, d_name)
+ if not os.path.isdir(current_dir):
+ continue
+ copy_all(current_dir, tempdb_dir.name)
+
+ if not tempdb.check_manifest():
+ raise Exception('Manifest check failed.')
+
+ self.clean()
+ copy_all(tempdb_dir.name, self.directory)
+
+ if not self.check_manifest():
+ raise Exception('Manifest check failed, db inconsistent.')
+
+ del download_dir
+ del temp_dir
+ del tempdb_dir
+
+ self.read()
def get_real_db_uri():
return self.db_uri
@@ -157,7 +190,7 @@ class PackageDB:
names = [self.INFO_NAME, self.CATEGORIES_NAME, self.URI_NAME]
for name in names:
if not name in manifest:
- raise RunTimeError('Bad manifest: no ' + name + ' entry')
+ raise Exception('Bad manifest: no ' + name + ' entry')
for name, value in manifest.items():
if hash_file(os.path.join(self.directory, name), hashlib.md5()) != \
diff --git a/tests/test_package_db.py b/tests/test_package_db.py
index 9fc0267..62b073f 100644
--- a/tests/test_package_db.py
+++ b/tests/test_package_db.py
@@ -11,10 +11,25 @@
:license: GPL-2, see LICENSE for more details.
"""
-import json, os, tempfile, unittest
+import json, http.server, os, shutil, tempfile, threading, \
+ unittest
from g_sorcery import package_db
+
+class Server(threading.Thread):
+ def __init__(self):
+ super().__init__()
+ server_address = ('127.0.0.1', 8080)
+ self.httpd = http.server.HTTPServer(server_address, http.server.SimpleHTTPRequestHandler)
+
+ def run(self):
+ self.httpd.serve_forever()
+
+ def shutdown(self):
+ self.httpd.shutdown()
+
+
class TestFileJSON(unittest.TestCase):
def setUp(self):
@@ -118,6 +133,10 @@ class DummyDB(package_db.PackageDB):
for package in self.packages:
self.add_package(package)
+ def get_real_db_uri(self):
+ print(self.db_uri)
+ return self.db_uri + '/dummy.tar.gz'
+
class TestDummyDB(unittest.TestCase):
@@ -174,6 +193,24 @@ class TestDummyDB(unittest.TestCase):
self.assertRaises(Exception, db.list_package_names, 'no_such_category', 'a')
self.assertRaises(Exception, db.list_package_names, categories[0], 'no_such_package')
+ def test_sync(self):
+ src_db = DummyDB(os.path.join(self.tempdir.name, 'src_testdb'), self.packages)
+ src_db.generate()
+
+ os.chdir(self.tempdir.name)
+ os.system('tar cvzf dummy.tar.gz src_testdb')
+
+ server = Server()
+ server.start()
+
+ db = DummyDB(os.path.join(self.tempdir.name, 'testdb'), self.packages)
+ db.sync(db_uri='127.0.0.1:8080')
+
+ server.shutdown()
+ server.join()
+
+ self.assertEqual(src_db.db, db.db)
+
def suite():
suite = unittest.TestSuite()
@@ -190,4 +227,5 @@ def suite():
suite.addTest(TestDummyDB('test_list_categories'))
suite.addTest(TestDummyDB('test_list_package_names'))
suite.addTest(TestDummyDB('test_list_package_versions'))
+ suite.addTest(TestDummyDB('test_sync'))
return suite
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-06-20 23:21 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-06-20 23:21 UTC (permalink / raw
To: gentoo-commits
commit: a6bcb6178365e66ac619d42e0a356f8498a206ea
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Thu Jun 20 23:13:18 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Thu Jun 20 23:13:18 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=a6bcb617
g_sorcery/package_db.py: list_package_versions
---
g_sorcery/package_db.py | 7 +++++++
tests/test_package_db.py | 13 +++++++++++++
2 files changed, 20 insertions(+)
diff --git a/g_sorcery/package_db.py b/g_sorcery/package_db.py
index aae3abc..0a2bdfb 100644
--- a/g_sorcery/package_db.py
+++ b/g_sorcery/package_db.py
@@ -268,3 +268,10 @@ class PackageDB:
if not category in self.db['packages']:
raise Exception('No such category: ' + category)
return list(self.db['packages'][category].keys())
+
+ def list_package_versions(self, category, name):
+ if not category in self.db['packages']:
+ raise Exception('No such category: ' + category)
+ if not name in self.db['packages'][category]:
+ raise Exception('No such package: ' + name)
+ return list(self.db['packages'][category][name])
diff --git a/tests/test_package_db.py b/tests/test_package_db.py
index 9977d8c..9fc0267 100644
--- a/tests/test_package_db.py
+++ b/tests/test_package_db.py
@@ -162,6 +162,18 @@ class TestDummyDB(unittest.TestCase):
self.assertEqual(package_names, db.list_package_names(category))
self.assertRaises(Exception, db.list_package_names, 'no_such_category')
+ def test_list_package_versions(self):
+ db = DummyDB(self.tempdir.name, self.packages)
+ db.generate()
+ categories = list(set([x.category for x in self.packages]))
+ for category in categories:
+ package_names = list(set([x.name for x in self.packages if x.category == category]))
+ for name in package_names:
+ versions = [x.version for x in self.packages if x.category == category and x.name == name]
+ self.assertEqual(versions, db.list_package_versions(category, name))
+ self.assertRaises(Exception, db.list_package_names, 'no_such_category', 'a')
+ self.assertRaises(Exception, db.list_package_names, categories[0], 'no_such_package')
+
def suite():
suite = unittest.TestSuite()
@@ -177,4 +189,5 @@ def suite():
suite.addTest(TestDummyDB('test_read'))
suite.addTest(TestDummyDB('test_list_categories'))
suite.addTest(TestDummyDB('test_list_package_names'))
+ suite.addTest(TestDummyDB('test_list_package_versions'))
return suite
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/
@ 2013-06-20 22:53 Jauhien Piatlicki
0 siblings, 0 replies; 20+ messages in thread
From: Jauhien Piatlicki @ 2013-06-20 22:53 UTC (permalink / raw
To: gentoo-commits
commit: 9707236329bf00fd198149eb73ef5bee1bc68f77
Author: Jauhien Piatlicki (jauhien) <piatlicki <AT> gmail <DOT> com>
AuthorDate: Thu Jun 20 22:53:59 2013 +0000
Commit: Jauhien Piatlicki <piatlicki <AT> gmail <DOT> com>
CommitDate: Thu Jun 20 22:53:59 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/g-sorcery.git;a=commit;h=97072363
g_sorcery/package_db.py: initial commit
---
g_sorcery/package_db.py | 265 +++++++++++++++++++++++++++++++++++++++++++++++
tests/test_package_db.py | 170 ++++++++++++++++++++++++++++++
2 files changed, 435 insertions(+)
diff --git a/g_sorcery/package_db.py b/g_sorcery/package_db.py
new file mode 100644
index 0000000..a925af4
--- /dev/null
+++ b/g_sorcery/package_db.py
@@ -0,0 +1,265 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+ package_db.py
+ ~~~~~~~~~~~~~
+
+ package database
+
+ :copyright: (c) 2013 by Jauhien Piatlicki
+ :license: GPL-2, see LICENSE for more details.
+"""
+
+import collections, hashlib, json, os, shutil
+
+Package = collections.namedtuple("Package", "category name version")
+
+class FileJSON:
+ def __init__(self, directory, name, mandatories):
+ """
+ Initialize
+
+ mandatories -- list of mandatory keys
+ """
+ self.directory = os.path.abspath(directory)
+ self.name = name
+ self.path = os.path.join(directory, name)
+ self.mandatories = mandatories
+
+ def read(self):
+ if not os.path.exists(self.directory):
+ os.makedirs(self.directory)
+ content = {}
+ if not os.path.isfile(self.path):
+ for key in self.mandatories:
+ content[key] = ""
+ with open(self.path, 'w') as f:
+ json.dump(content, f, indent=2, sort_keys=True)
+ else:
+ with open(self.path, 'r') as f:
+ content = json.load(f)
+ for key in self.mandatories:
+ if not key in content:
+ raise KeyError
+ return content
+
+ def write(self, content):
+ for key in self.mandatories:
+ if not key in content:
+ raise KeyError
+ if not os.path.exists(self.directory):
+ os.makedirs(self.directory)
+ with open(self.path, 'w') as f:
+ json.dump(content, f, indent=2, sort_keys=True)
+
+
+def hash_file(name, hasher, blocksize=65536):
+ with open(name, 'rb') as f:
+ buf = f.read(blocksize)
+ while len(buf) > 0:
+ hasher.update(buf)
+ buf = f.read(blocksize)
+ return hasher.hexdigest()
+
+
+class PackageDB:
+ def __init__(self, directory, repo_uri="", db_uri=""):
+ self.URI_NAME = 'uri.json'
+ self.INFO_NAME = 'info.json'
+ self.CATEGORIES_NAME = 'categories.json'
+ self.PACKAGES_NAME = 'packages.json'
+ self.VERSIONS_NAME = 'versions.json'
+ self.directory = os.path.abspath(directory)
+ self.reset_uri(repo_uri, db_uri)
+ self.reset_db()
+
+ def reset_uri(self, repo_uri="", db_uri=""):
+ uri_f = FileJSON(self.directory, self.URI_NAME, ['repo_uri', 'db_uri'])
+ uri = uri_f.read()
+ if not repo_uri:
+ self.repo_uri = uri['repo_uri']
+ if not db_uri:
+ self.db_uri = uri['db_uri']
+ uri['repo_uri'] = self.repo_uri
+ uri['db_uri'] = self.db_uri
+ uri_f.write(uri)
+
+ def reset_db(self):
+ self.db = {}
+ self.db['info'] = {}
+ self.db['categories'] = {}
+ self.db['packages'] = {}
+
+ def generate(self, repo_uri=""):
+ """
+ Generates a new package database
+
+ repo_uri -- repository uri
+ """
+ if repo_uri:
+ self.repo_uri = repo_uri
+ self.clean()
+ self.generate_tree()
+ self.write()
+ self.manifest()
+
+ def generate_tree(self):
+ """
+ Generate tree with JSON files containing info
+ about packages in a repository
+
+ Should be implemented in a subclass
+
+ repo_uri -- repository uri
+ if repo_uri is an empty string should use self.repo_uri
+ """
+ pass
+
+ def manifest(self):
+ categories = FileJSON(self.directory, self.CATEGORIES_NAME, [])
+ categories = categories.read()
+ manifest = {}
+ names = [self.INFO_NAME, self.CATEGORIES_NAME, self.URI_NAME]
+ for name in names:
+ manifest[name] = hash_file(os.path.join(self.directory, name),
+ hashlib.md5())
+ for category in categories:
+ category_path = os.path.join(self.directory, category)
+ if not os.path.isdir(category_path):
+ raise Exception('Empty category: ' + category)
+ for root, dirs, files in os.walk(category_path):
+ for f in files:
+ manifest[os.path.join(root[len(self.directory)+1:], f)] = \
+ hash_file(os.path.join(root, f), hashlib.md5())
+ m = FileJSON(self.directory, 'manifest.json', [])
+ m.write(manifest)
+
+ def check_manifest(self):
+ m = FileJSON(self.directory, 'manifest.json', [])
+ manifest = m.read()
+
+ result = True
+ errors = []
+
+ names = [self.INFO_NAME, self.CATEGORIES_NAME, self.URI_NAME]
+ for name in names:
+ if not name in manifest:
+ raise RunTimeError('Bad manifest: no ' + name + ' entry')
+
+ for name, value in manifest.items():
+ if hash_file(os.path.join(self.directory, name), hashlib.md5()) != \
+ value:
+ result = False
+ errors.append(name)
+
+ return (result, errors)
+
+ def clean(self):
+ shutil.rmtree(self.directory)
+ self.reset_uri(self.repo_uri, self.db_uri)
+ self.reset_db()
+
+ def write(self):
+ info_f = FileJSON(self.directory, self.INFO_NAME, [])
+ categories_f = FileJSON(self.directory, self.CATEGORIES_NAME, [])
+ info_f.write(self.db['info'])
+ categories_f.write(self.db['categories'])
+ for category in self.db['categories']:
+ if not category in self.db['packages']:
+ raise Exception('Empty category: ' + category)
+ for package, versions in self.db['packages'][category].items():
+ for version, content in versions.items():
+ f = FileJSON(os.path.join(self.directory, category, package),
+ version + '.json', [])
+ f.write(content)
+ self.additional_write_version(category, package, version)
+ f = FileJSON(os.path.join(self.directory, category, package),
+ self.VERSIONS_NAME, [])
+ f.write(list(versions.keys()))
+ self.additional_write_package(category, package)
+ f = FileJSON(os.path.join(self.directory, category),
+ self.PACKAGES_NAME, [])
+ f.write(list(self.db['packages'][category].keys()))
+ self.additional_write_category(category)
+ self.additional_write()
+
+ def additional_write_version(self, category, package, version):
+ pass
+
+ def additional_write_package(self, category, package):
+ pass
+
+ def additional_write_category(self, category):
+ pass
+
+ def additional_write(self):
+ pass
+
+ def read(self):
+ sane, errors = self.check_manifest()
+ if not sane:
+ raise Exception('Manifest error: ' + str(errors))
+ info_f = FileJSON(self.directory, self.INFO_NAME, [])
+ categories_f = FileJSON(self.directory, self.CATEGORIES_NAME, [])
+ self.db['info'] = info_f.read()
+ self.db['categories'] = categories_f.read()
+ for category in self.db['categories']:
+ category_path = os.path.join(self.directory, category)
+ if not os.path.isdir(category_path):
+ raise Exception('Empty category: ' + category)
+
+ f = FileJSON(category_path, self.PACKAGES_NAME, [])
+ packages = f.read()
+ if not packages:
+ raise Exception('Empty category: ' + category)
+
+ self.db['packages'][category] = {}
+ for name in packages:
+ package_path = os.path.join(category_path, name)
+ if not os.path.isdir(category_path):
+ raise Exception('Empty package: ' + category + '/' + name)
+
+ f = FileJSON(package_path, self.VERSIONS_NAME, [])
+ versions = f.read()
+ if not versions:
+ raise Exception('Empty package: ' + category + '/' + name)
+
+ self.db['packages'][category][name] = {}
+ for version in versions:
+ f = FileJSON(package_path, version + '.json', [])
+ description = f.read()
+ self.db['packages'][category][name][version] = description
+ self.additional_read_version(category, name, version)
+ self.additional_read_package(category, name)
+ self.additional_read_category(category)
+ self.additional_read()
+
+ def additional_read_version(self, category, package, version):
+ pass
+
+ def additional_read_package(self, category, package):
+ pass
+
+ def additional_read_category(self, category):
+ pass
+
+ def additional_read(self):
+ pass
+
+ def add_category(self, category, description={}):
+ self.db['categories'][category] = description;
+ self.db['packages'][category] = {}
+
+ def add_package(self, package, description={}):
+ category = package.category
+ name = package.name
+ version = package.version
+ if not category in self.db['packages']:
+ raise Exception('Non-existent category: ' + category)
+ if not name in self.db['packages'][category]:
+ self.db['packages'][category][name] = {}
+ self.db['packages'][category][name][version] = description
+
+ def list_categories(self):
+ return list(self.db['categories'].keys())
diff --git a/tests/test_package_db.py b/tests/test_package_db.py
new file mode 100644
index 0000000..1b3600b
--- /dev/null
+++ b/tests/test_package_db.py
@@ -0,0 +1,170 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+ test_package_db.py
+ ~~~~~~~~~~~~~~~~~~
+
+ package database test suite
+
+ :copyright: (c) 2013 by Jauhien Piatlicki
+ :license: GPL-2, see LICENSE for more details.
+"""
+
+import json, os, tempfile, unittest
+
+from g_sorcery import package_db
+
+class TestFileJSON(unittest.TestCase):
+
+ def setUp(self):
+ self.tempdir = tempfile.TemporaryDirectory()
+ self.path = os.path.join(self.tempdir.name, 'tst')
+ self.name = 'tst.json'
+
+ def tearDown(self):
+ del self.tempdir
+
+ def do_test_read_ok(self, mandatories, value_suffix=""):
+ f = package_db.FileJSON(self.path, self.name, mandatories)
+ content = f.read()
+ for key in mandatories:
+ self.assertTrue(key in content)
+ if value_suffix:
+ value = key + value_suffix
+ else:
+ value = ""
+ self.assertEqual(content[key], value)
+ self.assertTrue(os.path.isfile(os.path.join(self.path, self.name)))
+ with open(os.path.join(self.path, self.name), 'r') as f:
+ content_f = json.load(f)
+ self.assertEqual(content, content_f)
+
+ def test_read_dir_does_not_exist(self):
+ mandatories = ['tst1', 'tst2', 'tst3']
+ self.do_test_read_ok(mandatories)
+
+ def test_read_file_does_not_exist(self):
+ os.makedirs(self.path)
+ mandatories = ['tst1', 'tst2', 'tst3']
+ self.do_test_read_ok(mandatories)
+
+ def test_read_all_keys(self):
+ os.makedirs(self.path)
+ mandatories = ['tst1', 'tst2', 'tst3']
+ content = {}
+ for key in mandatories:
+ content[key] = key + "_v"
+ with open(os.path.join(self.path, self.name), 'w') as f:
+ json.dump(content, f)
+ self.do_test_read_ok(mandatories, "_v")
+
+ def test_read_missing_keys(self):
+ os.makedirs(self.path)
+ mandatories = ['tst1', 'tst2', 'tst3']
+ content = {}
+ for key in mandatories:
+ content[key] = key + "_v"
+ with open(os.path.join(self.path, self.name), 'w') as f:
+ json.dump(content, f)
+ f = package_db.FileJSON(self.path, self.name, mandatories)
+ mandatories.append("tst4")
+ self.assertRaises(KeyError, f.read)
+
+ def do_test_write_ok(self):
+ mandatories = ['tst1', 'tst2', 'tst3']
+ content = {}
+ for key in mandatories:
+ content[key] = key + '_v'
+ f = package_db.FileJSON(self.path, self.name, mandatories)
+ f.write(content)
+ self.assertTrue(os.path.isfile(os.path.join(self.path, self.name)))
+ with open(os.path.join(self.path, self.name), 'r') as f:
+ content_f = json.load(f)
+ self.assertEqual(content, content_f)
+
+ def test_write_missing_keys(self):
+ content = {'tst1' : '', 'tst2' : ''}
+ mandatories = ['tst1', 'tst2', 'tst3']
+ f = package_db.FileJSON(self.path, self.name, mandatories)
+ self.assertRaises(KeyError, f.write, content)
+
+ def test_write_dir_does_not_exist(self):
+ self.do_test_write_ok()
+
+ def test_write_file_does_not_exist(self):
+ os.makedirs(self.path)
+ self.do_test_write_ok()
+
+ def test_write_all_keys(self):
+ os.makedirs(self.path)
+ mandatories = ['tst11', 'tst12']
+ content = {}
+ for key in mandatories:
+ content[key] = key + "_v"
+ with open(os.path.join(self.path, self.name), 'w') as f:
+ json.dump(content, f)
+ self.do_test_write_ok()
+
+
+class DummyDB(package_db.PackageDB):
+ def __init__(self, directory, packages):
+ super().__init__(directory)
+ self.packages = packages
+
+ def generate_tree(self):
+ for category in [x.category for x in self.packages]:
+ self.add_category(category)
+ for package in self.packages:
+ self.add_package(package)
+
+
+class TestDummyDB(unittest.TestCase):
+
+ def setUp(self):
+ self.tempdir = tempfile.TemporaryDirectory()
+ category1 = 'app-test'
+ category2 = 'dev-test'
+ self.packages = [package_db.Package(category1, 'test', '0.2'),
+ package_db.Package(category1, 'tst', '0.1'),
+ package_db.Package(category1, 'dummy', '1'),
+ package_db.Package(category2, 'test', '0.1'),
+ package_db.Package(category2, 'test', '0.2'),
+ package_db.Package(category2, 'tst', '0.1')]
+
+ def tearDown(self):
+ del self.tempdir
+
+ def test_manifest(self):
+ db = DummyDB(self.tempdir.name, self.packages)
+ db.generate()
+ self.assertEqual(db.check_manifest(), (True, []))
+
+ def test_read(self):
+ db = DummyDB(self.tempdir.name, self.packages)
+ db.generate()
+ db2 = DummyDB(self.tempdir.name, self.packages)
+ db2.read()
+ self.assertEqual(db.db, db2.db)
+
+ def test_list_categories(self):
+ db = DummyDB(self.tempdir.name, self.packages)
+ db.generate()
+ categories = list(set([x.category for x in self.packages]))
+ self.assertEqual(categories, db.list_categories())
+
+
+def suite():
+ suite = unittest.TestSuite()
+ suite.addTest(TestFileJSON('test_read_dir_does_not_exist'))
+ suite.addTest(TestFileJSON('test_read_file_does_not_exist'))
+ suite.addTest(TestFileJSON('test_read_all_keys'))
+ suite.addTest(TestFileJSON('test_read_missing_keys'))
+ suite.addTest(TestFileJSON('test_write_missing_keys'))
+ suite.addTest(TestFileJSON('test_write_dir_does_not_exist'))
+ suite.addTest(TestFileJSON('test_write_file_does_not_exist'))
+ suite.addTest(TestFileJSON('test_write_all_keys'))
+ suite.addTest(TestDummyDB('test_manifest'))
+ suite.addTest(TestDummyDB('test_read'))
+ suite.addTest(TestDummyDB('test_list_categories'))
+ return suite
^ permalink raw reply related [flat|nested] 20+ messages in thread
end of thread, other threads:[~2015-04-22 7:35 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-20 23:21 [gentoo-commits] proj/g-sorcery:master commit in: g_sorcery/, tests/ Jauhien Piatlicki
-- strict thread matches above, loose matches on Subject: below --
2015-04-22 7:35 Jauhien Piatlicki
2013-07-04 20:24 Jauhien Piatlicki
2013-07-03 22:54 Jauhien Piatlicki
2013-07-02 14:48 Jauhien Piatlicki
2013-07-02 12:25 Jauhien Piatlicki
2013-07-01 20:51 Jauhien Piatlicki
2013-07-01 20:51 Jauhien Piatlicki
2013-07-01 0:05 Jauhien Piatlicki
2013-06-30 23:29 Jauhien Piatlicki
2013-06-30 23:29 Jauhien Piatlicki
2013-06-30 23:29 Jauhien Piatlicki
2013-06-30 19:55 Jauhien Piatlicki
2013-06-29 12:13 Jauhien Piatlicki
2013-06-23 21:39 Jauhien Piatlicki
2013-06-23 0:44 Jauhien Piatlicki
2013-06-23 0:44 Jauhien Piatlicki
2013-06-23 0:44 Jauhien Piatlicki
2013-06-20 23:21 Jauhien Piatlicki
2013-06-20 22:53 Jauhien Piatlicki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox