Rework tool/doc for updating reference docs (#10123)

* WIP - rework update imported docs

* Rework tool/doc for updating reference docs

This PR reimplement the reference docs generator in Python and fixes
some outdated docs and data:

- Do docs import using Python because the GoLang version of tool has
  some following drawbacks:
  * its not convenient for handling YAML config files
  * it has to be compiled to binaries to run on different platforms
  * for every tiny changes you need to compile a new version and check in
- The reference docs we use in website are actually not coming directly
  from `kubernetes/kubernetes`. Most of them come from the `reference-docs`
  project. The configuration files are thus changed to avoid confusion.
- We have changed the location of generated docs so the default configuration
  files and the docs are updated.
This commit is contained in:
Qiming
2018-09-22 05:08:50 +08:00
committed by k8s-ci-robot
parent 7b33ce4825
commit 26f0a81b65
8 changed files with 286 additions and 550 deletions
+26 -33
View File
@@ -1,12 +1,15 @@
# Update imported docs
This script updates the target files generated from other repos listed in the <config.yml> file, which is specified as the command line argument.
This script updates the docs files that are generated from other repos.
It accepts a YAML file name as its input which can be customized on a per-repo
basis.
## Requirements
Imported docs must follow these guidelines:
1. Be listed somewhere in the `/_data/imported.yml` table of contents file.
1. Adhere to the [Documentation Style Guide](/docs/home/contribute/style-guide/).
1. Have `title` defined in the front matter. For example:
```
@@ -16,49 +19,36 @@ Imported docs must follow these guidelines:
Rest of the .md file...
```
1. Be listed somewhere in a file under the `data` subdirectory, for example,
the `data/imported.yml` file.
1. Adhere to the [Documentation Style Guide](/docs/home/contribute/style-guide/).
1. Make sure the `PyYAML` package is installed:
```
sudo apt-get install python-pip
pip install PyYAML
```
## Usage
From within this directory, run the following command:
```
+./update-imported-docs-[linux|macos] <config.yaml>
+./update-imported-docs <CONFIG-FILE>
```
The output should look similar to the following:
where `<CONFIG-FILE>` can be any YAML configuration file in this directory.
```
Website root directory: /Users/someuser/git/kubernetes-website
## Configuration file format
* * *
Cloning repo "community"...
* * *
Docs imported! Run 'git add .' 'git commit -m <comment>' and 'git push' to upload them.
```
## Config file format
Each config file may contain multiple repos, which will be imported together. You should modify the corresponding `update-imported-docs/<config.yml>` file to reflect the desired `src` and `dst` paths.
You may also create new config files for different groups of documents to import. The following is an example of the YAML file format:
Each config file may contain multiple repos that will be imported together.
When necessary, you can customize the configuration file by manually editing
it. You may create new config files for importing other groups of documents.
The following is an example of the YAML configuration file:
```
repos:
- name: kubernetes #tmp directory name
remote: https://github.com/kubernetes/kubernetes.git
branch: release-1.9
generate-command: hack/generate-docs.sh #optional command to run
files:
- src: docs/admin/cloud-controller-manager.md
dst: docs/reference/generated/cloud-controller-manager.md
- src: docs/admin/kube-apiserver.md
dst: docs/reference/generated/kube-apiserver.md
- name: community #tmp directory name
- name: community
remote: https://github.com/kubernetes/community.git
branch: master
files:
@@ -68,8 +58,11 @@ repos:
dst: docs/imported/community/guide.md
```
Note: `generate-command` is an optional entry, which can be used to run a given command to auto-generate the docs from within that repo.
Note: `generate-command` is an optional entry, which can be used to run a
given command or a short script to generate the docs from within a repo.
## Fixing Links
To fix relative links within your imported files, set the repo config's `gen-absolute-links` value to `true`. You can see an example of this in [`community.yml`](community.yml).
To fix relative links within your imported files, set the repo config's
`gen-absolute-links` property to `true`. You can find an example of this in
[`community.yml`](community.yml).
+42 -184
View File
@@ -1,186 +1,44 @@
repos:
- name: kubernetes
remote: https://github.com/kubernetes/kubernetes.git
branch: release-1.11
generate-command: hack/generate-docs.sh
- name: reference-docs
remote: https://github.com/kubernetes-incubator/reference-docs.git
# This and the generate-command below needs a change when reference-docs has
# branches properly defined
branch: master
generate-command: |
cd $GOPATH
git clone https://github.com/kubernetes/kubernetes.git src/k8s.io/kubernetes
cd src/k8s.io/kubernetes
git checkout release-1.11
make generated_files
cp -L -R vendor $GOPATH/src
rm -r vendor
cd $GOPATH
go get -v github.com/kubernetes-incubator/reference-docs/gen-compdocs
cd src/github.com/kubernetes-incubator/reference-docs/
make comp
files:
- src: docs/admin/cloud-controller-manager.md
dst: content/en/docs/reference/command-line-tools-reference/kube-controller-manager.md
- src: docs/admin/kube-apiserver.md
dst: content/en/docs/reference/command-line-tools-reference/kube-apiserver.md
- src: docs/admin/kube-controller-manager.md
dst: content/en/docs/reference/command-line-tools-reference/kube-controller-manager.md
- src: docs/admin/kubelet.md
dst: content/en/docs/reference/command-line-tools-reference/kubelet.md
- src: docs/admin/kube-proxy.md
dst: content/en/docs/reference/command-line-tools-reference/kube-proxy.md
- src: docs/admin/kube-scheduler.md
dst: content/en/docs/reference/command-line-tools-reference/kube-scheduler.md
- src: docs/user-guide/kubectl/kubectl.md
dst: content/en/docs/reference/kubectl/kubectl.md
- src: docs/admin/kubeadm_alpha.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha.md
- src: docs/admin/kubeadm_alpha_phase_addon_all.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_addon_all.md
- src: docs/admin/kubeadm_alpha_phase_addon_coredns.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_addon_coredns.md
- src: docs/admin/kubeadm_alpha_phase_addon_kube-proxy.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_addon_kube-proxy.md
- src: docs/admin/kubeadm_alpha_phase_addon.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_addon.md
- src: docs/admin/kubeadm_alpha_phase_bootstrap-token_all.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_bootstrap-token_all.md
- src: docs/admin/kubeadm_alpha_phase_bootstrap-token_cluster-info.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_bootstrap-token_cluster-info.md
- src: docs/admin/kubeadm_alpha_phase_bootstrap-token_create.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_bootstrap-token_create.md
- src: docs/admin/kubeadm_alpha_phase_bootstrap-token.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_bootstrap-token.md
- src: docs/admin/kubeadm_alpha_phase_bootstrap-token_node_allow-auto-approve.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_bootstrap-token_node_allow-auto-approve.md
- src: docs/admin/kubeadm_alpha_phase_bootstrap-token_node_allow-post-csrs.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_bootstrap-token_node_allow-post-csrs.md
- src: docs/admin/kubeadm_alpha_phase_bootstrap-token_node.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_bootstrap-token_node.md
- src: docs/admin/kubeadm_alpha_phase_certs_all.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_all.md
- src: docs/admin/kubeadm_alpha_phase_certs_apiserver-etcd-client.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_apiserver-etcd-client.md
- src: docs/admin/kubeadm_alpha_phase_certs_apiserver-kubelet-client.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_apiserver-kubelet-client.md
- src: docs/admin/kubeadm_alpha_phase_certs_apiserver.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_apiserver.md
- src: docs/admin/kubeadm_alpha_phase_certs_ca.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_ca.md
- src: docs/admin/kubeadm_alpha_phase_certs_etcd-ca.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_etcd-ca.md
- src: docs/admin/kubeadm_alpha_phase_certs_etcd-healthcheck-client.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_etcd-healthcheck-client.md
- src: docs/admin/kubeadm_alpha_phase_certs_etcd-peer.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_etcd-peer.md
- src: docs/admin/kubeadm_alpha_phase_certs_etcd-server.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_etcd-server.md
- src: docs/admin/kubeadm_alpha_phase_certs_front-proxy-ca.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_front-proxy-ca.md
- src: docs/admin/kubeadm_alpha_phase_certs_front-proxy-client.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_front-proxy-client.md
- src: docs/admin/kubeadm_alpha_phase_certs.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs.md
- src: docs/admin/kubeadm_alpha_phase_certs_sa.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_certs_sa.md
- src: docs/admin/kubeadm_alpha_phase_controlplane_all.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_controlplane_all.md
- src: docs/admin/kubeadm_alpha_phase_controlplane_apiserver.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_controlplane_apiserver.md
- src: docs/admin/kubeadm_alpha_phase_controlplane_controller-manager.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_controlplane_controller-manager.md
- src: docs/admin/kubeadm_alpha_phase_controlplane.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_controlplane.md
- src: docs/admin/kubeadm_alpha_phase_controlplane_scheduler.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_controlplane_scheduler.md
- src: docs/admin/kubeadm_alpha_phase_etcd_local.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_etcd_local.md
- src: docs/admin/kubeadm_alpha_phase_etcd.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_etcd.md
- src: docs/admin/kubeadm_alpha_phase_kubeconfig_admin.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubeconfig_admin.md
- src: docs/admin/kubeadm_alpha_phase_kubeconfig_all.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubeconfig_all.md
- src: docs/admin/kubeadm_alpha_phase_kubeconfig_controller-manager.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubeconfig_controller-manager.md
- src: docs/admin/kubeadm_alpha_phase_kubeconfig_kubelet.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubeconfig_kubelet.md
- src: docs/admin/kubeadm_alpha_phase_kubeconfig.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubeconfig.md
- src: docs/admin/kubeadm_alpha_phase_kubeconfig_scheduler.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubeconfig_scheduler.md
- src: docs/admin/kubeadm_alpha_phase_kubeconfig_user.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubeconfig_user.md
- src: docs/admin/kubeadm_alpha_phase_kubelet_config_download.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubelet_config_download.md
- src: docs/admin/kubeadm_alpha_phase_kubelet_config_enable-dynamic.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubelet_config_enable-dynamic.md
- src: docs/admin/kubeadm_alpha_phase_kubelet_config.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubelet_config.md
- src: docs/admin/kubeadm_alpha_phase_kubelet_config_upload.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubelet_config_upload.md
- src: docs/admin/kubeadm_alpha_phase_kubelet_config_write-to-disk.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubelet_config_write-to-disk.md
- src: docs/admin/kubeadm_alpha_phase_kubelet.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubelet.md
- src: docs/admin/kubeadm_alpha_phase_kubelet_write-env-file.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_kubelet_write-env-file.md
- src: docs/admin/kubeadm_alpha_phase_mark-master.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_mark-master.md
- src: docs/admin/kubeadm_alpha_phase.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase.md
- src: docs/admin/kubeadm_alpha_phase_preflight_master.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_preflight_master.md
- src: docs/admin/kubeadm_alpha_phase_preflight.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_preflight.md
- src: docs/admin/kubeadm_alpha_phase_preflight_node.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_preflight_node.md
- src: docs/admin/kubeadm_alpha_phase_selfhosting_convert-from-staticpods.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_selfhosting_convert-from-staticpods.md
- src: docs/admin/kubeadm_alpha_phase_selfhosting.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_selfhosting.md
- src: docs/admin/kubeadm_alpha_phase_upload-config.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_alpha_phase_upload-config.md
- src: docs/admin/kubeadm_completion.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_completion.md
- src: docs/admin/kubeadm_config_images_list.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_images_list.md
- src: docs/admin/kubeadm_config_images.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_images.md
- src: docs/admin/kubeadm_config_images_pull.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_images_pull.md
- src: docs/admin/kubeadm_config.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config.md
- src: docs/admin/kubeadm_config_migrate.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_migrate.md
- src: docs/admin/kubeadm_config_print-default.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_print-default.md
- src: docs/admin/kubeadm_config_upload_from-file.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_upload_from-file.md
- src: docs/admin/kubeadm_config_upload_from-flags.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_upload_from-flags.md
- src: docs/admin/kubeadm_config_upload.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_upload.md
- src: docs/admin/kubeadm_config_view.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_config_view.md
- src: docs/admin/kubeadm_init.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_init.md
- src: docs/admin/kubeadm_join.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_join.md
- src: docs/admin/kubeadm_reset.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_reset.md
- src: docs/admin/kubeadm_token_create.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_token_create.md
- src: docs/admin/kubeadm_token_delete.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_token_delete.md
- src: docs/admin/kubeadm_token_generate.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_token_generate.md
- src: docs/admin/kubeadm_token_list.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_token_list.md
- src: docs/admin/kubeadm_token.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_token.md
- src: docs/admin/kubeadm_upgrade_apply.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md
- src: docs/admin/kubeadm_upgrade_diff.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_diff.md
- src: docs/admin/kubeadm_upgrade.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade.md
- src: docs/admin/kubeadm_upgrade_node_config.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node_config.md
- src: docs/admin/kubeadm_upgrade_node.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node.md
- src: docs/admin/kubeadm_upgrade_plan.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md
- src: docs/admin/kubeadm_version.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/kubeadm_version.md
- src: gen-compdocs/build/cloud-controller-manager.md
dst: content/en/docs/reference/command-line-tools-reference/
- src: gen-compdocs/build/kube-apiserver.md
dst: content/en/docs/reference/command-line-tools-reference/
- src: gen-compdocs/build/kube-controller-manager.md
dst: content/en/docs/reference/command-line-tools-reference/
# We have problems generating docs for kubelet, it is done manually now
# - src: gen-compdocs/build/kubelet.md
# dst: content/en/docs/reference/command-line-tools-reference/
- src: gen-compdocs/build/kube-proxy.md
dst: content/en/docs/reference/command-line-tools-reference/
- src: gen-compdocs/build/kube-scheduler.md
dst: content/en/docs/reference/command-line-tools-reference/
- src: gen-compdocs/build/kubectl.md
dst: content/en/docs/reference/kubectl/
- src: gen-compdocs/build/kubeadm*.md
dst: content/en/docs/reference/setup-tools/kubeadm/generated/
- name: federation
remote: https://github.com/kubernetes/federation.git
# # Change this to a release branch when federation has release branches.
# Change this to a release branch when federation has release branches.
branch: master
generate-command: hack/generate-docs.sh
files:
@@ -189,14 +47,14 @@ repos:
- src: docs/admin/federation-controller-manager.md
dst: content/en/docs/reference/command-line-tools-reference/federation-controller-manager.md
- src: docs/admin/kubefed_init.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed-init.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed_init.md
- src: docs/admin/kubefed_join.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed-join.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed_join.md
- src: docs/admin/kubefed.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed.md
- src: docs/admin/kubefed_options.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed-options.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed_options.md
- src: docs/admin/kubefed_unjoin.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed-unjoin.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed_unjoin.md
- src: docs/admin/kubefed_version.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed-version.md
dst: content/en/docs/reference/setup-tools/kubefed/kubefed_version.md
+158
View File
@@ -0,0 +1,158 @@
#!/usr/bin/env python
import glob
import os
import re
import shutil
import subprocess
import sys
try:
import yaml
except Exception:
print("Please ensure PyYAML package is installed. This can be done, for "
"example, by executing the following command:\n\n"
" pip install pyyaml\n")
sys.exit(-1)
def processLinks(content, remotePrefix, subPath):
"""Process markdown links found in the docs."""
def analyze(matchObj):
ankor = matchObj.group('ankor')
target = matchObj.group('target')
if not (target.startswith("https://") or
target.startswith("mailto:") or
target.startswith("#")):
if target.startswith("/"):
target = "/".join(remotePrefix, target[1:])
else:
target = "/".join(remotePrefix, subPath, target)
return "[%s](%s)" % (ankor, target)
# Links are in the form '[text](url)'
linkRegex = re.compile(r"\[(?P<ankor>.*)\]\((?P<target>.*)\)")
content = re.sub(linkRegex, analyze, content)
h1Regex = re.compile("^(# .*)?\n")
content = re.sub(h1Regex, "", content)
return content
def processFile(src, dst, repoPath, repoDir, rootDir, genAbsoluteLinks):
"""Process a file element.
:param src: A string containing the relative path of a source file. The
string may contain wildcard characters such as '*' or '?'.
:param dst: The path for the destination file. The string can be a
directory name or a file name.
"""
pattern = os.path.join(repoDir, repoPath, src)
dstPath = os.path.join(rootDir, dst)
for src in glob.glob(pattern):
# we don't dive into subdirectories
if not os.path.isfile(src):
print("[Error] skipping non-regular path %s" % src)
continue
content = ""
try:
with open(src, "r") as srcFile:
content = srcFile.read()
except Exception as ex:
print("[Error] failed in reading source file: " + str(ex))
continue
dst = dstPath
if dstPath.endswith("/"):
baseName = os.path.basename(src)
dst = os.path.join(dst, baseName)
try:
print("Writing doc: " + dst)
with open(dst, "w") as dstFile:
if genAbsoluteLinks:
srcDir = os.path.dirname(src)
remotePrefix = repoPath + "/tree/master"
content = processLinks(content, remotePrefix, srcDir)
dstFile.write(content)
except Exception as ex:
print("[Error] failed in writing target file '%s': %s"
"" % (dst, str(ex)))
continue
def main():
"""The main entry of the program."""
if len(sys.argv) < 2:
print("[Error] Please specify a config file")
return -1
configFile = sys.argv[1]
currDir = os.path.dirname(__file__)
rootDir = os.path.realpath(os.path.join(currDir, '..'))
try:
configData = yaml.load(open(configFile, 'r'))
except Exception as ex:
print("[Error] failed in loading config file - %s" % str(ex))
return -2
os.chdir(rootDir)
workDir = "/tmp/update_docs"
shutil.rmtree(workDir, True)
os.mkdir(workDir, 0750)
for repo in configData["repos"]:
if "name" not in repo:
print("[Error] repo missing name")
continue
repoName = repo["name"]
if "remote" not in repo:
print("[Error] repo '%s' missing repo path" % repoName)
continue
repoRemote = repo["remote"]
remoteRegex = re.compile(r"^https://(?P<prefix>.*)\.git$")
matches = remoteRegex.search(repoRemote)
if not matches:
print("[Error] repo path for '%s' is invalid" % repoName)
continue
repoPath = os.path.join("src", matches.group('prefix'))
os.chdir(workDir)
print("Cloning repo %s..." % repoName)
cmd = "git clone --depth=1 -b {0} {1} {2}".format(
repo["branch"], repoRemote, repoPath)
res = subprocess.call(cmd, shell=True)
if res != 0:
print("[Error] failed in cloning repo '%s'" % repoName)
continue
os.chdir(repoPath)
if "generate-command" in repo:
genCmd = repo["generate-command"]
genCmd = "export GOPATH=" + workDir + "\n" + genCmd
print("Generating docs for %s with %s" % (repoName, genCmd))
res = subprocess.call(genCmd, shell=True)
if res != 0:
print("[Error] failed in generating docs for '%s'" % repoName)
continue
os.chdir(rootDir)
for f in repo["files"]:
processFile(f['src'], f['dst'], repoPath, workDir, rootDir,
"gen-absolute-links" in repo)
print("Completed docs update. Now run the following command to commit:\n\n"
" git add .\n"
" git commit -m <comment>\n"
" git push\n")
if __name__ == '__main__':
sys.exit(main())
Binary file not shown.
Binary file not shown.
@@ -1,213 +0,0 @@
package main
import (
"bufio"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
"path/filepath"
"regexp"
"strings"
"github.com/ghodss/yaml"
)
func main() {
//get command line arguments without executable
clArgs := os.Args[1:]
//check that an argument has been passed in
if len(clArgs) == 0 {
fmt.Fprintf(os.Stderr, "Please specify a config file as a command line argument.\n")
os.Exit(1)
}
configFile := clArgs[0]
//get directory of executable
ex, err := os.Executable()
checkError(err)
exPath := filepath.Dir(ex) //file path of updated-imported-docs executable
suffix := filepath.Base(exPath) //should be "updated-imported-docs"
//check if suffix is "updated-imported-docs"
if suffix != "update-imported-docs" {
fmt.Fprintf(os.Stderr, "Instead of `go run update-imported-docs.go <config.yml>`, use the compiled binary `./update-imported-docs <config.yml>`\n")
os.Exit(1)
}
//set root directory of website
websiteRepo := filepath.Clean(strings.TrimSuffix(exPath,suffix)) //path of parent directory
fmt.Fprintf(os.Stdout, "Website root directory: %s\n", websiteRepo)
//read config.yaml file specified by first command line argument
content, err := ioutil.ReadFile(configFile)
if err != nil {
fmt.Fprintf(os.Stderr, "Error when reading file: %v\n", err)
os.Exit(1)
}
//convert contents of config.yml file into a map
var config map[string]interface{}
err = yaml.Unmarshal(content, &config)
if err != nil {
fmt.Fprintf(os.Stderr, "Error when unmarshal the config file: %v\n", err)
os.Exit(1)
}
//change working directory to website root
err = os.Chdir(websiteRepo)
checkError(err)
//clean out temp directory
tmpDir := "/tmp/update_docs"
os.RemoveAll(tmpDir)
os.Mkdir(tmpDir, 0750)
// Match the content between 2 `---`
// It mostly have something like:
// ---
// title: ***
// notile: ***
// ---
titleRegex := regexp.MustCompile("^---\ntitle:(.*\n)*?---\n")
// To extract repo path prefix from `remote`
remoteGitRegex := regexp.MustCompile("(https://.*)\\.git$")
//execute for each repo
repos := config["repos"].([]interface{})
for _, repo := range repos {
err = os.Chdir(tmpDir)
checkError(err)
//get config info for repo, clone repo locally
r := repo.(map[string]interface{})
repoName := r["name"].(string)
remotePathMatch := remoteGitRegex.FindAllStringSubmatch(r["remote"].(string), -1)
if (len(remotePathMatch) == 0) {
fmt.Fprintf(os.Stderr, "\n\t\t\t!\t!\t!\n\nInvalid remote path %q. Schema should look like: https://<url>.git\n", r["remote"].(string))
os.Exit(1)
}
remotePrefix := fmt.Sprintf("%s/tree/master", remotePathMatch[0][1])
cmd := "git"
args := []string{"clone", "--depth=1", "-b", r["branch"].(string), r["remote"].(string), repoName}
fmt.Fprintf(os.Stdout, "\n\t\t\t*\t*\t*\n\nCloning repo %q...\n", repoName)
if err := exec.Command(cmd, args...).Run(); err != nil {
fmt.Fprintf(os.Stderr, "\n\t\t\t!\t!\t!\n\nError when cloning repo %q: %v\n", repoName, err)
os.Exit(1)
}
err = os.Chdir(repoName)
checkError(err)
//if generate-command is specified in the repo config,
//run the command for that repo, e.g. "hack/generate-docs.sh"
if r["generate-command"] != nil {
genCmd := r["generate-command"].(string)
fmt.Fprintf(os.Stdout, "Generating docs for repo %q with %q...\n\n", repoName, genCmd)
cmd := exec.Command(genCmd)
cmdReader, err := cmd.StdoutPipe()
if err != nil {
fmt.Fprintf(os.Stderr, "\n\t\t\t!\t!\t!\n\nError when generating docs for repo %q: %v\n", repoName, err)
os.Exit(1)
}
//display running output of generate command
scanner := bufio.NewScanner(cmdReader)
go func() {
for scanner.Scan() {
fmt.Printf("generator output | %s\n", scanner.Text())
}
}()
err = cmd.Start()
if err != nil {
fmt.Fprintln(os.Stderr, "Error starting %q command\n", genCmd, err)
os.Exit(1)
}
err = cmd.Wait()
if err != nil {
fmt.Fprintln(os.Stderr, "Error waiting for %q command\n", genCmd, err)
os.Exit(1)
}
}
//copy and rename files from src -> dst specified in config
err = os.Chdir(websiteRepo)
checkError(err)
files := r["files"].([]interface{})
for _, file := range files {
f := file.(map[string]interface{})
src := f["src"].(string)
dst := f["dst"].(string)
srcDir := filepath.Dir(src)
absSrc, err := filepath.Abs(path.Join(tmpDir, repoName, src))
checkError(err)
absDst, err := filepath.Abs(dst)
checkError(err)
// Ignore the error if the old file is not found/
content, _ := ioutil.ReadFile(absDst)
titleBlock := titleRegex.Find(content)
content, err = ioutil.ReadFile(absSrc)
checkError(err)
// Write to new output file
dstFile, err := os.OpenFile(absDst, os.O_RDWR|os.O_CREATE, 0755)
checkError(err)
defer dstFile.Close()
_, err = dstFile.Write(titleBlock)
checkError(err)
// Process content if necessary
if r["gen-absolute-links"] != nil {
content = processLinks(content, remotePrefix, srcDir)
}
_, err = dstFile.Write(content)
checkError(err)
dstFile.Sync()
}
}
fmt.Fprintf(os.Stdout, "\n\t\t\t*\t*\t*\n\nDocs imported! Run 'git add .' 'git commit -m <comment>' and 'git push' to upload them.\n")
}
//
func processLinks(content []byte, remotePrefix string, subPath string) []byte {
// To catch anything of the form [text](url)
linkRegex := regexp.MustCompile("(\\[.+?\\])\\(([^\\s\\)]+)\\)")
// Regexes to skip
absUrlRegex := regexp.MustCompile("https*://")
mailRegex := regexp.MustCompile("mailto:")
processedContent := linkRegex.ReplaceAllFunc(content, func(b []byte) []byte {
if (absUrlRegex.Match(b) || mailRegex.Match(b)) {
return b // no processing needed
}
match := linkRegex.FindAllStringSubmatch(string(b), -1)
url := match[0][2]
if url[0] == '#' { // link on current page
return b
} else if url[0] == '/' { // link at root of repo
return []byte(fmt.Sprintf("%s(%s/%s)", match[0][1], remotePrefix, url[1:]))
} else { // link relative to current page
return []byte(fmt.Sprintf("%s(%s/%s/%s)", match[0][1], remotePrefix, subPath, url))
}
})
h1Regex := regexp.MustCompile("^(# .*)?\n")
processedContent = h1Regex.ReplaceAll(processedContent, []byte(""))
return processedContent
}
func checkError(err error) {
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}