Index: sitescripts/docs/bin/generate_docs.py |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/sitescripts/docs/bin/generate_docs.py |
@@ -0,0 +1,93 @@ |
+#!/usr/bin/env python |
+# coding: utf-8 |
Sebastian Noack
2016/02/05 18:02:32
Not that a coding declaration is necessary here. M
Felix Dahlke
2016/02/05 20:47:58
Wow true, either that part changed or we misunders
|
+ |
+# This file is part of Adblock Plus <https://adblockplus.org/>, |
+# Copyright (C) 2006-2016 Eyeo GmbH |
+# |
+# Adblock Plus is free software: you can redistribute it and/or modify |
+# it under the terms of the GNU General Public License version 3 as |
+# published by the Free Software Foundation. |
+# |
+# Adblock Plus is distributed in the hope that it will be useful, |
+# but WITHOUT ANY WARRANTY; without even the implied warranty of |
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+# GNU General Public License for more details. |
+# |
+# You should have received a copy of the GNU General Public License |
+# along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
+ |
+import os |
+import shutil |
+import subprocess |
+ |
+from sitescripts.utils import get_config |
+ |
+config = dict(get_config().items("docs")) |
Sebastian Noack
2016/02/05 18:02:31
I'd prefer if you use the ConfigParser API consist
Felix Dahlke
2016/02/05 20:47:57
Done.
|
+ |
+def read_projects(): |
+ projects = {} |
+ for key, value in config.iteritems(): |
+ key_parts = key.split("_", 1) |
+ if len(key_parts) < 2: |
+ continue |
+ project_name, field_name = key_parts |
+ if field_name not in ["repository", "target_directory", "command"]: |
Sebastian Noack
2016/02/05 18:02:32
Nit: A set seems more appropriate here. In case yo
Felix Dahlke
2016/02/05 20:47:58
No I didn't, nice. Done.
|
+ continue |
+ projects.setdefault(project_name, {}) |
Sebastian Noack
2016/02/05 18:02:31
There is a reason that setdefault() returns the re
Felix Dahlke
2016/02/05 20:47:58
Done.
|
+ projects[project_name][field_name] = value |
+ return projects |
+ |
+def sync_sources(sources_dir, repository_url): |
+ remote_id = subprocess.check_output(["hg", "id", "-i", repository_url]) |
Sebastian Noack
2016/02/05 18:02:32
Nit: Please use long option names in scripts, that
Felix Dahlke
2016/02/05 20:47:58
Done.
|
+ id_path = sources_dir.rstrip("/") + ".id" |
Sebastian Noack
2016/02/05 18:02:31
Please don't hard-code file separators, use.ospath
Felix Dahlke
2016/02/05 20:47:58
Done.
|
+ if os.path.exists(id_path): |
Sebastian Noack
2016/02/05 18:02:31
It's better to handle the corresponding IOError, r
Felix Dahlke
2016/02/05 20:47:57
Fair enough, I've gotten rid of the os.path.exists
|
+ with open(id_path, "r") as id_file: |
Sebastian Noack
2016/02/05 18:02:32
Please always add "b" to the file mode, for consis
Felix Dahlke
2016/02/05 20:47:58
Done.
|
+ local_id = id_file.read() |
+ if local_id == remote_id: |
+ return |
+ if os.path.exists(sources_dir): |
+ shutil.rmtree(sources_dir) |
+ subprocess.check_call(["hg", "archive", "-R", repository_url, "-r", "master", |
+ sources_dir]) |
+ |
+ # In theory, it is possible that some changesets are pushed after we fetch |
+ # the ID above, but before we run `hg archive`, which will lead to an |
+ # unnecessary `hg archive` operation the next time this runs. |
+ with open(id_path, "w") as id_file: |
+ id_file.write(remote_id) |
+ |
+def replace_dir(source_dir, target_dir): |
+ if not os.path.exists(target_dir): |
+ parent_dir = os.path.dirname(target_dir) |
+ if not os.path.exists(parent_dir): |
+ os.makedirs(parent_dir) |
+ os.rename(source_dir, target_dir) |
+ else: |
+ old_target_dir = target_dir.rstrip("/") + ".old" |
+ if os.path.exists(old_target_dir): |
+ shutil.rmtree(old_target_dir) |
+ os.rename(target_dir, old_target_dir) |
+ os.rename(source_dir, target_dir) |
+ shutil.rmtree(old_target_dir) |
+ |
+def run_generation_command(command, sources_dir, output_dir): |
+ if os.path.exists(output_dir): |
+ shutil.rmtree(output_dir) |
+ command = command.format(output_dir=output_dir) |
+ subprocess.check_call(command, shell=True, cwd=sources_dir) |
+ |
+def generate_docs(projects): |
+ temp_directory = config["temp_directory"] |
+ if not os.path.exists(temp_directory): |
+ os.makedirs(temp_directory) |
+ |
+ for name, data in projects.iteritems(): |
+ sources_dir = os.path.join(temp_directory, name) |
+ sync_sources(sources_dir, data["repository"]) |
+ output_dir = sources_dir.rstrip("/") + ".docs" |
+ run_generation_command(data["command"], sources_dir, output_dir) |
+ replace_dir(output_dir, data["target_directory"]) |
+ |
+if __name__ == "__main__": |
+ projects = read_projects() |
+ generate_docs(projects) |