mirror of
https://github.com/Boof2015/prism.git
synced 2026-08-12 05:10:51 +02:00
add version in top bar and update checking
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import { execFileSync } from 'node:child_process'
|
||||
|
||||
export interface AppBuildMetadata {
|
||||
commitHash: string | null
|
||||
isDirty: boolean
|
||||
}
|
||||
|
||||
interface ResolveAppBuildMetadataOptions {
|
||||
cwd?: string
|
||||
env?: NodeJS.ProcessEnv
|
||||
runGitCommand?: (cwd: string, args: string[]) => string
|
||||
}
|
||||
|
||||
const DIRTY_ENV_TRUE_VALUES = new Set(['1', 'true', 'yes', 'dirty'])
|
||||
const DIRTY_ENV_FALSE_VALUES = new Set(['0', 'false', 'no', 'clean'])
|
||||
|
||||
function normalizeCommitHash(value: string | undefined): string | null {
|
||||
if (typeof value !== 'string') return null
|
||||
|
||||
const trimmed = value.trim()
|
||||
return trimmed.length > 0 ? trimmed : null
|
||||
}
|
||||
|
||||
function parseDirtyEnvValue(value: string | undefined): boolean | null {
|
||||
if (typeof value !== 'string') return null
|
||||
|
||||
const normalized = value.trim().toLowerCase()
|
||||
if (!normalized) return null
|
||||
if (DIRTY_ENV_TRUE_VALUES.has(normalized)) return true
|
||||
if (DIRTY_ENV_FALSE_VALUES.has(normalized)) return false
|
||||
return null
|
||||
}
|
||||
|
||||
function execGitCommand(cwd: string, args: string[]): string {
|
||||
return execFileSync('git', args, {
|
||||
cwd,
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'ignore'],
|
||||
})
|
||||
}
|
||||
|
||||
function resolveGitCommitHash(
|
||||
cwd: string,
|
||||
runGitCommand: (cwd: string, args: string[]) => string,
|
||||
): string | null {
|
||||
try {
|
||||
return normalizeCommitHash(runGitCommand(cwd, ['rev-parse', 'HEAD']))
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
function resolveGitDirtyState(cwd: string, runGitCommand: (cwd: string, args: string[]) => string): boolean {
|
||||
try {
|
||||
return runGitCommand(cwd, ['status', '--porcelain']).trim().length > 0
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveAppBuildMetadata(options: ResolveAppBuildMetadataOptions = {}): AppBuildMetadata {
|
||||
const cwd = options.cwd ?? process.cwd()
|
||||
const env = options.env ?? process.env
|
||||
const runGitCommand = options.runGitCommand ?? execGitCommand
|
||||
|
||||
const envCommitHash = normalizeCommitHash(env.PRISM_GIT_COMMIT)
|
||||
const envDirtyState = parseDirtyEnvValue(env.PRISM_GIT_DIRTY)
|
||||
|
||||
if (envCommitHash) {
|
||||
return {
|
||||
commitHash: envCommitHash,
|
||||
isDirty: envDirtyState ?? false,
|
||||
}
|
||||
}
|
||||
|
||||
const commitHash = resolveGitCommitHash(cwd, runGitCommand)
|
||||
if (!commitHash) {
|
||||
return {
|
||||
commitHash: null,
|
||||
isDirty: false,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
commitHash,
|
||||
isDirty: envDirtyState ?? resolveGitDirtyState(cwd, runGitCommand),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const { execFileSync } = require('child_process')
|
||||
|
||||
const outputPath = path.resolve(__dirname, '../../out/build-metadata.json')
|
||||
const repoRoot = path.resolve(__dirname, '../..')
|
||||
|
||||
const DIRTY_ENV_TRUE_VALUES = new Set(['1', 'true', 'yes', 'dirty'])
|
||||
const DIRTY_ENV_FALSE_VALUES = new Set(['0', 'false', 'no', 'clean'])
|
||||
|
||||
function normalizeCommitHash(value) {
|
||||
if (typeof value !== 'string') return null
|
||||
const trimmed = value.trim()
|
||||
return trimmed.length > 0 ? trimmed : null
|
||||
}
|
||||
|
||||
function parseDirtyEnvValue(value) {
|
||||
if (typeof value !== 'string') return null
|
||||
const normalized = value.trim().toLowerCase()
|
||||
if (!normalized) return null
|
||||
if (DIRTY_ENV_TRUE_VALUES.has(normalized)) return true
|
||||
if (DIRTY_ENV_FALSE_VALUES.has(normalized)) return false
|
||||
return null
|
||||
}
|
||||
|
||||
function execGit(args) {
|
||||
return execFileSync('git', args, {
|
||||
cwd: repoRoot,
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'ignore'],
|
||||
})
|
||||
}
|
||||
|
||||
function resolveBuildMetadata() {
|
||||
const envCommitHash = normalizeCommitHash(process.env.PRISM_GIT_COMMIT)
|
||||
const envDirty = parseDirtyEnvValue(process.env.PRISM_GIT_DIRTY)
|
||||
|
||||
if (envCommitHash) {
|
||||
return {
|
||||
commitHash: envCommitHash,
|
||||
isDirty: envDirty ?? false,
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const commitHash = normalizeCommitHash(execGit(['rev-parse', 'HEAD']))
|
||||
if (!commitHash) {
|
||||
return {
|
||||
commitHash: null,
|
||||
isDirty: false,
|
||||
}
|
||||
}
|
||||
|
||||
const isDirty = envDirty ?? execGit(['status', '--porcelain']).trim().length > 0
|
||||
return {
|
||||
commitHash,
|
||||
isDirty,
|
||||
}
|
||||
} catch {
|
||||
return {
|
||||
commitHash: null,
|
||||
isDirty: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const metadata = resolveBuildMetadata()
|
||||
fs.mkdirSync(path.dirname(outputPath), { recursive: true })
|
||||
fs.writeFileSync(outputPath, `${JSON.stringify(metadata, null, 2)}\n`, 'utf8')
|
||||
@@ -0,0 +1,44 @@
|
||||
import { mkdtemp, rm } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join, dirname } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { spawn } from 'node:child_process'
|
||||
import { build } from 'esbuild'
|
||||
|
||||
const rootDir = dirname(dirname(fileURLToPath(import.meta.url)))
|
||||
const tempDir = await mkdtemp(join(tmpdir(), 'prism-build-metadata-tests-'))
|
||||
const bundledTestPath = join(tempDir, 'build-metadata.test.mjs')
|
||||
const entryPoint = join(rootDir, 'test', 'build-metadata.test.ts')
|
||||
|
||||
let exitCode = 1
|
||||
|
||||
try {
|
||||
await build({
|
||||
entryPoints: [entryPoint],
|
||||
outfile: bundledTestPath,
|
||||
bundle: true,
|
||||
platform: 'node',
|
||||
format: 'esm',
|
||||
target: 'node23',
|
||||
sourcemap: 'inline',
|
||||
})
|
||||
|
||||
exitCode = await new Promise((resolve) => {
|
||||
const child = spawn(process.execPath, ['--test', bundledTestPath], {
|
||||
stdio: 'inherit',
|
||||
cwd: rootDir,
|
||||
})
|
||||
|
||||
child.on('exit', (code) => {
|
||||
resolve(code ?? 1)
|
||||
})
|
||||
|
||||
child.on('error', () => {
|
||||
resolve(1)
|
||||
})
|
||||
})
|
||||
} finally {
|
||||
await rm(tempDir, { recursive: true, force: true })
|
||||
}
|
||||
|
||||
process.exit(exitCode)
|
||||
@@ -0,0 +1,44 @@
|
||||
import { mkdtemp, rm } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join, dirname } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { spawn } from 'node:child_process'
|
||||
import { build } from 'esbuild'
|
||||
|
||||
const rootDir = dirname(dirname(fileURLToPath(import.meta.url)))
|
||||
const tempDir = await mkdtemp(join(tmpdir(), 'prism-update-tests-'))
|
||||
const bundledTestPath = join(tempDir, 'updates.test.mjs')
|
||||
const entryPoint = join(rootDir, 'test', 'updates.test.ts')
|
||||
|
||||
let exitCode = 1
|
||||
|
||||
try {
|
||||
await build({
|
||||
entryPoints: [entryPoint],
|
||||
outfile: bundledTestPath,
|
||||
bundle: true,
|
||||
platform: 'node',
|
||||
format: 'esm',
|
||||
target: 'node23',
|
||||
sourcemap: 'inline',
|
||||
})
|
||||
|
||||
exitCode = await new Promise((resolve) => {
|
||||
const child = spawn(process.execPath, ['--test', bundledTestPath], {
|
||||
stdio: 'inherit',
|
||||
cwd: rootDir,
|
||||
})
|
||||
|
||||
child.on('exit', (code) => {
|
||||
resolve(code ?? 1)
|
||||
})
|
||||
|
||||
child.on('error', () => {
|
||||
resolve(1)
|
||||
})
|
||||
})
|
||||
} finally {
|
||||
await rm(tempDir, { recursive: true, force: true })
|
||||
}
|
||||
|
||||
process.exit(exitCode)
|
||||
Reference in New Issue
Block a user