diff --git a/BUILD b/BUILD index 121a8b91..571715e2 100644 --- a/BUILD +++ b/BUILD @@ -32,6 +32,7 @@ stardoc( "//brew:lib", "//common:lib", "//crates:lib", + "//docs:lib", "//gcp:lib", "//github:lib", "//maven:lib", @@ -77,6 +78,10 @@ stardoc( "assemble_crate", "deploy_crate", + # From: //docs:*/rules.bzl + "doxygen_docs", + "sphinx_docs", + # From: //gcp:rules.bzl "assemble_gcp", diff --git a/README.md b/README.md index 842c351b..a148b505 100755 --- a/README.md +++ b/README.md @@ -345,6 +345,32 @@ Deploy package built with `assemble_rpm` to RPM repository. | target | assemble_rpm target to deploy | Label | optional | None | + + +## doxygen_docs + +
+doxygen_docs(name, desc, main_page_md, project_name, sources, strip_prefix, version)
+
+ + + Creates HTML documentation for C++ projects using Doxygen. + + +**ATTRIBUTES** + + +| Name | Description | Type | Mandatory | Default | +| :------------- | :------------- | :------------- | :------------- | :------------- | +| name | A unique name for this target. | Name | required | | +| desc | A description for the project | String | optional | "" | +| main_page_md | The file to use as main page for the generate docs | Label | optional | None | +| project_name | The project name for the doxygen docs | String | required | | +| sources | A list of files made available to doxygen. This is NOT automatically included in the doxyfile | List of labels | required | | +| strip_prefix | Prefix to strip from path of files being processed | String | optional | "" | +| version | The version of the project being documented | String | optional | "" | + + ## generate_json_config @@ -370,7 +396,8 @@ Fills in JSON template with provided values ## java_deps
-java_deps(name, java_deps_root, java_deps_root_overrides, maven_name, target, version_file)
+java_deps(name, allowed_conflicting_jars, ignore_missing_maven_name, java_deps_root,
+          java_deps_root_overrides, maven_name, target, version_file)
 
Packs Java library alongside with its dependencies into archive @@ -381,6 +408,8 @@ Packs Java library alongside with its dependencies into archive | Name | Description | Type | Mandatory | Default | | :------------- | :------------- | :------------- | :------------- | :------------- | | name | A unique name for this target. | Name | required | | +| allowed_conflicting_jars | List of allowed JAR names that can conflict (ie. the same JAR name produced by two different dependencies). | List of strings | optional | [] | +| ignore_missing_maven_name | Don't fail if bundling using maven names when encountering a target that is missing a maven name | Boolean | optional | False | | java_deps_root | Folder inside archive to put JARs into | String | optional | "" | | java_deps_root_overrides | JARs with filenames matching the given patterns will be placed into the specified folders inside the archive, instead of the default folder. Patterns can be either the full name of a JAR, or a prefix followed by a '*'. | Dictionary: String -> String | optional | {} | | maven_name | Name JAR files inside archive based on Maven coordinates | Boolean | optional | False | @@ -388,6 +417,31 @@ Packs Java library alongside with its dependencies into archive | version_file | File containing version string. Alternatively, pass --define version=VERSION to Bazel invocation. Not specifying version at all defaults to '0.0.0' | Label | optional | None | + + +## sphinx_docs + +
+sphinx_docs(name, out, package_subdir, sphinx_conf, sphinx_rst, target)
+
+ + + Creates an HTML documentation for python module using Sphinx. + + +**ATTRIBUTES** + + +| Name | Description | Type | Mandatory | Default | +| :------------- | :------------- | :------------- | :------------- | :------------- | +| name | A unique name for this target. | Name | required | | +| out | Output directory | Label | required | | +| package_subdir | Directory with the module files in the package archive | String | required | | +| sphinx_conf | Configuration file for the Sphinx documentation builder | Label | required | | +| sphinx_rst | Sphinx documentation master file for the package | Label | required | | +| target | Package including .tar.gz archive | Label | required | | + + ## tgz2zip diff --git a/WORKSPACE b/WORKSPACE index 913273c3..919ab313 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -56,6 +56,12 @@ pip_deps() load("@vaticle_bazel_distribution_pip//:requirements.bzl", "install_deps") install_deps() +# Load //docs +load("//docs:python/deps.bzl", python_docs_deps = "deps") +python_docs_deps() +load("@vaticle_dependencies_tool_docs//:requirements.bzl", install_doc_deps = "install_deps") +install_doc_deps() + # TODO: remove this declaration once we upgrade to @io_bazel_stardoc with Bazel 5 support # Load @bazel_skylib http_archive( diff --git a/doc_hub.bzl b/doc_hub.bzl index ff7adb99..2e54e82a 100644 --- a/doc_hub.bzl +++ b/doc_hub.bzl @@ -47,6 +47,9 @@ load("//common/tgz2zip:rules.bzl", _tgz2zip = "tgz2zip") load("//crates:rules.bzl", _assemble_crate = "assemble_crate", _deploy_crate = "deploy_crate") +load("//docs/cpp:rules.bzl", _doxygen_docs = "doxygen_docs") +load("//docs/python:rules.bzl", _sphinx_docs = "sphinx_docs") + load("//gcp:rules.bzl", _assemble_gcp = "assemble_gcp") load('//github:rules.bzl', _deploy_github = "deploy_github") @@ -94,6 +97,9 @@ tgz2zip = _tgz2zip assemble_crate = _assemble_crate deploy_crate = _deploy_crate +doxygen_docs = _doxygen_docs +sphinx_docs = _sphinx_docs + assemble_gcp = _assemble_gcp deploy_github = _deploy_github diff --git a/docs/BUILD b/docs/BUILD new file mode 100644 index 00000000..c6191aa8 --- /dev/null +++ b/docs/BUILD @@ -0,0 +1,45 @@ +# +# Copyright (C) 2022 Vaticle +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +exports_files(["cpp/doxyfile.template"]) + +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") +load("@vaticle_dependencies_tool_docs//:requirements.bzl", docs_requirement = "requirement") + +py_binary( + name = "sphinx_runner", + srcs = [ + "python/sphinx_html_builder.py", + ], + main = "sphinx_html_builder.py", + deps = [docs_requirement("sphinx")], + visibility = ["//visibility:public"] +) + +bzl_library( + name = "lib", + srcs = [ + "cpp/rules.bzl", + "python/rules.bzl", + ], + deps = [], + visibility = ["//visibility:public"], +) diff --git a/docs/cpp/doxyfile.template b/docs/cpp/doxyfile.template new file mode 100644 index 00000000..b3654a14 --- /dev/null +++ b/docs/cpp/doxyfile.template @@ -0,0 +1,100 @@ +# Doxyfile 1.9.8 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). +#--------------------------------------------------------------------------- +# NOTE: +# This file has been cleaned up for doxygen doc generation via bazel +# To see all the options, generate a fresh one with +# `doxygen -g ` + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = ##{{PROJECT_NAME}} +PROJECT_NUMBER = ##{{PROJECT_NUMBER}} +PROJECT_BRIEF = ##{{PROJECT_BRIEF}} +OUTPUT_DIRECTORY = ##{{OUTPUT_DIRECTORY}} +CREATE_SUBDIRS = NO +ALLOW_UNICODE_NAMES = NO +OUTPUT_LANGUAGE = English + +BRIEF_MEMBER_DESC = YES +ALWAYS_DETAILED_SEC = YES +REPEAT_BRIEF = YES +STRIP_FROM_PATH = ##{{STRIP_FROM_PATH}} +INHERIT_DOCS = YES +INLINE_INHERITED_MEMB = NO + +MARKDOWN_SUPPORT = YES +AUTOLINK_SUPPORT = YES +FILE_PATTERNS = *.h *.hpp *.md *.html +CASE_SENSE_NAMES = NO + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +HIDE_FRIEND_COMPOUNDS = YES +SHOW_HEADERFILE = NO ## Show which header to include +SHOW_INCLUDE_FILES = NO +SORT_BRIEF_DOCS = NO ## NO: The short description at the top is in declaration order +SORT_MEMBER_DOCS = YES ## YES: The longer description which follows is sorted alphabetically +SORT_BY_SCOPE_NAME = NO + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_IF_INCOMPLETE_DOC = YES +WARN_NO_PARAMDOC = YES +WARN_IF_UNDOC_ENUM_VAL = YES +WARN_AS_ERROR = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = ##{{INPUT}} +INPUT_ENCODING = UTF-8 +RECURSIVE = NO ## bazel explicitly specifies files +EXCLUDE_SYMLINKS = NO ## bazel needs NO +USE_MDFILE_AS_MAINPAGE = ##{{USE_MDFILE_AS_MAINPAGE}} +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_COLORSTYLE = AUTO_LIGHT +ENUM_VALUES_PER_LINE = 4 +OBFUSCATE_EMAILS = YES +SEARCHENGINE = YES + +GENERATE_LATEX = NO + +#--------------------------------------------------------------------------- +# Configuration options related to diagram generator tools +#--------------------------------------------------------------------------- +HIDE_UNDOC_RELATIONS = YES +CLASS_GRAPH = YES +HAVE_DOT = NO ## Disables many details diff --git a/docs/cpp/rules.bzl b/docs/cpp/rules.bzl new file mode 100644 index 00000000..6b02d2af --- /dev/null +++ b/docs/cpp/rules.bzl @@ -0,0 +1,104 @@ +# +# Copyright (C) 2022 Vaticle +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +def _doxygen_docs_impl(ctx): + output_directory = ctx.actions.declare_directory(ctx.attr._output_directory) + files = [] + for target in ctx.attr.sources: + files.extend(target.files.to_list()) + + replacements = { + "PROJECT_NAME": ctx.attr.project_name, + "PROJECT_NUMBER" : ctx.attr.version, + "PROJECT_BRIEF" : ctx.attr.desc, + "OUTPUT_DIRECTORY" : output_directory.path, + "STRIP_FROM_PATH": ctx.attr.strip_prefix, + } + if ctx.file.main_page_md != None: + files.append(ctx.file.main_page_md) + replacements["USE_MDFILE_AS_MAINPAGE"] = ctx.file.main_page_md.path + + replacements["INPUT"] = " ".join([f.path for f in files]) + + # Prepare doxyfile + doxyfile = ctx.actions.declare_file("%s.doxyfile" % ctx.attr.name) + ctx.actions.expand_template( + template = ctx.file._doxyfile_template, + output = doxyfile, + substitutions = {"##{{%s}}"%k : replacements[k] for k in replacements} + ) + + files = [doxyfile] + files + print(doxyfile.path) + ctx.actions.run( + inputs = files, + outputs = [output_directory], + arguments = [doxyfile.path], + executable = "doxygen", + use_default_shell_env = True + ) + + return DefaultInfo(files = depset([output_directory])) + +doxygen_docs = rule( + implementation = _doxygen_docs_impl, + test = False, + attrs = { + "project_name" : attr.string( + doc = "The project name for the doxygen docs", + mandatory = True, + ), + "version" : attr.string( + doc = "The version of the project being documented", + default = "" + ), + "desc" : attr.string( + doc = "A description for the project", + default = "" + ), + "sources" : attr.label_list( + doc = "A list of files made available to doxygen. This is NOT automatically included in the doxyfile", + mandatory = True, + allow_files = True, + ), + "strip_prefix" : attr.string( + doc = "Prefix to strip from path of files being processed", + default = "" + ), + "main_page_md" : attr.label( + doc = "The file to use as main page for the generate docs", + allow_single_file = True, + mandatory = False + ), + "_doxyfile_template" : attr.label( + allow_single_file = True, + default = "//docs:cpp/doxyfile.template" + ), + "_output_directory" : attr.string( + doc = "The output directory for the doxygen docs", + default = "doxygen_docs" + ) + }, + doc = """ + Creates HTML documentation for C++ projects using Doxygen. + This rule is not hermetic, and requires doxygen to be installed on the host. + """ +) diff --git a/docs/java/deps.bzl b/docs/java/deps.bzl new file mode 100644 index 00000000..cb2a120e --- /dev/null +++ b/docs/java/deps.bzl @@ -0,0 +1,27 @@ +# +# Copyright (C) 2022 Vaticle +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +def deps(): + # Bazel Common Libraries (with javadoc) + http_archive( + name = "google_bazel_common", + sha256 = "e982cc2e4c9a7d664e77d97a99debb3d18261e6ac6ea5bc4d8f453a521fdf1cf", + strip_prefix = "bazel-common-78cc73600ddfa62f953652625abd7c6f1656cfac", + urls = ["https://github.com/google/bazel-common/archive/78cc73600ddfa62f953652625abd7c6f1656cfac.zip"], + ) diff --git a/docs/python/deps.bzl b/docs/python/deps.bzl new file mode 100644 index 00000000..46481bb1 --- /dev/null +++ b/docs/python/deps.bzl @@ -0,0 +1,24 @@ +# +# Copyright (C) 2022 Vaticle +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +load("@rules_python//python:pip.bzl", "pip_parse") + +def deps(): + pip_parse( + name = "vaticle_dependencies_tool_docs", + requirements_lock = "@vaticle_bazel_distribution//docs:python/requirements.txt", + ) diff --git a/docs/python/requirements.txt b/docs/python/requirements.txt new file mode 100644 index 00000000..3c22e712 --- /dev/null +++ b/docs/python/requirements.txt @@ -0,0 +1,46 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +alabaster==0.7.13 +Babel==2.12.1 +certifi==2022.12.7 +charset-normalizer==3.1.0 +docutils==0.18.1 +idna==3.4 +imagesize==1.4.1 +importlib-metadata==6.1.0 +Jinja2==3.1.2 +MarkupSafe==2.1.2 +packaging==23.0 +Pygments==2.14.0 +pytz==2023.2 +requests==2.28.2 +snowballstemmer==2.2.0 +Sphinx==6.1.3 +sphinx-rtd-theme==1.2.0 +sphinxcontrib-applehelp==1.0.4 +sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-htmlhelp==2.0.1 +sphinxcontrib-jquery==4.1 +sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-qthelp==1.0.3 +sphinxcontrib-serializinghtml==1.1.5 +typing-extensions==4.5.0 +urllib3==1.26.15 +zipp==3.15.0 diff --git a/docs/python/rules.bzl b/docs/python/rules.bzl new file mode 100644 index 00000000..4f3580e2 --- /dev/null +++ b/docs/python/rules.bzl @@ -0,0 +1,84 @@ +# +# Copyright (C) 2022 Vaticle +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +def _sphinx_docs_impl(ctx): + package = ctx.actions.declare_directory("package") + + ctx.actions.run_shell( + inputs = ctx.files.target, + outputs = [package], + command = 'PACKAGE=$(find . -name "*.tar.gz") && tar -xf ${PACKAGE} && mv */%s %s' + % (ctx.attr.package_subdir, package.path), + ) + + args = ctx.actions.args() + args.add('--output', ctx.outputs.out.path) + args.add('--package', package.path) + args.add('--source_dir', ctx.files.sphinx_conf[0].dirname) + + ctx.actions.run( + inputs = [ctx.executable._script, package] + ctx.files.sphinx_conf + ctx.files.sphinx_rst, + outputs = [ctx.outputs.out], + arguments = [args], + executable = ctx.executable._script, + env = {"PYTHONPATH": package.path}, + ) + + return DefaultInfo(files = depset([ctx.outputs.out])) + + +sphinx_docs = rule( + attrs = { + "_script": attr.label( + default = ":sphinx_runner", + executable = True, + cfg = "exec", + doc = "Script for running sphinx", + ), + "target": attr.label( + mandatory = True, + allow_files = True, + doc = "Package including .tar.gz archive", + ), + "sphinx_conf": attr.label( + mandatory = True, + allow_files = True, + doc = "Configuration file for the Sphinx documentation builder", + ), + "sphinx_rst": attr.label( + mandatory = True, + allow_files = True, + doc = "Sphinx documentation master file for the package", + ), + "out": attr.output( + mandatory = True, + doc = "Output directory", + ), + "package_subdir": attr.string( + mandatory = True, + doc = "Directory with the module files in the package archive", + ) + }, + implementation = _sphinx_docs_impl, + doc = """ + Creates an HTML documentation for python module using Sphinx. + """ +) diff --git a/docs/python/sphinx_html_builder.py b/docs/python/sphinx_html_builder.py new file mode 100644 index 00000000..debaa846 --- /dev/null +++ b/docs/python/sphinx_html_builder.py @@ -0,0 +1,36 @@ +# +# Copyright (C) 2022 Vaticle +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +import argparse +import sys + +from sphinx.cmd.build import main +from sphinx.ext import apidoc + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--output', help="Output directory") + parser.add_argument('--package', help="Package directory") + parser.add_argument('--source_dir', help="Sphinx source directory") + args = parser.parse_args() + + apidoc.main(["-o", args.source_dir, args.package]) + sys.exit(main(["-M", "html", args.source_dir, args.output])) diff --git a/maven/deps.bzl b/maven/deps.bzl index 4e8c39ea..0a32ddd5 100644 --- a/maven/deps.bzl +++ b/maven/deps.bzl @@ -23,6 +23,7 @@ maven_artifacts = [ "com.google.http-client:google-http-client", "info.picocli:picocli", "org.apache.commons:commons-compress", + "org.jsoup:jsoup", "org.zeroturnaround:zt-exec", ] @@ -33,5 +34,6 @@ maven_artifacts_with_versions = [ "com.google.http-client:google-http-client:1.34.2", "info.picocli:picocli:4.3.2", "org.apache.commons:commons-compress:1.21", + "org.jsoup:jsoup:1.16.1", "org.zeroturnaround:zt-exec:1.10", ]