1 # -*- encoding: utf-8 -*-
4 log = logging.getLogger('ral.mercurial')
6 __author__ = "Łukasz Rekucki"
7 __date__ = "$2009-09-25 09:35:06$"
8 __doc__ = "Module documentation."
11 import mercurial.error
15 log = logging.getLogger('wlrepo.document')
17 class MercurialDocument(wlrepo.Document):
19 def data(self, entry):
20 path = self._library._sanitize_string(self.id + u'.' + entry)
22 return self._library._filectx(path, \
23 self._revision.hgrev()).data().decode('utf-8')
24 except mercurial.error.LookupError, e:
25 fl = [x.decode('utf-8') for x in self._revision._changectx]
26 raise wlrepo.EntryNotFound(self._revision, path.decode('utf-8'), fl)
28 def quickwrite(self, entry, data, msg, user=None):
29 user = user or self.owner
31 if isinstance(data, unicode):
32 data = data.encode('utf-8')
34 user = self._library._sanitize_string(user)
35 msg = self._library._sanitize_string(msg)
36 entry = self._library._sanitize_string(entry)
39 raise ValueError("Can't determine user.")
42 f = l._fileopen(r(entry), "w+")
47 return self.invoke_and_commit(write, lambda d: (msg, \
48 self._library._sanitize_string(self.owner)) )
50 def invoke_and_commit(self, ops, commit_info):
51 lock = self._library.lock()
53 self._library._checkout(self._revision.hgrev())
55 def entry_path(entry):
56 return self._library._sanitize_string(self.id + u'.' + entry)
58 ops(self._library, entry_path)
59 message, user = commit_info(self)
61 message = self._library._sanitize_string(message)
62 user = self._library._sanitize_string(user)
64 self._library._commit(message, user)
66 return self._library.document(docid=self.id, user=user)
68 # rollback the last commit
69 self._library._rollback()
74 # def commit(self, message, user):
75 # """Make a new commit."""
76 # self.invoke_and_commit(message, user, lambda *a: True)
79 return self._revision.user_name is None
82 return (self == self.latest())
88 return self._library.document(docid=self.id)
91 return self._library.document(docid=self.id, user=self.owner)
94 fullid = self._library.fulldocid(self.id, user)
96 def take_action(library, resolve):
98 library._set_branchname(fullid)
100 if not self._library.has_revision(fullid):
101 log.info("Checking out document %s" % fullid)
103 self.invoke_and_commit(take_action, \
104 lambda d: ("$AUTO$ File checkout.", user) )
106 return self._library.document_for_rev(fullid)
108 def up_to_date(self):
109 return self.ismain() or (\
110 self.shared().ancestorof(self) )
113 def update(self, user):
114 """Update parts of the document."""
115 lock = self.library.lock()
118 # main revision of the document
121 if self._revision.has_children():
122 log.info('Update failed: has children.')
123 # can't update non-latest revision
124 return (False, False)
128 if self.parentof(sv):
131 if sv.ancestorof(self):
134 return self._revision.merge_with(sv._revision, user=user,
135 message="$AUTO$ Personal branch update.")
139 def share(self, message):
140 lock = self.library.lock()
143 return False # always shared
145 user = self._revision.user_name
146 main = self.shared()._revision
147 local = self._revision
152 # * <- can also be here!
157 # The local branch has been recently updated,
158 # so we don't need to update yet again, but we need to
159 # merge down to default branch, even if there was
160 # no commit's since last update
162 # This is actually the only good case!
163 if main.ancestorof(local):
164 success, changed = main.merge_with(local, user=user, message=message)
167 raise LibraryException("Merge failed.")
174 # * <- this case overlaps with previos one
180 # There was a recent merge to the defaul branch and
181 # no changes to local branch recently.
184 elif local.ancestorof(main):
187 # In all other cases, the local needs an update
188 # and possibly conflict resolution, so fail
189 raise LibraryExcepton("Document not prepared for sharing.")
195 def has_conflict_marks(self):
196 return re.search("^(?:<<<<<<< .*|=======|>>>>>>> .*)$", self.data('xml'), re.MULTILINE)
198 def __unicode__(self):
199 return u"Document(%s:%s)" % (self.id, self.owner)
202 return self.__unicode__().encode('utf-8')
204 def __eq__(self, other):
205 return (self._revision == other._revision)