docs: Simplify module creation docs using script
Change-Id: I894d7bc2509d184aea47041ee822b646e66bc9fb
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/200231
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Alexei Frolov <frolv@google.com>
Pigweed-Auto-Submit: Taylor Cramer <cramertj@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed-service-accounts.iam.gserviceaccount.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 973e71b..ef60866 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -76,8 +76,8 @@
add_subdirectory(pw_assert_zephyr EXCLUDE_FROM_ALL)
add_subdirectory(pw_async EXCLUDE_FROM_ALL)
add_subdirectory(pw_async_basic EXCLUDE_FROM_ALL)
-add_subdirectorY(pw_async2 EXCLUDE_FROM_ALL)
-add_subdirectorY(pw_async2_basic EXCLUDE_FROM_ALL)
+add_subdirectory(pw_async2 EXCLUDE_FROM_ALL)
+add_subdirectory(pw_async2_basic EXCLUDE_FROM_ALL)
add_subdirectory(pw_base64 EXCLUDE_FROM_ALL)
add_subdirectory(pw_blob_store EXCLUDE_FROM_ALL)
add_subdirectory(pw_bluetooth EXCLUDE_FROM_ALL)
diff --git a/docs/module_structure.rst b/docs/module_structure.rst
index 3ca2dad..80cf5aa 100644
--- a/docs/module_structure.rst
+++ b/docs/module_structure.rst
@@ -549,7 +549,8 @@
Creating a new Pigweed module
-----------------------------
-To create a new Pigweed module, follow the below steps.
+New Pigweed modules can be easily created using
+``pw module create MODULE_NAME`` (refer to the `Module name`_ guidelines).
.. tip::
@@ -560,45 +561,28 @@
accidentally duplicating work, or avoiding writing code that won't get
accepted.
-1. Create module folder following `Module name`_ guidelines.
-2. Add `C++ public headers`_ files in
+This command will create a folder with the provided module name as well as a
+number of basic build files. After this command has run, new code should be
+added in the following locations:
+
+1. Add `C++ public headers`_ files in
``{pw_module_dir}/public/{pw_module_name}/``
-3. Add `C++ implementation files`_ files in ``{pw_module_dir}/``
-4. Add module documentation
+2. Add `C++ implementation files`_ files in ``{pw_module_dir}/``
+3. Add module documentation to ``{pw_module_dir}/docs.rst``. See
+ :ref:`seed-0102` for additional documentation options.
+4. Add GN build targets to ``{pw_module_dir}/BUILD.gn``.
- - Add ``{pw_module_dir}/README.md`` that has a module summary
- - Add ``{pw_module_dir}/docs.rst`` that contains the main module
- documentation
- - Add optional documentation as described in :ref:`seed-0102`
+ - Add new ``pw_test`` targets to the list in ``pw_test_group("tests")``.
+ - Add any additional ``.rst`` documentation files to
+ ``pw_docs_group("docs")``.
-5. Add GN build support in ``{pw_module_dir}/BUILD.gn``
+5. Add Bazel build targets to ``{pw_module_dir}/BUILD.bazel``.
- - Declare tests in ``pw_test_group("tests")``
- - Declare docs in ``pw_docs_group("docs")``
+6. Add CMake build targets to ``{pw_module_dir}/CMakeLists.txt``.
- Both ``tests`` and ``docs`` are required, even if the module is empty!
-
-6. Add Bazel build support in ``{pw_module_dir}/BUILD.bazel``
-
-7. Add CMake build support in ``{pw_module_dir}/CMakeLists.txt``
-
-8. Add the new module to the ``/PIGWEED_MODULES`` list
-
- Modules must be listed one per line with no extra spaces or comments. This
- automatically adds the new module, its tests, and its docs, to the GN build.
-
-9. Update the generated Pigweed modules lists file
-
- .. code-block:: bash
-
- ninja -C out update_modules
-
-10. Add the new module to CMake build
-
- - In ``/CMakeLists.txt`` add ``add_subdirectory(pw_new)``
-
-11. Run :ref:`module-pw_module-module-check`
+7. Run :ref:`module-pw_module-module-check` to ensure that the new module has
+ been properly configured.
- ``$ pw module check {pw_module_dir}``
-12. Contribute your module to upstream Pigweed (optional but encouraged!)
+8. Contribute your module to upstream Pigweed (optional but encouraged!)
diff --git a/pw_module/py/pw_module/create.py b/pw_module/py/pw_module/create.py
index df626b4..ce24ed0 100644
--- a/pw_module/py/pw_module/create.py
+++ b/pw_module/py/pw_module/create.py
@@ -808,6 +808,8 @@
) -> _ModuleContext:
"""Creates the basic layout of a Pigweed module."""
module_dir.mkdir()
+ public_dir = module_dir / 'public' / module_name.full
+ public_dir.mkdir(parents=True)
ctx = _ModuleContext(
name=module_name,
@@ -827,6 +829,72 @@
return ctx
+def _add_to_pigweed_modules_file(
+ project_root: Path,
+ module_name: _ModuleName,
+) -> None:
+ modules_file = project_root / 'PIGWEED_MODULES'
+ if not modules_file.exists():
+ _LOG.error(
+ 'Could not locate PIGWEED_MODULES file; '
+ 'your repository may be in a bad state.'
+ )
+ return
+
+ modules_gni_file = (
+ project_root / 'pw_build' / 'generated_pigweed_modules_lists.gni'
+ )
+
+ # Cut off the extra newline at the end of the file.
+ modules_list = modules_file.read_text().split('\n')[:-1]
+ modules_list.append(module_name.full)
+ modules_list.sort()
+ modules_list.append('')
+ modules_file.write_text('\n'.join(modules_list))
+ print(' modify ' + str(modules_file.relative_to(Path.cwd())))
+
+ generate_modules_lists.main(
+ root=project_root,
+ modules_list=modules_file,
+ modules_gni_file=modules_gni_file,
+ mode=generate_modules_lists.Mode.UPDATE,
+ )
+ print(' modify ' + str(modules_gni_file.relative_to(Path.cwd())))
+
+
+def _add_to_root_cmakelists(
+ project_root: Path,
+ module_name: _ModuleName,
+) -> None:
+ new_line = f'add_subdirectory({module_name.full} EXCLUDE_FROM_ALL)\n'
+
+ path = project_root / 'CMakeLists.txt'
+ if not path.exists():
+ _LOG.error('Could not locate root CMakeLists.txt file.')
+ return
+
+ lines = []
+ with path.open() as f:
+ lines = f.readlines()
+
+ add_subdir_start = 0
+ while add_subdir_start < len(lines):
+ if lines[add_subdir_start].startswith('add_subdirectory'):
+ break
+ add_subdir_start += 1
+
+ insert_point = add_subdir_start
+ while (
+ lines[insert_point].startswith('add_subdirectory')
+ and lines[insert_point] < new_line
+ ):
+ insert_point += 1
+
+ lines.insert(insert_point, new_line)
+ path.write_text(''.join(lines))
+ print(' modify ' + str(path.relative_to(Path.cwd())))
+
+
def _create_module(
module: str, languages: Iterable[str], build_systems: Iterable[str]
) -> None:
@@ -876,33 +944,9 @@
build_file.write()
if is_upstream:
- modules_file = project_root / 'PIGWEED_MODULES'
- if not modules_file.exists():
- _LOG.error(
- 'Could not locate PIGWEED_MODULES file; '
- 'your repository may be in a bad state.'
- )
- return
-
- modules_gni_file = (
- project_root / 'pw_build' / 'generated_pigweed_modules_lists.gni'
- )
-
- # Cut off the extra newline at the end of the file.
- modules_list = modules_file.read_text().split('\n')[:-1]
- modules_list.append(module_name.full)
- modules_list.sort()
- modules_list.append('')
- modules_file.write_text('\n'.join(modules_list))
- print(' modify ' + str(modules_file.relative_to(Path.cwd())))
-
- generate_modules_lists.main(
- root=project_root,
- modules_list=modules_file,
- modules_gni_file=modules_gni_file,
- mode=generate_modules_lists.Mode.UPDATE,
- )
- print(' modify ' + str(modules_gni_file.relative_to(Path.cwd())))
+ _add_to_pigweed_modules_file(project_root, module_name)
+ if 'cmake' in build_systems:
+ _add_to_root_cmakelists(project_root, module_name)
print()
_LOG.info(
@@ -921,9 +965,9 @@
'Comma-separated list of build systems the module supports. '
f'Options: {", ".join(_BUILD_FILES.keys())}'
),
- type=csv,
+ choices=_BUILD_FILES.keys(),
default=_BUILD_FILES.keys(),
- metavar='BUILD[,BUILD,...]',
+ type=csv,
)
parser.add_argument(
'--languages',
@@ -931,9 +975,9 @@
'Comma-separated list of languages the module will use. '
f'Options: {", ".join(_LANGUAGE_GENERATORS.keys())}'
),
- type=csv,
+ choices=_LANGUAGE_GENERATORS.keys(),
default=[],
- metavar='LANG[,LANG,...]',
+ type=csv,
)
parser.add_argument(
'module', help='Name of the module to create.', metavar='MODULE_NAME'