Add QMD_CONFIG_DIR environment variable for test isolation

Collections module now supports QMD_CONFIG_DIR environment variable
to override the default config directory (~/.config/qmd). This allows
tests to use isolated YAML config files without affecting the user's
actual configuration.

All CONFIG_PATH and CONFIG_DIR references now use dynamic functions
that check the environment variable.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Tobi Lutke 2025-12-13 11:19:03 -05:00
parent 47f58c6c14
commit 0c7f65f95a
No known key found for this signature in database
2 changed files with 13 additions and 10 deletions

View File

@ -33,5 +33,5 @@
{"id":"qmd-vro","title":"Update 'qmd get' to support virtual paths","description":"Allow qmd get to accept both virtual paths (qmd://journals/...) and filesystem paths, plus fuzzy matching by filename.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-12-12T15:29:53.963113-05:00","updated_at":"2025-12-12T15:47:29.178955-05:00","closed_at":"2025-12-12T15:47:29.178955-05:00","dependencies":[{"issue_id":"qmd-vro","depends_on_id":"qmd-ama","type":"discovered-from","created_at":"2025-12-12T15:29:53.963641-05:00","created_by":"daemon"}]}
{"id":"qmd-x19","title":"Update 'qmd add-context' for collection-scoped contexts","description":"Update add-context to work with collections:\n- qmd add-context \u003ccollection\u003e/\u003cpath\u003e \"context description\"\n- Support both virtual and filesystem paths\n- Update to use new path_contexts schema","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-12T15:29:38.142575-05:00","updated_at":"2025-12-12T15:53:00.525001-05:00","closed_at":"2025-12-12T15:53:00.525001-05:00"}
{"id":"qmd-x64","title":"for each collection, on update, check if there is a .git directory, if so write out the git status, add --pull as a qmd update --pull parameter which also executes git pull before reindexing\n","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-12T17:04:15.994054-05:00","updated_at":"2025-12-12T17:14:40.107181-05:00","closed_at":"2025-12-12T17:14:40.107181-05:00"}
{"id":"qmd-yzj","title":"Add optional update: command support to collections YAML","description":"Collections can now specify an optional 'update:' key with a bash command that will be executed during 'qmd update' before indexing files. Runs in cwd, prints output, stops on error.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-13T11:16:32.527608-05:00","updated_at":"2025-12-13T11:16:32.527608-05:00"}
{"id":"qmd-yzj","title":"Add optional update: command support to collections YAML","description":"Collections can now specify an optional 'update:' key with a bash command that will be executed during 'qmd update' before indexing files. Runs in cwd, prints output, stops on error.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-12-13T11:16:32.527608-05:00","updated_at":"2025-12-13T11:17:57.500434-05:00","closed_at":"2025-12-13T11:17:57.500434-05:00"}
{"id":"qmd-zin","title":"Improve qmd ls command to be more like ls -l with colors","description":"Make qmd ls more Unix-like:\n1. Format like ls -l with columns (permissions, size, date, name)\n2. Add colors (directories, files, etc.)\n3. Dim the qmd:// prefix to show it's optional\n4. Show file sizes in human-readable format\n5. Show modification times\n6. Consider adding -l flag for long format","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-13T09:44:48.703843-05:00","updated_at":"2025-12-13T09:48:22.298822-05:00","closed_at":"2025-12-13T09:48:22.298822-05:00"}

View File

@ -66,8 +66,9 @@ function getConfigFilePath(): string {
* Ensure config directory exists
*/
function ensureConfigDir(): void {
if (!existsSync(CONFIG_DIR)) {
mkdirSync(CONFIG_DIR, { recursive: true });
const configDir = getConfigDir();
if (!existsSync(configDir)) {
mkdirSync(configDir, { recursive: true });
}
}
@ -80,12 +81,13 @@ function ensureConfigDir(): void {
* Returns empty config if file doesn't exist
*/
export function loadConfig(): CollectionConfig {
if (!existsSync(CONFIG_PATH)) {
const configPath = getConfigFilePath();
if (!existsSync(configPath)) {
return { collections: {} };
}
try {
const content = readFileSync(CONFIG_PATH, "utf-8");
const content = readFileSync(configPath, "utf-8");
const config = YAML.parse(content) as CollectionConfig;
// Ensure collections object exists
@ -95,7 +97,7 @@ export function loadConfig(): CollectionConfig {
return config;
} catch (error) {
throw new Error(`Failed to parse ${CONFIG_PATH}: ${error}`);
throw new Error(`Failed to parse ${configPath}: ${error}`);
}
}
@ -104,15 +106,16 @@ export function loadConfig(): CollectionConfig {
*/
export function saveConfig(config: CollectionConfig): void {
ensureConfigDir();
const configPath = getConfigFilePath();
try {
const yaml = YAML.stringify(config, {
indent: 2,
lineWidth: 0, // Don't wrap lines
});
writeFileSync(CONFIG_PATH, yaml, "utf-8");
writeFileSync(configPath, yaml, "utf-8");
} catch (error) {
throw new Error(`Failed to write ${CONFIG_PATH}: ${error}`);
throw new Error(`Failed to write ${configPath}: ${error}`);
}
}
@ -356,14 +359,14 @@ export function findContextForPath(
* Get the config file path (useful for error messages)
*/
export function getConfigPath(): string {
return CONFIG_PATH;
return getConfigFilePath();
}
/**
* Check if config file exists
*/
export function configExists(): boolean {
return existsSync(CONFIG_PATH);
return existsSync(getConfigFilePath());
}
/**