1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
#!/usr/bin/env python3
# author: Ole Schuett
import os
import logging
from os import path
from time import time
import tempfile
import subprocess
from subprocess import PIPE, STDOUT
from flask import Flask, request, abort
app = Flask(__name__)
app.config["MAX_CONTENT_LENGTH"] = 1024 * 1024 # 1MB
app.logger.setLevel(logging.INFO)
app.logger.info("CP2K Precommit Server is up and running :-)")
# ======================================================================================
@app.route("/")
def hello():
return "cp2k precommit server revision: " + os.environ["REVISION"]
# ======================================================================================
@app.route("/black", methods=["POST"])
def black():
return run_tool(["black"])
# ======================================================================================
@app.route("/shfmt", methods=["POST"])
def shfmt():
return run_tool(["shfmt", "-i=2", "-ci", "-sr", "-w"])
# ======================================================================================
@app.route("/shellcheck", methods=["POST"])
def shellcheck():
return run_tool(["shellcheck"])
# ======================================================================================
@app.route("/mdformat", methods=["POST"])
@app.route("/markdownlint", methods=["POST"]) # for backwards compatibility
def mdformat():
return run_tool(["mdformat", "--wrap=100"])
# ======================================================================================
@app.route("/clangformat", methods=["POST"])
def clangformat():
return run_tool(["clang-format", "--style=llvm", "-i"])
# ======================================================================================
@app.route("/cmakeformat", methods=["POST"])
def cmakeformat():
return run_tool(["cmake-format", "-i"])
# ======================================================================================
def run_tool(cmd, timeout=30):
assert len(request.files) == 1
orig_fn = list(request.files.keys())[0]
data_before = request.files[orig_fn].read()
data_kb = len(data_before) / 1024.0
fn = path.basename(orig_fn)
workdir = tempfile.TemporaryDirectory()
abs_fn = path.join(workdir.name, fn)
open(abs_fn, "wb").write(data_before)
t1 = time()
try:
p = subprocess.run(
cmd + [fn], cwd=workdir.name, timeout=timeout, stdout=PIPE, stderr=STDOUT
)
except subprocess.TimeoutExpired:
app.logger.info(f"Timeout of {cmd[0]} on {data_kb:.1f}KB after {timeout}s.")
return f"Timeout while running {cmd[0]} - please try again.", 504
t2 = time()
app.logger.info(f"Ran {cmd[0]} on {data_kb:.1f}KB in {t2-t1:.1f}s.")
if p.returncode != 0:
return p.stdout, 422 # Unprocessable Entity
data_after = open(abs_fn, "rb").read()
if data_after == data_before:
return "Not Modified", 304
return data_after, 200
# ======================================================================================
if __name__ == "__main__":
app.run()
# EOF
|