Anastasia Klimchuk submitted this change.

View Change

Approvals: Anastasia Klimchuk: Looks good to me, approved build bot (Jenkins): Verified
doc: autogenerate a list of authors and hall of fame

This adds a build-time option to automatically generate a list of
authors from git history, and includes it in the documentation by
reading the output from git in a Sphinx extension. When git isn't
available or the project source doesn't appear to be a git checkout, the
list is not generated and gracefully replaced with a message explaining
its absence.

Change-Id: I1e9634a90e84262aafd80590deba9875f4b71a3c
Signed-off-by: Peter Marheine <pmarheine@chromium.org>
Reviewed-on: https://review.coreboot.org/c/flashrom/+/86350
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Anastasia Klimchuk <aklm@chromium.org>
---
A doc/_ext/.gitignore
A doc/_ext/flashrom_authors.py
A doc/about_flashrom/hall_of_fame.rst
M doc/about_flashrom/index.rst
M doc/classic_cli_manpage.rst
A doc/collect-authors.sh
M doc/conf.py
M doc/dev_guide/building_from_source.rst
M doc/how_to_support_flashrom.rst
M doc/meson.build
M doc/release_notes/devel.rst
M meson_options.txt
12 files changed, 278 insertions(+), 12 deletions(-)

diff --git a/doc/_ext/.gitignore b/doc/_ext/.gitignore
new file mode 100644
index 0000000..5ec9334
--- /dev/null
+++ b/doc/_ext/.gitignore
@@ -0,0 +1,2 @@
+# Python bytecode cache generated on module import
+/__pycache__/
\ No newline at end of file
diff --git a/doc/_ext/flashrom_authors.py b/doc/_ext/flashrom_authors.py
new file mode 100644
index 0000000..f160d21
--- /dev/null
+++ b/doc/_ext/flashrom_authors.py
@@ -0,0 +1,82 @@
+from docutils import nodes
+from pathlib import Path
+from typing import TYPE_CHECKING
+
+from sphinx.application import Sphinx
+from sphinx.util.docutils import SphinxDirective
+
+if TYPE_CHECKING:
+ from sphinx.util.typing import ExtensionMetadata
+
+
+class FlashromAuthorsDirective(SphinxDirective):
+ required_arguments = 1
+ has_content = True
+
+ def make_table(self, list_file: Path):
+ body = nodes.tbody()
+ with list_file.open("r") as f:
+ for line in f:
+ count, _, name = line.strip().partition("\t")
+
+ body += nodes.row(
+ "",
+ nodes.entry("", nodes.paragraph(text=name)),
+ nodes.entry("", nodes.paragraph(text=count)),
+ )
+
+ return nodes.table(
+ "",
+ nodes.tgroup(
+ "",
+ nodes.colspec(colname="name"),
+ nodes.colspec(colname="count"),
+ nodes.thead(
+ "",
+ nodes.row(
+ "",
+ nodes.entry("", nodes.paragraph(text="Name")),
+ nodes.entry("", nodes.paragraph(text="Number of changes")),
+ ),
+ ),
+ body,
+ cols=2,
+ ),
+ )
+
+ def make_placeholder(self, contents):
+ return nodes.admonition(
+ "",
+ nodes.title("", text="List not available"),
+ *contents,
+ )
+
+ def run(self) -> list[nodes.Node]:
+ config = self.config.flashrom_authors_list_files
+
+ source_name = self.arguments[0]
+ list_file = (config or {}).get(source_name)
+ if list_file is None:
+ if config is not None:
+ available_names = ','.join(config.keys())
+ raise self.error(
+ 'Undefined authors list file: "{}" (available names: {})'.format(
+ source_name, available_names
+ )
+ )
+ container = nodes.Element()
+ self.state.nested_parse(self.content, 0, container)
+ return [self.make_placeholder(container.children)]
+ else:
+ return [self.make_table(Path(list_file))]
+
+
+def setup(app: Sphinx) -> 'ExtensionMetadata':
+ app.add_config_value(
+ "flashrom_authors_list_files", default=None, rebuild="html", types=[dict]
+ )
+ app.add_directive("flashrom-authors", FlashromAuthorsDirective)
+
+ return {
+ "version": "1",
+ }
diff --git a/doc/about_flashrom/hall_of_fame.rst b/doc/about_flashrom/hall_of_fame.rst
new file mode 100644
index 0000000..88f2728
--- /dev/null
+++ b/doc/about_flashrom/hall_of_fame.rst
@@ -0,0 +1,57 @@
+============
+Hall of Fame
+============
+
+This is the flashrom project's hall of fame, where we credit everybody who
+has contributed to flashrom's code in the past.
+
+Based on the Git history (dating back to 2002!), this page separately lists all
+:ref:`authors <authors>` and :ref:`reviewers <reviewers>` where each line
+lists a person's name and how many commits they are credited for. [#svn]_
+
+flashrom is alive and running because of you all, the people who during all
+these years (and decades!) give their time, energy, knowledge, and a piece of
+their heart to flashrom. The project is what we all are creating together.
+
+**Thank you everyone so much!**
+
+.. _authors:
+
+Authors
+=======
+
+The people listed here are those credited as the author or a co-author (as
+in ``Co-authored-by`` or ``Co-developed-by``) of at least one Git commit in
+flashrom.
+
+.. flashrom-authors:: authors
+
+ This copy of the flashrom documentation was built without
+ generating the list of authors. To generate it, ensure
+ the :code:`generate_authors_list`
+ :ref:`Meson option <meson_configuration>` is enabled when
+ building.
+
+.. _reviewers:
+
+Reviewers
+=========
+
+The people listed here are those credited as a reviewer (``Reviewed-by``)
+of at least one Git commit in flashrom.
+
+We very much appreciate flashrom code reviews; you can read more about it
+in our :ref:`code review documentation <support-code-reviews>`.
+
+.. flashrom-authors:: reviewers
+
+ This copy of the flashrom documentation was built without
+ generating the list of reviewers. To generate it, ensure
+ the :code:`generate_authors_list`
+ :ref:`Meson option <meson_configuration>` is enabled when
+ building.
+
+.. [#svn] Data for contributions prior to 2017 may be inaccurate or missing,
+ because flashrom used SVN rather than Git prior to then and old metadata might
+ not be in a format that is understood by the scripts that automatically generate
+ this page.
diff --git a/doc/about_flashrom/index.rst b/doc/about_flashrom/index.rst
index 143c7b6..753a19d 100644
--- a/doc/about_flashrom/index.rst
+++ b/doc/about_flashrom/index.rst
@@ -5,5 +5,6 @@
:maxdepth: 1

team
+ hall_of_fame
code_of_conduct
privacy_policy
diff --git a/doc/classic_cli_manpage.rst b/doc/classic_cli_manpage.rst
index af897a0..243cf4f 100644
--- a/doc/classic_cli_manpage.rst
+++ b/doc/classic_cli_manpage.rst
@@ -1565,14 +1565,12 @@
AUTHORS
-------

-Andrew Morgan, Anastasia Klimchuk, Carl-Daniel Hailfinger, Claus Gindhart, David Borg, David Hendricks, Dominik Geyer,
-Edward O'Callaghan, Eric Biederman, Giampiero Giancipoli, Helge Wagner, Idwer Vollering, Joe Bao, Joerg Fischer,
-Joshua Roys, Kyösti Mälkki, Luc Verhaegen, Li-Ta Lo, Mark Marshall, Markus Boas, Mattias Mattsson, Michael Karcher,
-Nikolay Petukhov, Patrick Georgi, Peter Lemenkov, Peter Stuge, Reinder E.N. de Haan, Ronald G. Minnich, Ronald Hoogenboom,
-Sean Nelson, Stefan Reinauer, Stefan Tauner, Stefan Wildemann, Stephan Guilloux, Steven James, Urja Rannikko, Uwe Hermann,
-Wang Qingpei, Yinghai Lu and others, please see the **flashrom** git history for details.
+More than 350 authors have contributed to Flashrom over its life. Each individual
+is credited in the `hall of fame <https://flashrom.org/about_flashrom/hall_of_fame.html>`_,
+or author metadata can be found in the git history.

All still active authors can be reached via `the mailing list <flashrom\@flashrom.org>`_.

-This manual page was written by `Uwe Hermann <uwe\@hermann-uwe.de>`_, Carl-Daniel Hailfinger, Stefan Tauner and others.
-It is licensed under the terms of the GNU GPL (version 2 or later).
+This manual page was written by `Uwe Hermann <uwe\@hermann-uwe.de>`_,
+Carl-Daniel Hailfinger, Stefan Tauner and others. It is licensed under the
+terms of the GNU GPL (version 2 or later).
diff --git a/doc/collect-authors.sh b/doc/collect-authors.sh
new file mode 100644
index 0000000..96db87c
--- /dev/null
+++ b/doc/collect-authors.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+if [ $# -ne 3 ]
+then
+ echo "Wrong number of arguments. Usage: $0 [authors|reviewers] outfile git_dir" >&2
+ exit 1
+fi
+
+case "$1" in
+ authors)
+ GROUP_ARGS="--group=author --group=trailer:Co-Authored-by --group=trailer:Co-Developed-by"
+ ;;
+ reviewers)
+ GROUP_ARGS="--group=trailer:Reviewed-by"
+ ;;
+ *)
+ echo "Unknown contributor kind: \"$1\"" >&2
+ exit 1
+ ;;
+esac
+OUTFILE="$2"
+# GIT_DIR is passed explicitly so we never need to guess where
+# the source directory is. It may be somewhere entirely different
+# from where meson is running us.
+GIT_DIR="$3"
+
+if ! command -v git >/dev/null
+then
+ echo "git not available" >&2
+ exit 1
+fi
+
+if [ ! -d "$GIT_DIR" ]
+then
+ echo "GIT_DIR ($GIT_DIR) does not exist" >&2
+ exit 1
+fi
+
+git --no-pager --git-dir="$GIT_DIR" shortlog --summary --numbered $GROUP_ARGS HEAD > "$OUTFILE"
diff --git a/doc/conf.py b/doc/conf.py
index be9cc01..b7fb2d4 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -3,7 +3,13 @@
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

