mirror of
https://github.com/MeshEnvy/mesh-forge.git
synced 2026-08-07 09:22:56 +02:00
feat: enhance plugin configuration with diagnostics options and refactor build hash computation
This commit is contained in:
Vendored
+2
@@ -15,6 +15,7 @@ import type * as builds from "../builds.js";
|
||||
import type * as helpers from "../helpers.js";
|
||||
import type * as http from "../http.js";
|
||||
import type * as lib_filename from "../lib/filename.js";
|
||||
import type * as lib_flags from "../lib/flags.js";
|
||||
import type * as lib_r2 from "../lib/r2.js";
|
||||
import type * as plugins from "../plugins.js";
|
||||
import type * as profiles from "../profiles.js";
|
||||
@@ -33,6 +34,7 @@ declare const fullApi: ApiFromModules<{
|
||||
helpers: typeof helpers;
|
||||
http: typeof http;
|
||||
"lib/filename": typeof lib_filename;
|
||||
"lib/flags": typeof lib_flags;
|
||||
"lib/r2": typeof lib_r2;
|
||||
plugins: typeof plugins;
|
||||
profiles: typeof profiles;
|
||||
|
||||
+41
-17
@@ -4,6 +4,7 @@ import { api, internal } from "./_generated/api"
|
||||
import type { Doc, Id } from "./_generated/dataModel"
|
||||
import { internalMutation, mutation, query } from "./_generated/server"
|
||||
import { ArtifactType, getArtifactFilenameBase } from "./lib/filename"
|
||||
import { computeFlagsFromConfig } from "./lib/flags"
|
||||
import { generateSignedDownloadUrl } from "./lib/r2"
|
||||
import { buildFields } from "./schema"
|
||||
|
||||
@@ -31,18 +32,8 @@ export const getByHash = query({
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
* Computes flags string from build config.
|
||||
* Only excludes modules explicitly marked as excluded (config[id] === true).
|
||||
*/
|
||||
export function computeFlagsFromConfig(config: Doc<"builds">["config"]): string {
|
||||
// Sort modules to ensure consistent order
|
||||
return Object.keys(config.modulesExcluded)
|
||||
.sort()
|
||||
.filter(module => config.modulesExcluded[module])
|
||||
.map((moduleExcludedName: string) => `-D${moduleExcludedName}=1`)
|
||||
.join(" ")
|
||||
}
|
||||
// Re-export for backward compatibility
|
||||
export { computeFlagsFromConfig } from "./lib/flags"
|
||||
|
||||
/**
|
||||
* Encodes a byte array to base62 string.
|
||||
@@ -77,16 +68,39 @@ async function computeBuildHashInternal(
|
||||
version: string,
|
||||
target: string,
|
||||
flags: string,
|
||||
plugins: string[]
|
||||
plugins: string[],
|
||||
pluginConfig?: Record<string, Record<string, boolean>>
|
||||
): Promise<string> {
|
||||
// Input is now the exact parameters used for the build
|
||||
// Sort plugins array for consistent hashing
|
||||
const sortedPlugins = [...plugins].sort()
|
||||
// Sort plugin config for consistent hashing
|
||||
const sortedPluginConfig = pluginConfig
|
||||
? Object.keys(pluginConfig)
|
||||
.sort()
|
||||
.reduce(
|
||||
(acc, pluginSlug) => {
|
||||
const sortedOptions = Object.keys(pluginConfig[pluginSlug])
|
||||
.sort()
|
||||
.reduce(
|
||||
(opts, optKey) => {
|
||||
opts[optKey] = pluginConfig[pluginSlug][optKey]
|
||||
return opts
|
||||
},
|
||||
{} as Record<string, boolean>
|
||||
)
|
||||
acc[pluginSlug] = sortedOptions
|
||||
return acc
|
||||
},
|
||||
{} as Record<string, Record<string, boolean>>
|
||||
)
|
||||
: undefined
|
||||
const input = JSON.stringify({
|
||||
version,
|
||||
target,
|
||||
flags,
|
||||
plugins: sortedPlugins,
|
||||
pluginConfig: sortedPluginConfig,
|
||||
})
|
||||
|
||||
// Use Web Crypto API for SHA-256 hashing
|
||||
@@ -103,10 +117,13 @@ async function computeBuildHashInternal(
|
||||
* Computes buildHash from build config.
|
||||
* This is the single source of truth for build hash computation.
|
||||
*/
|
||||
export async function computeBuildHash(config: Doc<"builds">["config"]): Promise<{ hash: string; flags: string }> {
|
||||
const flags = computeFlagsFromConfig(config)
|
||||
export async function computeBuildHash(
|
||||
config: Doc<"builds">["config"],
|
||||
registryData?: Record<string, { configOptions?: Record<string, { define: string }> }>
|
||||
): Promise<{ hash: string; flags: string }> {
|
||||
const flags = computeFlagsFromConfig(config, registryData)
|
||||
const plugins = config.pluginsEnabled ?? []
|
||||
const hash = await computeBuildHashInternal(config.version, config.target, flags, plugins)
|
||||
const hash = await computeBuildHashInternal(config.version, config.target, flags, plugins, config.pluginConfigs)
|
||||
return { hash, flags }
|
||||
}
|
||||
|
||||
@@ -185,6 +202,8 @@ export const ensureBuildFromConfig = mutation({
|
||||
version: v.string(),
|
||||
modulesExcluded: v.optional(v.record(v.string(), v.boolean())),
|
||||
pluginsEnabled: v.optional(v.array(v.string())),
|
||||
pluginConfigs: v.optional(v.record(v.string(), v.record(v.string(), v.boolean()))),
|
||||
registryData: v.optional(v.any()),
|
||||
profileName: v.optional(v.string()),
|
||||
profileDescription: v.optional(v.string()),
|
||||
},
|
||||
@@ -195,10 +214,15 @@ export const ensureBuildFromConfig = mutation({
|
||||
modulesExcluded: args.modulesExcluded ?? {},
|
||||
target: args.target,
|
||||
pluginsEnabled: args.pluginsEnabled,
|
||||
pluginConfigs: args.pluginConfigs,
|
||||
}
|
||||
|
||||
// Compute build hash (single source of truth)
|
||||
const { hash: buildHash, flags } = await computeBuildHash(config)
|
||||
// Registry data is optional - diagnostics works for all plugins without registry lookup
|
||||
const registryData = args.registryData as
|
||||
| Record<string, { configOptions?: Record<string, { define: string }> }>
|
||||
| undefined
|
||||
const { hash: buildHash, flags } = await computeBuildHash(config, registryData)
|
||||
|
||||
const existingBuild = await ctx.db
|
||||
.query("builds")
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import type { Doc } from "../_generated/dataModel"
|
||||
|
||||
/**
|
||||
* Computes flags string from build config.
|
||||
* Only excludes modules explicitly marked as excluded (config[id] === true).
|
||||
* Also includes plugin config options (e.g., diagnostics).
|
||||
*
|
||||
* @param config - Build configuration with modulesExcluded and pluginConfigs
|
||||
* @param registryData - Optional registry data for custom config options (not needed for diagnostics)
|
||||
*/
|
||||
export function computeFlagsFromConfig(
|
||||
config: Doc<"builds">["config"],
|
||||
registryData?: Record<string, { configOptions?: Record<string, { define: string }> }>
|
||||
): string {
|
||||
const flags: string[] = []
|
||||
|
||||
// Sort modules to ensure consistent order
|
||||
const moduleFlags = Object.keys(config.modulesExcluded)
|
||||
.sort()
|
||||
.filter(module => config.modulesExcluded[module])
|
||||
.map((moduleExcludedName: string) => `-D${moduleExcludedName}=1`)
|
||||
flags.push(...moduleFlags)
|
||||
|
||||
// Add plugin config options (diagnostics is available for all plugins)
|
||||
if (config.pluginConfigs) {
|
||||
for (const [pluginSlug, pluginOptions] of Object.entries(config.pluginConfigs)) {
|
||||
// Handle diagnostics option (available for all plugins)
|
||||
if (pluginOptions.diagnostics) {
|
||||
// Convert plugin slug to uppercase define name (e.g., "lofs" -> "LOFS_PLUGIN_DIAGNOSTICS")
|
||||
const defineName = `${pluginSlug.toUpperCase().replace(/-/g, "_")}_PLUGIN_DIAGNOSTICS`
|
||||
flags.push(`-D${defineName}`)
|
||||
}
|
||||
|
||||
// Handle other custom config options from registry (if any)
|
||||
if (registryData) {
|
||||
const plugin = registryData[pluginSlug]
|
||||
if (plugin?.configOptions) {
|
||||
for (const [optionKey, enabled] of Object.entries(pluginOptions)) {
|
||||
if (optionKey !== "diagnostics" && enabled) {
|
||||
const option = plugin.configOptions[optionKey]
|
||||
if (option?.define) {
|
||||
flags.push(`-D${option.define}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return flags.join(" ")
|
||||
}
|
||||
@@ -7,6 +7,7 @@ export const buildConfigFields = {
|
||||
modulesExcluded: v.record(v.string(), v.boolean()),
|
||||
target: v.string(),
|
||||
pluginsEnabled: v.optional(v.array(v.string())),
|
||||
pluginConfigs: v.optional(v.record(v.string(), v.record(v.string(), v.boolean()))),
|
||||
}
|
||||
|
||||
export const profileFields = {
|
||||
|
||||
Reference in New Issue
Block a user