(slug: string)
| 64 | * (git commands, hook execution, chdir). |
| 65 | */ |
| 66 | export function validateWorktreeSlug(slug: string): void { |
| 67 | if (slug.length > MAX_WORKTREE_SLUG_LENGTH) { |
| 68 | throw new Error( |
| 69 | `Invalid worktree name: must be ${MAX_WORKTREE_SLUG_LENGTH} characters or fewer (got ${slug.length})`, |
| 70 | ) |
| 71 | } |
| 72 | // Leading or trailing `/` would make path.join produce an absolute path |
| 73 | // or a dangling segment. Splitting and validating each segment rejects |
| 74 | // both (empty segments fail the regex) while allowing `user/feature`. |
| 75 | for (const segment of slug.split('/')) { |
| 76 | if (segment === '.' || segment === '..') { |
| 77 | throw new Error( |
| 78 | `Invalid worktree name "${slug}": must not contain "." or ".." path segments`, |
| 79 | ) |
| 80 | } |
| 81 | if (!VALID_WORKTREE_SLUG_SEGMENT.test(segment)) { |
| 82 | throw new Error( |
| 83 | `Invalid worktree name "${slug}": each "/"-separated segment must be non-empty and contain only letters, digits, dots, underscores, and dashes`, |
| 84 | ) |
| 85 | } |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | // Helper function to create directories recursively |
| 90 | async function mkdirRecursive(dirPath: string): Promise<void> { |
no outgoing calls
no test coverage detected