-import os
+import sys
+
+from pathlib import Path
+
+
+sys.path.append(str(Path('_ext').resolve()))
+

# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
@@ -18,7 +24,8 @@
master_doc = 'index' # this is needed for old versions

extensions = [
- 'sphinx.ext.todo'
+ 'sphinx.ext.todo',
+ 'flashrom_authors'
]

#templates_path = ['_templates']
diff --git a/doc/dev_guide/building_from_source.rst b/doc/dev_guide/building_from_source.rst
index a8521ce..2394767 100644
--- a/doc/dev_guide/building_from_source.rst
+++ b/doc/dev_guide/building_from_source.rst
@@ -216,8 +216,11 @@
.. todo:: Add building instructions for libpayload


+.. _meson_configuration:
+
Configuration
-------------
+
In the flashrom repository run::

meson setup [builtin options] [flashrom options] <builddir>
diff --git a/doc/how_to_support_flashrom.rst b/doc/how_to_support_flashrom.rst
index 7fdfdf8..bb5cdaa 100644
--- a/doc/how_to_support_flashrom.rst
+++ b/doc/how_to_support_flashrom.rst
@@ -39,6 +39,8 @@

For some types of contributions we have more detailed guidelines, check the list :doc:`/contrib_howtos/index`.

+.. _support-code-reviews:
+
Code reviews
============

