# Copyright (C) 2015 Mozilla Contributors # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # As a special exception, the copyright holders of this code give you # permission to combine this code with the software known as 'mozbuild', # and to distribute those combinations without any restriction # coming from the use of this file. (The General Public License # restrictions do apply in other respects; for example, they cover # modification of the file, and distribution when not combined with # mozbuild.) # # If you modify this code, you may extend this exception to your # version of the code, but you are not obliged to do so. If you # do not wish to do so, delete this exception statement from your # version. from __future__ import absolute_import import mercurial.error as error import mercurial.hg as hg import mercurial.ui as hgui from .files import ( BaseFinder, MercurialFile, ) import mozpack.path as mozpath # This isn't a complete implementation of BaseFile. But it is complete # enough for moz.build reading. class MercurialNativeFile(MercurialFile): def __init__(self, data): self.data = data def read(self): return self.data class MercurialNativeRevisionFinder(BaseFinder): def __init__(self, repo, rev='.', recognize_repo_paths=False): """Create a finder attached to a specific changeset. Accepts a Mercurial localrepo and changectx instance. """ if isinstance(repo, (str, unicode)): path = repo repo = hg.repository(hgui.ui(), repo) else: path = repo.root super(MercurialNativeRevisionFinder, self).__init__(base=repo.root) self._repo = repo self._rev = rev self._root = mozpath.normpath(path) self._recognize_repo_paths = recognize_repo_paths def _find(self, pattern): if self._recognize_repo_paths: raise NotImplementedError('cannot use find with recognize_repo_path') return self._find_helper(pattern, self._repo[self._rev], self._get) def get(self, path): if self._recognize_repo_paths: if not path.startswith(self._root): raise ValueError('lookups in recognize_repo_paths mode must be ' 'prefixed with repo path: %s' % path) path = path[len(self._root) + 1:] return self._get(path) def _get(self, path): if isinstance(path, unicode): path = path.encode('utf-8', 'replace') try: fctx = self._repo.filectx(path, self._rev) return MercurialNativeFile(fctx.data()) except error.LookupError: return None