Skip to content

Commit 6b342b8

Browse files
authored
Merge pull request #2251 from arturcic/feature/output-file
Feature/output file
2 parents 3e2a3e3 + d755bf2 commit 6b342b8

File tree

11 files changed

+107
-8
lines changed

11 files changed

+107
-8
lines changed

src/GitVersionCore/Core/GitVersionTool.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public void OutputVariables(VersionVariables variables)
8585

8686
using (outputGenerator)
8787
{
88-
outputGenerator.Execute(variables, new OutputContext(gitVersionOptions.WorkingDirectory));
88+
outputGenerator.Execute(variables, new OutputContext(gitVersionOptions.WorkingDirectory, gitVersionOptions.OutputFile));
8989
}
9090
}
9191

src/GitVersionCore/Model/GitVersionOptions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public GitVersionOptions()
3939

4040
public string LogFilePath;
4141
public string ShowVariable;
42+
public string OutputFile;
4243
public ISet<OutputType> Output = new HashSet<OutputType>();
4344
public Verbosity Verbosity = Verbosity.Normal;
4445

src/GitVersionCore/Model/OutputType.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ namespace GitVersion.Model
33
public enum OutputType
44
{
55
BuildServer,
6-
7-
Json
6+
Json,
7+
File
88
}
99
}

src/GitVersionCore/VersionConverters/OutputGenerator/OutputContext.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ namespace GitVersion.VersionConverters.OutputGenerator
22
{
33
public readonly struct OutputContext : IConverterContext
44
{
5-
public OutputContext(string workingDirectory)
5+
public OutputContext(string workingDirectory, string outputFile)
66
{
77
WorkingDirectory = workingDirectory;
8+
OutputFile = outputFile;
89
}
910

1011
public string WorkingDirectory { get; }
12+
public string OutputFile { get; }
1113
}
1214
}

src/GitVersionCore/VersionConverters/OutputGenerator/OutputGenerator.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ public interface IOutputGenerator : IVersionConverter<OutputContext>
1313
public class OutputGenerator : IOutputGenerator
1414
{
1515
private readonly IConsole console;
16+
private readonly IFileSystem fileSystem;
1617
private readonly IOptions<GitVersionOptions> options;
1718
private readonly ICurrentBuildAgent buildAgent;
1819

19-
public OutputGenerator(ICurrentBuildAgent buildAgent, IConsole console, IOptions<GitVersionOptions> options)
20+
public OutputGenerator(ICurrentBuildAgent buildAgent, IConsole console, IFileSystem fileSystem, IOptions<GitVersionOptions> options)
2021
{
2122
this.console = console ?? throw new ArgumentNullException(nameof(console));
23+
this.fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
2224
this.options = options ?? throw new ArgumentNullException(nameof(options));
2325
this.buildAgent = buildAgent;
2426
}
@@ -30,6 +32,10 @@ public void Execute(VersionVariables variables, OutputContext context)
3032
{
3133
buildAgent?.WriteIntegration(console.WriteLine, variables);
3234
}
35+
if (gitVersionOptions.Output.Contains(OutputType.File))
36+
{
37+
fileSystem.WriteAllText(context.OutputFile, variables.ToString());
38+
}
3339
if (gitVersionOptions.Output.Contains(OutputType.Json))
3440
{
3541
switch (gitVersionOptions.ShowVariable)

src/GitVersionExe.Tests/ArgumentParserTests.cs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,16 @@ public void UsernameAndPasswordCanBeParsed()
155155
public void UnknownOutputShouldThrow()
156156
{
157157
var exception = Assert.Throws<WarningException>(() => argumentParser.ParseArguments("targetDirectoryPath -output invalid_value"));
158-
exception.Message.ShouldBe("Value 'invalid_value' cannot be parsed as output type, please use 'json' or 'buildserver'");
158+
exception.Message.ShouldBe("Value 'invalid_value' cannot be parsed as output type, please use 'json', 'file' or 'buildserver'");
159159
}
160160

161161
[Test]
162162
public void OutputDefaultsToJson()
163163
{
164164
var arguments = argumentParser.ParseArguments("targetDirectoryPath");
165165
arguments.Output.ShouldContain(OutputType.Json);
166+
arguments.Output.ShouldNotContain(OutputType.BuildServer);
167+
arguments.Output.ShouldNotContain(OutputType.File);
166168
}
167169

168170
[Test]
@@ -171,6 +173,7 @@ public void OutputJsonCanBeParsed()
171173
var arguments = argumentParser.ParseArguments("targetDirectoryPath -output json");
172174
arguments.Output.ShouldContain(OutputType.Json);
173175
arguments.Output.ShouldNotContain(OutputType.BuildServer);
176+
arguments.Output.ShouldNotContain(OutputType.File);
174177
}
175178

176179
[Test]
@@ -179,6 +182,7 @@ public void MultipleOutputJsonCanBeParsed()
179182
var arguments = argumentParser.ParseArguments("targetDirectoryPath -output json -output json");
180183
arguments.Output.ShouldContain(OutputType.Json);
181184
arguments.Output.ShouldNotContain(OutputType.BuildServer);
185+
arguments.Output.ShouldNotContain(OutputType.File);
182186
}
183187

