Skip to content

Commit f6f3ffa

Browse files
List and sync runtimes
1 parent 457314a commit f6f3ffa

File tree

5 files changed

+126
-34
lines changed

5 files changed

+126
-34
lines changed

bun.lockb

765 Bytes
Binary file not shown.

commands/list.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,42 @@
11
import yargs, { ArgumentsCamelCase, Argv, CommandBuilder, CommandModule } from 'yargs'
2-
import { getInstalledSdks } from '../util/dotnet'
2+
import { getInstalledRuntimeVersions, getInstalledSdkVersions } from '../util/dotnet'
33
import { getListPreference, outputList } from '../util/lists'
4+
import chalk from 'chalk'
45

56
export const listCommand: CommandModule = {
67
command: 'list',
78
describe: 'List .NET software',
89
aliases: ['ls', 'get'],
910
builder: (command: CommandBuilder) => command
1011
.command(getSdkCommand)
12+
.command(getRuntimeCommand),
13+
handler: async (argv: Argv) => {
14+
console.log(`${chalk.bold.bgBlue.white('Installed sdks')}`)
15+
const installedSdks = await getInstalledSdkVersions()
16+
outputList(installedSdks, getListPreference(argv))
17+
18+
console.log(`${chalk.bold.bgBlue.white('Installed runtimes')}`)
19+
const installedRuntimes = await getInstalledRuntimeVersions()
20+
outputList(installedRuntimes, getListPreference(argv))
21+
}
1122
}
1223

1324
const getSdkCommand: CommandModule = {
1425
command: 'sdk',
1526
describe: 'Get installed SDKs',
1627
handler: async (argv: Argv) => {
17-
const installedSdks = await getInstalledSdks()
28+
const installedSdks = await getInstalledSdkVersions()
1829

1930
outputList(installedSdks, getListPreference(argv))
2031
}
32+
}
33+
34+
const getRuntimeCommand: CommandModule = {
35+
command: 'runtime',
36+
describe: 'Get installed runtimes',
37+
handler: async (argv: Argv) => {
38+
const installedRuntimes = await getInstalledRuntimeVersions()
39+
40+
outputList(installedRuntimes, getListPreference(argv))
41+
}
2142
}

commands/sync.ts

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,51 @@
11
import yargs, { ArgumentsCamelCase, Argv, CommandBuilder, CommandModule } from 'yargs'
2-
import { fetchInstallScript, getDotnetRootPath, getInstalledSdks, hasInstallScript, syncSdk, updateSdk } from '../util/dotnet'
2+
import { getChannelFromVersion, getInstalledRuntimeVersions, getInstalledSdkVersions, syncRuntimeChannel, syncSdkChannel } from '../util/dotnet'
33

44
export const syncCommand: CommandModule = {
5-
command: 'sync',
5+
command: 'sync [target]',
66
describe: 'Synchronize .NET software',
77
aliases: ['s'],
88
builder: (command: CommandBuilder) => command
9-
.command(syncSdkCommand)
10-
}
11-
12-
const syncSdkCommand: CommandModule = {
13-
command: 'sdk',
14-
describe: 'Synchronize .NET SDKs',
15-
builder: (command: CommandBuilder) => command
9+
.positional('target', {
10+
type: 'string',
11+
describe: 'The target to sync.',
12+
default: 'all',
13+
choices: [
14+
'all',
15+
'sdk',
16+
'runtime'
17+
]
18+
})
1619
.option('channel', {
1720
type: 'string',
18-
default: 'LTS',
19-
describe: 'Channel to sync'
21+
describe: 'Channel to sync.'
2022
}),
2123
handler: async (argv: Argv) => {
22-
if (!(await hasInstallScript())) {
23-
await fetchInstallScript()
24-
}
24+
// TODO: this is very stupid, but kind of amusing
25+
const targets = argv.target === 'all'
26+
? ['sdk', 'runtime']
27+
: [argv.target]
28+
29+
for (const target of targets) {
30+
if (target === 'sdk') {
31+
const channels: string[] = argv.channel
32+
? Array.isArray(argv.channel) ? argv.channel : [argv.channel]
33+
: (await getInstalledSdkVersions()).map(version => getChannelFromVersion(version))
34+
35+
for (const channel of channels) {
36+
await syncSdkChannel(channel)
37+
}
38+
}
2539

26-
const sdkMajorVersions = (await getInstalledSdks())
27-
// distinct by major version
28-
.filter((value, index, self) =>
29-
index === self.findIndex(x => x.major === value.major))
40+
if (target === 'runtime') {
41+
const channels = argv.channel
42+
? Array.isArray(argv.channel) ? argv.channel : [argv.channel]
43+
: (await getInstalledRuntimeVersions()).map(version => getChannelFromVersion(version))
3044

31-
for (const sdk of sdkMajorVersions) {
32-
await syncSdk(sdk)
45+
for (const channel of channels) {
46+
await syncRuntimeChannel(channel)
47+
}
48+
}
3349
}
3450
}
3551
}

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
"version": "0.0.1",
66
"devDependencies": {
77
"@types/bun": "latest",
8+
"@types/node": "^20.11.17",
89
"@types/yargs": "^17.0.32"
910
},
1011
"peerDependencies": {
1112
"typescript": "^5.0.0"
1213
},
1314
"dependencies": {
15+
"chalk": "^5.3.0",
1416
"yargs": "^17.7.2"
1517
}
1618
}

