|
1 | 1 | import { type ExecSyncOptions, execSync } from "node:child_process" |
2 | 2 | import { cpSync, existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs" |
3 | 3 | import os from "node:os" |
4 | | -import { join, resolve } from "node:path" |
| 4 | +import { join, relative, resolve } from "node:path" |
5 | 5 | import { parseArgs } from "node:util" |
6 | 6 | import chalk from "chalk" |
7 | 7 | import semver from "semver" |
@@ -33,6 +33,30 @@ const resetDir = (p: string) => { |
33 | 33 | const contentDir = "content" |
34 | 34 | const workspaceRoot = process.cwd() |
35 | 35 | const outputDir = resolve(workspaceRoot, "generated-docs") |
| 36 | + |
| 37 | +// If this script is executed from a subdirectory of the repository (for example |
| 38 | +// the `docs/` package inside a monorepo), we need the path of that subdir |
| 39 | +// relative to the repository root so worktrees point at the right package. |
| 40 | +let repoRoot = workspaceRoot |
| 41 | +let workspaceRelativePath = "" |
| 42 | +try { |
| 43 | + // This will return the repository top-level directory. |
| 44 | + repoRoot = run("git rev-parse --show-toplevel") |
| 45 | + // Compute the path from repo root to the current working dir. If empty, |
| 46 | + // we are at repo root and no adjustment is needed. |
| 47 | + // Use posix-style join/resolve via path utilities already imported. |
| 48 | + workspaceRelativePath = repoRoot === workspaceRoot ? "" : relative(repoRoot, workspaceRoot) |
| 49 | +} catch { |
| 50 | + // If git is not available or the command fails, fall back to assuming the |
| 51 | + // current working directory is the repository root. |
| 52 | + repoRoot = workspaceRoot |
| 53 | + workspaceRelativePath = "" |
| 54 | +} |
| 55 | + |
| 56 | +// biome-ignore lint/suspicious/noConsole: TODO remove this |
| 57 | +console.log(chalk.cyan(`Docs workspace root: ${workspaceRoot}`)) |
| 58 | +// biome-ignore lint/suspicious/noConsole: TODO remove this |
| 59 | +console.log("outputDir:", outputDir) |
36 | 60 | const allTags = () => run("git tag --list").split("\n").filter(Boolean) |
37 | 61 |
|
38 | 62 | function resolveTagsFromSpec(spec: string) { |
@@ -64,6 +88,8 @@ function buildDocs(sourceDir: string, outDir: string) { |
64 | 88 | ) |
65 | 89 | } |
66 | 90 |
|
| 91 | + // biome-ignore lint/suspicious/noConsole: TODO remove this |
| 92 | + console.log(chalk.cyan(`Building docs from: ${sourceDir} → ${outDir}`)) |
67 | 93 | const docsContentDir = resolve(sourceDir, contentDir) |
68 | 94 | if (!existsSync(docsContentDir)) { |
69 | 95 | throw new Error( |
@@ -123,8 +149,12 @@ function buildRef(ref: string, labelForOutDir: string) { |
123 | 149 | }) |
124 | 150 | } |
125 | 151 |
|
| 152 | + // If this script was run from a subdirectory (for example `docs/` inside |
| 153 | + // a monorepo), adjust the sourceDir inside the created worktree so we |
| 154 | + // build the correct package. |
| 155 | + const sourceDir = workspaceRelativePath ? resolve(worktreePath, workspaceRelativePath) : worktreePath |
126 | 156 | const outDir = resolve(outputDir, labelForOutDir) |
127 | | - buildDocs(worktreePath, outDir) |
| 157 | + buildDocs(sourceDir, outDir) |
128 | 158 | } finally { |
129 | 159 | run(`git worktree remove "${worktreePath}" --force`, { |
130 | 160 | cwd: workspaceRoot, |
|
0 commit comments