Files
systemd/tools/sync-docs.py
Luca Boccassi d80cabbd49 sync-docs: add '(latest stable)' next to the latest version in the menu
Add visual indicator of what is the latest version in the
version menu

(cherry picked from commit 90b0222091)
(cherry picked from commit 1b4abc3314)
2025-06-25 18:17:42 +01:00

159 lines
4.5 KiB
Python
Executable File

#!/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 == data[1]) {
latest = " (latest stable)";
} else {
latest = "";
}
if (version == dirname) {
items.push( "<option selected value='" + version + "'>" + "systemd " + version + latest + "</option>");
} else if (dirname == "latest" && version == data[1]) {
items.push( "<option selected value='" + version + "'>" + "systemd " + version + latest + "</option>");
} else {
items.push( "<option value='" + version + "'>" + "systemd " + version + latest + "</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 get_latest_version():
tags = subprocess.check_output(["git", "tag", "-l", "v*"], text=True).split()
versions = []
for tag in tags:
m = re.match(r"v?(\d+).*", tag)
if m:
versions.append(int(m.group(1)))
return max(versions)
def main(version, directory, www_target):
index_filename = os.path.join(directory, "index.json")
nav_filename = os.path.join(directory, "nav.js")
# The upload directory does not contain point release suffixes
version = re.sub(r"\..+$", "", version)
current_branch = subprocess.check_output(["git", "branch", "--show-current"], text=True).strip()
if current_branch != 'main' and not current_branch.endswith("-stable"):
sys.exit("doc-sync should only be run from main or a stable branch")
for filename in glob.glob(os.path.join(directory, "*.html")):
process_file(filename)
if current_branch == "main":
version = "devel"
dirs = ["devel"]
elif int(version) == get_latest_version():
dirs = [version, "latest"]
else:
dirs = [version]
with open(nav_filename, "w") as f:
f.write(NAV_JS)
update_index_file(version, index_filename)
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, "man", d),
]
)
subprocess.check_call(
[
"rsync",
"-v",
os.path.join(directory, "index.json"),
os.path.join(directory, "nav.js"),
os.path.join(www_target, "man"),
]
)
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument("--version", required=True)
parser.add_argument("directory")
parser.add_argument("www_target")
args = parser.parse_args()
main(args.version, args.directory, args.www_target)