Skip to content

fix: add pre-flight check for existing files and normalize target path#14

Draft
amarsingh-me wants to merge 1 commit into
zenika-open-source:mainfrom
amarsingh-me:feature/destination-file-check
Draft

fix: add pre-flight check for existing files and normalize target path#14
amarsingh-me wants to merge 1 commit into
zenika-open-source:mainfrom
amarsingh-me:feature/destination-file-check

Conversation

@amarsingh-me
Copy link
Copy Markdown

Adds check_existing_files (bash) / Test-ExistingFiles (PowerShell) to
abort early with a clear error if any destination files would be
overwritten, rather than silently clobbering them. Also strips trailing
slashes from the user-supplied target path so error messages never show
double slashes in file paths.

Adds check_existing_files (bash) / Test-ExistingFiles (PowerShell) to
  abort early with a clear error if any destination files would be
  overwritten, rather than silently clobbering them. Also strips trailing
  slashes from the user-supplied target path so error messages never show
  double slashes in file paths.
Copy link
Copy Markdown

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

Adds a pre-flight overwrite detection step to the init scripts and normalizes the user-provided target path to improve error output and prevent silent clobbering during scaffolding initialization.

Changes:

  • Normalize Bash TARGET_PATH by trimming a trailing slash.
  • Add a Bash check_existing_files pre-flight check that aborts if destination files already exist.
  • Add a PowerShell Test-ExistingFiles pre-flight check that aborts if destination files already exist.

Reviewed changes

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

File Description
scripts/init.sh Adds target-path normalization and a pre-flight scan intended to detect would-be overwrites before copying agents/instructions/guidelines and optional OpenCode/Claude assets.
scripts/init.ps1 Adds a pre-flight scan intended to detect would-be overwrites before copying agents/instructions/guidelines and optional OpenCode/Claude assets.

Comment thread scripts/init.sh
Comment on lines +164 to +182
for f in "${AGENTS_SRC_DIR}"/*.md; do
dst="${TARGET_AGENTS_DIR}/$(basename "$f")"
[[ -f "$dst" ]] && existing+=("$dst")
done

for f in "${INSTRUCTIONS_SRC_DIR}"/*.md; do
dst="${TARGET_INSTRUCTIONS_DIR}/$(basename "$f")"
[[ -f "$dst" ]] && existing+=("$dst")
done

for f in "${TARGET_GUIDELINES_DIR}"/*.md; do
[[ -f "$f" ]] && existing+=("$f")
done

if [[ "${DEPLOY_OPENCODE}" == "true" ]]; then
for f in "${AGENTS_SRC_DIR}"/*.md; do
agent_name=$(basename "$f" .md | sed 's/\.agent//')
dst="${TARGET_PATH}/.opencode/skills/${agent_name}/SKILL.md"
[[ -f "$dst" ]] && existing+=("$dst")
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

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

In check_existing_files, variables like dst and agent_name are assigned without local, which leaks them into the global scope and can lead to surprising interactions later in the script (especially with set -u). Declare these as local within the function (and within loops where appropriate) to keep the function side-effect free aside from existing.

Copilot uses AI. Check for mistakes.
Comment thread scripts/init.ps1
Comment on lines +171 to +174
Get-ChildItem (Join-Path $TargetGuidelinesDir '*.md') -ErrorAction SilentlyContinue | ForEach-Object {
if (Test-Path $_.FullName -PathType Leaf) { $existing += $_.FullName }
}

Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

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

This pre-flight check aborts if any *.md exists under $TargetGuidelinesDir, but the script overwrites only a fixed set of destination filenames (architecture-, review-, and optional documentation-* / conventions.md). This will incorrectly block runs when users have unrelated markdown files in that folder that wouldn’t be overwritten. Instead, test only the exact destination paths this run will write, based on $BackendDocFile/$FrontendDocFile and $includeConventions.

Suggested change
Get-ChildItem (Join-Path $TargetGuidelinesDir '*.md') -ErrorAction SilentlyContinue | ForEach-Object {
if (Test-Path $_.FullName -PathType Leaf) { $existing += $_.FullName }
}
$guidelineDestinations = @(
(Join-Path $TargetGuidelinesDir $BackendArchFile),
(Join-Path $TargetGuidelinesDir $BackendReviewFile),
(Join-Path $TargetGuidelinesDir $FrontendArchFile),
(Join-Path $TargetGuidelinesDir $FrontendReviewFile)
)
if ($BackendDocFile) {
$guidelineDestinations += Join-Path $TargetGuidelinesDir $BackendDocFile
}
if ($FrontendDocFile) {
$guidelineDestinations += Join-Path $TargetGuidelinesDir $FrontendDocFile
}
if ($includeConventions) {
$guidelineDestinations += Join-Path $TargetGuidelinesDir 'conventions.md'
}
$guidelineDestinations | ForEach-Object {
if ($_ -and (Test-Path $_ -PathType Leaf)) { $existing += $_ }
}

Copilot uses AI. Check for mistakes.
Comment thread scripts/init.sh
Comment on lines +62 to 63
TARGET_PATH="${TARGET_PATH%/}"

Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

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

TARGET_PATH="${TARGET_PATH%/}" only removes a single trailing slash and turns an input of / into an empty string, which then results in paths like /.github/... while printing an empty “Target path”. Consider trimming all trailing slashes while preserving / (and/or validating that TARGET_PATH is non-empty after normalization).

Suggested change
TARGET_PATH="${TARGET_PATH%/}"
while [[ "${TARGET_PATH}" != "/" && "${TARGET_PATH}" == */ ]]; do
TARGET_PATH="${TARGET_PATH%/}"
done
if [[ -z "${TARGET_PATH}" ]]; then
echo "Error: target path must not be empty." >&2
exit 1
fi

Copilot uses AI. Check for mistakes.
Comment thread scripts/init.sh
Comment on lines +174 to +176
for f in "${TARGET_GUIDELINES_DIR}"/*.md; do
[[ -f "$f" ]] && existing+=("$f")
done
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

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

The pre-flight check treats any existing *.md under .github/guidelines/ as a blocker, but this script only overwrites a fixed set of filenames (architecture-, review-, and optional documentation-* / conventions.md). As written, users with unrelated/custom markdown files in that directory will be prevented from running even though nothing would be overwritten. Update the check to test only the specific destination files that this run will write (based on BACKEND_DOC_FILE/FRONTEND_DOC_FILE and INCLUDE_CONVENTIONS).

Copilot uses AI. Check for mistakes.
@amarsingh-me amarsingh-me marked this pull request as draft April 26, 2026 17:01
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