Skip to content

Commit dfbf531

Browse files
committed
Address nojaf feedback by making more fault tolerant
1 parent 3db1fbf commit dfbf531

File tree

2 files changed

+74
-36
lines changed

2 files changed

+74
-36
lines changed

src/FSharp.Formatting.Literate/ParsePynb.fs

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -31,45 +31,44 @@ module internal ParsePynb =
3131
match x.TryGetProperty("text/html") with
3232
| true, html ->
3333
let html = html.EnumerateArray() |> Seq.map (fun x -> x.GetString()) |> String.concat "\n"
34-
Some("""<p>""" + html + """</p>""")
34+
Some $"<p>{html}</p>"
3535
| _ -> None
3636

3737
let (|TextPlain|_|) (x: JsonElement) =
3838
match x.TryGetProperty("text/plain") with
3939
| true, text ->
4040
let text = text.EnumerateArray() |> Seq.map (fun x -> x.GetString()) |> String.concat ""
41-
42-
Some(
43-
"""<table class="pre"><tbody><tr><td><pre><code>"""
44-
+ text
45-
+ """</code></pre></td></tr></tbody></table>"""
46-
)
41+
Some $"""<table class="pre"><tbody><tr><td><pre><code>{text}</code></pre></td></tr></tbody></table>"""
4742
| _ -> None
4843

4944
let (|DisplayData|_|) (x: JsonElement) =
50-
if x.GetProperty("output_type").GetString() = "display_data" then
51-
match x.GetProperty("data") with
52-
| TextHtml html -> html
53-
| TextPlain text -> text
54-
| s -> failwith $"unknown ouptut {s}"
55-
|> Some
56-
else
57-
None
45+
match x.TryGetProperty("output_type") with
46+
| true, outputType ->
47+
if outputType.GetString() = "display_data" then
48+
match x.TryGetProperty("data") with
49+
| true, TextHtml html -> html
50+
| true, TextPlain text -> text
51+
| true, s -> failwith $"unknown output {s}"
52+
| false, _ -> failwith "no data property"
53+
|> Some
54+
else
55+
None
56+
| _ -> failwith "no output_type property"
5857

5958
let (|Stream|_|) (x: JsonElement) =
60-
if x.GetProperty("output_type").GetString() = "stream" then
61-
let text =
62-
x.GetProperty("text").EnumerateArray()
63-
|> Seq.map (fun x -> x.GetString())
64-
|> String.concat ""
65-
66-
Some(
67-
"""<table class="pre"><tbody><tr><td><pre><code>"""
68-
+ text
69-
+ """</code></pre></td></tr></tbody></table>"""
70-
)
71-
else
72-
None
59+
match x.TryGetProperty("output_type") with
60+
| true, outputType ->
61+
if outputType.GetString() = "stream" then
62+
let text =
63+
match x.TryGetProperty("text") with
64+
| true, xs -> xs.EnumerateArray() |> Seq.map (fun x -> x.GetString()) |> String.concat ""
65+
| _ -> failwith "no text property"
66+
67+
Some
68+
$"""<table class="pre"><tbody><tr><td><pre><code>{text}</code></pre></td></tr></tbody></table>"""
69+
else
70+
None
71+
| _ -> failwith "no output_type property"
7372

7473
let parse (output: JsonElement) =
7574
match output with

src/fsdocs-tool/BuildCommand.fs

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,12 @@ type internal DocContent
185185

186186
if name.StartsWith('.') then
187187
printfn "skipping file %s" inputFileFullPath
188-
elif not (name.StartsWith("_template", StringComparison.Ordinal)) then
189-
let isFsx = inputFileFullPath.EndsWith(".fsx", true, CultureInfo.InvariantCulture)
188+
elif not (name.StartsWith "_template") then
189+
let isFsx = inputFileFullPath.EndsWith(".fsx", StringComparison.OrdinalIgnoreCase)
190190

191-
let isMd = inputFileFullPath.EndsWith(".md", true, CultureInfo.InvariantCulture)
191+
let isMd = inputFileFullPath.EndsWith(".md", StringComparison.OrdinalIgnoreCase)
192192

193-
let isPynb = inputFileFullPath.EndsWith(".ipynb", true, CultureInfo.InvariantCulture)
193+
let isPynb = inputFileFullPath.EndsWith(".ipynb", StringComparison.OrdinalIgnoreCase)
194194

195195
// A _template.tex or _template.pynb is needed to generate those files
196196
match outputKind, template with
@@ -351,19 +351,58 @@ type internal DocContent
351351
printfn " preparing %s --> %s" inputFileFullPath outputFileRelativeToRoot
352352

353353
let evaluateNotebook ipynbFile =
354+
let args =
355+
$"repl --run {ipynbFile} --default-kernel fsharp --exit-after-run --output-path {ipynbFile}"
356+
354357
let psi =
355358
ProcessStartInfo(
356359
fileName = "dotnet",
357-
arguments =
358-
$"repl --run {ipynbFile} --default-kernel fsharp --exit-after-run --output-path {ipynbFile}",
360+
arguments = args,
359361
UseShellExecute = false,
360362
CreateNoWindow = true
361363
)
362364

363-
let p = Process.Start(psi)
364-
p.WaitForExit()
365+
try
366+
let p = Process.Start(psi)
367+
p.WaitForExit()
368+
with _ ->
369+
let msg =
370+
$"Failed to evaluate notebook {ipynbFile} using dotnet-repl\n"
371+
+ $"""try running "{args}" at the command line and inspect the error"""
372+
373+
failwith msg
374+
375+
let checkDotnetReplInstall () =
376+
let failmsg =
377+
"'dotnet-repl' is not installed. Please install it using 'dotnet tool install dotnet-repl'"
378+
379+
try
380+
let psi =
381+
ProcessStartInfo(
382+
fileName = "dotnet",
383+
arguments = "tool list --local",
384+
UseShellExecute = false,
385+
CreateNoWindow = true,
386+
RedirectStandardOutput = true
387+
)
388+
389+
let p = Process.Start(psi)
390+
let ol = p.StandardOutput.ReadToEnd()
391+
p.WaitForExit()
392+
psi.Arguments <- "tool list --global"
393+
p.Start() |> ignore
394+
let og = p.StandardOutput.ReadToEnd()
395+
let output = $"{ol}\n{og}"
396+
397+
if not (output.Contains("dotnet-repl")) then
398+
failwith failmsg
399+
400+
p.WaitForExit()
401+
with _ ->
402+
failwith failmsg
365403

366404
if evaluate then
405+
checkDotnetReplInstall ()
367406
printfn $" evaluating {inputFileFullPath} with dotnet-repl"
368407
evaluateNotebook inputFileFullPath
369408

0 commit comments

Comments
 (0)