From c330700f36e286e95b50a3f4f81601509afea040 Mon Sep 17 00:00:00 2001 From: Marcus Huewe Date: Wed, 22 Dec 2010 23:17:11 +0100 Subject: [PATCH] - refactored getStatus into the Project/Package class - removed getStatus - added the following new methods to the Project class: * get_status: get the status of all packages in the project * status: get the status of a single package * get_pacobj: return a new Package object - added the following new method to the Package class: * get_status: get the status of all files in the package - do_commit: fixed getStatus() call - do_status: rewrite (uses new methods) --- osc/commandline.py | 72 ++++++++++++++++--------------- osc/core.py | 103 +++++++++++++++++++++------------------------ 2 files changed, 86 insertions(+), 89 deletions(-) diff --git a/osc/commandline.py b/osc/commandline.py index 8a523f15..f1496255 100644 --- a/osc/commandline.py +++ b/osc/commandline.py @@ -2878,41 +2878,42 @@ Please submit there instead, or use --nodevelproject to force direct submission. ${cmd_option_list} """ - args = parseargs(args) + if opts.quiet and opts.verbose: + raise oscerr.WrongOptions('\'--quiet\' and \'--verbose\' are mutually exclusive') - # storage for single Package() objects - pacpaths = [] - # storage for a project dir ( { prj_instance : [ package objects ] } ) - prjpacs = {} + args = parseargs(args) + lines = [] + excl_states = (' ',) + if opts.quiet: + excl_states += ('?',) + elif opts.verbose: + excl_states = () for arg in args: - # when 'status' is run inside a project dir, it should - # stat all packages existing in the wc if is_project_dir(arg): prj = Project(arg, False) - - if conf.config['do_package_tracking']: - prjpacs[prj] = [] - for pac in prj.pacs_have: - # we cannot create package objects if the dir does not exist - if not pac in prj.pacs_broken: - prjpacs[prj].append(os.path.join(arg, pac)) - else: - pacpaths += [arg + '/' + n for n in prj.pacs_have] - elif is_package_dir(arg): - pacpaths.append(arg) - elif os.path.isfile(arg) or is_package_dir(os.path.dirname(arg)): - pacpaths.append(arg) + # don't exclude packages with state ' ' because the packages + # might have modified etc. files + prj_excl = [st for st in excl_states if st != ' '] + for st, pac in sorted(prj.get_status(*prj_excl), lambda x, y: cmp(x[1], y[1])): + p = prj.get_pacobj(pac) + if p is None: + # state is != ' ' + lines.append(statfrmt(st, os.path.normpath(os.path.join(prj.dir, pac)))) + continue + if st == ' ' and opts.verbose or st != ' ': + lines.append(statfrmt(st, os.path.normpath(os.path.join(prj.dir, pac)))) + states = p.get_status(opts.show_excluded, *excl_states) + for st, filename in sorted(states, lambda x, y: cmp(x[1], y[1])): + lines.append(statfrmt(st, os.path.normpath(os.path.join(p.dir, filename)))) else: - msg = '\'%s\' is neither a project or a package directory' % arg - raise oscerr.NoWorkingCopy, msg - lines = [] - # process single packages - lines = getStatus(findpacs(pacpaths), None, opts.verbose, opts.quiet, opts.show_excluded) - # process project dirs - for prj, pacs in prjpacs.iteritems(): - lines += getStatus(findpacs(pacs), prj, opts.verbose, opts.quiet, opts.show_excluded) - if lines: - print '\n'.join(lines) + p = findpacs([arg])[0] + for st, filename in sorted(p.get_status(opts.show_excluded, *excl_states), lambda x, y: cmp(x[1], y[1])): + lines.append(statfrmt(st, os.path.normpath(os.path.join(p.dir, filename)))) + # arrange the lines in order: unknown files first + # filenames are already sorted + lines = [l for l in lines if l[0] == '?'] + \ + [l for l in lines if l[0] != '?'] + print '\n'.join(lines) def do_add(self, subcmd, opts, *args): @@ -3060,13 +3061,14 @@ Please submit there instead, or use --nodevelproject to force direct submission. # but first, produce status and diff to append to the template footer = [] lines = [] - for pac in pacs: - changed = getStatus([pac], quiet=True) + for p in pacs: + states = sorted(p.get_status(False, ' ', '?'), lambda x, y: cmp(x[1], y[1])) + changed = [statfrmt(st, os.path.normpath(os.path.join(p.dir, filename))) for st, filename in states] if changed: footer += changed - footer.append('\nDiff for working copy: %s' % pac.dir) - footer.extend([''.join(i) for i in pac.get_diff(ignoreUnversioned=True)]) - lines.extend(get_commit_message_template(pac)) + footer.append('\nDiff for working copy: %s' % p.dir) + footer.extend([''.join(i) for i in p.get_diff(ignoreUnversioned=True)]) + lines.extend(get_commit_message_template(p)) if template == None: template='\n'.join(lines) msg = '' diff --git a/osc/core.py b/osc/core.py index 896d6093..78918099 100644 --- a/osc/core.py +++ b/osc/core.py @@ -494,6 +494,39 @@ class Project: pathname=getTransActPath(os.path.join(self.dir, pac)), \ prj_obj=self, prj_dir=self.dir, expand_link=expand_link, progress_obj=self.progress_obj) + def status(self, pac): + exists = os.path.exists(os.path.join(self.absdir, pac)) + st = self.get_state(pac) + if st is None and exists: + return '?' + elif st is None: + raise oscerr.OscIOError(None, 'osc: \'%s\' is not under version control' % pac) + elif st in ('A', ' ') and not exists: + return '!' + elif st == 'D' and not exists: + return 'D' + else: + return st + + def get_status(self, *exclude_states): + res = [] + for pac in self.pacs_have: + st = self.status(pac) + if not st in exclude_states: + res.append((st, pac)) + if not '?' in exclude_states: + res.extend([('?', pac) for pac in self.pacs_unvers]) + return res + + def get_pacobj(self, pac, *pac_args, **pac_kwargs): + try: + st = self.status(pac) + if st in ('?', '!') or st == 'D' and not os.path.exists(os.path.join(self.dir, pac)): + return None + return Package(os.path.join(self.dir, pac), *pac_args, **pac_kwargs) + except oscerr.OscIOError: + return None + def set_state(self, pac, state): node = self.get_package_node(pac) if node == None: @@ -1475,6 +1508,22 @@ class Package: if i.name == n: return i + def get_status(self, excluded=False, *exclude_states): + global store + todo = self.todo + if not todo: + todo = self.filenamelist + self.to_be_added + \ + [i for i in self.filenamelist_unvers if not os.path.isdir(os.path.join(self.absdir, i))] + if excluded: + todo.extend([i for i in self.excluded if i != store]) + todo = set(todo) + res = [] + for fname in sorted(todo): + st = self.status(fname) + if not st in exclude_states: + res.append((st, fname)) + return res + def status(self, n): """ status can be: @@ -5447,60 +5496,6 @@ def getTransActPath(pac_dir): pathn = '' return pathn -def getStatus(pacs, prj_obj=None, verbose=False, quiet=False, excluded=False): - """ - calculates the status of certain packages. pacs is a list of Package() - objects and prj_obj is a Project() object. If prj_obj is specified all - Package() objects in the pacs list have to belong to this project. - """ - global store - lines = [] - if prj_obj: - if conf.config['do_package_tracking']: - for data in prj_obj.pacs_unvers: - lines.append(statfrmt('?', os.path.normpath(os.path.join(prj_obj.dir, data)))) - for data in prj_obj.pacs_broken: - if prj_obj.get_state(data) == 'D': - lines.append(statfrmt('D', os.path.normpath(os.path.join(prj_obj.dir, data)))) - else: - lines.append(statfrmt('!', os.path.normpath(os.path.join(prj_obj.dir, data)))) - - for p in pacs: - if not p.todo and excluded: - # all files + dirs in pwd (except .osc storedir) - p.todo = p.filenamelist + p.filenamelist_unvers + [i for i in p.excluded if i != store] - elif not p.todo: - # only files, no dirs and no excluded files - p.todo = p.filenamelist + [i for i in p.filenamelist_unvers if not os.path.isdir(i)] - p.todo.sort() - - if prj_obj and conf.config['do_package_tracking']: - state = prj_obj.get_state(p.name) - if state != None and (state != ' ' or verbose): - lines.append(statfrmt(state, os.path.normpath(os.path.join(prj_obj.dir, p.name)))) - - for filename in p.todo: -# if filename.startswith('_service:'): -# continue - if filename in p.excluded and not excluded: - continue -# if filename in p.skipped: -# continue - s = p.status(filename) - if s == 'F': - lines.append(statfrmt('!', pathjoin(p.dir, filename))) - elif s != ' ' or (s == ' ' and verbose): - lines.append(statfrmt(s, pathjoin(p.dir, filename))) - - if quiet: - lines = [line for line in lines if line[0] != '?'] - else: - # arrange the lines in order: unknown files first - # filenames are already sorted - lines = [line for line in lines if line[0] == '?'] \ - + [line for line in lines if line[0] != '?'] - return lines - def get_commit_message_template(pac): """ Read the difference in .changes file(s) and put them as a template to commit message.