import * as path from 'path'; import inquirer from 'inquirer'; import { findAllContextFiles, File } from '../filesystem/findAllContextFiles'; interface ContextFileOption { name: string value: string checked: boolean } /** * Prompts the user to select a context file from the list of context files in the context directory. * * @param contextDirectory The directory to search for context files in * @returns The absolute path of the selected context file */ async function selectContext(contextDirectory: string): Promise { const contextFiles = await findAllContextFiles(contextDirectory) // In the .env file, you specify which files are default context files. const defaultFileNames = process.env.DEFAULT_CONTEXT_FILES?.split(" ") ?? [] exitIfDefaultContextSpecifiedButNotFileWithNameExists(defaultFileNames, contextFiles) // If there are no context files, return null if (contextFiles.length === 0) { throw new Error("No context files found. Please create at least one context file and try again. Please see README for more details."); } // If there is only one context file, just return that and don't ask the user for input if (contextFiles.length === 1) { const absolutePathOfOnlyContextFile = contextFiles[0].absolutePath return [absolutePathOfOnlyContextFile] } warnUserIfNoContextFilesAreDefault(contextFiles, defaultFileNames) const contextFileOptions = contextFiles.map(file => { const preChecked = defaultFileNames?.includes(file.fileName) ?? false const contextFileOption: ContextFileOption = { name: file.fileName, value: file.absolutePath, checked: preChecked } return contextFileOption }) // This will prompt the user to select a value from the list, and they select by pressing 'Enter'. // The 'name' field will be displayed, and the 'value' field will be returned. interface InquirerResponse { contextSelection: string[] } const selectedContext: InquirerResponse = await inquirer.prompt([ { type: 'checkbox', name: 'contextSelection', message: 'Please select context for this PR review', choices: contextFileOptions }, ]) return selectedContext.contextSelection } function warnUserIfNoContextFilesAreDefault(contextFiles: File[], defaultContextFiles: string[]) { const contextFileNames = contextFiles.map(file => file.fileName) const noContextFilesAreDefault = contextFileNames.every(fileName => !defaultContextFiles.includes(fileName)) if (noContextFilesAreDefault) { process.stdout.write("WARNING: You have not selected any default context files in the .env file. See README for more details.") } } function exitIfDefaultContextSpecifiedButNotFileWithNameExists(defaultContextFiles: string[], contextFiles: File[]) { const contextFileNames = contextFiles.map(file => file.fileName) const defaultContextFilesNotInContextFiles = defaultContextFiles.every(fileName => !contextFileNames.includes(fileName)) if (defaultContextFilesNotInContextFiles) { const defaultContextFilesString = defaultContextFiles.join(", ") process.stdout.write(`The default context files specified in the .env file do not exist. Please check your .env file and ensure that the default context files are specified correctly. Exiting. Default context files specified: ${defaultContextFilesString}`) process.exit() } } export { selectContext }