def latest_revision(self): """Return the latest remote revision.""" spkg = SourcePackage(self.project, self.name) directory = spkg.list(rev='latest', apiurl=self.apiurl) if self.is_link(): if directory.linkinfo.has_error(): # FIXME: proper error handling return 'latest' elif self.is_expanded(): return directory.linkinfo.get('xsrcmd5') return directory.get('srcmd5')
def repair(path, ext_storedir=None, revision='latest', **kwargs): """Repair a working copy. path is the path to the package working copy. Keyword arguments: project -- name of the project (default: '') package -- name of the package (default: '') apiurl -- apiurl is the apiurl (default: '') revision -- the revision of the package (default: 'latest') ext_storedir -- path to the storedir (default: None) """ global _PKG_DATA if not os.path.exists(_storedir(path)): wc_init(path, ext_storedir=ext_storedir) missing, xml_data, pkg_data = Package.wc_check(path) for filename in ('_project', '_package', '_apiurl'): if filename not in missing: continue key = filename[1:] if key not in kwargs: raise ValueError("%s argument required" % key) meth_name = 'wc_write_' + key globals()[meth_name](path, kwargs[key]) project = wc_read_project(path) package = wc_read_package(path) apiurl = wc_read_apiurl(path) if '_files' in missing or xml_data: spkg = SourcePackage(project, package) directory = spkg.list(rev=revision, apiurl=apiurl) xml_data = etree.tostring(directory, pretty_print=True) wc_write_files(path, xml_data) if '_version' in missing: wc_write_version(path) if _PKG_DATA in missing: os.mkdir(wc_pkg_data_filename(path, '')) files = wc_read_files(path) # check again - only pkg_data left missing, xml_data, pkg_data = Package.wc_check(path) for filename in pkg_data: fname = wc_pkg_data_filename(path, filename) f = files.find(filename).file() f.write_to(fname) # clean unused storefiles store = wc_pkg_data_filename(path, '') for filename in os.listdir(store): if files.find(filename) is None: os.unlink(os.path.join(store, filename))
def _list(info): expand = '' if hasattr(info, 'expand'): expand = info.expand if hasattr(info, 'package'): spkg = SourcePackage(info.project, info.package) directory = spkg.list(expand=expand) title = "%s: %s" % (os.path.join( info.project, info.package), directory.get('srcmd5')) else: title = info.project + ':' sprj = SourceProject(info.project) directory = sprj.list(expand=expand) print title for entry in directory: print entry.get('name')
def _list(info): expand = '' if hasattr(info, 'expand'): expand = info.expand if hasattr(info, 'package'): spkg = SourcePackage(info.project, info.package) directory = spkg.list(expand=expand) title = "%s: %s" % (os.path.join(info.project, info.package), directory.get('srcmd5')) else: title = info.project + ':' sprj = SourceProject(info.project) directory = sprj.list(expand=expand) print title for entry in directory: print entry.get('name')
def list_package(renderer, project, package, info): """Lists package contents. illegal options: --%(opt)s is not supported at package level. """ global FILE_LIST_TEMPLATE pkg = Package(project, package) query = {'apiurl': info.apiurl, 'rev': info.revision} if info.expand: query['expand'] = '1' if info.deleted: query['deleted'] = '1' if info.meta: query['meta'] = '1' directory = pkg.list(**query) renderer.render(FILE_LIST_TEMPLATE, directory=directory, info=info)
def _calculate_updateinfo(self, revision='', remote_files=None, **kwargs): unchanged = [] added = [] deleted = [] modified = [] conflicted = [] skipped = [] if remote_files is None: spkg = SourcePackage(self.project, self.name) remote_files = spkg.list(rev=revision, apiurl=self.apiurl, **kwargs) local_files = self.files() data = {} for rfile in remote_files: rfname = rfile.get('name') data[rfname] = rfile if rfname not in local_files: if os.path.exists(os.path.join(self.path, rfname)): conflicted.append(rfname) else: added.append(rfname) continue st = self.status(rfname) lfile = self._files.find(rfname) if st == 'A': conflicted.append(rfname) elif st == 'S': skipped.append(rfname) elif lfile.get('md5') == rfile.get('md5'): unchanged.append(rfname) else: modified.append(rfname) remote_fnames = [f.get('name') for f in remote_files] for lfname in local_files: if lfname not in remote_fnames: st = self.status(lfname) if st == 'A': # added files shouldn't be deleted # so treat them as unchanged unchanged.append(lfname) else: deleted.append(lfname) data[lfname] = self._files.find(lfname) return FileUpdateInfo(unchanged, added, deleted, modified, conflicted, skipped, data, remote_files)
def test7(self): """test commit log""" pkg = Package('foo', 'bar') log = pkg.log() self.assertTrue(len(log.revision[:]) == 2) self.assertEqual(log.revision[0].get('rev'), '1') self.assertEqual(log.revision[0].get('vrev'), '1') self.assertEqual(log.revision[0].srcmd5, 'abc') self.assertEqual(log.revision[0].version, 'unknown') self.assertEqual(log.revision[0].time, '1308140485') self.assertEqual(log.revision[0].user, 'foo') self.assertEqual(log.revision[0].comment, 'updated pkg') self.assertFalse('requestid' in log.revision[0]) # second entry self.assertEqual(log.revision[1].get('rev'), '2') self.assertEqual(log.revision[1].get('vrev'), '1') self.assertEqual(log.revision[1].srcmd5, 'fff') self.assertEqual(log.revision[1].version, 'unknown') self.assertEqual(log.revision[1].time, '1308140486') self.assertEqual(log.revision[1].user, 'foo') self.assertEqual(log.revision[1].comment, 'request') self.assertEqual(log.revision[1].requestid, '123')
def test5(self): """test invalid xml data (file list)""" Package.LIST_SCHEMA = self.fixture_file('directory.xsd') pkg = Package('foo', 'bar') self.assertRaises(etree.DocumentInvalid, pkg.list)
def test6(self): """list a specific package revision""" pkg = Package('foo', 'bar') pkg.list(rev='fff')
def diff(self, diff, *filenames, **kwargs): """Initialize diff object. filenames are the working copy filenames which should be considered. If no filenames are specified all working copy files will be used. A ValueError is raised if a filename is not tracked. Keyword arguments: revision -- diff against the remote revision revision (default: '') """ def consider_filenames(info, filenames): if set(filenames) == set(self.files()): return # only consider filenames remove = [] for filename in info: if filename not in filenames: remove.append(filename) for filename in remove: info.remove(filename) untracked = [f for f in filenames if self.status(f) == '?'] if untracked: msg = ("diff not possible untracked files: %s" % ', '.join(untracked)) raise ValueError(msg) revision = kwargs.get('revision', '') if not filenames: filenames = self.files() diff.wc_path = self.path diff.revision_data = self._files.revision_data() if revision: spkg = SourcePackage(self.project, self.name) directory = spkg.list(rev=revision, apiurl=self.apiurl) info = self._calculate_updateinfo(remote_files=directory) consider_filenames(info, filenames) # swap added and deleted tmp = info.added info.added = info.deleted info.deleted = tmp # treat files with state 'A' as added local_added = [f for f in info.unchanged if self.status(f) == 'A'] for filename in local_added: info.unchanged.remove(filename) info.added.append(filename) # check for missing files missing = [f for f in info if self.status(f) == '!'] # treat files with state 'D' as deleted deleted = [f for f in info if self.status(f) == 'D'] for filename in missing + deleted: info.remove(filename) info.conflicted.extend(missing) info.deleted.extend(deleted) diff._remote_files = directory srcmd5 = directory.get('srcmd5') diff.old_path = wc_diff_mkdir(self.path, srcmd5) diff.revision_data = {'rev': revision, 'srcmd5': srcmd5} else: info = self._calculate_commitinfo(*filenames) consider_filenames(info, filenames) skipped = [f for f in info.unchanged if self.status(f) == 'S'] for filename in skipped: info.remove(filename) info.skipped = skipped diff.old_path = wc_pkg_data_filename(self.path, '') listnames = ('added', 'deleted', 'modified', 'unchanged', 'skipped') for listname in listnames: for filename in getattr(info, listname): diff.append(filename, listname) for filename in info.conflicted: if self.status(filename) == '!': diff.append(filename, 'missing') else: diff.append(filename, 'modified')