def get_builds(proj): if not os.path.isfile(getProjPath(proj) + "/.ci.json"): return "Not found", 404 if os.path.exists(getBuildPath(proj)): dirs = [ entry for entry in os.listdir(getBuildPath(proj)) if entry != "latest" and os.path.isdir(getBuildPath(proj, entry)) ] data = [] for ref in dirs: toAdd = { "commit": git.getCommitDetails(proj, ref), "build": compile.getStatus(proj, ref) } if ((proj, ref) in compile.q): toAdd["build"]["status"] = "queued" data.append(toAdd) return json.dumps({ "list": data, "language": getConfig(proj).get("language", None), "id": git.repos[proj]["github"], "latest": parseRef(proj, "latest") }), { "Content-Type": "application/json" } else: return json.dumps({ "list": [], "language": None, "latest": "" }), { "Content-Type": "application/json" }
def get_latest_svg(proj): return mySendFile(getBuildPath(proj, parseRef(proj, "latest")) + "/.status.svg", mimetype="image/svg+xml")
def get_build_zip(proj, ref): return mySendFile(getBuildPath(proj, parseRef(proj, ref)) + "/output.zip", mimetype="application/zip")
def get_build_pdf(proj, ref): return mySendFile(getBuildPath(proj, parseRef(proj, ref)) + "/main.pdf", mimetype="application/pdf", content_disposition='inline; filename=' + proj + '.pdf')
def get_build_svg(proj, ref): return mySendFile(getBuildPath(proj, parseRef(proj, ref)) + "/.status.svg", mimetype="image/svg+xml")
def get_build_log(proj, ref): return mySendFile(getBuildPath(proj, parseRef(proj, ref)) + "/.log", mimetype="text/plain")
def getStatus(proj: str, ref: str, raw: bool = False) -> Union[dict, str]: if raw: return getBuildPath(proj, ref) + "/.status.json" return loadJSON(getBuildPath(proj, ref) + "/.status.json")
def updateStatus(proj: str, ref: str, channel: Channel, msg: str, start_duration: Tuple[float, float], errorMsg: str = None, stats: dict = {}) -> None: (start, duration) = start_duration if msg == "success": color = "#4c1" elif msg == "pending": color = "#efc60f" else: color = "red" svg = """ <svg xmlns="http://www.w3.org/2000/svg" width="90" height="20"> <linearGradient id="a" x2="0" y2="100%"> <stop offset="0" stop-color="#bbb" stop-opacity=".1" /> <stop offset="1" stop-opacity=".1" /> </linearGradient> <rect rx="3" width="90" height="20" fill="#555" /> <rect rx="3" x="37" width="53" height="20" fill="{}" /> <path fill="{}" d="M37 0h4v20h-4z" /> <rect rx="3" width="90" height="20" fill="url(#a)" /> <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"> <text x="19.5" y="15" fill="#010101" fill-opacity=".3">built</text> <text x="19.5" y="14">built</text> <text x="62.5" y="15" fill="#010101" fill-opacity=".3">{}</text> <text x="62.5" y="14">{}</text> </g> </svg>""".format(color, color, ref[:7], ref[:7]) with open(getBuildPath(proj, ref) + "/.status.svg", "w") as f: f.write(svg) data = { "ref": ref, "status": msg, "errorMsg": errorMsg, "start": round(start * 1000), "artifacts": {}, "duration": duration, "stats": stats } if msg == "success": config = getConfig(proj, ref) lang = config.get("language", None) if lang == "latex": main = config.get("main", None) if os.path.isfile(getBuildPath(proj, ref) + "/" + main + ".pdf"): data["artifacts"]["pdf"] = "PDF" elif lang == "npm": if os.path.isfile(getBuildPath(proj, ref) + "/output.zip"): data["artifacts"]["output.zip"] = "ZIP" channel.publish(proj, {"event": "status", "data": data}) with open(getBuildPath(proj, ref) + "/.status.json", "w") as f: f.write(json.dumps(data)) if TOKEN: git.setStatus(proj, ref, msg, DOMAIN + "/" + proj + "/" + ref, errorMsg)
def compile(proj: str, ref: str, channel: Channel) -> None: if not os.path.exists(getBuildPath(proj, ref)): os.makedirs(getBuildPath(proj, ref)) with open(getBuildPath(proj, ref) + "/.log", 'w', 1) as logFile: def log(s): logFile.write(s) channel.publish(proj, {"event": "log", "ref": ref[:7], "data": s}) try: timeStart = time.time() updateStatus(proj, ref, channel, "pending", (timeStart, None)) print(">> Started: " + time.strftime("%c")) log(">> Started: " + time.strftime("%c") + "\n") successful = True successfulGit = updateGit(proj, ref, log) successful = successfulGit shutil.copy2( getProjPath(proj) + "/.ci.json", getBuildPath(proj, ref) + "/.ci.json") cfg = getConfig(proj, ref) if successful: successfulCfg = True lang = cfg.get("language", None) if not lang: successfulCfg = False successful = successfulCfg if successful: if not os.path.exists(getBuildPath(proj)): log("creating " + getBuildPath(proj)) os.makedirs(getBuildPath(proj)) successfulCompile = compileLang[lang](proj, getBuildPath( proj, ref), cfg, log) successful = successfulCompile else: log("not compiling" + "\n") stats = {} #type: Dict[str, Union[str, Any]] if successful: if "stats" in cfg: if cfg["language"] == "latex" and "counts" in cfg["stats"]: (success, counts) = latex.count(getProjPath(proj), getBuildPath(proj, ref), cfg["main"] + ".tex") if success: stats["counts"] = counts else: stats["counts"] = False print(">> Finished " + ref) log((">>" if successful else ">!") + " Finished: " + time.strftime("%X") + " " + ref + "\n") except Exception as e: successful = False log(">! " + str(e)) print(">> Error: " + ref) traceback.print_exc() updateStatus( proj, ref, channel, "success" if successful else "error", (timeStart, time.time() - timeStart), "Git stage failed" if not successfulGit else "Config error" if not successfulCfg else "Compile stage failed" if not successfulCompile else None, stats) symlink_force(ref, getBuildPath(proj, "latest"))