Skip to content

Commit

Permalink
generate toml for reference-docs (pantsbuild#19718)
Browse files Browse the repository at this point in the history
Fixes pantsbuild#19705.

Adds a `toml` snippet to each configuration option in the reference.

Not quite sure how to validate this across the hundreds of files
generated -- I've looked at a few ones for examples of enums, bools,
lists, maps, and scalars. Not sure what other fun things might happen,
or what kind of weird setup might exist in other places.

Open questions:
- Should each config add the header? I think *yes* for clarity, but it
does add a *lot* of extra lines to some pages.

---
<img width="518" alt="image"
src="https://github.com/pantsbuild/pants/assets/8234817/645e2942-26a2-4b3a-9460-c1565b106d28">
<img width="492" alt="image"
src="https://github.com/pantsbuild/pants/assets/8234817/58c5bef0-a84c-4fbf-a92f-7d3236f74e99">
<img width="817" alt="image"
src="https://github.com/pantsbuild/pants/assets/8234817/6fc14e14-e884-4ecb-9618-9e20467fef11">
tgolsson authored Sep 1, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent e658334 commit a103211
Showing 2 changed files with 65 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -4,6 +4,11 @@

<code>{{comma_separated_display_args}}</code><br>
<code>{{env_var}}</code><br>
{{#toml}}
```toml pants.toml
{{{toml}}}
```
{{/toml}}
</div>
<div style="padding-left: 2em;">
{{#comma_separated_choices}}
@@ -22,4 +27,3 @@ Can be overriden by field `{{target_field_name}}` on `local_environment`, `docke
{{/target_field_name}}
</div>
<br>

65 changes: 60 additions & 5 deletions build-support/bin/generate_docs.py
Original file line number Diff line number Diff line change
@@ -320,6 +320,59 @@ def _link(scope: str, *, sync: bool) -> str:
url_safe_scope = scope.replace(".", "-")
return f"reference-{url_safe_scope}" if sync else f"{url_safe_scope}.md"

@staticmethod
def _generate_toml_snippet(option_data, scope) -> str:
"""Generate TOML snippet for a single option."""

# Generate a toml block for the option to help users fill out their `pants.toml`. For
# scalars and arrays, we put them inline directly in the scope, while for maps we put
# them in a nested table. Since the metadata doesn't contain type info, we'll need to
# parse command line args a bit.

if not option_data.get("config_key", None):
# This option is not configurable.
return ""

toml_lines = []
example_cli = option_data["display_args"][0]
config_key = option_data["config_key"]

if "[no-]" in example_cli:
val = "<bool>"
else:
_, val = example_cli.split("=", 1)

is_map = val.startswith('"{') and val.endswith('}"')
is_array = val.startswith('"[') and val.endswith(']"')
if is_map:
toml_lines.append(f"[{scope}.{config_key}]")
val = val[2:-2] # strip the quotes and brackets

pairs = val.split(", ")
for pair in pairs:
if ":" in pair:
k, v = pair.split(": ", 1)
if k.startswith('"') or k.startswith("'"):
k = k[1:-1]

toml_lines.append(f"{k} = {v}")
else:
# generally just the trailing ...
toml_lines.append(pair)

elif is_array:
toml_lines.append(f"[{scope}]")
toml_lines.append(f"{config_key} = [")
val = val[2:-2]
for item in val.split(", "):
toml_lines.append(f" {item},")
toml_lines.append("]")
else:
toml_lines.append(f"[{scope}]")
toml_lines.append(f"{config_key} = {val}")

return "\n".join(toml_lines)

@classmethod
def process_options_input(cls, help_info: dict[str, Any], *, sync: bool) -> dict:
scope_to_help_info = help_info["scope_to_help_info"]
@@ -342,7 +395,7 @@ def process_options_input(cls, help_info: dict[str, Any], *, sync: bool) -> dict

# Process the option data.

def munge_option(option_data):
def munge_option(option_data, scope):
# Munge the default so we can display it nicely when it's multiline, while
# still displaying it inline if it's not.
default_help_repr = option_data.get("default_help_repr")
@@ -369,13 +422,15 @@ def munge_option(option_data):
else:
option_data["marked_up_default"] = f"<code>{escaped_default_str}</code>"

for shi in scope_to_help_info.values():
option_data["toml"] = cls._generate_toml_snippet(option_data, scope)

for scope, shi in scope_to_help_info.items():
for opt in shi["basic"]:
munge_option(opt)
munge_option(opt, scope)
for opt in shi["advanced"]:
munge_option(opt)
munge_option(opt, scope)
for opt in shi["deprecated"]:
munge_option(opt)
munge_option(opt, scope)

return help_info

0 comments on commit a103211

Please sign in to comment.