fix: use tag-specific complexity reports (#857)
* fix(expand-task): Use tag-specific complexity reports - Add getTagAwareFilePath utility function to resolve tag-specific file paths - Update expandTask to use tag-aware complexity report paths - Fix issue where expand-task always used default complexity report - Add comprehensive tests for getTagAwareFilePath utility - Ensure proper handling of file extensions and directory structures Fixes #850: Expanding tasks not using tag-specific complexity reports The expandTask function now correctly uses complexity reports specific to the current tag context (e.g., task-complexity-report_feature-branch.json) instead of always using the default task-complexity-report.json file. This enables proper task expansion behavior when working with multiple tag contexts, ensuring complexity analysis is tag-specific and accurate. * chore: Add changeset for tag-specific complexity reports fix * test(expand-task): Add tests for tag-specific complexity report integration - Introduced a new test suite for verifying the integration of tag-specific complexity reports in the expandTask function. - Added a test case to ensure the correct complexity report is used when available for a specific tag. - Mocked file system interactions to simulate the presence of tag-specific complexity reports. This enhances the test coverage for task expansion behavior, ensuring it accurately reflects the complexity analysis based on the current tag context. * refactor(task-manager): unify and simplify tag-aware file path logic and tests - Reformatted imports and cleaned up comments in test files for readability - Centralized mocks: moved getTagAwareFilePath & slugifyTagForFilePath mocks to setup.js for consistency and maintainability - Simplified utils/getTagAwareFilePath: replaced manual parsing with path.parse() & path.format(); improved extension handling - Enhanced test mocks for path.parse, path.format & reset path.join in beforeEach to avoid interference - All tests now pass consistently; no change in functionality
This commit is contained in:
@@ -2,7 +2,13 @@ import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { log, readJSON, writeJSON, isSilentMode } from '../utils.js';
|
||||
import {
|
||||
log,
|
||||
readJSON,
|
||||
writeJSON,
|
||||
isSilentMode,
|
||||
getTagAwareFilePath
|
||||
} from '../utils.js';
|
||||
|
||||
import {
|
||||
startLoadingIndicator,
|
||||
@@ -497,9 +503,18 @@ async function expandTask(
|
||||
let complexityReasoningContext = '';
|
||||
let systemPrompt; // Declare systemPrompt here
|
||||
|
||||
const complexityReportPath = path.join(projectRoot, COMPLEXITY_REPORT_FILE);
|
||||
// Use tag-aware complexity report path
|
||||
const complexityReportPath = getTagAwareFilePath(
|
||||
COMPLEXITY_REPORT_FILE,
|
||||
tag,
|
||||
projectRoot
|
||||
);
|
||||
let taskAnalysis = null;
|
||||
|
||||
logger.info(
|
||||
`Looking for complexity report at: ${complexityReportPath}${tag && tag !== 'master' ? ` (tag-specific for '${tag}')` : ''}`
|
||||
);
|
||||
|
||||
try {
|
||||
if (fs.existsSync(complexityReportPath)) {
|
||||
const complexityReport = readJSON(complexityReportPath);
|
||||
|
||||
@@ -64,6 +64,51 @@ function resolveEnvVariable(key, session = null, projectRoot = null) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// --- Tag-Aware Path Resolution Utility ---
|
||||
|
||||
/**
|
||||
* Slugifies a tag name to be filesystem-safe
|
||||
* @param {string} tagName - The tag name to slugify
|
||||
* @returns {string} Slugified tag name safe for filesystem use
|
||||
*/
|
||||
function slugifyTagForFilePath(tagName) {
|
||||
if (!tagName || typeof tagName !== 'string') {
|
||||
return 'unknown-tag';
|
||||
}
|
||||
|
||||
// Replace invalid filesystem characters with hyphens and clean up
|
||||
return tagName
|
||||
.replace(/[^a-zA-Z0-9_-]/g, '-') // Replace invalid chars with hyphens
|
||||
.replace(/^-+|-+$/g, '') // Remove leading/trailing hyphens
|
||||
.replace(/-+/g, '-') // Collapse multiple hyphens
|
||||
.toLowerCase() // Convert to lowercase
|
||||
.substring(0, 50); // Limit length to prevent overly long filenames
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a file path to be tag-aware, following the pattern used by other commands.
|
||||
* For non-master tags, appends _slugified-tagname before the file extension.
|
||||
* @param {string} basePath - The base file path (e.g., '.taskmaster/reports/task-complexity-report.json')
|
||||
* @param {string|null} tag - The tag name (null, undefined, or 'master' uses base path)
|
||||
* @param {string} [projectRoot='.'] - The project root directory
|
||||
* @returns {string} The resolved file path
|
||||
*/
|
||||
function getTagAwareFilePath(basePath, tag, projectRoot = '.') {
|
||||
// Use path.parse and format for clean tag insertion
|
||||
const parsedPath = path.parse(basePath);
|
||||
if (!tag || tag === 'master') {
|
||||
return path.join(projectRoot, basePath);
|
||||
}
|
||||
|
||||
// Slugify the tag for filesystem safety
|
||||
const slugifiedTag = slugifyTagForFilePath(tag);
|
||||
|
||||
// Append slugified tag before file extension
|
||||
parsedPath.base = `${parsedPath.name}_${slugifiedTag}${parsedPath.ext}`;
|
||||
const relativePath = path.format(parsedPath);
|
||||
return path.join(projectRoot, relativePath);
|
||||
}
|
||||
|
||||
// --- Project Root Finding Utility ---
|
||||
/**
|
||||
* Recursively searches upwards for project root starting from a given directory.
|
||||
@@ -1338,6 +1383,8 @@ export {
|
||||
addComplexityToTask,
|
||||
resolveEnvVariable,
|
||||
findProjectRoot,
|
||||
getTagAwareFilePath,
|
||||
slugifyTagForFilePath,
|
||||
aggregateTelemetry,
|
||||
getCurrentTag,
|
||||
resolveTag,
|
||||
|
||||
Reference in New Issue
Block a user