Skip to content

Refactor path handling#1

Merged
JUVOJustin merged 3 commits intomainfrom
simplify-api-fix-path-commands
Nov 28, 2025
Merged

Refactor path handling#1
JUVOJustin merged 3 commits intomainfrom
simplify-api-fix-path-commands

Conversation

@JUVOJustin
Copy link
Owner

@JUVOJustin JUVOJustin commented Nov 28, 2025

This pull request refactors the DDEV plugin implementation in ddev.ts to improve command handling, caching, and project state detection. The changes replace the previous status-checking logic with a more robust caching system, introduce advanced command cleaning to ensure correct container execution, and streamline the interface for checking DDEV availability and running state.

The main reason for this PR was that path were previously fixed only for cd bash commands. Now all commands are processed. I came across this issue when the ai executed mkdirinside ddev, but with the full path. This is the solution.

Caching and State Detection Improvements

  • Replaced the old DdevStatus type and status-checking logic with a new DdevCache structure, which caches raw DDEV project data and only persists the cache when DDEV is running. Added helper functions isAvailable() and isRunning() for more reliable state checks. [1] [2] [3]

Command Cleaning and Path Handling

  • Introduced the cleanCommand() function to convert host paths to container-relative paths, remove redundant cd commands, and ensure commands are properly formatted for container execution. This replaces the previous removeRedundantCd() logic and is used in the new wrapWithDdevExec() function. [1] [2]

Container Working Directory Calculation

  • Added getContainerWorkingDir() to dynamically determine the correct container working directory based on the host directory and DDEV project root, improving path mapping for commands executed in the container. [1] [2]

Plugin Initialization and Event Handling

  • Updated plugin initialization and event handling to use the new caching and state detection logic, ensuring that commands are only wrapped and executed in the container when DDEV is available and running. [1] [2]

Logging and Tool Registration

  • Improved debug logging to reflect the new command cleaning process, and updated tool registration logic to use the new availability check.

These changes make the DDEV plugin more robust and maintainable by improving state management, command handling, and container path mapping.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the DDEV plugin to improve path handling across all commands (not just cd commands). The refactor replaces the previous status-checking approach with a more robust caching system, introduces comprehensive path cleaning that converts host paths to container paths, and streamlines the DDEV availability detection interface.

  • Replaced DdevStatus with DdevCache structure that caches raw DDEV project data with timestamp-based invalidation
  • Introduced cleanCommand() function that converts host paths to container-relative paths for all commands (previously only handled cd)
  • Added helper functions (isAvailable(), isRunning(), getProjectRoot(), getContainerWorkingDir()) for cleaner state management

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

ddev.ts Outdated
const containerWorkingDir = getContainerWorkingDir();
const escapedCommand = JSON.stringify(cleanedCommand);

return `ddev exec --dir="${containerWorkingDir}" bash -c ${escapedCommand}`;
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The containerWorkingDir is interpolated directly into the command string without escaping on line 292. If the container working directory path contains special characters (e.g., quotes, spaces), this could break the generated ddev exec command.

While it's unlikely that DDEV container paths would contain such characters (they're typically under /var/www/html), consider using proper escaping or validation for robustness. For example:

return `ddev exec --dir=${JSON.stringify(containerWorkingDir)} bash -c ${escapedCommand}`;

Or add validation to ensure containerWorkingDir doesn't contain problematic characters.

Suggested change
return `ddev exec --dir="${containerWorkingDir}" bash -c ${escapedCommand}`;
return `ddev exec --dir=${JSON.stringify(containerWorkingDir)} bash -c ${escapedCommand}`;

Copilot uses AI. Check for mistakes.
ddev.ts Outdated

const output = result.stdout.toString();
const { path: projectRoot, status: projectStatus } = extractProjectInfo(output);
const data = JSON.parse(output);
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The JSON.parse(output) call on line 249 could throw an error if the output from ddev describe -j is malformed JSON. While this is caught by the try-catch block on lines 239-268, it would be helpful to have more specific error handling or logging to distinguish between parse errors and other errors.

Consider adding a specific try-catch around the JSON.parse to provide clearer error messages, e.g.:

let data;
try {
  data = JSON.parse(output);
} catch (parseError) {
  console.error(`Failed to parse DDEV JSON output: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
  ddevCache = null;
  return;
}

This would make debugging easier if DDEV's output format changes or becomes corrupted.

Suggested change
const data = JSON.parse(output);
let data;
try {
data = JSON.parse(output);
} catch (parseError) {
console.error(`Failed to parse DDEV JSON output: ${parseError instanceof Error ? parseError.message : String(parseError)}`);
ddevCache = null;
return;
}

Copilot uses AI. Check for mistakes.
@JUVOJustin JUVOJustin merged commit e623d7e into main Nov 28, 2025
@JUVOJustin JUVOJustin deleted the simplify-api-fix-path-commands branch November 28, 2025 18:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants