123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- # -*- coding: utf-8 -*-
- import os
- import json
- import pathlib
- import subprocess
- import sys
- import tempfile
- from sphinx.cmd import build as sphinx_build
- from sphinx import project as sphinx_project
- from . import sphinx
- from . import git
- def main(argv=None):
- if not argv:
- argv = sys.argv[1:]
- parser = sphinx_build.get_parser()
- args = parser.parse_args(argv)
- # Find the indices
- srcdir_index = None
- outdir_index = None
- for i, value in enumerate(argv):
- if value == args.sourcedir:
- argv[i] = '{{{SOURCEDIR}}}'
- test_args = parser.parse_args(argv)
- if test_args.sourcedir == argv[i]:
- srcdir_index = i
- argv[i] = args.sourcedir
- if value == args.outputdir:
- argv[i] = '{{{OUTPUTDIR}}}'
- test_args = parser.parse_args(argv)
- if test_args.outputdir == argv[i]:
- outdir_index = i
- argv[i] = args.outputdir
- if srcdir_index is None:
- raise ValueError("Failed to find srcdir index")
- if outdir_index is None:
- raise ValueError("Failed to find outdir index")
- # Parse config
- confpath = os.path.join(args.confdir, 'conf.py')
- with open(confpath, mode='r') as f:
- config = sphinx.parse_conf(f.read())
- for d in args.define:
- key, _, value = d.partition('=')
- config[key] = value
- tag_whitelist = config.get('smv_tag_whitelist', sphinx.DEFAULT_TAG_WHITELIST)
- branch_whitelist = config.get('smv_branch_whitelist', sphinx.DEFAULT_BRANCH_WHITELIST)
- remote_whitelist = config.get('smv_remote_whitelist', sphinx.DEFAULT_REMOTE_WHITELIST)
- outputdir_format = config.get('smv_outputdir_format', sphinx.DEFAULT_OUTPUTDIR_FORMAT)
- gitroot = pathlib.Path('.').resolve()
- versions = git.find_versions(str(gitroot), 'source/conf.py', tag_whitelist, branch_whitelist, remote_whitelist)
- remotes = dict(git.get_remotes(str(gitroot)))
- with tempfile.TemporaryDirectory() as tmp:
- # Generate Metadata
- metadata = {}
- outputdirs = set()
- sourcedir = os.path.relpath(args.sourcedir, str(gitroot))
- for versionref in versions:
- # Ensure that there are not duplicate output dirs
- outputdir = sphinx.format_outputdir(
- outputdir_format, versionref, language=config["language"])
- if outputdir in outputdirs:
- print("outputdir '%s' of version %r conflicts with other versions!"
- % (outputdir, versionref))
- continue
- outputdirs.add(outputdir)
- # Clone Git repo
- repopath = os.path.join(tmp, str(hash(versionref)))
- srcdir = os.path.join(repopath, sourcedir)
- if versionref.source.startswith('remotes/'):
- repo_url = remotes[versionref.source.partition("/")[2]]
- else:
- repo_url = gitroot.as_uri()
- try:
- git.shallow_clone(repo_url, repopath, versionref.name)
- except subprocess.CalledProcessError:
- outputdirs.remove(outputdir)
- continue
- # Get List of files
- source_suffixes = config.get("source_suffix", "")
- if isinstance(source_suffixes, str):
- source_suffixes = [source_suffixes]
- project = sphinx_project.Project(srcdir, source_suffixes)
- metadata[versionref.name] = {
- "name": versionref.name,
- "source": versionref.source,
- "sourcedir": srcdir,
- "outputdir": outputdir,
- "docnames": list(project.discover())
- }
- metadata_path = os.path.abspath(os.path.join(tmp, "versions.json"))
- with open(metadata_path, mode='w') as fp:
- json.dump(metadata, fp, indent=2)
- # Run Sphinx
- argv.extend(["-D", "smv_metadata_path={}".format(metadata_path)])
- for version_name, data in metadata.items():
- current_argv = argv.copy()
- current_argv.extend([
- "-D", "smv_current_version={}".format(version_name),
- ])
- outdir = os.path.join(args.outputdir, data["outputdir"])
- current_argv[srcdir_index] = data["sourcedir"]
- current_argv[outdir_index] = outdir
- os.makedirs(outdir, exist_ok=True)
- status = sphinx_build.build_main(current_argv)
- if status not in (0, None):
- break
|