import pathlib,subprocess,time,shutil,json,os,signal
from gate import REPO,R,TAG,HEAD,shell
os.umask(0o077)
assert json.loads((R/'gate.json').read_text())['status']=='PASS'
assert not (R/'build.json').exists()
assert shell(['git','-C',str(REPO),'rev-parse','HEAD']).strip()==HEAD
assert not shell(['git','-C',str(REPO),'status','--porcelain']).strip()
start=time.monotonic(); reason=None
with (R/'build.log').open('w') as log:
 p=subprocess.Popen(['docker','build','-f','docker/Dockerfile','--target','app','-t',TAG,'.'],cwd=REPO,
                    stdout=log,stderr=subprocess.STDOUT,start_new_session=True,env=dict(os.environ,DOCKER_BUILDKIT='1'))
 while p.poll() is None:
  if time.monotonic()-start>1200 or shutil.disk_usage('/').free<15*1024**3:
   reason='TIME_OR_DISK_CAP';os.killpg(p.pid,signal.SIGTERM)
   try:p.wait(15)
   except subprocess.TimeoutExpired:os.killpg(p.pid,signal.SIGKILL)
   break
  time.sleep(2)
 code=p.wait()
d={'returncode':code,'abort_reason':reason,'elapsed_seconds':round(time.monotonic()-start,2),'tag':TAG,'source':HEAD}
if code==0 and not reason:
 data=json.loads(shell(['docker','image','inspect',TAG]))[0]
 d.update(image_id=data['Id'],size=data['Size'])
(R/'build.json').write_text(json.dumps(d,indent=2));print(json.dumps(d))
raise SystemExit(code or bool(reason))
