def autoswitch(svn, wcpath, wcurl, newbaseurl=None): """Switches between mirror, default_parent, or newbaseurl""" nobase = False mirror = mirror_url() repository = layout.repository_url() current = repository if repository is None: raise Error("the option repository from repsys.conf is "\ "required") indefault = same_base(repository, wcurl) if not newbaseurl: if not mirror: raise Error("an URL is needed when the option mirror "\ "from repsys.conf is not set") if indefault: chosen = mirror elif same_base(mirror, wcurl): current = mirror chosen = repository else: nobase = True else: if mirror and same_base(mirror, wcurl): current = mirror elif indefault: pass # !!!! else: nobase = True chosen = newbaseurl if nobase: raise Error("the URL of this working copy is not based in "\ "repository nor mirror URLs") assert current != chosen newurl = mirror_relocate(current, chosen, wcurl, wcpath) return newurl
def get_submit_info(path): path = os.path.abspath(path) # First, look for SPECS and SOURCES directories. found = False while path != "/": if os.path.isdir(path): specsdir = os.path.join(path, "SPECS") sourcesdir = os.path.join(path, "SOURCES") if os.path.isdir(specsdir) and os.path.isdir(sourcesdir): found = True break path = os.path.dirname(path) if not found: raise Error("SPECS and/or SOURCES directories not found") # Then, check if this is really a subversion directory. if not os.path.isdir(os.path.join(path, ".svn")): raise Error("subversion directory not found") svn = detectVCS(path) # Now, extract the package name. info = svn.info2(path) url = info.get("URL") if url is None: raise Error("missing URL from svn info %s" % path) toks = url.split("/") if len(toks) < 2 or toks[-1] != "current": raise Error("unexpected URL received from 'svn info'") name = toks[-2] url = "/".join(toks[:-1]) # Finally, guess revision. max = -1 files = [] files.extend(glob.glob("%s/*" % specsdir)) files.extend(glob.glob("%s/*" % sourcesdir)) for file in files: try: info = svn.info2(file) except Error: # possibly not tracked continue if info is None: continue rawrev = info.get("Last Changed Rev") if rawrev: rev = int(rawrev) if rev > max: max = rev if max == -1: raise Error("revision tag not found in 'svn info' output") if mirror.using_on(url): url = mirror.switchto_parent_url(url) return name, url, max
def interpolate(optname, format, data): tmpl = string.Template(format) try: return tmpl.substitute(data) except KeyError as e: raise Error("the key %s was not found in LDAP search, " \ "check your %s configuration" % (e, optname)) except (TypeError, ValueError) as e: raise Error("LDAP response formatting error: %s. Check " \ "your %s configuration" % (e, optname))
def log(self, url, start=None, end=0, limit=None, **kwargs): cmd = ["log", "-v", url] if start is not None or end != 0: if start is not None and type(start) is not type(0): try: start = int(start) except (ValueError, TypeError): raise Error("invalid log start revision provided") if type(end) is not type(0): try: end = int(end) except (ValueError, TypeError): raise Error("invalid log end revision provided") start = start or "HEAD" cmd.extend(("-r", "%s:%s" % (start, end))) if limit is not None: try: limit = int(limit) except (ValueError, TypeError): raise Error("invalid limit number provided") cmd.extend(("--limit", str(limit))) status, output = self._execVcs(*cmd, xml=True, **kwargs) if status != 0: return None xmllog = ElementTree.fromstring(output) log = [] logentries = xmllog.getiterator("logentry") for entry in logentries: changed = [] lines = [] for pathelem in entry.getiterator("paths"): path = pathelem.find("path") from_rev = path.get("copyfrom-rev") if from_rev: from_rev = int(from_rev) changed.append({ "from_rev": from_rev, "from_path": path.get("copyfrom-path"), "action": path.get("action"), "path": path.text }) date = entry.findtext("date").split("T") timestr = "%s %s" % (date[0], date[1].split(".")[0]) timetuple = time.strptime(timestr, "%Y-%m-%d %H:%M:%S") lines.extend(entry.findtext("msg").rstrip().split("\n")) logentry = VCSLogEntry(int(entry.attrib["revision"]), entry.findtext("author"), timetuple, [line.rstrip() for line in lines], changed) log.append(logentry) log.sort() log.reverse() return log
def parse_options(): parser = OptionParser(help=HELP) opts, args = parser.parse_args() if len(args) < 1: raise Error("invalid arguments") opts.func = globals().get("fedpkg_" + args[0], None) if args[0] == "clone": opts.pkg = args[1] else: raise Error("invalid arguments: %s" % str(args)) return opts
def download_binaries(topdir): spath = sources_path(topdir) if not os.path.exists(spath): raise Error("'%s' was not found" % spath) entries = parse_sources(spath) for name, sha1 in entries.items(): download_binary(topdir, sha1, name)
def parse_options(): parser = OptionParser(help=HELP) opts, args = parser.parse_args() if len(args) != 1: raise Error("invalid arguments") opts.author = args[0] return opts
def download_sources(self): f = open(join(self._git.path, "sources")) downloader = config.get( "global", "download-command", "wget -c -O '$dest' $url").strip("'$dest' $url").split() for line in f.readlines(): fields = line.split() binurl = self.binrepo + "/" + self._package + "/" if len(fields) == 2: checksum, source = fields binurl += source + "/" else: pattern = re.compile(r'^(.*) \((.*)\) = (.*)') match = pattern.match(line) hashtype = match.group(1) source = match.group(2) checksum = match.group(3) binurl += source + "/" + hashtype.lower() + "/" binurl += checksum + "/" + source cmd = downloader + [join(self._git.path, source), binurl] f.close() status, output = execcmd(cmd, show=True) if status == 0: return True else: raise Error("Failed downloading %s, retcode: %d err: %s\n", status, output)
def get_revision_offset(): try: revoffset = config.getint("log", "revision-offset", 0) except (ValueError, TypeError): raise Error("Invalid revision-offset number in configuration " "file(s).") return revoffset or 0
def parse_options(): parser = OptionParser(help=HELP) parser.add_option("-r", dest="revision") parser.add_option("--distribution", "-d", dest="distro", default=None) parser.add_option("--branch", "-b", dest="branch", default=None) parser.add_option("--backports", "-k", dest="backports", default=None) parser.add_option("-s", "--spec", dest="spec", default=False, action="store_true") parser.add_option("-M", "--no-mirror", action="callback", callback=disable_mirror) opts, args = parser.parse_args() if len(args) not in (1, 2): raise Error("invalid arguments") # here we don't use package_url in order to notify the user we are # using the mirror opts.pkgdirurl = args[0] if len(args) == 2: opts.path = args[1] else: opts.path = None return opts
def split_url_revision(url): """Returns a tuple (url, rev) from an subversion URL with @REV If the revision is not present in the URL, rev is None. """ parsed = list(urllib.parse.urlparse(url)) path = os.path.normpath(parsed[2]) dirs = path.rsplit("/", 1) lastname = dirs[-1] newname = lastname index = lastname.rfind("@") rev = None if index != -1: newname = lastname[:index] rawrev = lastname[index + 1:] if rawrev: try: rev = int(rawrev) if rev < 0: raise ValueError except ValueError: raise Error("invalid revision specification on URL: %s" % url) dirs[-1] = newname newpath = "/".join(dirs) parsed[2] = newpath newurl = urllib.parse.urlunparse(parsed) return newurl, rev
def commit(target=".", message=None, logfile=None): svn = detectVCS(target) status = svn.status(target, quiet=True) if not status: print("nothing to commit") return info = svn.info2(target) url = info.get("URL") if url is None: raise Error("working copy URL not provided by svn info") mirrored = mirror.using_on(url) if mirrored: newurl = mirror.switchto_parent(svn, url, target) print("relocated to", newurl) # we can't use the svn object here because svn --non-interactive option # hides VISUAL opts = [] if message is not None: opts.append("-m \"%s\"" % message) if logfile is not None: opts.append("-F \"%s\"" % logfile) mopts = " ".join(opts) os.system("svn ci %s %s" % (mopts, target)) if mirrored: print("use \"repsys switch\" in order to switch back to mirror "\ "later")
def getpkgtopdir(basedir=os.path.curdir): vcs = detectVCS(basedir) if vcs: basedir = os.path.relpath(vcs.get_topdir()) if ispkgtopdir(basedir, vcs_dirname=vcs.vcs_dirname): return basedir raise Error("can't find top package directories SOURCES and SPECS")
def cp_srpms(revision, revname, geturl, targetdirs, srpmsdir, verbose): targetsrpms = [] urlrev = None if revname: urlrev = revision or layout.get_url_revision(geturl) if not targetdirs: targetdirs = (".", ) srpms = glob.glob(os.path.join(srpmsdir, "*.src.rpm")) if not srpms: # something fishy happened raise Error("no SRPMS were found at %s" % srpmsdir) for srpm in srpms: name = os.path.basename(srpm) if revname: name = "@%s:%s" % (urlrev, name) for targetdir in targetdirs: newpath = os.path.join(targetdir, name) targetsrpms.append(newpath) if os.path.exists(newpath): # should we warn? os.unlink(newpath) shutil.copy(srpm, newpath) if verbose: sys.stderr.write("Wrote: %s\n" % newpath) return targetsrpms
def _split_changelog(stream): current = None count = 0 def finish(entry): lines = entry[2] # strip newlines at the end for i in range(len(lines) - 1, -1, -1): if lines[i] != "\n": break del lines[i] return entry for line in stream: if line.startswith("*"): if current: yield finish(current) fields = line.split() rawdate = " ".join(fields[:5]) try: date = time.strptime(rawdate, "* %a %b %d %Y") except ValueError as e: raise Error("failed to parse spec changelog: %s" % e) curlines = [line] current = (date, count, curlines) # count used to ensure stable sorting when changelog entries # have the same date, otherwise it would also compare the # changelog lines count -= 1 elif current: curlines.append(line) else: pass # not good, but ignore if current: yield finish(current)
def parse_options(): parser = OptionParser(help=HELP) opts, args = parser.parse_args() if len(args): opts.paths = args else: raise Error("you need to provide a path") return opts
def parse_options(): parser = OptionParser(help=HELP) parser.add_option("-m", dest="log", default=None) opts, args = parser.parse_args() if len(args) != 1: raise Error("invalid arguments") opts.pkgdirurl = args[0] return opts
def parse_options(): parser = OptionParser(help=HELP) opts, args = parser.parse_args() if len(args): opts.maintdb_args = args else: raise Error("you need to provide arguments, see them with --help") return opts
def parse_options(): parser = OptionParser(help=HELP) opts, args = parser.parse_args() if len(args) != 1: raise Error("invalid arguments") opts.pkgdirurl = package_url(args[0], mirrored=False) opts.verbose = 1 # Unconfigurable return opts
def upload_binary(topdir, filename): filepath = os.path.join(topdir, 'SOURCES', filename) if not os.path.exists(filepath): raise Error("'%s' was not found" % filepath) sha1sum = file_hash(filepath) if binary_exists(sha1sum): return host = config.get("binrepo", "upload_host") upload_bin_helper = get_helper("upload-bin") command = ["ssh", host, upload_bin_helper, filename] try: filein = open(filepath, 'r') except Error as e: raise Error("Could not open file %s\n" % filepath) status, output = execcmd(*command, show=True, collecterr=True, stdin=filein)
def switch(mirrorurl=None): svn = SVN() topdir = getpkgtopdir() info = svn.info2(topdir) wcurl = info.get("URL") if wcurl is None: raise Error("working copy URL not provided by svn info") newurl = mirror.autoswitch(svn, topdir, wcurl, mirrorurl) print("switched to", newurl)
def list_targets(option, opt, val, parser): host = config.get("submit", "host") if host is None: raise Error("no submit host defined in repsys.conf") createsrpm = get_helper("create-srpm") #TODO make it configurable args = ["ssh", host, createsrpm, "--list"] execcmd(args, show=true) sys.exit(0) # it is invoked via optparse callback, thus we need to
def parse_options(): parser = OptionParser(help=HELP) parser.add_option("-l", dest="log", default="") opts, args = parser.parse_args() if len(args) != 2: raise Error("invalid arguments") opts.pkgdirurl = package_url(args[0], mirrored=False) opts.patchfile = args[1] return opts
def clone(self, url=None, targetpath=None, **kwargs): if not url: url = self.url if not targetpath: targetpath = self.path.rstrip(self.vcs_dirname) vcs = getattr(self, "vcs") for vcs in getattr(self, "vcs"): if os.path.lexists(os.path.join(targetpath, vcs[1])): raise Error("target path %s already contains %s repository, aborting..." \ % (targetpath, vcs[0])) if self.vcs_supports['clone']: cmd = ["clone", url, targetpath] if self.url.split(':')[0].find("svn") < 0: return self._execVcs_success(*cmd, **kwargs) else: return False else: raise Error("%s doesn't support 'clone'" % self.vcs_name)
def default_parent(url): if url.find("://") == -1: default_parent = config.get("global", "default_parent") if not default_parent: raise Error("received a relative url, " \ "but default_parent was not setup") parsed = list(urllib.parse.urlparse(default_parent)) parsed[2] = os.path.normpath(parsed[2] + "/" + url) url = urllib.parse.urlunparse(parsed) return url
def parse_options(): parser = OptionParser(help=HELP) parser.add_option("-t", dest="targetdir", default=".") parser.add_option("-M", "--no-mirror", action="callback", callback=disable_mirror) opts, args = parser.parse_args() if len(args) != 1: raise Error("invalid arguments") opts.pkgdirurl = package_url(args[0]) return opts
def patch_spec(pkgdirurl, patchfile, log=""): #FIXME use get_spec svn = detectVCS(pkgdirurl) tmpdir = tempfile.mktemp() try: geturl = layout.checkout_url(pkgdirurl, append_path="SPECS") svn.checkout(geturl, tmpdir) speclist = glob.glob(os.path.join(tmpdir, "*.spec")) if not speclist: raise Error("no spec files found") spec = speclist[0] status, output = execcmd(["patch", spec, patchfile]) if status != 0: raise Error("can't apply patch:\n%s\n" % output) else: svn.commit(tmpdir, log="") finally: if os.path.isdir(tmpdir): shutil.rmtree(tmpdir)
def parse_macrosref(refs, config): macros = [] for name in refs: secname = "macros %s" % name try: macros.extend(config.walk(secname, raw=True)) except NoSectionError: raise Error("missing macros section " \ "%r in configuration" % secname) return macros
def mode_callback(option, opt, val, parser, mode): opts = parser.values opts.mode = mode if mode == "version": try: opts.version, opts.release = val.split("-", 1) except ValueError: raise Error("wrong version, use something like 2.2-1mdk") elif mode == "revision": opts.revision = val
def _add_revision(self, cmd_args, received_kwargs, optional=0): if not optional or "rev" in received_kwargs: ret = received_kwargs.get("rev") if isinstance(ret, str): if not ret.startswith("{"): # if not a datespec try: ret = int(ret) except ValueError: raise Error("invalid revision provided") if ret: cmd_args.extend(("-r", str(ret)))