( targetDir: string, targetRepo: string, sha: string, offline = false, )
| 105 | } |
| 106 | |
| 107 | export function commitMetadata( |
| 108 | targetDir: string, |
| 109 | targetRepo: string, |
| 110 | sha: string, |
| 111 | offline = false, |
| 112 | ): CommitMetadata { |
| 113 | const separator = "\x1f"; |
| 114 | const raw = run( |
| 115 | "git", |
| 116 | [ |
| 117 | "show", |
| 118 | "-s", |
| 119 | `--format=%H${separator}%P${separator}%an${separator}%ae${separator}%cn${separator}%ce${separator}%aI${separator}%cI${separator}%s${separator}%B`, |
| 120 | sha, |
| 121 | ], |
| 122 | { cwd: targetDir }, |
| 123 | ); |
| 124 | const parts = raw.split(separator); |
| 125 | const body = parts.slice(9).join(separator); |
| 126 | // Offline mode (e.g. local-review) must not contact GitHub: skip the gh-api |
| 127 | // author/committer hydration. `gh` uses its own configured auth, so removing |
| 128 | // token env vars is not enough — the only way to honor the "no GitHub access" |
| 129 | // contract is to not run `gh` at all. |
| 130 | const githubAuthor = offline |
| 131 | ? "" |
| 132 | : optionalGhJson(`repos/${targetRepo}/commits/${sha}`, ".author.login // empty"); |
| 133 | const githubCommitter = offline |
| 134 | ? "" |
| 135 | : optionalGhJson(`repos/${targetRepo}/commits/${sha}`, ".committer.login // empty"); |
| 136 | return { |
| 137 | sha: assertSha(parts[0] ?? sha), |
| 138 | parents: (parts[1] ?? "") |
| 139 | .split(/\s+/) |
| 140 | .map((parent) => parent.trim()) |
| 141 | .filter(Boolean), |
| 142 | authorName: parts[2] ?? "", |
| 143 | authorEmail: parts[3] ?? "", |
| 144 | committerName: parts[4] ?? "", |
| 145 | committerEmail: parts[5] ?? "", |
| 146 | authoredAt: parts[6] ?? "", |
| 147 | committedAt: parts[7] ?? "", |
| 148 | subject: parts[8] ?? "", |
| 149 | coAuthors: parseCoAuthors(body), |
| 150 | githubAuthor, |
| 151 | githubCommitter, |
| 152 | }; |
| 153 | } |
| 154 | |
| 155 | function yamlScalar(value: string): string { |
| 156 | return JSON.stringify(value); |
no test coverage detected