From 4a19faadf36e2399a709c1fcb9b2760369447373 Mon Sep 17 00:00:00 2001 From: Marcus Huewe Date: Thu, 9 Sep 2010 12:30:49 +0200 Subject: [PATCH] - Package class: moved validation code into a new method "validate" - do_commit: call validate before asking the user for a commit msg - Project class: added new validate_pacs method - minor fixes here and there --- osc/commandline.py | 87 +++++++++++++++++++++++++--------------------- osc/core.py | 72 +++++++++++++++++++++++++------------- 2 files changed, 95 insertions(+), 64 deletions(-) diff --git a/osc/commandline.py b/osc/commandline.py index 7f4d52a7..c9d6ceb9 100644 --- a/osc/commandline.py +++ b/osc/commandline.py @@ -2981,6 +2981,30 @@ Please submit there instead, or use --nodevelproject to force direct submission. ${cmd_usage} ${cmd_option_list} """ + def get_commit_msg(pacs): + template = store_read_file(os.path.abspath('.'), '_commit_msg') + # open editor for commit message + # but first, produce status and diff to append to the template + footer = [] + lines = [] + for pac in pacs: + changed = getStatus([pac], quiet=True) + 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)) + if template == None: + template='\n'.join(lines) + msg = '' + # if footer is empty, there is nothing to commit, and no edit needed. + if footer: + msg = edit_message(footer='\n'.join(footer), template=template) + if msg: + store_write_string(os.path.abspath('.'), '_commit_msg', msg + '\n') + else: + store_unlink_file(os.path.abspath('.'), '_commit_msg') + return msg args = parseargs(args) @@ -3006,10 +3030,12 @@ Please submit there instead, or use --nodevelproject to force direct submission. arg_list = args[:] for arg in arg_list: if conf.config['do_package_tracking'] and is_project_dir(arg): - if not msg: - msg = edit_message() try: - Project(arg).commit(msg=msg, validators=validators, verbose_validation=verbose_validation) + prj = Project(arg) + prj.validate_pacs(validators, verbose_validation) + if not msg: + msg = edit_message() + prj.commit(msg=msg) except oscerr.ExtRuntimeError, e: print >>sys.stderr, "ERROR: source_validator failed", e return 1 @@ -3020,34 +3046,12 @@ Please submit there instead, or use --nodevelproject to force direct submission. if conf.config['check_filelist'] and not opts.force: check_filelist_before_commit(pacs) - if not msg: - template = store_read_file(os.path.abspath('.'), '_commit_msg') - # open editor for commit message - # but first, produce status and diff to append to the template - footer = [] - lines = [] - for pac in pacs: - changed = getStatus([pac], quiet=True) - 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)) - if template == None: - template='\n'.join(lines) - # if footer is empty, there is nothing to commit, and no edit needed. - if footer: - msg = edit_message(footer='\n'.join(footer), template=template) - - if msg: - store_write_string(os.path.abspath('.'), '_commit_msg', msg + '\n') - else: - store_unlink_file(os.path.abspath('.'), '_commit_msg') - if conf.config['do_package_tracking'] and len(pacs) > 0: prj_paths = {} single_paths = [] files = {} + # XXX: this is really ugly + pac_objs = {} # it is possible to commit packages from different projects at the same # time: iterate over all pacs and put each pac to the right project in the dict for pac in pacs: @@ -3055,24 +3059,29 @@ Please submit there instead, or use --nodevelproject to force direct submission. if is_project_dir(path): pac_path = os.path.basename(os.path.normpath(pac.absdir)) prj_paths.setdefault(path, []).append(pac_path) + pac_objs.setdefault(path, []).append(pac) files[pac_path] = pac.todo else: single_paths.append(pac.dir) - for prj, packages in prj_paths.iteritems(): - try: - Project(prj).commit(tuple(packages), msg=msg, files=files, validators=validators, verbose_validation=verbose_validation) - except oscerr.ExtRuntimeError, e: - print >>sys.stderr, "ERROR: source_validator failed", e - return 1 + for prj_path, packages in prj_paths.iteritems(): + prj = Project(prj_path) + prj.validate_pacs(validators, verbose_validation, *packages) + if not msg: + msg = get_commit_msg(pac_objs[prj_path]) + prj.commit(packages, msg=msg, files=files) for pac in single_paths: - try: - Package(pac).commit(msg, validators=validators, verbose_validation=verbose_validation) - except oscerr.ExtRuntimeError, e: - print >>sys.stderr, "ERROR: source_validator failed", e - return 1 + p = Package(pac) + p.validate(validators, verbose_validation) + if not msg: + msg = get_commit_msg([p]) + p.commit(msg) else: for p in pacs: - p.commit(msg, validators=validators, verbose_validation=verbose_validation) + p = Package(pac) + p.validate(validators, verbose_validation) + if not msg: + msg = get_commit_msg([p]) + p.commit(msg) store_unlink_file(os.path.abspath('.'), '_commit_msg') diff --git a/osc/core.py b/osc/core.py index a846a8ed..8a0b2ad6 100644 --- a/osc/core.py +++ b/osc/core.py @@ -637,7 +637,24 @@ class Project: finally: self.write_packages() - def commit(self, pacs = (), msg = '', files = {}, validators = None, verbose_validation = None): + def validate_pacs(self, validators, verbose_validation=False, *pacs): + if len(pacs) == 0: + for pac in self.pacs_broken: + if self.get_state(pac) != 'D': + msg = 'validation failed: package \'%s\' is missing' % pac + raise oscerr.PackageMissing(self.name, pac, msg) + pacs = self.pacs_have + for pac in pacs: + if pac in self.pacs_broken and self.get_state(pac) != 'D': + msg = 'validation failed: package \'%s\' is missing' % pac + raise oscerr.PackageMissing(self.name, pac, msg) + if os_path_samefile(os.path.join(self.dir, pac), os.getcwd()): + p = Package('.') + else: + p = Package(os.path.join(self.dir, pac)) + p.validate(validators, verbose_validation) + + def commit(self, pacs = (), msg = '', files = {}, validators_dir = None, verbose_validation = None): if len(pacs): try: for pac in pacs: @@ -646,7 +663,7 @@ class Project: todo = files[pac] state = self.get_state(pac) if state == 'A': - self.commitNewPackage(pac, msg, todo, validators=validators, verbose_validation=verbose_validation) + self.commitNewPackage(pac, msg, todo, validators_dir=validators_dir, verbose_validation=verbose_validation) elif state == 'D': self.commitDelPackage(pac) elif state == ' ': @@ -656,7 +673,7 @@ class Project: else: p = Package(os.path.join(self.dir, pac)) p.todo = todo - p.commit(msg, validators=validators, verbose_validation=verbose_validation) + p.commit(msg, validators_dir=validators_dir, verbose_validation=verbose_validation) elif pac in self.pacs_unvers and not is_package_dir(os.path.join(self.dir, pac)): print 'osc: \'%s\' is not under version control' % pac elif pac in self.pacs_broken: @@ -676,15 +693,15 @@ class Project: state = self.get_state(pac) if state == ' ': # do a simple commit - Package(os.path.join(self.dir, pac)).commit(msg, validators=validators, verbose_validation=verbose_validation) + Package(os.path.join(self.dir, pac)).commit(msg, validators_dir=validators_dir, verbose_validation=verbose_validation) elif state == 'D': self.commitDelPackage(pac) elif state == 'A': - self.commitNewPackage(pac, msg, validators=validators, verbose_validation=verbose_validation) + self.commitNewPackage(pac, msg, validators_dir=validators_dir, verbose_validation=verbose_validation) finally: self.write_packages() - def commitNewPackage(self, pac, msg = '', files = [], validators = None, verbose_validation = None): + def commitNewPackage(self, pac, msg = '', files = [], validators_dir = None, verbose_validation = None): """creates and commits a new package if it does not exist on the server""" if pac in self.pacs_available: print 'package \'%s\' already exists' % pac @@ -705,7 +722,7 @@ class Project: p = Package(os.path.join(self.dir, pac)) p.todo = files print statfrmt('Sending', os.path.normpath(p.dir)) - p.commit(msg=msg, validators=validators, verbose_validation=verbose_validation) + p.commit(msg=msg, validators_dir=validators_dir, verbose_validation=verbose_validation) self.set_state(pac, ' ') os.chdir(olddir) @@ -1049,34 +1066,39 @@ class Package: todo.append(n.get('name')) return todo - def commit(self, msg='', validators=None, verbose_validation=None): + def validate(self, validators_dir, verbose_validation=False): + import subprocess + import stat + if validators_dir is None or self.name.startswith('_'): + return + for validator in sorted(os.listdir(validators_dir)): + if validator.startswith('.'): + continue + fn = os.path.join(validators_dir, validator) + mode = os.stat(fn).st_mode + if stat.S_ISREG(mode): + if verbose_validation: + print 'osc runs source validator: %s' % fn + p = subprocess.Popen([fn, '--verbose'], close_fds=True) + else: + p = subprocess.Popen([fn], close_fds=True) + if p.wait() != 0: + raise oscerr.ExtRuntimeError('ERROR: source_validator failed:\n%s' % p.stdout, validator) + + def commit(self, msg='', validators_dir=None, verbose_validation=None): # commit only if the upstream revision is the same as the working copy's upstream_rev = self.latest_rev() if self.rev != upstream_rev: raise oscerr.WorkingCopyOutdated((self.absdir, self.rev, upstream_rev)) + if not validators_dir is None: + self.validate(validators_dir, verbose_validation) + if not self.todo: self.todo = [i for i in self.to_be_added if not i in self.filenamelist] + self.filenamelist pathn = getTransActPath(self.dir) - if validators and not self.name.startswith('_'): - import subprocess - import stat - for validator in sorted(os.listdir(validators)): - if validator.startswith('.'): - continue - fn = os.path.join(validators, validator) - mode = os.stat(fn).st_mode - if stat.S_ISREG(mode): - if verbose_validation: - print "osc runs source service:", fn - p = subprocess.Popen([fn, "--verbose"], close_fds=True) - else: - p = subprocess.Popen([fn], close_fds=True) - if p.wait() != 0: - raise oscerr.ExtRuntimeError(p.stdout, validator ) - todo_send = {} todo_delete = [] real_send = []