diff options
author | Abderrahim Kitouni <abderrahim.kitouni@codethink.co.uk> | 2023-10-03 21:00:19 +0200 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@gmail.com> | 2023-10-09 12:16:20 +0200 |
commit | 3c1f396f694069a71699ecc9a53806d531a25748 (patch) | |
tree | c7c3d2a69c553b8a763883551dd2aadafbbec554 | |
parent | Merge pull request #29495 from yuwata/network-manager-state-file (diff) | |
download | systemd-3c1f396f694069a71699ecc9a53806d531a25748.tar.xz systemd-3c1f396f694069a71699ecc9a53806d531a25748.zip |
man: support multiple versions of the documentation on the website
This changes the doc-sync meson target from a simple rsync command to a
script that:
* puts the documentation in a subdirectory according to the version
* injects a bit of javascript to add a drop-down to switch between versions
* updates an index.json file with the newly uploaded version
* keeps the latest/ directory up to date with the latest version
* supports a --no-latest switch to be used when uploading older versions
-rw-r--r-- | man/meson.build | 9 | ||||
-rw-r--r-- | meson.build | 1 | ||||
-rwxr-xr-x | tools/sync-docs.py | 134 |
3 files changed, 138 insertions, 6 deletions
diff --git a/man/meson.build b/man/meson.build index e6798b7d4e..e4f2905d60 100644 --- a/man/meson.build +++ b/man/meson.build @@ -190,12 +190,9 @@ if rsync.found() run_target( 'doc-sync', depends : man_pages + html_pages, - command : [rsync, '-rlv', - '--delete-excluded', - '--include=man', - '--include=*.html', - '--exclude=*', - '--omit-dir-times', + command : [sync_docs_py, + '--version', + '@0@'.format(meson.project_version()), meson.current_build_dir(), get_option('www-target')]) endif diff --git a/meson.build b/meson.build index 5e9ca285ac..b01dd9cd73 100644 --- a/meson.build +++ b/meson.build @@ -1795,6 +1795,7 @@ export_dbus_interfaces_py = find_program('tools/dbus_exporter.py') generate_gperfs = find_program('tools/generate-gperfs.py') make_autosuspend_rules_py = find_program('tools/make-autosuspend-rules.py') make_directive_index_py = find_program('tools/make-directive-index.py') +sync_docs_py = find_program('tools/sync-docs.py') make_man_index_py = find_program('tools/make-man-index.py') meson_render_jinja2 = find_program('tools/meson-render-jinja2.py') update_dbus_docs_py = find_program('tools/update-dbus-docs.py') diff --git a/tools/sync-docs.py b/tools/sync-docs.py new file mode 100755 index 0000000000..bab99f8cb3 --- /dev/null +++ b/tools/sync-docs.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: LGPL-2.1-or-later + +from argparse import ArgumentParser +import glob +import json +import os +import re +import subprocess +import sys + +import requests + +BASE_URL = "https://www.freedesktop.org/software/systemd/man/" +JQUERY_URL = "https://code.jquery.com/jquery-3.7.1.min.js" +SCRIPT_TAG = '<script src="{}"></script>' + +NAV_JS = """ +$(document).ready(function() { + $.getJSON("../index.json", function(data) { + data.sort().reverse(); + + var [filename, dirname] = window.location.pathname.split("/").reverse(); + + var items = []; + $.each( data, function(_, version) { + if (version == dirname) { + items.push( "<option selected value='" + version + "'>" + "systemd " + version + "</option>"); + } else if (dirname == "latest" && version == data[0]) { + items.push( "<option selected value='" + version + "'>" + "systemd " + version + "</option>"); + } else { + items.push( "<option value='" + version + "'>" + "systemd " + version + "</option>"); + } + }); + + $("span:first").html($( "<select/>", { + id: "version-selector", + html: items.join( "" ) + })); + + $("#version-selector").on("change", function() { + window.location.assign("../" + $(this).val() + "/" + filename); + }); + }); +}); +""" + + +def process_file(filename): + with open(filename) as f: + contents = f.read() + + if SCRIPT_TAG.format("../nav.js") in contents: + return + + body_tag = re.search("<body[^>]*>", contents) + new_contents = ( + contents[: body_tag.end()] + + SCRIPT_TAG.format(JQUERY_URL) + + SCRIPT_TAG.format("../nav.js") + + contents[body_tag.end() :] + ) + + with open(filename, "w") as f: + f.write(new_contents) + + +def update_index_file(version, index_filename): + response = requests.get(BASE_URL + "index.json") + if response.status_code == 404: + index = [] + elif response.ok: + index = response.json() + else: + sys.exit(f"Error getting index: {response.status_code} {response.reason}") + + if version not in index: + index.insert(0, version) + + with open(index_filename, "w") as f: + json.dump(index, f) + + +def main(version, directory, www_target, latest): + index_filename = os.path.join(directory, "index.json") + nav_filename = os.path.join(directory, "nav.js") + + for filename in glob.glob(os.path.join(directory, "*.html")): + process_file(filename) + + with open(nav_filename, "w") as f: + f.write(NAV_JS) + + update_index_file(version, index_filename) + + dirs = [version] + + if latest: + dirs.append("latest") + + for d in dirs: + subprocess.check_call( + [ + "rsync", + "-rlv", + "--delete-excluded", + "--include=*.html", + "--exclude=*", + "--omit-dir-times", + directory + "/", # copy contents of directory + os.path.join(www_target, d), + ] + ) + + subprocess.check_call( + [ + "rsync", + "-v", + os.path.join(directory, "index.json"), + os.path.join(directory, "nav.js"), + www_target, + ] + ) + + +if __name__ == "__main__": + parser = ArgumentParser() + parser.add_argument("--version", required=True) + parser.add_argument("--no-latest", dest="latest", action="store_false") + parser.add_argument("directory") + parser.add_argument("www_target") + + args = parser.parse_args() + main(args.version, args.directory, args.www_target, args.latest) |