import { Command } from '@effect/cli'; import { Command as PlatformCommand } from '@effect/platform'; import { BunContext, BunRuntime } from '@effect/platform-bun'; import { Effect } from 'effect'; import pkg from '../package.json' with { type: 'json' }; import { defineConfig, defineWingetPackage } from './dsl'; import { CommandUtils } from './utils'; import { decodeAndPrettyLogTestResult, decodeAndPrettyLogSetResult, } from './dsc-utils'; const machineConfig = defineConfig({ $schema: 'https://aka.ms/dsc/schemas/v3/config/document.json', resources: [ // { // name: 'example-registry-key', // type: 'Microsoft.Windows/Registry', // properties: { // keyPath: 'HKCU\\Software\\WinosConfig', // valueName: 'Version', // valueData: { // String: pkg.version, // }, // _exist: true, // }, // }, defineWingetPackage({ id: 'BurntSushi.ripgrep.MSVC' }), ], }); const runDscConfig = ( subcommand: 'set' | 'test', options: { whatIf?: boolean } = {}, ) => Effect.gen(function* () { const args = ['config', subcommand, '--file', '-']; if (options.whatIf) { args.push('--what-if'); } yield* Effect.logDebug(`Running dsc ${args.join(' ')}`); const command = PlatformCommand.make('dsc', ...args).pipe( PlatformCommand.feed(JSON.stringify(machineConfig)), ); const { exitCode, stdout, stderr } = yield* CommandUtils.runCommandBuffered(command); if (stderr) { yield* Effect.logError(stderr); } if (exitCode !== 0) { yield* Effect.logError(`DSC exited with code ${exitCode}`); } if (stdout) { if (subcommand === 'test') { yield* decodeAndPrettyLogTestResult(stdout); } else if (subcommand === 'set') { yield* decodeAndPrettyLogSetResult(stdout); } else { try { const parsed = JSON.parse(stdout); yield* Effect.log(JSON.stringify(parsed, null, 2)); } catch { yield* Effect.log(stdout); } } } else if (exitCode === 0 && !stderr) { yield* Effect.log('DSC completed successfully with no output.'); } }); const setCommand = Command.make('set', {}, () => Effect.gen(function* () { yield* Effect.log('Applying configuration changes...'); yield* runDscConfig('set').pipe(Effect.scoped); }), ); const testCommand = Command.make('test', {}, () => Effect.gen(function* () { yield* Effect.log('Running configuration test...'); yield* runDscConfig('test').pipe(Effect.scoped); }), ); const cliName = 'winos-config'; const app = Command.make(cliName, {}).pipe( Command.withDescription('NixOS-like tool for windows'), Command.withSubcommands([setCommand, testCommand]), ); const cli = Command.run(app, { name: cliName, version: pkg.version, }); cli(process.argv).pipe(Effect.provide(BunContext.layer), BunRuntime.runMain);