|
| 1 | +import os |
| 2 | +from os import path |
| 3 | +import json |
| 4 | +import glob |
| 5 | +import shutil |
| 6 | +import subprocess |
| 7 | +import platform |
| 8 | +from util import get_newest_tag |
| 9 | +from util import copy_contents |
| 10 | + |
| 11 | +# default values in case the build config file is missing |
| 12 | +git_urls = { |
| 13 | + 'common': "https://github.com/datajoint/datajoint-docs.git", |
| 14 | + 'matlab': "https://github.com/datajoint/datajoint-matlab.git", |
| 15 | + 'python': "https://github.com/datajoint/datajoint-python.git" |
| 16 | +} |
| 17 | + |
| 18 | +def create_build_folders(lang): |
| 19 | + """ |
| 20 | + Prepares the necessary parts for full-versioned documentation site building by |
| 21 | + cloning and checking out appropriate tags from the `lang` respective repositories. |
| 22 | + Prepared parts will be inside `build-all` directory |
| 23 | + """ |
| 24 | + raw_tags = subprocess.Popen(["git", "tag"], cwd= path.join("build-all", "datajoint-" + lang), stdout=subprocess.PIPE).communicate()[0].decode("utf-8").split() |
| 25 | + |
| 26 | + with open("build_versions.json") as f: |
| 27 | + print(f) |
| 28 | + min_tags = json.load(f) |
| 29 | + |
| 30 | + tags = [get_newest_tag(t, raw_tags) for t in min_tags[lang]] |
| 31 | + |
| 32 | + for tag in tags: |
| 33 | + subprocess.Popen(["git", "checkout", tag], |
| 34 | + cwd=path.join("build-all", "datajoint-" + lang), stdout=subprocess.PIPE).wait() |
| 35 | + dsrc_lang = path.join("build-all", "datajoint-" + lang, "docs-parts") |
| 36 | + dst_build_folder = path.join("build-all", lang + "-" + tag) |
| 37 | + dst_main = path.join(dst_build_folder, "contents") |
| 38 | + dst_temp = path.join(dst_main, "comm") |
| 39 | + |
| 40 | + if path.exists(dst_build_folder): |
| 41 | + shutil.rmtree(dst_build_folder) |
| 42 | + |
| 43 | + # copy over the lang source doc contents into the build folder |
| 44 | + shutil.copytree(dsrc_lang, dst_main) |
| 45 | + |
| 46 | + # grab which version of the common folder the lang doc needs to be merged with |
| 47 | + with open(path.join(dsrc_lang, "version_common.json")) as f: |
| 48 | + # expected in this format { "comm_version" : "v0.0"} |
| 49 | + version_info = json.load(f) |
| 50 | + |
| 51 | + raw_tags_comm = subprocess.Popen(["git", "tag"], cwd=path.join("build-all", "datajoint-docs"), stdout=subprocess.PIPE).communicate()[0].decode("utf-8").split() |
| 52 | + comm_to_build = get_newest_tag(version_info['comm_version'], raw_tags_comm) |
| 53 | + |
| 54 | + subprocess.Popen(["git", "checkout", comm_to_build],cwd=path.join("build-all", "datajoint-docs"), stdout=subprocess.PIPE).wait() |
| 55 | + dsrc_comm = path.join("build-all", "datajoint-docs", "contents") |
| 56 | + # copy over the cmmon source doc contents into the build folder |
| 57 | + shutil.copytree(dsrc_comm, dst_temp) |
| 58 | + |
| 59 | + # unpacking the content of common into lang-specific build folder |
| 60 | + copy_contents(dst_temp, dst_main) |
| 61 | + |
| 62 | + # removing the temporary comm folder because that shouldn't get build |
| 63 | + shutil.rmtree(dst_temp) |
| 64 | + |
| 65 | + # copy the datajoint_theme folder, conf.py and makefile for individual lang-ver folder building |
| 66 | + shutil.copytree("datajoint_theme", path.join(dst_build_folder, "datajoint_theme")) |
| 67 | + shutil.copy2("Makefile", path.join(dst_build_folder, "Makefile")) |
| 68 | + shutil.copy2(path.join("contents", "conf.py"), path.join(dst_build_folder, "contents", "conf.py")) |
| 69 | + shutil.copy2("report.txt", path.join(dst_build_folder, "report.txt")) |
| 70 | + |
| 71 | + # add current_version <p> tag into the datajoint_theme folder |
| 72 | + with open(path.join(dst_build_folder, 'datajoint_theme', 'this_version.html'), 'w+') as f: |
| 73 | + f.write('<p class="thisVersion">' + lang + "-" + ".".join(tag.split(".")[:-1]) + '</p>') |
| 74 | + |
| 75 | + # add current_version as release into the conf.py file (for pdf generation) |
| 76 | + with open(path.join(dst_build_folder, "contents", "conf.py"), 'a+') as f: |
| 77 | + f.write('release = "' + lang + "-" + ".".join(tag.split(".")[:-1]) + '"') |
| 78 | + |
| 79 | + |
| 80 | +# generate site folder with all contents using the above build folders |
| 81 | +def make_full_site(): |
| 82 | + """ |
| 83 | + Builds the full-versioned site using the `build-all` directory and puts the resulting html/pdf into `full_site` directory. |
| 84 | + """ |
| 85 | + |
| 86 | + if path.exists('full_site'): |
| 87 | + shutil.rmtree('full_site') |
| 88 | + os.makedirs('full_site') |
| 89 | + |
| 90 | + # build individual lang-ver folder |
| 91 | + to_make = [folder for folder in glob.glob(path.join('build-all', '**')) if not path.basename(folder).startswith('datajoint')] |
| 92 | + |
| 93 | + with open("build_versions.json") as f: |
| 94 | + min_tags = json.load(f) |
| 95 | + # min_tags look like this {'python': ['v0.9'], 'matlab': ['v3.2']} |
| 96 | + |
| 97 | + # create full version-menu listing using the built folders from above |
| 98 | + with open(path.join('datajoint_theme', 'version-menu.html'), 'w+') as f: |
| 99 | + for lang in min_tags: |
| 100 | + for ver in min_tags[lang]: |
| 101 | + # f.write('<li class="version-menu"><a href="/' + lang + "/" + ver + '">' + lang + "-" + ver + '</a></li>\n') |
| 102 | + f.write('<li class="version-menu"><a href="/{lang}/{ver}">{lang}-{ver}</a></li>\n'.format(lang=lang, ver=ver)) |
| 103 | + |
| 104 | + # copy over the full version-menu listing to datajoint_theme FIRST, |
| 105 | + # then build individual folders, and copy to full_site folder |
| 106 | + |
| 107 | + for folder in to_make: |
| 108 | + shutil.copy2(path.join('datajoint_theme', 'version-menu.html'), path.join(folder, "datajoint_theme", "version-menu.html")) |
| 109 | + if platform.system() == "Windows": |
| 110 | + subprocess.Popen(["sphinx-build", ".", "..\_build\html"], cwd=path.join(folder, "contents")).wait() # builds html by default |
| 111 | + subprocess.Popen(["sphinx-build", "-b", "latex", ".", "..\_build\latex"], cwd=path.join(folder, "contents")).wait() |
| 112 | + if path.exists(path.join(folder, "site")): |
| 113 | + shutil.rmtree(path.join(folder, "site")) |
| 114 | + os.makedirs(path.join(folder, "site")) |
| 115 | + copy_contents(path.join(folder, "_build", "html"), path.join(folder, "site")) |
| 116 | + else: |
| 117 | + subprocess.Popen(["make", "site"], cwd=folder).wait() |
| 118 | + |
| 119 | + # making pdf out of the latex directory only if pdflatex runs |
| 120 | + try: |
| 121 | + subprocess.Popen(["pdflatex", "DataJointDocs.tex"], cwd=path.join(folder, '_build', 'latex')).wait() |
| 122 | + subprocess.Popen(["pdflatex", "DataJointDocs.tex"], cwd=path.join(folder, '_build', 'latex')).wait() |
| 123 | + except: |
| 124 | + print("Latex environment not set up - no pdf will be generated") |
| 125 | + |
| 126 | + lang_version = folder.split(os.sep)[1] # 'matlab-v3.2.2' |
| 127 | + lang, version = lang_version.split("-") # e.g. 'matlab', 'v3.2.2' |
| 128 | + abbr_ver = '.'.join(version.split('.')[:-1]) # e.g. 'v3.2' |
| 129 | + abbr_lang_ver = lang + '-' + abbr_ver |
| 130 | + |
| 131 | + shutil.copytree(path.join(folder, "site"), path.join('full_site', lang_version.split("-")[0], abbr_ver)) |
| 132 | + |
| 133 | + if path.exists(path.join(folder, '_build', 'latex', 'DataJointDocs.pdf')): |
| 134 | + os.rename(path.join(folder, '_build', 'latex', 'DataJointDocs.pdf'), path.join(folder, '_build', 'latex', 'DataJointDocs_{}.pdf'.format(abbr_lang_ver))) |
| 135 | + shutil.copy2(path.join(folder, '_build', 'latex', 'DataJointDocs_{}.pdf'.format(abbr_lang_ver)), path.join('full_site', lang_version.split("-")[0], abbr_ver)) |
| 136 | + |
| 137 | + for lang in min_tags: |
| 138 | + ver_list=[] |
| 139 | + for to_sort in glob.glob(path.join('full_site', lang, '**')): |
| 140 | + ver_list.append(float((path.basename(to_sort).strip("v")))) |
| 141 | + # ensure clean format in case float above produces something like 3.70000000000001 |
| 142 | + newest_ver = 'v{:.1f}'.format(max(ver_list)) |
| 143 | + src_path = path.join('full_site', lang, newest_ver) |
| 144 | + copy_contents(src_path, path.join('full_site', lang)) |
| 145 | + |
| 146 | + copy_contents('dj_root_theme', 'full_site') |
| 147 | + copy_contents(path.join('full_site', 'python', '_static'), path.join('full_site', '_static')) |
| 148 | + |
| 149 | + |
| 150 | +########################################################## |
| 151 | +####====== begin building full version doc here ======#### |
| 152 | +if __name__ == "__main__": |
| 153 | + # if build_config file exists, override the default git_url values with config values |
| 154 | + try: |
| 155 | + import build_config as config |
| 156 | + git_urls = dict(git_urls, **config.config_urls) |
| 157 | + except: |
| 158 | + print("build_config.py file missing - will use default values for git repo") |
| 159 | + |
| 160 | + # ensure build folder is clean before the build |
| 161 | + if path.exists('build-all'): |
| 162 | + shutil.rmtree('build-all') |
| 163 | + os.makedirs('build-all') |
| 164 | + |
| 165 | + subprocess.Popen( |
| 166 | + ["git", "clone", git_urls['common'], "datajoint-docs"], cwd="build-all").wait() |
| 167 | + |
| 168 | + subprocess.Popen( |
| 169 | + ["git", "clone", git_urls['matlab'], "datajoint-matlab"], cwd="build-all").wait() |
| 170 | + |
| 171 | + subprocess.Popen( |
| 172 | + ["git", "clone", git_urls['python'], "datajoint-python"], cwd="build-all").wait() |
| 173 | + |
| 174 | + create_build_folders("matlab") |
| 175 | + create_build_folders("python") |
| 176 | + make_full_site() |
0 commit comments