pw_module: Start module structure documentation
This adds some basic documentation about the Pigweed module structure.
Much more will need to get added, such as rationale and more.
Change-Id: I7b2b16319bc3461ba66db29e9d64a72c862fb157
diff --git a/docs/BUILD.gn b/docs/BUILD.gn
index 70eee10..ac10d91 100644
--- a/docs/BUILD.gn
+++ b/docs/BUILD.gn
@@ -32,9 +32,10 @@
":core_docs",
"$dir_pw_bloat:docs",
"$dir_pw_docgen:docs",
- "$dir_pw_dumb_io:docs",
"$dir_pw_dumb_io_baremetal_stm32f429:docs",
+ "$dir_pw_dumb_io:docs",
"$dir_pw_dumb_io_stdio:docs",
+ "$dir_pw_module:docs",
"$dir_pw_preprocessor:docs",
"$dir_pw_presubmit:docs",
"$dir_pw_span:docs",
diff --git a/docs/modules.rst b/docs/modules.rst
index 4bf4bc1..5e5de96 100644
--- a/docs/modules.rst
+++ b/docs/modules.rst
@@ -7,9 +7,10 @@
pw_bloat/bloat
pw_docgen/docgen
- pw_dumb_io/docs
pw_dumb_io_baremetal_stm32f429/docs
+ pw_dumb_io/docs
pw_dumb_io_stdio/docs
+ pw_module/docs
pw_preprocessor/docs
pw_presubmit/docs
pw_span/docs
diff --git a/modules.gni b/modules.gni
index 76d5de2..2684714 100644
--- a/modules.gni
+++ b/modules.gni
@@ -29,6 +29,7 @@
dir_pw_dumb_io_baremetal_stm32f429 =
"$dir_pigweed/pw_dumb_io_baremetal_stm32f429"
dir_pw_dumb_io_stdio = "$dir_pigweed/pw_dumb_io_stdio"
+dir_pw_module = "$dir_pigweed/pw_module"
dir_pw_preprocessor = "$dir_pigweed/pw_preprocessor"
dir_pw_presubmit = "$dir_pigweed/pw_presubmit"
dir_pw_span = "$dir_pigweed/pw_span"
diff --git a/pw_module/BUILD.gn b/pw_module/BUILD.gn
new file mode 100644
index 0000000..9eed4a2
--- /dev/null
+++ b/pw_module/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright 2019 The Pigweed Authors
+#
+# Licensed 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
+#
+# https://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("$dir_pw_docgen/docs.gni")
+
+pw_doc_group("docs") {
+ sources = [
+ "docs.rst",
+ ]
+}
diff --git a/pw_module/docs.rst b/pw_module/docs.rst
new file mode 100644
index 0000000..1821b9d
--- /dev/null
+++ b/pw_module/docs.rst
@@ -0,0 +1,246 @@
+.. _chapter-module:
+
+.. default-domain:: cpp
+
+.. highlight:: sh
+
+---------
+pw_module
+---------
+
+The ``pw_module`` module is the "meta-module" for Pigweed, containing
+documentation for Pigweed's module structure as well as tools to detect when
+modules are in or out of conformance to the module style.
+
+The Pigweed module structure
+----------------------------
+
+The Pigweed module structure is designed to keep as much code as possible for a
+particular slice of functionality in one place. That means including the code
+from multiple languages, as well as all the related documentation and tests.
+
+Additionally, the structure is desigend to limit the number of places a file
+could go, so that when reading callsites it is obvious where a header is from.
+That is where the duplicated ``<module>`` occurences in file paths comes from.
+
+tl;dr example module structure
+------------------------------
+
+.. code-block:: python
+
+ pw_foo/...
+
+ docs.rst # If there is just 1 docs file, call it docs.rst
+ README.md # All modules must have a short README for gittiles
+
+ BUILD.gn # GN build required
+ BUILD # Bazel build required
+
+ # Public headers; the repeated module name is required
+ public/pw_foo/foo.h
+ public/pw_foo/baz.h
+
+ # Exposed public headers go under internal/
+ public/pw_foo/internal/bar.h
+ public/pw_foo/internal/qux.h
+
+ # Public override headers must go in 'public_overrides'
+ public_overrides/gtest/gtest.h
+ public_overrides/string.h
+
+ # Private headers go into <module>_*/...
+ pw_foo_internal/zap.h
+ pw_foo_private/zip.h
+ pw_foo_secret/alxx.h
+
+ # C++ implementations go in the root
+ foo_impl.cc
+ foo.cc
+ baz.cc
+ bar.cc
+ zap.cc
+ zip.cc
+ alxx.cc
+
+ # C++ tests also go in the root
+ foo_test.cc
+ bar_test.cc
+ zip_test.cc
+
+ # Python files go into 'py/<module>/...'
+ py/setup.py # All Python must be a Python module with setup.py
+ py/foo_test.py # Tests go in py/ but outside of the Python module
+ py/bar_test.py
+ py/pw_foo/__init__.py
+ py/pw_foo/__main__.py
+ py/pw_foo/bar.py
+
+ # Go files go into 'go/...'
+ go/...
+
+ # Examples go in examples/, mixing different languages
+ examples/demo.py
+ examples/demo.cc
+ examples/demo.go
+ examples/BUILD.gn
+ examples/BUILD
+
+ # Size reports go under size_report/
+ size_report/BUILD.gn
+ size_report/base.cc
+ size_report/use_case_a.cc
+ size_report/use_case_b.cc
+
+ # Other directories are fine, but should be private.
+ data/...
+ graphics/...
+ collection_of_tests/...
+ code_relating_to_subfeature/...
+
+Module name
+-----------
+Pigweed upstream modules are always named with a prefix ``pw_`` to enforce
+namespacing. Projects using Pigweed that wish to make their own modules can use
+whatever name they like, but we suggest picking a short prefix to namespase
+your product (e.g. for an Internet of Toast project, perhaps the prefix could
+be ``it_``.
+
+C++ file and directory locations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Public headers - ``public/<module>``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Thes are headers that must be exposed due to C++ limitations (i.e. are
+included from the public interface, but are not intended for public use)
+
+**Public headers** should take the form:
+
+``<module>/public/<module>/*.h``
+
+**Exposed private headers** should take the form:
+
+``<module>/public/<module>/internal/*.h``
+
+Examples:
+
+.. code-block::
+
+ pw_foo/...
+ public/pw_foo/foo.h
+ public/pw_foo/a_header.h
+ public/pw_foo/baz.h
+
+For headers that must be exposed due to C++ limitations (i.e. are included from
+the public interface, but are not intended for use), place the headers in a
+``internal`` subfolder under the public headers directory; as
+``public/<module>/internal/*.h``. For example:
+
+.. code-block::
+
+ pw_foo/...
+ public/pw_foo/internal/secret.h
+ public/pw_foo/internal/business.h
+
+.. note::
+
+ These headers must not override headers from other modules. For
+ that, there is the ``public_overrides/`` directory.
+
+Public override headers - ``public_overrides/<module>``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+In general, the Pigweed philosophy is to avoid having "things hiding under
+rocks", and having header files with the same name that can override each other
+is considered a rock where surprising things can hide. Additionally, a design
+goal of the Pigweed module structure is to make it so there is ideally exactly
+one obvious place to find a header based on an ``#include``.
+
+However, in some cases header overrides are necessary to enable flexibly
+combining modules. To make this as explicit as possible, headers which override
+other headers must go in
+
+``<module>/public_overrides/...```
+
+For example, the ``pw_unit_test`` module provides a header override for
+``gtest/gtest.h``. The structure of the module is (omitting some files):
+
+.. code-block::
+
+ pw_unit_test/...
+
+ public_overrides/gtest
+ public_overrides/gtest/gtest.h
+
+ public/pw_unit_test
+ public/pw_unit_test/framework.h
+ public/pw_unit_test/simple_printing_event_handler.h
+ public/pw_unit_test/event_handler.h
+
+Note that the overrides are in a separate directory ``public_overrides``.
+
+Public override headers - ``public_overrides/<module>``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+C++ implementation files go at the top level of the module. Implementation files
+must always use "" style includes.
+
+Example:
+
+.. code-block::
+
+ pw_unit_test/...
+ main.cc
+ framework.cc
+ test.gni
+ BUILD.gn
+ README.md
+
+Documentation
+~~~~~~~~~~~~~
+Documentation should go in the root module folder, typically in the
+``docs.rst`` file. There must be a docgen entry for the documentation in the
+``BUILD.gn`` file with the target name ``docs``; so the full target for the
+docs would be ``<module>:docs``.
+
+.. code-block::
+
+ pw_example_module/...
+
+ docs.rst
+
+For modules with more involved documentation, create a separate directory
+called ``docs/`` under the module root, and put the ``.rst`` files and other
+related files (like images and diagrams) there.
+
+.. code-block::
+
+ pw_example_module/...
+
+ docs/docs.rst
+ docs/bar.rst
+ docs/foo.rst
+ docs/image/screenshot.png
+ docs/image/diagram.svg
+
+Command: ``pw module-check``
+----------------------------
+
+The ``pw module-check`` command exists to ensure that your module conforms to
+the Pigweed module norms.
+
+For example, at time of writing ``pw module-check pw_module`` is not passing
+its own lint:
+
+.. code-block:: none
+
+ $ pw module-check pw_module
+
+ ▒█████▄ █▓ ▄███▒ ▒█ ▒█ ░▓████▒ ░▓████▒ ▒▓████▄
+ ▒█░ █░ ░█▒ ██▒ ▀█▒ ▒█░ █ ▒█ ▒█ ▀ ▒█ ▀ ▒█ ▀█▌
+ ▒█▄▄▄█░ ░█▒ █▓░ ▄▄░ ▒█░ █ ▒█ ▒███ ▒███ ░█ █▌
+ ▒█▀ ░█░ ▓█ █▓ ░█░ █ ▒█ ▒█ ▄ ▒█ ▄ ░█ ▄█▌
+ ▒█ ░█░ ░▓███▀ ▒█▓▀▓█░ ░▓████▒ ░▓████▒ ▒▓████▀
+
+ 20191205 17:05:19 INF Checking module: pw_module
+ 20191205 17:05:19 ERR PWCK005: Missing ReST documentation; need at least e.g. "docs.rst"
+ 20191205 17:05:19 ERR FAIL: Found errors when checking module pw_module
+
+