184188
[Test]
@@ -187,6 +191,7 @@ public void OutputBuildserverCanBeParsed()
187191
var arguments = argumentParser.ParseArguments("targetDirectoryPath -output buildserver");
188192
arguments.Output.ShouldContain(OutputType.BuildServer);
189193
arguments.Output.ShouldNotContain(OutputType.Json);
194+
arguments.Output.ShouldNotContain(OutputType.File);
190195
}
191196

192197
[Test]
@@ -195,6 +200,25 @@ public void MultipleOutputBuildserverCanBeParsed()
195200
var arguments = argumentParser.ParseArguments("targetDirectoryPath -output buildserver -output buildserver");
196201
arguments.Output.ShouldContain(OutputType.BuildServer);
197202
arguments.Output.ShouldNotContain(OutputType.Json);
203+
arguments.Output.ShouldNotContain(OutputType.File);
204+
}
205+
206+
[Test]
207+
public void OutputFileCanBeParsed()
208+
{
209+
var arguments = argumentParser.ParseArguments("targetDirectoryPath -output file");
210+
arguments.Output.ShouldContain(OutputType.File);
211+
arguments.Output.ShouldNotContain(OutputType.BuildServer);
212+
arguments.Output.ShouldNotContain(OutputType.Json);
213+
}
214+
215+
[Test]
216+
public void MultipleOutputFileCanBeParsed()
217+
{
218+
var arguments = argumentParser.ParseArguments("targetDirectoryPath -output file -output file");
219+
arguments.Output.ShouldContain(OutputType.File);
220+
arguments.Output.ShouldNotContain(OutputType.BuildServer);
221+
arguments.Output.ShouldNotContain(OutputType.Json);
198222
}
199223

200224
[Test]
@@ -203,6 +227,16 @@ public void OutputBuildserverAndJsonCanBeParsed()
203227
var arguments = argumentParser.ParseArguments("targetDirectoryPath -output buildserver -output json");
204228
arguments.Output.ShouldContain(OutputType.BuildServer);
205229
arguments.Output.ShouldContain(OutputType.Json);
230+
arguments.Output.ShouldNotContain(OutputType.File);
231+
}
232+
233+
[Test]
234+
public void OutputBuildserverAndJsonAndFileCanBeParsed()
235+
{
236+
var arguments = argumentParser.ParseArguments("targetDirectoryPath -output buildserver -output json -output file");
237+
arguments.Output.ShouldContain(OutputType.BuildServer);
238+
arguments.Output.ShouldContain(OutputType.Json);
239+
arguments.Output.ShouldContain(OutputType.File);
206240
}
207241

208242
[Test]
@@ -212,6 +246,16 @@ public void MultipleArgsAndFlag()
212246
arguments.Output.ShouldContain(OutputType.BuildServer);
213247
}
214248

249+
[TestCase("-output file", "GitVersion.json")]
250+
[TestCase("-output file -outputfile version.json", "version.json")]
251+
public void OutputFileArgumentCanBeParsed(string args, string outputFile)
252+
{
253+
var arguments = argumentParser.ParseArguments(args);
254+
255+
arguments.Output.ShouldContain(OutputType.File);
256+
arguments.OutputFile.ShouldBe(outputFile);
257+
}
258+
215259
[Test]
216260
public void UrlAndBranchNameCanBeParsed()
217261
{

src/GitVersionExe.Tests/HelpWriterTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public void AllArgsAreInHelp()
3131
{ nameof(Arguments.Init), "init" },
3232
{ nameof(Arguments.TargetBranch), "/b" },
3333
{ nameof(Arguments.LogFilePath) , "/l" },
34+
{ nameof(Arguments.OutputFile) , "/outputfile" },
3435
{ nameof(Arguments.DynamicRepositoryClonePath), "/dynamicRepoLocation" },
3536
{ nameof(Arguments.IsHelp), "/?" },
3637
{ nameof(Arguments.IsVersion), "/version" },

src/GitVersionExe.Tests/JsonOutputOnBuildServerTest.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
using System.Collections.Generic;
2+
using System.IO;
23
using GitTools.Testing;
34
using GitVersion.BuildAgents;
5+
using GitVersion.OutputVariables;
6+
using Newtonsoft.Json;
47
using NUnit.Framework;
58
using Shouldly;
69

@@ -41,5 +44,31 @@ public void BeingOnBuildServerWithOutputJsonDoesNotFail()
4144
result.OutputVariables.ShouldNotBeNull();
4245
result.OutputVariables.FullSemVer.ShouldBeEquivalentTo(version);
4346
}
47+
48+
[TestCase("", "GitVersion.json")]
49+
[TestCase("version.json", "version.json")]
50+
public void BeingOnBuildServerWithOutputJsonAndOutputFileDoesNotFail(string outputFile, string fileName)
51+
{
52+
using var fixture = new RemoteRepositoryFixture();
53+
fixture.Repository.MakeATaggedCommit("1.2.3");
54+
fixture.Repository.MakeACommit();
55+
56+
var env = new KeyValuePair<string, string>(TeamCity.EnvironmentVariableName, "8.0.0");
57+
58+
var result = GitVersionHelper.ExecuteIn(fixture.LocalRepositoryFixture.RepositoryPath, arguments: $" /output json /output buildserver /output file /outputfile {outputFile}", environments: env);
59+
60+
result.ExitCode.ShouldBe(0);
61+
const string version = "0.1.0+4";
62+
result.Output.ShouldContain($"##teamcity[buildNumber '{version}']");
63+
result.OutputVariables.ShouldNotBeNull();
64+
result.OutputVariables.FullSemVer.ShouldBeEquivalentTo(version);
65+
66+
var filePath = Path.Combine(fixture.LocalRepositoryFixture.RepositoryPath, fileName);
67+
var json = File.ReadAllText(filePath);
68+
69+
var outputVariables = VersionVariables.FromDictionary(JsonConvert.DeserializeObject<Dictionary<string, string>>(json));
70+
outputVariables.ShouldNotBeNull();
71+
outputVariables.FullSemVer.ShouldBeEquivalentTo(version);
72+
}
4473
}
4574
}

