diff --git a/osc/commandline.py b/osc/commandline.py index 8b592b8b..61fa3e94 100644 --- a/osc/commandline.py +++ b/osc/commandline.py @@ -6043,12 +6043,28 @@ Please submit there instead, or use --nodevelproject to force direct submission. else: print >>sys.stderr, '\'%s\' is neither a project working copy ' \ 'nor a package working copy' % i - for i in pacs: + cp = conf.get_configParser(conf.config['conffile']) + apiurls = [i.rstrip('/') for i in cp.sections() if i != 'general'] + for pdir in pacs: try: - p = Package(i) - except oscerr.WorkingCopyInconsistent: - p = Package(i, wc_check=False) - p.wc_repair() + p = Package(pdir) + except oscerr.WorkingCopyInconsistent, e: + apiurl = None + if '_apiurl' in e.dirty_files: + print 'No apiurl is defined for this package.\n' \ + 'Please choose one from the following list (enter the number):' + for i in range(len(apiurls)): + print ' %d) %s' % (i, apiurls[i]) + num = raw_input('> ') + try: + num = int(num) + except ValueError: + raise oscerr.WrongArgs('\'%s\' is not a number. Aborting' % num) + if num < 0 or num >= len(apiurls): + raise oscerr.WrongArgs('number \'%s\' out of range. Aborting' % num) + apiurl = apiurls[num] + p = Package(pdir, wc_check=False) + p.wc_repair(apiurl) print 'done. Please check the state of the wc (via \'osc status %s\').' % i else: print >>sys.stderr, 'osc: working copy \'%s\' is not inconsistent' % i diff --git a/osc/core.py b/osc/core.py index 47124ea7..5a80a945 100644 --- a/osc/core.py +++ b/osc/core.py @@ -810,43 +810,54 @@ class Package: self.prjname = store_read_project(self.dir) self.name = store_read_package(self.dir) - self.apiurl = store_read_apiurl(self.dir, defaulturl=False) + self.apiurl = store_read_apiurl(self.dir, defaulturl=not wc_check) self.update_datastructs() - if wc_check and self.wc_check(): + dirty_files = [] + if wc_check: + dirty_files = self.wc_check() + if dirty_files: msg = 'Your working copy \'%s\' is in an inconsistent state.\n' \ 'Please run \'osc repairwc %s\' (Note this might _remove_\n' \ 'files from the .osc/ dir). Please check the state\n' \ 'of the working copy afterwards (via \'osc status %s\')' % (self.dir, self.dir, self.dir) - raise oscerr.WorkingCopyInconsistent(self.prjname, self.name, msg) + raise oscerr.WorkingCopyInconsistent(self.prjname, self.name, dirty_files, msg) self.todo = [] def wc_check(self): - dirty = False + dirty_files = [] for fname in self.filenamelist: if not os.path.exists(os.path.join(self.storedir, fname)) and not fname in self.skipped: - dirty = True + dirty_files.append(fname) for fname in Package.REQ_STOREFILES: if not os.path.isfile(os.path.join(self.storedir, fname)): - dirty = True + dirty_files.append(fname) for fname in os.listdir(self.storedir): if fname in Package.REQ_STOREFILES or fname in Package.OPT_STOREFILES or \ fname.startswith('_build'): continue elif fname in self.filenamelist and fname in self.skipped: - dirty = True + dirty_files.append(fname) elif not fname in self.filenamelist: - dirty = True + dirty_files.append(fname) for fname in self.to_be_deleted[:]: if not fname in self.filenamelist: - dirty = True + dirty_files.append(fname) for fname in self.in_conflict[:]: if not fname in self.filenamelist: - dirty = True - return dirty + dirty_files.append(fname) + return dirty_files - def wc_repair(self): + def wc_repair(self, apiurl=None): + if not os.path.exists(os.path.join(self.storedir, '_apiurl')): + if apiurl is None: + msg = 'cannot repair wc: the \'_apiurl\' file is missing but ' \ + 'no \'apiurl\' was passed to wc_repair' + # hmm should we raise oscerr.WrongArgs? + raise oscerr.WorkingCopyInconsistent(self.prjname, self.name, [], msg) + store_write_apiurl(self.dir, apiurl) + self.apiurl = store_read_apiurl(self.dir, defaulturl=False) # all files which are present in the filelist have to exist in the storedir for f in self.filelist: # XXX: should we also check the md5? @@ -4689,7 +4700,13 @@ def store_read_apiurl(dir, defaulturl=True): # (former osc versions may stored an apiurl with a trailing slash etc.) apiurl = conf.urljoin(*conf.parse_apisrv_url(None, url)) except: - if not defaulturl: + if not defaulturl and is_package_dir(dir): + msg = 'Your working copy \'%s\' is in an inconsistent state.\n' \ + 'Please run \'osc repairwc %s\' (Note this might _remove_\n' \ + 'files from the .osc/ dir). Please check the state\n' \ + 'of the working copy afterwards (via \'osc status %s\')' % (dir, dir, dir) + raise oscerr.WorkingCopyInconsistent(store_read_project(dir), store_read_package(dir), ['_apiurl'], msg) + elif not defaulturl: msg = 'Error: \'%s\' is not an osc package working copy' % os.path.abspath(dir) raise oscerr.NoWorkingCopy(msg) apiurl = conf.config['apiurl'] diff --git a/osc/oscerr.py b/osc/oscerr.py index bbfbf460..b989fd33 100644 --- a/osc/oscerr.py +++ b/osc/oscerr.py @@ -84,8 +84,9 @@ class PackageError(OscBaseError): class WorkingCopyInconsistent(PackageError): """Exception raised when the working copy is in an inconsistent state""" - def __init__(self, prj, pac, msg): + def __init__(self, prj, pac, dirty_files, msg): PackageError.__init__(self, prj, pac) + self.dirty_files = dirty_files self.msg = msg class LinkExpandError(PackageError):