diff --git a/doc/meson.build b/doc/meson.build
index 5bc57b9..ff1e7bc 100644
--- a/doc/meson.build
+++ b/doc/meson.build
@@ -1,6 +1,6 @@
-
sphinx = find_program('sphinx-build', native : true, required : get_option('man-pages').enabled() or get_option('documentation').enabled())
sphinx_wrapper = meson.current_source_dir() / 'sphinx-wrapper.sh'
+collect_authors = meson.current_source_dir() / 'collect-authors.sh'

man_pages = [
'flashrom.8'
@@ -24,9 +24,67 @@
endif

if get_option('documentation').auto() or get_option('documentation').enabled()
+
+ with_authors_list = get_option('generate_authors_list')
+ git = find_program('git', native : true, required : with_authors_list)
+ git_dir = meson.project_source_root() / '.git'
+
+ # When with_authors_list is requested, unsatisfied requirements are an error.
+ if with_authors_list.enabled()
+ if not git.found()
+ error('generate_authors_list was force-enabled but git is not available')
+ endif
+ if not fs.is_dir(git_dir)
+ error('generate_authors_list was force-enabled but a .git directory was not found in the source tree')
+ endif
+ endif
+
+ if (
+ (with_authors_list.enabled() or with_authors_list.auto())
+ and git.found() and fs.is_dir(git_dir)
+ )
+ # If requirements are met and authors list is allowed, generate it.
+ authors_lst = custom_target(
+ 'authors_lst',
+ output : 'authors.lst',
+ command : [collect_authors, 'authors', '@OUTPUT0@', git_dir],
+ )
+ reviewers_lst = custom_target(
+ 'reviewers_lst',
+ output : 'reviewers.lst',
+ command : [collect_authors, 'reviewers', '@OUTPUT0@', git_dir],
+ )
+ authors_list_options = [
+ '-Dflashrom_authors_list_files.authors=' + authors_lst.full_path(),
+ '-Dflashrom_authors_list_files.reviewers=' + reviewers_lst.full_path(),
+ ]
+ doc_depends = [authors_lst, reviewers_lst]
+ else
+ # Disabled or prerequisites not met. Continue without the authors list.
+ # Checks earlier in this file will raise an error if the feature is enabled
+ # but the prerequisites aren't met.
+ authors_list_options = []
+ doc_depends = []
+
+ if with_authors_list.auto()
+ # Explain what wasn't satisfied to help the user understand why
+ # the authors list is missing.
+ if not git.found()
+ message('git not found; will not generate authors list')
+ elif not fs.is_dir(git_dir)
+ message('.git directory not found in project; will not generate authors list')
+ endif
+ endif
+ endif
+
custom_target(
'documentation',
- command : [sphinx, '-b', 'html', '-q', '-d', '@PRIVATE_DIR@', '-Drelease=' + flashrom_version,'@CURRENT_SOURCE_DIR@', '@OUTDIR@/html'],
+ command : [
+ sphinx, '-b', 'html', '-q', '-d', '@PRIVATE_DIR@',
+ '-Drelease=' + flashrom_version,
+ '@CURRENT_SOURCE_DIR@', '@OUTDIR@/html'
+ ] + authors_list_options,
+ depends : doc_depends,
build_always_stale : true, # sphinx handles rebuilds
output : 'html',
install : true,
diff --git a/doc/release_notes/devel.rst b/doc/release_notes/devel.rst
index 05fe4a0..62dffb0 100644
--- a/doc/release_notes/devel.rst
+++ b/doc/release_notes/devel.rst
@@ -35,3 +35,19 @@
-------------------------------------------

See :doc:`/classic_cli_manpage` for details.
+
+Hall of Fame added to documentation
+-----------------------------------
+
+The flashrom HTML documentation (and web site) now includes an
+automatically-generated list of historical contributors, to acknowledge
+everybody who has made flashrom into what it is:
+:doc:`../about_flashrom/hall_of_fame`.
+
+When building the documentation, the ``generate_authors_list`` Meson option will
+cause the lists to be generated, requiring a runnable copy of Git on the system
+and that the source tree being built is a Git working copy. If those
+requirements are not satisfied or the option is disabled, the authors lists will
+be replaced with placeholders unless the ``generate_authors_list`` option is set
+to ``enabled`` in which case the build will fail if the requirements are not
+satisfied.
diff --git a/meson_options.txt b/meson_options.txt
index 87456a9..318a419 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -19,6 +19,7 @@
option('llvm_cov', type : 'feature', value : 'disabled', description : 'build for llvm code coverage')
option('man-pages', type : 'feature', value : 'auto', description : 'build the man-page for classic_cli')
option('documentation', type : 'feature', value : 'auto', description : 'build the html documentation')
+option('generate_authors_list', type : 'feature', value : 'auto', description : 'include automatically-generated lists of authors in the HTML documentation')
option('ni845x_search_path', type : 'string', value : 'C:\Program Files (x86)\National Instruments\Ni-845x\MS Visual C',
description : 'Path to search for the proprietary ni845x library and header (32-bit Windows only)')
option('delay_minimum_sleep_us', type : 'integer', min : 0, value : 100,

To view, visit change 86350. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: merged
Gerrit-Project: flashrom
Gerrit-Branch: main
Gerrit-Change-Id: I1e9634a90e84262aafd80590deba9875f4b71a3c
Gerrit-Change-Number: 86350
Gerrit-PatchSet: 14
Gerrit-Owner: Peter Marheine <pmarheine@chromium.org>
Gerrit-Reviewer: Anastasia Klimchuk <aklm@chromium.org>
Gerrit-Reviewer: Patrick Georgi <patrick@coreboot.org>
Gerrit-Reviewer: build bot (Jenkins) <no-reply@coreboot.org>