src/GitVersionExe/ArgumentParser.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class ArgumentParser : IArgumentParser
1717
private readonly ICurrentBuildAgent buildAgent;
1818
private readonly IConsole console;
1919
private readonly IGlobbingResolver globbingResolver;
20+
private const string defaultOutputFileName = "GitVersion.json";
2021

2122
public ArgumentParser(IEnvironment environment, ICurrentBuildAgent buildAgent, IConsole console, IGlobbingResolver globbingResolver)
2223
{
@@ -91,6 +92,11 @@ public Arguments ParseArguments(string[] commandLineArguments)
9192
arguments.Output.Add(OutputType.Json);
9293
}
9394

95+
if (arguments.Output.Contains(OutputType.File) && arguments.OutputFile == null)
96+
{
97+
arguments.OutputFile = defaultOutputFileName;
98+
}
99+
94100
// If the first argument is a switch, it should already have been consumed in the above loop,
95101
// or else a WarningException should have been thrown and we wouldn't end up here.
96102
arguments.TargetPath ??= firstArgumentIsSwitch
@@ -223,6 +229,13 @@ private static bool ParseSwitches(Arguments arguments, string name, string[] val
223229
return true;
224230
}
225231

232+
if (name.IsSwitch("outputfile"))
233+
{
234+
EnsureArgumentValueCount(values);
235+
arguments.OutputFile = value;
236+
return true;
237+
}
238+
226239
if (name.IsSwitch("nofetch"))
227240
{
228241
arguments.NoFetch = true;
@@ -417,7 +430,7 @@ private static void ParseOutput(Arguments arguments, string[] values)
417430
{
418431
if (!Enum.TryParse(v, true, out OutputType outputType))
419432
{
420-
throw new WarningException($"Value '{v}' cannot be parsed as output type, please use 'json' or 'buildserver'");
433+
throw new WarningException($"Value '{v}' cannot be parsed as output type, please use 'json', 'file' or 'buildserver'");
421434
}
422435

423436
arguments.Output.Add(outputType);

src/GitVersionExe/Arguments.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public class Arguments
3434

3535
public string LogFilePath;
3636
public string ShowVariable;
37+
public string OutputFile;
3738
public ISet<OutputType> Output = new HashSet<OutputType>();
3839
public Verbosity Verbosity = Verbosity.Normal;
3940

@@ -108,6 +109,7 @@ public GitVersionOptions ToOptions()
108109
ShowVariable = ShowVariable,
109110
Verbosity = Verbosity,
110111
Output = Output,
112+
OutputFile = OutputFile,
111113

112114
// TODO obsolete to be removed in version 6.0.0
113115
Proj = Proj,

src/GitVersionExe/HelpWriter.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ path The directory containing .git. If not defined current directory
3838
/h or /? Shows Help
3939
4040
/targetpath Same as 'path', but not positional
41-
/output Determines the output to the console. Can be either 'json' or 'buildserver', will default to 'json'.
41+
/output Determines the output to the console. Can be either 'json', 'file' or 'buildserver', will default to 'json'.
42+
/outputfile Path to output file. It is used in combination with /output 'file'.
4243
/showvariable Used in conjuntion with /output json, will output just a particular variable.
4344
eg /output json /showvariable SemVer - will output `1.2.3+beta.4`
4445
/l Path to logfile.

0 commit comments

Comments
 (0)