refactor: unwrap TuiConfig namespace + self-reexport (#22952)
This commit is contained in:
@@ -17,43 +17,42 @@ import { InstallationLocal, InstallationVersion } from "@/installation/version"
|
|||||||
import { makeRuntime } from "@/cli/effect/runtime"
|
import { makeRuntime } from "@/cli/effect/runtime"
|
||||||
import { Filesystem, Log } from "@/util"
|
import { Filesystem, Log } from "@/util"
|
||||||
|
|
||||||
export namespace TuiConfig {
|
const log = Log.create({ service: "tui.config" })
|
||||||
const log = Log.create({ service: "tui.config" })
|
|
||||||
|
|
||||||
export const Info = TuiInfo
|
export const Info = TuiInfo
|
||||||
|
|
||||||
type Acc = {
|
type Acc = {
|
||||||
result: Info
|
result: Info
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
config: Info
|
config: Info
|
||||||
deps: Array<Fiber.Fiber<void, AppFileSystem.Error>>
|
deps: Array<Fiber.Fiber<void, AppFileSystem.Error>>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Info = z.output<typeof Info> & {
|
export type Info = z.output<typeof Info> & {
|
||||||
// Internal resolved plugin list used by runtime loading.
|
// Internal resolved plugin list used by runtime loading.
|
||||||
plugin_origins?: ConfigPlugin.Origin[]
|
plugin_origins?: ConfigPlugin.Origin[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Interface {
|
export interface Interface {
|
||||||
readonly get: () => Effect.Effect<Info>
|
readonly get: () => Effect.Effect<Info>
|
||||||
readonly waitForDependencies: () => Effect.Effect<void>
|
readonly waitForDependencies: () => Effect.Effect<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Service extends Context.Service<Service, Interface>()("@opencode/TuiConfig") {}
|
export class Service extends Context.Service<Service, Interface>()("@opencode/TuiConfig") {}
|
||||||
|
|
||||||
function pluginScope(file: string, ctx: { directory: string }): ConfigPlugin.Scope {
|
function pluginScope(file: string, ctx: { directory: string }): ConfigPlugin.Scope {
|
||||||
if (Filesystem.contains(ctx.directory, file)) return "local"
|
if (Filesystem.contains(ctx.directory, file)) return "local"
|
||||||
// if (ctx.worktree !== "/" && Filesystem.contains(ctx.worktree, file)) return "local"
|
// if (ctx.worktree !== "/" && Filesystem.contains(ctx.worktree, file)) return "local"
|
||||||
return "global"
|
return "global"
|
||||||
}
|
}
|
||||||
|
|
||||||
function customPath() {
|
function customPath() {
|
||||||
return Flag.OPENCODE_TUI_CONFIG
|
return Flag.OPENCODE_TUI_CONFIG
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalize(raw: Record<string, unknown>) {
|
function normalize(raw: Record<string, unknown>) {
|
||||||
const data = { ...raw }
|
const data = { ...raw }
|
||||||
if (!("tui" in data)) return data
|
if (!("tui" in data)) return data
|
||||||
if (!isRecord(data.tui)) {
|
if (!isRecord(data.tui)) {
|
||||||
@@ -67,17 +66,17 @@ export namespace TuiConfig {
|
|||||||
...tui,
|
...tui,
|
||||||
...data,
|
...data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resolvePlugins(config: Info, configFilepath: string) {
|
async function resolvePlugins(config: Info, configFilepath: string) {
|
||||||
if (!config.plugin) return config
|
if (!config.plugin) return config
|
||||||
for (let i = 0; i < config.plugin.length; i++) {
|
for (let i = 0; i < config.plugin.length; i++) {
|
||||||
config.plugin[i] = await ConfigPlugin.resolvePluginSpec(config.plugin[i], configFilepath)
|
config.plugin[i] = await ConfigPlugin.resolvePluginSpec(config.plugin[i], configFilepath)
|
||||||
}
|
}
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
async function mergeFile(acc: Acc, file: string, ctx: { directory: string }) {
|
async function mergeFile(acc: Acc, file: string, ctx: { directory: string }) {
|
||||||
const data = await loadFile(file)
|
const data = await loadFile(file)
|
||||||
acc.result = mergeDeep(acc.result, data)
|
acc.result = mergeDeep(acc.result, data)
|
||||||
if (!data.plugin?.length) return
|
if (!data.plugin?.length) return
|
||||||
@@ -89,9 +88,9 @@ export namespace TuiConfig {
|
|||||||
])
|
])
|
||||||
acc.result.plugin = plugins.map((item) => item.spec)
|
acc.result.plugin = plugins.map((item) => item.spec)
|
||||||
acc.result.plugin_origins = plugins
|
acc.result.plugin_origins = plugins
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadState(ctx: { directory: string }) {
|
async function loadState(ctx: { directory: string }) {
|
||||||
let projectFiles = Flag.OPENCODE_DISABLE_PROJECT_CONFIG ? [] : await ConfigPaths.projectFiles("tui", ctx.directory)
|
let projectFiles = Flag.OPENCODE_DISABLE_PROJECT_CONFIG ? [] : await ConfigPaths.projectFiles("tui", ctx.directory)
|
||||||
const directories = await ConfigPaths.directories(ctx.directory)
|
const directories = await ConfigPaths.directories(ctx.directory)
|
||||||
const custom = customPath()
|
const custom = customPath()
|
||||||
@@ -140,9 +139,9 @@ export namespace TuiConfig {
|
|||||||
config: acc.result,
|
config: acc.result,
|
||||||
dirs: acc.result.plugin?.length ? dirs : [],
|
dirs: acc.result.plugin?.length ? dirs : [],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const layer = Layer.effect(
|
export const layer = Layer.effect(
|
||||||
Service,
|
Service,
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const directory = yield* CurrentWorkingDirectory
|
const directory = yield* CurrentWorkingDirectory
|
||||||
@@ -168,30 +167,30 @@ export namespace TuiConfig {
|
|||||||
)
|
)
|
||||||
return Service.of({ get, waitForDependencies })
|
return Service.of({ get, waitForDependencies })
|
||||||
}).pipe(Effect.withSpan("TuiConfig.layer")),
|
}).pipe(Effect.withSpan("TuiConfig.layer")),
|
||||||
)
|
)
|
||||||
|
|
||||||
export const defaultLayer = layer.pipe(Layer.provide(Npm.defaultLayer))
|
export const defaultLayer = layer.pipe(Layer.provide(Npm.defaultLayer))
|
||||||
|
|
||||||
const { runPromise } = makeRuntime(Service, defaultLayer)
|
const { runPromise } = makeRuntime(Service, defaultLayer)
|
||||||
|
|
||||||
export async function waitForDependencies() {
|
export async function waitForDependencies() {
|
||||||
await runPromise((svc) => svc.waitForDependencies())
|
await runPromise((svc) => svc.waitForDependencies())
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function get() {
|
export async function get() {
|
||||||
return runPromise((svc) => svc.get())
|
return runPromise((svc) => svc.get())
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadFile(filepath: string): Promise<Info> {
|
async function loadFile(filepath: string): Promise<Info> {
|
||||||
const text = await ConfigPaths.readFile(filepath)
|
const text = await ConfigPaths.readFile(filepath)
|
||||||
if (!text) return {}
|
if (!text) return {}
|
||||||
return load(text, filepath).catch((error) => {
|
return load(text, filepath).catch((error) => {
|
||||||
log.warn("failed to load tui config", { path: filepath, error })
|
log.warn("failed to load tui config", { path: filepath, error })
|
||||||
return {}
|
return {}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function load(text: string, configFilepath: string): Promise<Info> {
|
async function load(text: string, configFilepath: string): Promise<Info> {
|
||||||
return ConfigParse.load(Info, text, {
|
return ConfigParse.load(Info, text, {
|
||||||
type: "path",
|
type: "path",
|
||||||
path: configFilepath,
|
path: configFilepath,
|
||||||
@@ -209,5 +208,6 @@ export namespace TuiConfig {
|
|||||||
log.warn("invalid tui config", { path: configFilepath, error })
|
log.warn("invalid tui config", { path: configFilepath, error })
|
||||||
return {}
|
return {}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export * as TuiConfig from "./tui"
|
||||||
|
|||||||
Reference in New Issue
Block a user