setup-hugo/src/dart-sass.ts

141 lines
3.7 KiB
TypeScript
Raw Normal View History

2024-05-02 18:38:23 +02:00
import { IGithubRelease, IReleaseLookup } from './asset-lookup'
2024-05-03 16:17:32 +02:00
import { DartSass } from './constants'
2024-05-02 18:38:23 +02:00
import { components } from '@octokit/openapi-types'
2024-05-03 14:12:12 +02:00
import * as tc from '@actions/tool-cache'
2024-05-02 18:38:23 +02:00
import * as core from '@actions/core'
import { Platform } from './os'
2024-05-03 14:12:12 +02:00
import * as os from 'node:os'
import path from 'path'
2024-05-03 16:17:32 +02:00
import { mv, rmRF } from '@actions/io'
import { randomUUID } from 'crypto'
import { errorMsg } from './utils/error'
2024-05-02 18:38:23 +02:00
export interface IDartSassInstallCommand {
version: string
}
export class DartSassInstaller {
private readonly releaseLookup: IReleaseLookup
private readonly platform: Platform
2024-05-03 16:34:46 +02:00
constructor(releaseLookup: IReleaseLookup, platform?: Platform) {
this.platform = platform ?? new Platform()
2024-05-02 18:38:23 +02:00
this.releaseLookup = releaseLookup
}
async install(cmd: IDartSassInstallCommand): Promise<void> {
const release = await this.releaseLookup.getRelease(
DartSass.Org,
DartSass.Repo,
cmd.version,
DartSassReleaseTransformer
)
core.debug(`Operating System: ${this.platform.os}`)
core.debug(`Processor Architecture: ${this.platform.arch}`)
2024-05-03 14:12:12 +02:00
const tmpDir = os.tmpdir()
2024-05-02 18:38:23 +02:00
2024-05-03 16:17:32 +02:00
try {
2024-05-03 16:34:46 +02:00
const cachedDartSass = tc.find(
DartSass.Name,
release.tag_name,
this.platform.arch
)
if (cachedDartSass) {
core.addPath(cachedDartSass)
return
}
2024-05-03 16:17:32 +02:00
} catch (e) {
core.warning(`Failed to lookup cached version: ${errorMsg(e)}`)
}
2024-05-02 18:38:23 +02:00
const toolUrl = release.assetUrl(this.platform)
if (!toolUrl) {
throw new Error('No matching URL detected for given platform')
}
2024-05-03 14:12:12 +02:00
const destPath = path.join(
tmpDir,
2024-05-03 16:17:32 +02:00
`dart-sass-${randomUUID()}${this.platform.archiveExtension()}`
2024-05-03 14:12:12 +02:00
)
await tc.downloadTool(toolUrl, destPath)
core.debug(`Extract archive: ${destPath}`)
if (this.platform.isWindows()) {
await tc.extractZip(destPath, tmpDir)
} else {
await tc.extractTar(destPath, tmpDir)
}
2024-05-03 16:17:32 +02:00
await rmRF(destPath)
core.debug(`Add 'dart-sass' directory to cache`)
try {
const cachedDartSass = await tc.cacheDir(
path.join(tmpDir, 'dart-sass'),
DartSass.Name,
release.tag_name,
this.platform.arch
2024-05-03 16:17:32 +02:00
)
core.addPath(cachedDartSass)
2024-05-03 16:17:32 +02:00
} catch (e) {
core.warning(`Failed to cache dart-sass directory: ${errorMsg(e)}`)
const binDir = await this.platform.ensureBinDir()
core.debug(`Move binaries to binDir: ${binDir}`)
await mv(path.join(tmpDir, 'dart-sass'), binDir)
2024-05-03 16:34:46 +02:00
core.addPath(path.join(binDir, 'dart-sass'))
2024-05-03 16:17:32 +02:00
}
2024-05-02 18:38:23 +02:00
}
}
export const DartSassReleaseTransformer = {
map(release: components['schemas']['release']): DartSassRelease {
return new DartSassRelease(
release.tag_name.replace('v', ''),
release.assets
)
}
}
export class DartSassRelease implements IGithubRelease {
private static readonly keyReplacementRegex = new RegExp(
'dart-sass-*(\\d+.\\d+.\\d+)-'
)
private static readonly platformMapping: { [index: string]: string } = {
linux: 'linux',
win32: 'windows',
darwin: 'macos'
}
private readonly assets: Map<string, string>
readonly tag_name: string
constructor(
tag_name: string,
assets: components['schemas']['release']['assets']
) {
this.tag_name = tag_name
this.assets = new Map<string, string>()
2024-05-03 16:17:32 +02:00
for (const asset of assets) {
2024-05-02 18:38:23 +02:00
this.assets.set(
asset.name.replace(DartSassRelease.keyReplacementRegex, ''),
2024-05-03 16:17:32 +02:00
asset.browser_download_url
2024-05-02 18:38:23 +02:00
)
2024-05-03 16:17:32 +02:00
}
2024-05-02 18:38:23 +02:00
}
assetUrl(platform: Platform): string | undefined {
const mappedOS = DartSassRelease.platformMapping[platform.os]
return this.assets.get(
`${mappedOS}-${platform.arch}${platform.archiveExtension()}`
)
}
}