util/dotnet.ts

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,48 +30,94 @@ export const getDotnetRootPath = () => {
3030
return path.join(Bun.env.HOME, '.dotnet')
3131
}
3232

33-
export type DotnetSdk = {
33+
export type DotnetSdkVersion = {
3434
major: number
3535
minor: number
3636
patch: number
3737
}
3838

39-
export type DotnetRuntime = {
39+
export type DotnetRuntimeVersion = {
4040
major: number
4141
minor: number
4242
patch: number
43+
type: 'net' | 'aspnetcore' | 'netcoreapp'
4344
}
4445

45-
export const getInstalledSdks = async (): Promise<DotnetSdk[]> => {
46+
export const getInstalledSdkVersions = async (): Promise<DotnetSdkVersion[]> => {
4647
const sdkPath = path.join(getDotnetRootPath(), 'sdk')
4748

4849
const dirs = await getDirectories(sdkPath)
4950

5051
return dirs.map(dir => {
51-
const split = dir
52+
const split = dir.name
5253
.split('.')
5354
.map(n => parseInt(n))
5455

5556
return {
5657
major: split[0],
5758
minor: split[1],
58-
patch: split[2]
59-
} as DotnetSdk
59+
patch: split[2],
60+
path: dir.path
61+
} as DotnetSdkVersion
6062
})
6163
}
6264

63-
const getDirectories = async (source: string) =>
65+
export const getInstalledRuntimeVersions = async (): Promise<DotnetSdkVersion[]> => {
66+
const netcoreRuntimePath = path.join(getDotnetRootPath(), 'shared', 'Microsoft.NETCore.App')
67+
const aspnetCoreAllPath = path.join(getDotnetRootPath(), 'shared', 'Microsoft.AspNetCore.All') // old ASPNET Core 2.1 stuff
68+
const aspnetCoreAppPath = path.join(getDotnetRootPath(), 'shared', 'Microsoft.AspNetCore.App')
69+
70+
const dirs = (await getDirectories(netcoreRuntimePath))
71+
.concat((await getDirectories(aspnetCoreAllPath)))
72+
.concat((await getDirectories(aspnetCoreAppPath)))
73+
74+
return dirs.map(dir => {
75+
const versionSplit = dir.name
76+
.split('.')
77+
.map(n => parseInt(n))
78+
79+
return {
80+
major: versionSplit[0],
81+
minor: versionSplit[1],
82+
patch: versionSplit[2],
83+
type: dir.path.startsWith(netcoreRuntimePath) ? 'net'
84+
: dir.path.startsWith(aspnetCoreAppPath) ? 'aspnetcore'
85+
: dir.path.startsWith(aspnetCoreAllPath) ? 'netcoreapp' : null,
86+
path: dir.path
87+
} as DotnetRuntimeVersion
88+
})
89+
}
90+
91+
const getDirectories = async (source: string): Promise<Directory[]> =>
6492
(await readdir(source, { withFileTypes: true }))
6593
.filter(dirent => dirent.isDirectory())
66-
.map(dirent => dirent.name)
94+
.map(dirent => ({
95+
name: dirent.name,
96+
path: path.resolve(source, dirent.name)
97+
}) as Directory)
98+
99+
type Directory = {
100+
name: string
101+
path: string
102+
}
67103

104+
export const syncSdkVersion = async (sdk: DotnetSdkVersion) => {
105+
await syncSdkChannel(`${sdk.major}.${sdk.minor}`)
106+
}
107+
108+
export const getChannelFromVersion = (version: DotnetSdkVersion | DotnetRuntimeVersion) =>
109+
`${version.major}.${version.minor}`
110+
111+
export const syncSdkChannel = async (channel: string) => {
112+
if (!(await hasInstallScript())) {
113+
await fetchInstallScript()
114+
}
68115

69-
export const syncSdk = async (sdk: DotnetSdk) => {
70116
const proc = Bun.spawn([
71117
'bash',
72118
getInstallScriptPath(),
73119
'--channel',
74-
`${sdk.major}.${sdk.minor}`
120+
channel
75121
], {
76122
stdout: 'inherit',
77123
stderr: 'inherit',
@@ -88,12 +134,19 @@ export const syncSdk = async (sdk: DotnetSdk) => {
88134
}
89135
}
90136

91-
export const syncRuntime = async (runtime: DotnetRuntime) => {
137+
export const syncRuntime = async (runtime: DotnetRuntimeVersion) =>
138+
await syncRuntimeChannel(`${runtime.major}/${runtime.minor}`)
139+
140+
export const syncRuntimeChannel = async (channel: string) => {
141+
if (!(await hasInstallScript())) {
142+
await fetchInstallScript()
143+
}
144+
92145
const proc = Bun.spawn([
93146
'bash',
94147
getInstallScriptPath(),
95148
'--channel',
96-
`${runtime.major}.${runtime.minor}`,
149+
channel,
97150
'--runtime'
98151
], {
99152
stdout: 'inherit',

0 commit comments

Comments
 (0)