Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
agateau committed Jan 25, 2016
1 parent 0fadd50 commit 3c7aa22
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 6 deletions.
6 changes: 4 additions & 2 deletions yokadi/sync/README.md
Expand Up @@ -25,14 +25,15 @@ Configuration file

- Make DB read-only
- Check Git repository is clean. If not, warn and propose committing pending changes
- Note current commit id in $oldCommitId
- git pull. If conflicts, handle them...
- Commit changes
- List all Git changes since $oldCommitId
- List all Git changes since `synced` branch
- for all new files: create task
- for all modified files: update task
- for all removed files: remove task
- Make DB read-write
- Updated `synced` branch to HEAD:
git branch --force synced

## gs.push

Expand All @@ -48,6 +49,7 @@ Configuration file
- Declare a Git remote
- Publish remote
- Make origin/master the upstream branch of master
- Create the `synced` branch

## gs.clone

Expand Down
35 changes: 35 additions & 0 deletions yokadi/sync/gitvcsimpl.py
Expand Up @@ -3,6 +3,13 @@
import subprocess


class VcsChanges(object):
def __init__(self):
self.added = []
self.modified = []
self.removed = []


class GitVcsImpl(object):
name = "Git"

Expand Down Expand Up @@ -69,6 +76,34 @@ def getConflicts(self):
def abortMerge(self):
self._run("merge", "--abort")

def getCommitId(self, branchName="master"):
output = self._run("branch", "--list", "-v", "--no-abbrev", branchName).decode("utf-8")
# output looks like this:
# " dirs af5bea2a51e09f0d3441b2b46083f513af2047dc Drop Python 3.3 support"

# Skip "current branch" indicator
output = output[2:]

return output.split(" ")[0]

def getChangesSince(self, commitId):
output = self._run("diff", "--name-status", commitId + "..").decode("utf-8")
changes = VcsChanges()
for line in output.splitlines():
status, filename = line.split()
if status == "M":
changes.modified.append(filename)
elif status == "A":
changes.added.append(filename)
elif status == "D":
changes.removed.append(filename)
else:
raise Exception("Unknown status {} in line '{}'".format(status, line))
return changes

def updateBranch(self, branchName, commitId):
self._run("branch", "--force", branchName, commitId)

def _run(self, *args, **kwargs):
cwd = kwargs.get("cwd", self._srcDir)
cmd = ["git", "-C", cwd]
Expand Down
33 changes: 29 additions & 4 deletions yokadi/sync/pull.py
@@ -1,23 +1,41 @@
import os

import icalendar

from yokadi.core import db
from yokadi.core.db import Task

from yokadi.sync.gitvcsimpl import GitVcsImpl
from yokadi.yical import yical


def getTaskUuidFromFilename(filename):
return os.path.splitext(filename)[0]


def addTask(taskDir, filename):
pass
uuid = getTaskUuidFromFilename(filename)
session = db.getSession()
task = Task(uuid=uuid)
_updateTaskFromVtodo(task, taskDir, filename)
session.add(task)


def updateTask(taskDir, filename):
uuid = getTaskUuidFromFilename(filename)
session = db.getSession()
task = session.query(Task).filter_by(uuid=uuid).one()
_updateTaskFromVtodo(task, taskDir, filename)
session.add(task)


def _updateTaskFromVtodo(task, taskDir, filename):
with open(os.path.join(taskDir, filename), "rt") as f:
content = f.read()
cal = icalendar.Calendar.from_ical(content)
for vTodo in cal.walk():
if "UID" in vTodo:
yical.updateTaskFromVTodo(task, vTodo)


def removeTask(filename):
Expand All @@ -31,21 +49,28 @@ def pull(dumpDir, vcsImpl=None, conflictResolver=None):
vcsImpl = GitVcsImpl()

vcsImpl.setDir(dumpDir)
commitId = vcsImpl.getCommitId()
vcsImpl.pull()

for conflict in vcsImpl.getConflicts():
if not conflictResolver.resolve(conflict):
if not conflictResolver or not conflictResolver.resolve(conflict):
vcsImpl.abortMerge()
return False

if not vcsImpl.isWorkTreeClean():
vcsImpl.commit("Pulled")

changes = vcsImpl.getChangesSince(commitId)
syncedCommitId = vcsImpl.getCommitId("synced")
changes = vcsImpl.getChangesSince(syncedCommitId)
for name in changes.added:
print("added {}".format(name))
addTask(dumpDir, name)
for name in changes.modified:
print("modified {}".format(name))
updateTask(dumpDir, name)
for name in changes.removed:
removeTask(name)

session = db.getSession()
session.commit()

vcsImpl.updateBranch("synced", vcsImpl.getCommitId())

0 comments on commit 3c7aa22

Please sign in to comment.