| Left: | ||
| Right: |
| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/env python | |
| 2 # 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
| |
| 3 | |
| 4 # This file is part of Adblock Plus <https://adblockplus.org/>, | |
| 5 # Copyright (C) 2006-2016 Eyeo GmbH | |
| 6 # | |
| 7 # Adblock Plus is free software: you can redistribute it and/or modify | |
| 8 # it under the terms of the GNU General Public License version 3 as | |
| 9 # published by the Free Software Foundation. | |
| 10 # | |
| 11 # Adblock Plus is distributed in the hope that it will be useful, | |
| 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 14 # GNU General Public License for more details. | |
| 15 # | |
| 16 # You should have received a copy of the GNU General Public License | |
| 17 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | |
| 18 | |
| 19 import os | |
| 20 import shutil | |
| 21 import subprocess | |
| 22 | |
| 23 from sitescripts.utils import get_config | |
| 24 | |
| 25 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.
| |
| 26 | |
| 27 def read_projects(): | |
| 28 projects = {} | |
| 29 for key, value in config.iteritems(): | |
| 30 key_parts = key.split("_", 1) | |
| 31 if len(key_parts) < 2: | |
| 32 continue | |
| 33 project_name, field_name = key_parts | |
| 34 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.
| |
| 35 continue | |
| 36 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.
| |
| 37 projects[project_name][field_name] = value | |
| 38 return projects | |
| 39 | |
| 40 def sync_sources(sources_dir, repository_url): | |
| 41 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.
| |
| 42 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.
| |
| 43 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
| |
| 44 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.
| |
| 45 local_id = id_file.read() | |
| 46 if local_id == remote_id: | |
| 47 return | |
| 48 if os.path.exists(sources_dir): | |
| 49 shutil.rmtree(sources_dir) | |
| 50 subprocess.check_call(["hg", "archive", "-R", repository_url, "-r", "master", | |
| 51 sources_dir]) | |
| 52 | |
| 53 # In theory, it is possible that some changesets are pushed after we fetch | |
| 54 # the ID above, but before we run `hg archive`, which will lead to an | |
| 55 # unnecessary `hg archive` operation the next time this runs. | |
| 56 with open(id_path, "w") as id_file: | |
| 57 id_file.write(remote_id) | |
| 58 | |
| 59 def replace_dir(source_dir, target_dir): | |
| 60 if not os.path.exists(target_dir): | |
| 61 parent_dir = os.path.dirname(target_dir) | |
| 62 if not os.path.exists(parent_dir): | |
| 63 os.makedirs(parent_dir) | |
| 64 os.rename(source_dir, target_dir) | |
| 65 else: | |
| 66 old_target_dir = target_dir.rstrip("/") + ".old" | |
| 67 if os.path.exists(old_target_dir): | |
| 68 shutil.rmtree(old_target_dir) | |
| 69 os.rename(target_dir, old_target_dir) | |
| 70 os.rename(source_dir, target_dir) | |
| 71 shutil.rmtree(old_target_dir) | |
| 72 | |
| 73 def run_generation_command(command, sources_dir, output_dir): | |
| 74 if os.path.exists(output_dir): | |
| 75 shutil.rmtree(output_dir) | |
| 76 command = command.format(output_dir=output_dir) | |
| 77 subprocess.check_call(command, shell=True, cwd=sources_dir) | |
| 78 | |
| 79 def generate_docs(projects): | |
| 80 temp_directory = config["temp_directory"] | |
| 81 if not os.path.exists(temp_directory): | |
| 82 os.makedirs(temp_directory) | |
| 83 | |
| 84 for name, data in projects.iteritems(): | |
| 85 sources_dir = os.path.join(temp_directory, name) | |
| 86 sync_sources(sources_dir, data["repository"]) | |
| 87 output_dir = sources_dir.rstrip("/") + ".docs" | |
| 88 run_generation_command(data["command"], sources_dir, output_dir) | |
| 89 replace_dir(output_dir, data["target_directory"]) | |
| 90 | |
| 91 if __name__ == "__main__": | |
| 92 projects = read_projects() | |
| 93 generate_docs(projects) | |
| OLD | NEW |