caide.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #!/usr/bin/python3
  2. import argparse
  3. import sys
  4. from os import makedirs
  5. from os.path import abspath, expanduser, join
  6. from pathlib import Path
  7. from shutil import copy2, rmtree
  8. from subprocess import PIPE, Popen
  9. from tempfile import TemporaryDirectory
  10. def check_exists(docker_image):
  11. proc = Popen(['docker', 'images'], stdout=PIPE)
  12. proc.wait()
  13. if proc.returncode != 0:
  14. exit(proc.returncode)
  15. if docker_image not in proc.stdout.read().decode():
  16. print(f"Image {docker_image} not found.")
  17. exit(1)
  18. def main():
  19. check_exists('caide-docker')
  20. parser = argparse.ArgumentParser(
  21. "Caide-Docker", description="Inline c++ code from libraries in a single file.")
  22. parser.add_argument(
  23. 'main_file', help="Path to the .cpp that contains the main function.")
  24. parser.add_argument('-l', '--libraries', default='',
  25. help="List of libraries to be used other than the std. Use comma (,) to separate several libraries.")
  26. parser.add_argument('-o', '--output', default='',
  27. help="Name of file to store final submission. stdout is used by default.")
  28. args = parser.parse_args()
  29. main_file = abspath(args.main_file)
  30. libraries = [abspath(lib) for lib in args.libraries.split(',') if lib]
  31. target_folder = Path(abspath(expanduser('~/.caide-docker/tmp')))
  32. rmtree(target_folder, ignore_errors=True)
  33. makedirs(target_folder, exist_ok=True)
  34. copy2(main_file, join(target_folder, 'main.cpp'))
  35. command = ["docker",
  36. "run",
  37. f"--volume={target_folder}:/home/io"] +\
  38. [f"--volume={lib}:/home/cpplib" for lib in libraries] +\
  39. ["caide-docker"]
  40. proc = Popen(command)
  41. proc.wait()
  42. err = target_folder / 'output.err'
  43. out = target_folder / 'submission.cpp'
  44. if err.exists():
  45. with open(err) as f:
  46. print(f.read(), file=sys.stderr)
  47. if out.exists():
  48. file = sys.stdout
  49. should_close = False
  50. if args.output:
  51. file = open(args.output, 'w')
  52. should_close = True
  53. with open(out) as f:
  54. print(f.read(), file=file)
  55. if should_close:
  56. file.close()
  57. if __name__ == '__main__':
  58. main()