Skip to content

Commit 0f681ea

Browse files
authored
feat(graindoc)!: Add --current-version flag, required for since/history attributes (#1116)
chore(stdlib): Regenerate markdown docs with `--current-version` flag
1 parent d7386eb commit 0f681ea

File tree

8 files changed

+85
-45
lines changed

8 files changed

+85
-45
lines changed

cli/bin/grain.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,10 @@ program
215215
program
216216
.command("doc <file>")
217217
.description("generate documentation for a grain file")
218+
.forwardOption(
219+
"--current-version <version>",
220+
"provide a version to use as current when generating markdown for `@since` and `@history` attributes"
221+
)
218222
.action(
219223
wrapAction(function (file, options, program) {
220224
doc(file, program);

compiler/graindoc/docblock.re

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,27 @@ type t = {
1111
attributes: list(Comments.Attribute.t),
1212
};
1313

14+
exception
15+
MissingFlag({
16+
flag: string,
17+
attr: string,
18+
});
19+
20+
let () =
21+
Printexc.register_printer(exn => {
22+
switch (exn) {
23+
| MissingFlag({flag, attr}) =>
24+
let msg =
25+
Printf.sprintf(
26+
"Must provide %s when generating docs with `%s` attribute.",
27+
flag,
28+
attr,
29+
);
30+
Some(msg);
31+
| _ => None
32+
}
33+
});
34+
1435
let module_name_of_location = (loc: Grain_parsing.Location.t) => {
1536
Grain_utils.Files.filename_to_module_name(loc.loc_start.pos_fname);
1637
};
@@ -27,6 +48,35 @@ let title_for_api = (~module_name, ident: Ident.t) => {
2748
Format.asprintf("%s.**%a**", module_name, Printtyp.ident, ident);
2849
};
2950

51+
let output_for_since = (~current_version, attr_version) => {
52+
let current_version =
53+
switch (current_version) {
54+
| Some(version) => version
55+
| None => raise(MissingFlag({flag: "--current-version", attr: "@since"}))
56+
};
57+
let (<) = Version.String.less_than;
58+
if (current_version < attr_version) {
59+
Format.sprintf("Added in %s", Html.code("next"));
60+
} else {
61+
Format.sprintf("Added in %s", Html.code(attr_version));
62+
};
63+
};
64+
65+
let output_for_history = (~current_version, attr_version, attr_desc) => {
66+
let current_version =
67+
switch (current_version) {
68+
| Some(version) => version
69+
| None =>
70+
raise(MissingFlag({flag: "--current-version", attr: "@history"}))
71+
};
72+
let (<) = Version.String.less_than;
73+
if (current_version < attr_version) {
74+
[Html.code("next"), attr_desc];
75+
} else {
76+
[Html.code(attr_version), attr_desc];
77+
};
78+
};
79+
3080
let types_for_function = (~ident, vd: Types.value_description) => {
3181
switch (Ctype.repr(vd.val_type).desc) {
3282
| TTyArrow(_) =>
@@ -162,12 +212,7 @@ let to_markdown = (~current_version, docblock) => {
162212
|> Option.map((attr: Comments.Attribute.t) => {
163213
switch (attr) {
164214
| Since({attr_version}) =>
165-
let (<) = Version.String.less_than;
166-
if (current_version < attr_version) {
167-
Format.sprintf("Added in %s", Html.code("next"));
168-
} else {
169-
Format.sprintf("Added in %s", Html.code(attr_version));
170-
};
215+
output_for_since(~current_version, attr_version)
171216
| _ =>
172217
failwith("Unreachable: Non-`since` attribute can't exist here.")
173218
}
@@ -178,12 +223,7 @@ let to_markdown = (~current_version, docblock) => {
178223
|> List.map((attr: Comments.Attribute.t) => {
179224
switch (attr) {
180225
| History({attr_version, attr_desc}) =>
181-
let (<) = Version.String.less_than;
182-
if (current_version < attr_version) {
183-
[Html.code("next"), attr_desc];
184-
} else {
185-
[Html.code(attr_version), attr_desc];
186-
};
226+
output_for_history(~current_version, attr_version, attr_desc)
187227
| _ =>
188228
failwith("Unreachable: Non-`since` attribute can't exist here.")
189229
}

compiler/graindoc/graindoc.re

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ type params = {
6767
/** Output filename */
6868
[@name "o"] [@docv "FILE"]
6969
output: option(Output.t),
70+
/**
71+
The version to use as current when generating markdown for `@since` and `@history` attributes.
72+
Any future versions will be replace with `next` in the output.
73+
*/
74+
[@name "current-version"] [@docv "VERSION"]
75+
current_version: option(string),
7076
};
7177

7278
let compile_typed = (opts: params) => {
@@ -97,11 +103,7 @@ let compile_typed = (opts: params) => {
97103
};
98104

99105
let generate_docs =
100-
(
101-
~version as current_version,
102-
opts: params,
103-
program: Typedtree.typed_program,
104-
) => {
106+
({current_version, output}: params, program: Typedtree.typed_program) => {
105107
Comments.setup_comments(program.comments);
106108

107109
let env = program.env;
@@ -132,12 +134,7 @@ let generate_docs =
132134
|> Option.map((attr: Comments.Attribute.t) => {
133135
switch (attr) {
134136
| Since({attr_version}) =>
135-
let (<) = Version.String.less_than;
136-
if (current_version < attr_version) {
137-
Format.sprintf("Added in %s", Html.code("next"));
138-
} else {
139-
Format.sprintf("Added in %s", Html.code(attr_version));
140-
};
137+
Docblock.output_for_since(~current_version, attr_version)
141138
| _ =>
142139
failwith("Unreachable: Non-`since` attribute can't exist here.")
143140
}
@@ -148,12 +145,11 @@ let generate_docs =
148145
|> List.map((attr: Comments.Attribute.t) => {
149146
switch (attr) {
150147
| History({attr_version, attr_desc}) =>
151-
let (<) = Version.String.less_than;
152-
if (current_version < attr_version) {
153-
[Html.code("next"), attr_desc];
154-
} else {
155-
[Html.code(attr_version), attr_desc];
156-
};
148+
Docblock.output_for_history(
149+
~current_version,
150+
attr_version,
151+
attr_desc,
152+
)
157153
| _ =>
158154
failwith("Unreachable: Non-`since` attribute can't exist here.")
159155
}
@@ -240,7 +236,7 @@ let generate_docs =
240236
};
241237

242238
let contents = Buffer.to_bytes(buf);
243-
switch (opts.output) {
239+
switch (output) {
244240
| Some(outfile) =>
245241
let oc = Fs_access.open_file_for_writing(outfile);
246242
output_bytes(oc, contents);
@@ -251,13 +247,14 @@ let generate_docs =
251247
`Ok();
252248
};
253249

254-
let graindoc = (~version, opts) =>
255-
try({
256-
let program = compile_typed(opts);
257-
generate_docs(~version, opts, program);
258-
}) {
259-
| e => `Error((false, Printexc.to_string(e)))
250+
let graindoc = opts => {
251+
let program = compile_typed(opts);
252+
try(generate_docs(opts, program)) {
253+
| exn =>
254+
Format.eprintf("@[%s@]@.", Printexc.to_string(exn));
255+
exit(2);
260256
};
257+
};
261258

262259
let cmd = {
263260
open Term;
@@ -270,8 +267,7 @@ let cmd = {
270267
};
271268

272269
(
273-
Grain_utils.Config.with_cli_options(graindoc(~version))
274-
$ params_cmdliner_term(),
270+
Grain_utils.Config.with_cli_options(graindoc) $ params_cmdliner_term(),
275271
Term.info(Sys.argv[0], ~version, ~doc),
276272
);
277273
};

stdlib/array.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ Returns:
266266
### Array.**cycle**
267267

268268
<details disabled>
269-
<summary tabindex="-1">Added in <code>next</code></summary>
269+
<summary tabindex="-1">Added in <code>0.4.4</code></summary>
270270
No other changes yet.
271271
</details>
272272

@@ -1030,7 +1030,7 @@ Returns:
10301030
### Array.**sort**
10311031

10321032
<details disabled>
1033-
<summary tabindex="-1">Added in <code>next</code></summary>
1033+
<summary tabindex="-1">Added in <code>0.4.5</code></summary>
10341034
No other changes yet.
10351035
</details>
10361036

@@ -1052,7 +1052,7 @@ Parameters:
10521052
### Array.**rotate**
10531053

10541054
<details disabled>
1055-
<summary tabindex="-1">Added in <code>next</code></summary>
1055+
<summary tabindex="-1">Added in <code>0.4.5</code></summary>
10561056
No other changes yet.
10571057
</details>
10581058

stdlib/number.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ Returns:
459459
### Number.**parseInt**
460460

461461
<details disabled>
462-
<summary tabindex="-1">Added in <code>next</code></summary>
462+
<summary tabindex="-1">Added in <code>0.4.5</code></summary>
463463
No other changes yet.
464464
</details>
465465

stdlib/option.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ No other changes yet.
533533
</details>
534534

535535
```grain
536-
( or ) : (Option<a>, Option<a>) -> Option<a>
536+
or : (Option<a>, Option<a>) -> Option<a>
537537
```
538538

539539
Behaves like a logical OR (`||`) where the first Option is only returned if it is the `Some` variant and falling back to the second Option in all other cases.

stdlib/result.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ No other changes yet.
272272
</details>
273273

274274
```grain
275-
( or ) : (Result<a, b>, Result<a, b>) -> Result<a, b>
275+
or : (Result<a, b>, Result<a, b>) -> Result<a, b>
276276
```
277277

278278
Behaves like a logical OR (`||`) where the first Result is only returned if it is the `Ok` variant and falling back to the second Result in all other cases.

stdlib/string.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ String.implode([> 'H', 'e', 'l', 'l', 'o']) == "Hello"
266266
### String.**reverse**
267267

268268
<details disabled>
269-
<summary tabindex="-1">Added in <code>next</code></summary>
269+
<summary tabindex="-1">Added in <code>0.4.5</code></summary>
270270
No other changes yet.
271271
</details>
272272

0 commit comments

Comments
 (0)