Example #1
0
def updateGit(proj: str, ref: str, log: Callable[[str], None]):
    successful = True
    try:
        log(">>> git fetch --all\n")
        rv = runSubprocess(["git", "fetch", "--all"],
                           log,
                           cwd=getProjPath(proj))
        if rv != 0:
            raise Exception(rv)

        log(">>> git reset --hard " + ref + "\n")
        rv = runSubprocess(["git", "reset", "--hard", ref],
                           log,
                           cwd=getProjPath(proj))
        if rv != 0:
            raise Exception(rv)

        log(">>> git diff --stat " + ref + "~1 " + ref + "\n")
        rv = runSubprocess(["git", "diff", "--stat=100", ref + "~1", ref],
                           log,
                           cwd=getProjPath(proj))
        if rv != 0:
            raise Exception(rv)

    except Exception as e:
        successful = False
        log("git operations failed: " + str(e) + "\n")

    return successful
Example #2
0
def doCompile(proj: str, buildPath: str, cfg: dict,
              log: Callable[[str], None]) -> bool:
    successful = True
    copyFolderStructure(getProjPath(proj), buildPath)

    main = cfg.get("main", None)
    if main:
        cmd = [
            "latexmk",
            "-interaction=nonstopmode",
            # "-gg",
            "-file-line-error",
            "-outdir=" + buildPath,
            "-pdf",
            main + ".tex"
        ]

        env = {
            "max_print_line": "100",
            "error_line": "254",
            "half_error_line": "238"
        }

        log(">>> " + (" ".join(cmd)) + "\n")
        rv = runSubprocess(cmd, log, cwd=getProjPath(proj), env=env)
        if rv != 0:
            log("latexmk failed: " + str(rv) + "\n")
            successful = False

    else:
        log("Missing 'main' in config")
        successful = False

    return successful
Example #3
0
def npm(proj: str, buildPath: str, cfg: dict, log: Callable[[str],
                                                            None]) -> bool:
    successful = True

    root = cfg.get("root", "")
    output = cfg.get("output", "")
    env = cfg.get("env", {})
    cwd = getProjPath(proj) + "/" + root

    if output:
        try:
            log(">>> yarn install\n")
            rv = runSubprocess(["yarn", "install"], log, cwd=cwd, env=env)
            if rv != 0:
                raise Exception(rv)

            log(">>> yarn build\n")
            rv = runSubprocess(["yarn", "build"], log, cwd=cwd, env=env)
            if rv != 0:
                raise Exception(rv)

            log(">>> creating output archive...\n")
            shutil.make_archive(buildPath + "/output",
                                "zip",
                                root_dir=cwd,
                                base_dir="./" + output)

        except Exception as e:
            successful = False
            log("yarn failed: " + str(e) + "\n")
    else:
        successful = False
        log("Missing 'output' in config")

    return successful
Example #4
0
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"
        }
Example #5
0
from threading import Timer

import flask_sse
import compile, git
from utils import getBuildPath, getProjPath, parseRef, getConfig

SECRET = os.environ.get('SECRET', "").encode("utf-8")
PASSWORD = os.environ.get('PASSWORD', "")
JWT_SECRET = os.environ.get('JWT_SECRET', "secret")
PROJECTS = json.loads("[]" if os.environ.get('PROJECTS', None) is None else (
    "[" +
    ",".join(['"' + x + '"'
              for x in os.environ.get('PROJECTS').split(",")]) + "]"))

for p in PROJECTS:
    git.getRepo(p, getProjPath(p))


class StringConverter(BaseConverter):
    def __init__(self, url_map, exc="."):
        super(StringConverter, self).__init__(url_map)
        self.exc = list(exc)

    def to_python(self, value):
        if any(x not in value for x in self.exc):
            return value
        raise ValidationError()

    def to_url(self, value):
        return value and 'yes' or 'no'
Example #6
0
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"))