Skip to content

Commit e7cf60f

Browse files
committed
docs(website): generate the policy page's count and list of refused defaults
The choices table's count and the list of known differences the defaults refuse come from the policy, as the quickstart's do, so no count or name of a default is written by hand.
1 parent 95c721e commit e7cf60f

2 files changed

Lines changed: 78 additions & 9 deletions

File tree

‎website/scripts/generate_known_differences.py‎

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
between the generated markers of `website/src/content/docs/docs/known-differences.mdx`: first the
77
ones that can return a different value, then the ones that raise an error instead, by area. It also
88
writes the `[allow]` example on `website/src/content/docs/docs/policy.mdx` that refuses each one the
9-
defaults allow that can return a different value, and the sentence on
10-
`website/src/content/docs/docs/quickstart.mdx` naming the ones the defaults refuse. With `--check`
11-
it writes nothing and exits 1 when a page differs from what the entries give.
9+
defaults allow that can return a different value, that page's count and list of the ones the
10+
defaults refuse, and the sentence on `website/src/content/docs/docs/quickstart.mdx` naming them.
11+
With `--check` it writes nothing and exits 1 when a page differs from what the entries give.
1212
1313
Usage: python3 scripts/generate_known_differences.py [--check] (from website/)
1414
"""
@@ -46,7 +46,21 @@
4646
" defaults refuse. */}"
4747
)
4848
REFUSED_END = "{/* End of the generated defaults. */}"
49+
COUNT_BEGIN = "{/* Generated: how many the defaults refuse. */}"
50+
COUNT_END = "{/* End of the generated count. */}"
51+
DEFAULTS_BEGIN = (
52+
"{/* Generated by website/scripts/generate_known_differences.py: the known differences the\n"
53+
" defaults refuse, and why. */}"
54+
)
55+
DEFAULTS_END = "{/* End of the generated list of refused defaults. */}"
4956
NUMBERS = "no one two three four five six seven eight nine ten eleven twelve".split()
57+
# Why the defaults refuse a known difference, where it isn't that its values can differ.
58+
REFUSED_UNTIL = {
59+
"project_udf": (
60+
"until `python_runtime = true` under `[project]` says a Python runtime registers\n"
61+
" the project's functions."
62+
),
63+
}
5064

5165
CONSTANT = re.compile(r"pub const (\w+): &str =\s*" + STRING + r";", re.S)
5266
ENTRY = re.compile(r"KnownDifference \{(.*?)\}", re.S)
@@ -195,16 +209,64 @@ def refuse_allowed(known: list[dict[str, str]], default: dict[str, str]) -> list
195209
return [ALLOW_BEGIN, "", "```toml", "[allow]", *refusals, "```", "", ALLOW_END]
196210

197211

212+
def refused(known: list[dict[str, str]], default: dict[str, str]) -> list[dict[str, str]]:
213+
"""The entries the defaults refuse, in table order."""
214+
return [entry for entry in known if default[entry["name"]] == "refused"]
215+
216+
217+
def number(count: int) -> str:
218+
"""A count in words, as the pages write it."""
219+
return NUMBERS[count] if count < len(NUMBERS) else str(count)
220+
221+
222+
def listed(names: list[str]) -> str:
223+
"""Names in code, as `a`, `b` and `c`."""
224+
names = [f"`{name}`" for name in names]
225+
return ", ".join(names[:-1]) + f" and {names[-1]}" if len(names) > 1 else "".join(names)
226+
227+
228+
def refused_count(known: list[dict[str, str]], default: dict[str, str]) -> list[str]:
229+
"""How many the defaults refuse, in words, inline in the policy page's choices table."""
230+
return [COUNT_BEGIN + number(len(refused(known, default))) + COUNT_END]
231+
232+
233+
def refused_list(known: list[dict[str, str]], default: dict[str, str]) -> list[str]:
234+
"""The policy page's list of the known differences the defaults refuse, and why."""
235+
names = [entry["name"] for entry in refused(known, default)]
236+
stray = sorted(set(REFUSED_UNTIL) - set(names))
237+
if stray:
238+
raise SystemExit(f"REFUSED_UNTIL in {__file__} names ones the defaults allow: {stray}")
239+
by_value = sorted(name for name in names if name not in REFUSED_UNTIL)
240+
loud = [
241+
e["name"] for e in known if e["name"] in by_value and e["failure"] != FAILS_WITH["Value"]
242+
]
243+
if loud:
244+
raise SystemExit(f"{loud} are refused but only raise an error; give each a REFUSED_UNTIL")
245+
lines = [
246+
DEFAULTS_BEGIN,
247+
"",
248+
f"The defaults allow every known difference except these {number(len(names))}, which they"
249+
" refuse:",
250+
"",
251+
]
252+
if by_value:
253+
lines += [
254+
f"- {listed(by_value)}, whose values can differ",
255+
" from Snowflake's with no error.",
256+
]
257+
lines += [f"- `{name}`, {REFUSED_UNTIL[name]}" for name in names if name in REFUSED_UNTIL]
258+
return lines + ["", DEFAULTS_END]
259+
260+
198261
def refused_by_default(known: list[dict[str, str]], default: dict[str, str]) -> list[str]:
199262
"""A paragraph naming the known differences the defaults refuse."""
200-
names = [f"`{entry['name']}`" for entry in known if default[entry["name"]] == "refused"]
201-
listed = ", ".join(names[:-1]) + f" and {names[-1]}" if len(names) > 1 else "".join(names)
202-
count = NUMBERS[len(names)] if len(names) < len(NUMBERS) else str(len(names))
263+
names = [entry["name"] for entry in refused(known, default)]
203264
return [
204265
REFUSED_BEGIN,
205266
"",
206-
f"The defaults refuse {count} known difference{'' if len(names) == 1 else 's'},",
207-
f"{listed},",
267+
f"The defaults refuse {number(len(names))} known"
268+
f" difference{'' if len(names) == 1 else 's'},",
269+
f"{listed(names)},",
208270
"and allow the rest with a warning.",
209271
"[Can return a different value](/docs/known-differences/#can-return-a-different-value)",
210272
"lists the ones whose values can differ from Snowflake's with no error, and their",
@@ -225,6 +287,8 @@ def main(argv: list[str]) -> int:
225287
blocks = [
226288
(PAGE, BEGIN, END, table(known, default)),
227289
(POLICY_PAGE, ALLOW_BEGIN, ALLOW_END, refuse_allowed(known, default)),
290+
(POLICY_PAGE, COUNT_BEGIN, COUNT_END, refused_count(known, default)),
291+
(POLICY_PAGE, DEFAULTS_BEGIN, DEFAULTS_END, refused_list(known, default)),
228292
(QUICKSTART, REFUSED_BEGIN, REFUSED_END, refused_by_default(known, default)),
229293
]
230294
stale = 0

‎website/src/content/docs/docs/policy.mdx‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ When a statement needs a known difference, you choose what happens:
1818

1919
| Choice | What happens | How |
2020
|--------|--------------|-----|
21-
| [Refuse](#refuse) | The statement isn't converted. [`SQ0008`](/docs/diagnostics/reference/#sq0008) points at the construct. | `name = false` under `[allow]` in `sqlquack.toml`. The default for five. |
21+
| [Refuse](#refuse) | The statement isn't converted. [`SQ0008`](/docs/diagnostics/reference/#sq0008) points at the construct. | `name = false` under `[allow]` in `sqlquack.toml`. The default for {/* Generated: how many the defaults refuse. */}five{/* End of the generated count. */}. |
2222
| [Allow](#allow) | The statement converts. A warning names the known difference it relies on. | `name = true` under `[allow]`. The default for the rest. |
2323
| [Replace](#replace) | Calls to a Snowflake function use your own DuckDB SQL. | One file under `overrides/`. |
2424

@@ -49,13 +49,18 @@ sqlquack convert: refused, 1 refusal
4949
[project](/docs/project/)'s `sqlquack.toml`, or from the file `--config` names, on top of the
5050
defaults. Without one, they use the defaults alone.
5151

52+
{/* Generated by website/scripts/generate_known_differences.py: the known differences the
53+
defaults refuse, and why. */}
54+
5255
The defaults allow every known difference except these five, which they refuse:
5356

5457
- `hash`, `sequences`, `source_variant_json` and `variant_chain_type`, whose values can differ
5558
from Snowflake's with no error.
5659
- `project_udf`, until `python_runtime = true` under `[project]` says a Python runtime registers
5760
the project's functions.
5861

62+
{/* End of the generated list of refused defaults. */}
63+
5964
`sqlquack explain --differences` lists how the defaults and your `sqlquack.toml` treat each one.
6065

6166
`--no-config` uses the defaults alone even where a `sqlquack.toml` exists.

0 commit comments

Comments
 (0)