Skip to content

Commit d013950

Browse files
authored
Merge pull request #1815 from GitTools/copilot/use-json-file-output
Use GitVersion `/outputfile` instead of parsing JSON from stdout
2 parents 5778fdc + e9431f9 commit d013950

File tree

5 files changed

+193
-39
lines changed

5 files changed

+193
-39
lines changed

dist/tools/libs/gitversion.mjs

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
import * as path from 'node:path';
2+
import * as fs from 'node:fs/promises';
3+
import * as crypto from 'node:crypto';
14
import { S as SettingsProvider, D as DotnetTool, k as keysOf, A as ArgumentsBuilder, R as RunnerBase } from './tools.mjs';
2-
import 'node:crypto';
3-
import 'node:fs/promises';
45
import 'node:os';
5-
import 'node:path';
66
import './semver.mjs';
77
import { allIndexesOf } from '../lib.mjs';
88

@@ -63,9 +63,12 @@ class GitVersionTool extends DotnetTool {
6363
const settings = this.settingsProvider.getExecuteSettings();
6464
const workDir = await this.getRepoDir(settings);
6565
await this.checkShallowClone(settings, workDir);
66-
const args = await this.getExecuteArguments(workDir, settings);
66+
const outputFile = path.join(this.buildAgent.tempDir, `gitversion-${crypto.randomUUID()}.json`);
67+
this.buildAgent.debug(`Writing GitVersion variables to file: ${outputFile}`);
68+
const args = await this.getExecuteArguments(workDir, settings, outputFile);
6769
await this.setDotnetRoot();
68-
return await this.executeTool(args);
70+
const result = await this.executeTool(args);
71+
return { ...result, outputFile };
6972
}
7073
async executeCommand() {
7174
const settings = this.settingsProvider.getCommandSettings();
@@ -104,8 +107,14 @@ class GitVersionTool extends DotnetTool {
104107
async getRepoDir(settings) {
105108
return await super.getRepoPath(settings.targetPath);
106109
}
107-
async getExecuteArguments(workDir, options) {
108-
const builder = new ArgumentsBuilder().addArgument(workDir).addArgument("/output").addArgument("json").addArgument("/l").addArgument("console");
110+
async getExecuteArguments(workDir, options, outputFile) {
111+
const builder = new ArgumentsBuilder().addArgument(workDir);
112+
if (outputFile) {
113+
builder.addArgument("/output").addArgument("file").addArgument("/outputfile").addArgument(outputFile);
114+
} else {
115+
builder.addArgument("/output").addArgument("json");
116+
}
117+
builder.addArgument("/l").addArgument("console");
109118
const {
110119
disableCache,
111120
disableNormalization,
@@ -169,6 +178,13 @@ class GitVersionTool extends DotnetTool {
169178
}
170179
}
171180
}
181+
async readGitVersionOutput(outputFile) {
182+
const content = await fs.readFile(outputFile, "utf8");
183+
const output = JSON.parse(content);
184+
await fs.unlink(outputFile).catch(() => {
185+
});
186+
return output;
187+
}
172188
toCamelCase(input) {
173189
return input.replace(/^\w|[A-Z]|\b\w|\s+/g, function(match, index) {
174190
if (+match === 0) return "";
@@ -203,33 +219,49 @@ class Runner extends RunnerBase {
203219
async execute() {
204220
return this.safeExecute(async () => {
205221
const result = await this.tool.executeJson();
206-
return this.processGitVersionOutput(result);
222+
return await this.processGitVersionOutput(result);
207223
}, "GitVersion executed successfully");
208224
}
209225
async command() {
210226
return this.safeExecute(async () => await this.tool.executeCommand(), "GitVersion executed successfully");
211227
}
212-
processGitVersionOutput(result) {
213-
this.buildAgent.debug("Parsing GitVersion output");
228+
async processGitVersionOutput(result) {
229+
this.buildAgent.debug("Processing GitVersion output");
214230
if (result.code !== 0) {
215231
return result;
216232
}
217-
const stdout = result.stdout;
218-
const gitVersionOutput = this.extractGitVersionOutput(stdout);
233+
let gitVersionOutput = null;
234+
if (result.outputFile) {
235+
this.buildAgent.debug(`Reading GitVersion variables from file: ${result.outputFile}`);
236+
try {
237+
gitVersionOutput = await this.tool.readGitVersionOutput(result.outputFile);
238+
} catch (error) {
239+
return this.handleOutputError(`Failed to read or parse GitVersion variables file: ${this.getErrorMessage(error)}`);
240+
}
241+
} else {
242+
this.buildAgent.debug("Parsing GitVersion output from stdout");
243+
const stdout = result.stdout;
244+
gitVersionOutput = this.extractGitVersionOutput(stdout);
245+
}
219246
if (gitVersionOutput === null) {
220-
const errorMessage = "GitVersion output is not valid JSON, see output details";
221-
this.buildAgent.debug(errorMessage);
222-
this.buildAgent.setFailed(errorMessage, true);
223-
return {
224-
code: -1,
225-
error: new Error(errorMessage)
226-
};
247+
return this.handleOutputError("GitVersion output is not valid JSON, see output details");
227248
}
228249
this.tool.writeGitVersionToAgent(gitVersionOutput);
229250
this.tool.updateBuildNumber();
230251
this.buildAgent.setSucceeded("GitVersion executed successfully", true);
231252
return result;
232253
}
254+
getErrorMessage(error) {
255+
return error instanceof Error ? error.message : String(error);
256+
}
257+
handleOutputError(message) {
258+
this.buildAgent.debug(message);
259+
this.buildAgent.setFailed(message, true);
260+
return {
261+
code: -1,
262+
error: new Error(message)
263+
};
264+
}
233265
/**
234266
* Attempts to extract and parse a JSON object representing `GitVersionOutput` from the given input string.
235267
* The method assumes the last closing curly brace (`}`) in the input belongs to the end of the JSON object,

0 commit comments

Comments
 (0)