piknik

Unnamed repository; edit this file 'description' to name the repository.
Info | Log | Files | Refs | README | LICENSE

commit 2ae43ba4b7ecbc313f4f0a1c230b2c19874b8d9b
parent 1ccfe31ae93da8a1cd5aa92d688146af95fa30b8
Author: lash <dev@holbrook.no>
Date:   Sun,  6 Nov 2022 15:54:37 +0000

Implement file store, add missing files, add issue cli tool

Diffstat:
Mpiknik/basket.py | 7++++---
Apiknik/error.py | 2++
Mpiknik/issue.py | 9+++++++++
Apiknik/runnable/add.py | 24++++++++++++++++++++++++
Apiknik/store/__init__.py | 17+++++++++++++++++
Mtest/test_basic.py | 56++++++++++++++++++++++++++++----------------------------
Atest/test_issue.py | 18++++++++++++++++++
Atest/test_store.py | 40++++++++++++++++++++++++++++++++++++++++
8 files changed, 142 insertions(+), 31 deletions(-)

diff --git a/piknik/basket.py b/piknik/basket.py @@ -28,9 +28,10 @@ class Basket: def add(self, issue): - self.state.put(issue.id, contents=issue) - self.issues_rev[issue.id] = issue - return issue.id + issue_id = str(issue.id) + self.state.put(issue_id, contents=str(issue)) + self.issues_rev[issue_id] = issue + return issue_id def get(self, issue_id): diff --git a/piknik/error.py b/piknik/error.py @@ -0,0 +1,2 @@ +class DeadIssue(Exception): + pass diff --git a/piknik/issue.py b/piknik/issue.py @@ -1,7 +1,16 @@ import uuid +import json + class Issue: def __init__(self, title): self.id = uuid.uuid4() self.title = title + + + def __str__(self): + return json.dumps({ + 'id': str(self.id), + 'title': self.title, + }) diff --git a/piknik/runnable/add.py b/piknik/runnable/add.py @@ -0,0 +1,24 @@ +import sys +import argparse + +from piknik import Basket +from piknik import Issue +from piknik.cli import FileStoreFactory + + +argp = argparse.ArgumentParser() +argp.add_argument('title', type=str, help='issue title') +arg = argp.parse_args(sys.argv[1:]) + + +store_factory = FileStoreFactory() +basket = Basket(store_factory.create) + + +def main(): + o = Issue(arg.title) + basket.add(o) + + +if __name__ == '__main__': + main() diff --git a/piknik/store/__init__.py b/piknik/store/__init__.py @@ -0,0 +1,17 @@ +import os + +from shep.store.file import SimpleFileStoreFactory +from shep.persist import PersistedState + + +class FileStoreFactory: + + def __init__(self, directory=None): + if directory == None: + directory = os.path.join(os.environ['HOME'], '.piknik') + self.directory = directory + self.factory = SimpleFileStoreFactory(directory).add + + + def create(self, logger=None, default_state=None, verifier=None): + return PersistedState(self.factory, 6, logger=logger, verifier=verifier, default_state=default_state) diff --git a/test/test_basic.py b/test/test_basic.py @@ -29,8 +29,8 @@ class TestBasic(unittest.TestCase): def test_issue_basic(self): o = Issue('The first issue') v = self.b.add(o) - self.assertEqual(v, o.id) - r = self.b.get(o.id) + self.assertEqual(v, str(o.id)) + r = self.b.get(v) self.assertEqual(r, o) @@ -45,21 +45,21 @@ class TestBasic(unittest.TestCase): def test_progres(self): o = Issue('The first issue') - self.b.add(o) - self.b.advance(o.id) - self.b.advance(o.id) - self.b.advance(o.id) - self.b.advance(o.id) + v = self.b.add(o) + self.b.advance(v) + self.b.advance(v) + self.b.advance(v) + self.b.advance(v) with self.assertRaises(DeadIssue): - self.b.advance(o.id) + self.b.advance(v) def test_list_jump(self): o = Issue('The first issue') - self.b.add(o) + v = self.b.add(o) o_two = Issue('The second issue') self.b.add(o_two) - self.b.doing(o.id) + self.b.doing(v) r = self.b.list('backlog') self.assertEqual(len(r), 1) @@ -70,37 +70,37 @@ class TestBasic(unittest.TestCase): def test_jump(self): o = Issue('The first issue') - self.b.add(o) - self.b.doing(o.id) + v = self.b.add(o) + self.b.doing(v) r = self.b.list('doing') - self.assertEquals(len(r), 1) - self.b.review(o.id) + self.assertEqual(len(r), 1) + self.b.review(v) r = self.b.list('review') - self.assertEquals(len(r), 1) - self.b.backlog(o.id) + self.assertEqual(len(r), 1) + self.b.backlog(v) r = self.b.list('backlog') - self.assertEquals(len(r), 1) - self.b.finish(o.id) + self.assertEqual(len(r), 1) + self.b.finish(v) r = self.b.list('finished') - self.assertEquals(len(r), 1) + self.assertEqual(len(r), 1) def test_magic_unblock(self): o = Issue('The first issue') - self.b.add(o) - self.b.advance(o.id) - self.b.block(o.id) - self.assertIn(o.id, self.b.blocked()) - self.b.advance(o.id) - self.assertNotIn(o.id, self.b.blocked()) + v = self.b.add(o) + self.b.advance(v) + self.b.block(v) + self.assertIn(v, self.b.blocked()) + self.b.advance(v) + self.assertNotIn(v, self.b.blocked()) def test_no_resurrect(self): o = Issue('The first issue') - self.b.add(o) - self.b.finish(o.id) + v = self.b.add(o) + self.b.finish(v) with self.assertRaises(DeadIssue): - self.b.doing(o.id) + self.b.doing(v) if __name__ == '__main__': diff --git a/test/test_issue.py b/test/test_issue.py @@ -0,0 +1,18 @@ +import unittest +import logging + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + +from piknik import Issue + + +class TestIssue(unittest.TestCase): + + def test_basic(self): + o = Issue('foo') + v = o.serialize() + + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_store.py b/test/test_store.py @@ -0,0 +1,40 @@ +import unittest +import shep +import logging +import tempfile + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + +from piknik import ( + Basket, + Issue, + ) +from piknik.error import DeadIssue +from piknik.store import FileStoreFactory + + +def debug_out(self, k, v): + logg.debug('TRACE: {} {}'.format(k, v)) + + +class TestStore(unittest.TestCase): + + def setUp(self): + self.d = tempfile.mkdtemp() + store_factory = FileStoreFactory(self.d) + self.b = Basket(store_factory.create) + + + def tearDown(self): + logg.debug('tempdir is {}'.format(self.d)) + pass + + + def test_basic(self): + o = Issue('foo') + v = self.b.add(o) + + +if __name__ == '__main__': + unittest.main()