build.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #!/usr/bin/python
  2. from browser.linkjs import link
  3. import argparse
  4. import os
  5. import shutil
  6. import stat
  7. import subprocess
  8. import sys
  9. import zipfile
  10. class package( object ):
  11. root = 'bin/js'
  12. archive = 'bin/compiled.zip'
  13. @staticmethod
  14. def pack():
  15. file = zipfile.ZipFile(package.archive, 'w')
  16. for f in os.listdir(package.root):
  17. file.write(os.path.join('bin/js', f), f)
  18. @staticmethod
  19. def unpack():
  20. cleanup(package.root)
  21. file = zipfile.ZipFile(package.archive, 'r')
  22. file.extractall(package.root)
  23. # http://stackoverflow.com/questions/1889597/deleting-directory-in-python
  24. def remove_readonly(fn, path, excinfo):
  25. if fn is os.rmdir:
  26. os.chmod(path, stat.S_IWRITE)
  27. os.rmdir(path)
  28. elif fn is os.remove:
  29. os.chmod(path, stat.S_IWRITE)
  30. os.remove(path)
  31. def norm_path(path):
  32. return os.path.normcase(os.path.normpath(os.path.realpath(os.path.abspath(path))))
  33. def is_parent_for(parent, child):
  34. parent = norm_path(parent)
  35. child = norm_path(child)
  36. while True:
  37. if parent == child:
  38. return True
  39. next = os.path.dirname(child)
  40. if next == child:
  41. return False
  42. child = next
  43. def cleanup(dir):
  44. if not os.path.exists(dir):
  45. return
  46. this_dir = os.path.dirname(__file__)
  47. if is_parent_for(dir, this_dir):
  48. raise Exception("cannot delete itself: %s" % this_dir)
  49. shutil.rmtree(dir, onerror=remove_readonly)
  50. def copy(src, dst_dir):
  51. dst = os.path.join(dst_dir, os.path.basename(src))
  52. if os.path.exists(dst):
  53. os.chmod(dst, stat.S_IWRITE)
  54. print('%s -> %s' % (src, dst))
  55. shutil.copy(src, dst)
  56. def copytree(src, dst):
  57. cleanup(dst)
  58. print('%s -> %s' % (src, dst))
  59. shutil.copytree(src, dst)
  60. def run(cmd):
  61. p = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.STDOUT, shell = True)
  62. return p.stdout.read().decode()
  63. def build(options):
  64. version = None
  65. if not options.no_git:
  66. print(run('git pull'))
  67. version = run('git log -1 --format="%ci%n%H"')
  68. out = options.output
  69. build_version = None
  70. build_version_path = os.path.join(out, 'version.txt')
  71. try:
  72. with open(build_version_path) as f:
  73. build_version = f.read()
  74. except:
  75. pass
  76. if (not build_version is None) and build_version == version:
  77. print("current html is up to date, do nothing")
  78. return
  79. if options.pack:
  80. print 'packaing compiled js to %s...' % package.root
  81. package.pack()
  82. else:
  83. print 'unpackaing compiled js to %s...' % package.root
  84. package.unpack()
  85. if not os.path.exists(out):
  86. os.mkdir(out)
  87. link(['oc.js', 'oberon/oberon_grammar.js', 'eberon/eberon_grammar.js'],
  88. os.path.join(out, 'oc.js'),
  89. ['src', 'bin'],
  90. version)
  91. copy('browser/oberonjs.html', out)
  92. for d in ['codemirror', 'jslibs']:
  93. copytree(os.path.join('browser', d), os.path.join(out, d))
  94. if version is None:
  95. if os.path.exists(build_version_path):
  96. os.remove(build_version_path)
  97. else:
  98. with open(build_version_path, 'w') as f:
  99. f.write(version)
  100. if __name__ == '__main__':
  101. parser = argparse.ArgumentParser(description='Pull repo and build html page')
  102. parser.add_argument('output', help='output directory')
  103. parser.add_argument('--no-git', help='do not pull from git', action="store_true")
  104. parser.add_argument('--pack', help='pack compiled source', action="store_true")
  105. args = parser.parse_args()
  106. build(args)