-
Notifications
You must be signed in to change notification settings - Fork 368
/
JupyterInstallCommand.cs
96 lines (73 loc) · 3.37 KB
/
JupyterInstallCommand.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.CommandLine;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.DotNet.Interactive.Http;
using Microsoft.DotNet.Interactive.Utility;
namespace Microsoft.DotNet.Interactive.App;
public class JupyterInstallCommand
{
private readonly IConsole _console;
private readonly IJupyterKernelSpecInstaller _jupyterKernelSpecInstaller;
private readonly HttpPortRange _httpPortRange;
private readonly DirectoryInfo _path;
private static readonly JsonSerializerOptions JsonSerializerOptions = new(JsonSerializerDefaults.Web)
{
WriteIndented = true
};
public JupyterInstallCommand(IConsole console, IJupyterKernelSpecInstaller jupyterKernelSpecInstaller, HttpPortRange httpPortRange = null, DirectoryInfo path = null)
{
_console = console;
_jupyterKernelSpecInstaller = jupyterKernelSpecInstaller;
_httpPortRange = httpPortRange;
_path = path;
}
public async Task<int> InvokeAsync()
{
var errorCount = 0;
using (var disposableDirectory = DisposableDirectory.Create())
{
var assembly = typeof(Program).Assembly;
using (var resourceStream = assembly.GetManifestResourceStream("dotnetKernel.zip"))
{
var zipPath = Path.Combine(disposableDirectory.Directory.FullName, "dotnetKernel.zip");
using (var fileStream = new FileStream(zipPath, FileMode.Create, FileAccess.Write))
{
resourceStream.CopyTo(fileStream);
}
var dotnetDirectory = disposableDirectory.Directory;
ZipFile.ExtractToDirectory(zipPath, dotnetDirectory.FullName);
if (_httpPortRange is not null)
{
ComputeKernelSpecArgs(_httpPortRange, dotnetDirectory);
}
foreach (var kernelSpecSourcePath in dotnetDirectory.GetDirectories())
{
var succeeded = await _jupyterKernelSpecInstaller.TryInstallKernelAsync(kernelSpecSourcePath, _path);
if (!succeeded)
{
errorCount++;
}
}
}
}
return errorCount;
}
private static void ComputeKernelSpecArgs(HttpPortRange httpPortRange, DirectoryInfo directory)
{
var kernelSpecs = directory.GetFiles("kernel.json", SearchOption.AllDirectories);
foreach (var kernelSpec in kernelSpecs)
{
var newKernelSpec = JsonDocument.Parse(File.ReadAllText(kernelSpec.FullName)).RootElement.EnumerateObject().ToDictionary(p => p.Name, p => p.Value);
var argv = newKernelSpec["argv"].EnumerateArray().Select(e => e.GetString()).ToList();
argv.Add( "--http-port-range");
argv.Add($"{httpPortRange.Start}-{httpPortRange.End}");
newKernelSpec["argv"] = JsonSerializer.SerializeToElement(argv);
File.WriteAllText(kernelSpec.FullName, JsonSerializer.Serialize(newKernelSpec, JsonSerializerOptions));
}
}
}