1// Copyright 2025 The Pigweed Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); you may not 4// use this file except in compliance with the License. You may obtain a copy of 5// the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12// License for the specific language governing permissions and limitations under 13// the License. 14 15import * as fs from 'fs'; 16import * as fs_p from 'fs/promises'; 17import * as path from 'path'; 18 19import { parse as parseYaml } from 'yaml'; 20import { z } from 'zod'; 21import { workingDir } from './vscode'; 22 23const DEFAULT_BUILD_DIR_NAME = 'out'; 24const DEFAULT_TARGET_INFERENCE = '?'; 25const DEFAULT_WORKSPACE_ROOT = workingDir.get(); 26const DEFAULT_WORKING_DIR = workingDir.get(); 27const LEGACY_SETTINGS_FILE_PATH = path.join(workingDir.get(), '.pw_ide.yaml'); 28 29const legacySettingsSchema = z.object({ 30 cascade_settings: z.boolean().default(false), 31 clangd_alternate_path: z.string().optional(), 32 clangd_additional_query_drivers: z.array(z.string()).default([]), 33 compdb_gen_cmd: z.string().optional(), 34 compdb_search_paths: z 35 .array(z.array(z.string())) 36 .default([[DEFAULT_BUILD_DIR_NAME, DEFAULT_TARGET_INFERENCE]]), 37 default_target: z.string().optional(), 38 // TODO(chadnorvell): Test that this works with a non-default value. 39 workspace_root: z.string().default(DEFAULT_WORKSPACE_ROOT), 40 // needs some thought 41 sync: z.string().optional(), 42 targets_exclude: z.array(z.string()).default([]), 43 targets_include: z.array(z.string()).default([]), 44 target_inference: z.string().default('?'), 45 // TODO(chadnorvell): Test that this works with a non-default value. 46 working_dir: z.string().default(DEFAULT_WORKING_DIR), 47}); 48 49type LegacySettings = z.infer<typeof legacySettingsSchema>; 50 51export async function loadLegacySettings( 52 settingsData: string, 53 onFailureReturnDefault: true, 54): Promise<LegacySettings>; 55 56export async function loadLegacySettings( 57 settingsData: string, 58 onFailureReturnDefault?: false, 59): Promise<LegacySettings | null>; 60 61export async function loadLegacySettings( 62 settingsData: string, 63 onFailureReturnDefault = false, 64): Promise<LegacySettings | null> { 65 const fallback = onFailureReturnDefault 66 ? legacySettingsSchema.parse({}) 67 : null; 68 69 const parsed = parseYaml(settingsData); 70 if (!parsed) return fallback; 71 72 try { 73 return legacySettingsSchema.parse(parsed); 74 } catch { 75 return fallback; 76 } 77} 78 79export async function loadLegacySettingsFile(): Promise<string | null> { 80 if (!fs.existsSync(LEGACY_SETTINGS_FILE_PATH)) return null; 81 const data = await fs_p.readFile(LEGACY_SETTINGS_FILE_PATH); 82 return data.toString(); 83} 84