Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ public void TestBuildNumber()
DoTest(x => x.WriteBuildNumber("100500.5"), "##teamcity[buildNumber '100500.5']");
}

[Test]
public void TestBuildProblemWithoutIdentity()
{
DoTest(x => x.WriteBuildProblem("aaaa"), "##teamcity[buildProblem description='aaaa']");
}

[Test]
public void TestBuildProblem()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace JetBrains.TeamCity.ServiceMessages.Tests.Write.Specials
{
using NUnit.Framework;
using ServiceMessages.Write.Special;
using ServiceMessages.Write.Special.Impl.Writer;

[TestFixture]
public class TeamCityProgressWriterTest : TeamCityWriterBaseTest<ITeamCityProgressWriter>
{
protected override ITeamCityProgressWriter Create(IServiceMessageProcessor proc)
{
return new TeamCityProgressWriter(proc);
}

[Test]
public void TestProgressMessage()
{
DoTest(x => x.WriteProgress("aaaa"), "##teamcity[progressMessage 'aaaa']");
}

[Test]
public void OpenProgressBlock()
{
DoTest(x => x.OpenProgress("aaaa").Dispose(),
"##teamcity[progressStart 'aaaa']",
"##teamcity[progressFinish 'aaaa']");
}
}
}
2 changes: 1 addition & 1 deletion TeamCity.ServiceMessages/TeamCity.ServiceMessages.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<GenerateAssemblyVersionAttribute>true</GenerateAssemblyVersionAttribute>
<GenerateNeutralResourcesLanguageAttribute>true</GenerateNeutralResourcesLanguageAttribute>

<TargetFrameworks>netstandard1.3;net35;net40;net45;netcoreapp1.0;netcoreapp2.0;netcoreapp3.0</TargetFrameworks>
<TargetFrameworks>netstandard1.3;netstandard2.0;net35;net40;net45;netcoreapp1.0;netcoreapp2.0;netcoreapp3.0;net6.0;net8.0</TargetFrameworks>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please share the reasoning behind adding new targets? As far as I understand, netstandard1.3 should cover all the frameworks that are covered by the added targets. Maybe some targets can even be removed, as netcoreapp1.0;netcoreapp2.0;netcoreapp3.0 seem redundant here.
I'm not sure what we should do with the target frameworks and I'm interested in hearing your opinion.

<AssemblyName>TeamCity.ServiceMessages</AssemblyName>
<PackageId>TeamCity.ServiceMessages</PackageId>
<RootNamespace>JetBrains.TeamCity.ServiceMessages</RootNamespace>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ public interface ITeamCityBuildStatusWriter
void WriteBuildNumber([NotNull] string buildNumber);


/// <summary>
/// Generates build problem service message
/// </summary>
/// <param name="description">problem message</param>
void WriteBuildProblem([NotNull] string description);

/// <summary>
/// Generates build problem service message
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions TeamCity.ServiceMessages/Write/Special/ITeamCityFlowWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ namespace JetBrains.TeamCity.ServiceMessages.Write.Special

/// <summary>
/// Starts another flowId reporting starting. This call would emmit
/// <pre>##teamcity[flowStarted flowId='%lt;new flow id>' parent='current flow id']</pre>
/// <pre>##teamcity[flowStarted flowId='&lt;new flow id>' parent='current flow id']</pre>
/// and
/// <pre>##teamcity[flowFinished flowId='%lt;new flow id>']</pre>
/// <pre>##teamcity[flowFinished flowId='&lt;new flow id>']</pre>
/// on writer dispose
/// </summary>
/// <remarks>
Expand Down
41 changes: 41 additions & 0 deletions TeamCity.ServiceMessages/Write/Special/ITeamCityProgressWriter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
namespace JetBrains.TeamCity.ServiceMessages.Write.Special
{
using System;

/// <summary>
/// <para>
/// Use <see cref="WriteProgress"/> method to add progress message
/// <pre>
/// ##teamcity[progressMessage '&lt;message text>' ]
/// </pre>
/// </para>
///
/// <para>
/// Use <see cref="OpenProgress"/> method to add progress message
/// <pre>##teamcity[progressStart '&lt;message>']</pre>
/// and
/// <pre>##teamcity[progressFinish '&lt;message>']</pre>
/// on writer dispose.
/// </para>
/// <para>
/// http://confluence.jetbrains.net/display/TCD18/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ReportingMessagesForBuildLog
/// </para>
/// </summary>
Comment on lines +5 to +23

@boris-yakhno Boris Yakhno (boris-yakhno) Sep 3, 2024

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of remarks:

I suggest something like this:

Suggested change
/// <summary>
/// <para>
/// Use <see cref="WriteProgress"/> method to add progress message
/// <pre>
/// ##teamcity[progressMessage '&lt;message text>' ]
/// </pre>
/// </para>
///
/// <para>
/// Use <see cref="OpenProgress"/> method to add progress message
/// <pre>##teamcity[progressStart '&lt;message>']</pre>
/// and
/// <pre>##teamcity[progressFinish '&lt;message>']</pre>
/// on writer dispose.
/// </para>
/// <para>
/// http://confluence.jetbrains.net/display/TCD18/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ReportingMessagesForBuildLog
/// </para>
/// </summary>
/// <summary>
/// <para>
/// Use the <see cref="WriteProgress"/> method to add a progress message:
/// <pre>##teamcity[progressMessage '&lt;message text>' ]</pre>
/// </para>
///
/// <para>
/// Use the <see cref="OpenProgress"/> method to add a progress start message:
/// <pre>##teamcity[progressStart '&lt;message>']</pre>
/// and a
/// <pre>##teamcity[progressFinish '&lt;message>']</pre>
/// progress finish message on writer dispose.
/// </para>
/// <para>
/// https://www.jetbrains.com/help/teamcity/service-messages.html#Reporting+Build+Progress
/// </para>
/// </summary>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, the documentation link in my previous comment was wrong. I have edited the comment to include the correct link.

/// <remarks>
/// Implementation is not thread-safe. Create an instance for each thread instead.
/// </remarks>
public interface ITeamCityProgressWriter
{
/// <summary>
/// Writes normal message

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about "Writes a single progress message"?

/// </summary>
/// <param name="message">text</param>
void WriteProgress([NotNull] string message);

/// <summary>
/// Generates start flow message and returns disposable object to close flow

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about "Writes a progress start message and returns a disposable object that writes a progress finish message on dispose"?

/// </summary>
/// <returns></returns>
IDisposable OpenProgress(string message);
}
}
2 changes: 1 addition & 1 deletion TeamCity.ServiceMessages/Write/Special/ITeamCityWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace JetBrains.TeamCity.ServiceMessages.Write.Special
/// <remarks>
/// Implementation is not thread-safe. Create an instance for each thread instead.
/// </remarks>
public interface ITeamCityWriter : ITeamCityBlockWriter<ITeamCityWriter>, ITeamCityFlowWriter<ITeamCityWriter>, ITeamCityMessageWriter, ITeamCityTestsWriter, ITeamCityCompilationBlockWriter<ITeamCityWriter>, ITeamCityArtifactsWriter, ITeamCityBuildStatusWriter, IDisposable
public interface ITeamCityWriter : ITeamCityBlockWriter<ITeamCityWriter>, ITeamCityFlowWriter<ITeamCityWriter>, ITeamCityMessageWriter, ITeamCityTestsWriter, ITeamCityCompilationBlockWriter<ITeamCityWriter>, ITeamCityArtifactsWriter, ITeamCityBuildStatusWriter, ITeamCityProgressWriter, IDisposable
{
/// <summary>
/// Allows sending bare service message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class TeamCityWriterFacade : ITeamCityWriter
private readonly ITeamCityMessageWriter _messageWriter;
private readonly IServiceMessageProcessor _processor;
private readonly ITeamCityBuildStatusWriter _statusWriter;
private readonly ITeamCityProgressWriter _progressWriter;
private readonly ITeamCityTestsWriter _testsWriter;
private volatile bool _isDisposed;

Expand All @@ -26,6 +27,7 @@ public TeamCityWriterFacade(
[NotNull] ITeamCityArtifactsWriter artifactsWriter,
[NotNull] ITeamCityBuildStatusWriter statusWriter,
[NotNull] ITeamCityFlowWriter<ITeamCityWriter> flowWriter,
[NotNull] ITeamCityProgressWriter progressWriter,
[NotNull] IDisposable disposeCallback)
{
if (processor == null) throw new ArgumentNullException(nameof(processor));
Expand All @@ -36,6 +38,7 @@ public TeamCityWriterFacade(
if (artifactsWriter == null) throw new ArgumentNullException(nameof(artifactsWriter));
if (statusWriter == null) throw new ArgumentNullException(nameof(statusWriter));
if (flowWriter == null) throw new ArgumentNullException(nameof(flowWriter));
if (progressWriter == null) throw new ArgumentNullException(nameof(progressWriter));
if (disposeCallback == null) throw new ArgumentNullException(nameof(disposeCallback));
_processor = processor;
_blockWriter = blockWriter;
Expand All @@ -45,6 +48,7 @@ public TeamCityWriterFacade(
_artifactsWriter = artifactsWriter;
_statusWriter = statusWriter;
_flowWriter = flowWriter;
_progressWriter = progressWriter;
_dispose = disposeCallback;
}

Expand All @@ -61,6 +65,13 @@ public void WriteBuildNumber(string buildNumber)
_statusWriter.WriteBuildNumber(buildNumber);
}

public void WriteBuildProblem(string description)
{
if (description == null) throw new ArgumentNullException(nameof(description));
CheckConsistency();
_statusWriter.WriteBuildProblem(description);
}

public void WriteBuildProblem(string identity, string message)
{
if (identity == null) throw new ArgumentNullException(nameof(identity));
Expand Down Expand Up @@ -106,6 +117,20 @@ public void WriteError(string text, string errorDetails = null)
_messageWriter.WriteError(text, errorDetails);
}

public void WriteProgress(string message)
{
if (message == null) throw new ArgumentNullException(nameof(message));
CheckConsistency();
_progressWriter.WriteProgress(message);
}

public IDisposable OpenProgress(string message)
{
if (message == null) throw new ArgumentNullException(nameof(message));
CheckConsistency();
return _progressWriter.OpenProgress(message);
}

public virtual void Dispose()
{
_isDisposed = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public TeamCityWriterImpl(
new TeamCityMessageWriter(processor),
new TeamCityArtifactsWriter(processor),
new TeamCityBuildStatusWriter(processor),
new TeamCityProgressWriter(processor),
dispose)
{
if (processor == null) throw new ArgumentNullException(nameof(processor));
Expand All @@ -36,8 +37,9 @@ private TeamCityWriterImpl(
[NotNull] ITeamCityMessageWriter messageWriter,
[NotNull] ITeamCityArtifactsWriter artifactsWriter,
[NotNull] ITeamCityBuildStatusWriter statusWriter,
[NotNull] ITeamCityProgressWriter progressWriter,
[NotNull] IDisposable dispose)
: base(processor, blockWriter, compilationWriter, testsWriter, messageWriter, artifactsWriter, statusWriter, flowWriter, dispose)
: base(processor, blockWriter, compilationWriter, testsWriter, messageWriter, artifactsWriter, statusWriter, flowWriter, progressWriter, dispose)
{
if (processor == null) throw new ArgumentNullException(nameof(processor));
if (flowWriter == null) throw new ArgumentNullException(nameof(flowWriter));
Expand All @@ -47,6 +49,7 @@ private TeamCityWriterImpl(
if (messageWriter == null) throw new ArgumentNullException(nameof(messageWriter));
if (artifactsWriter == null) throw new ArgumentNullException(nameof(artifactsWriter));
if (statusWriter == null) throw new ArgumentNullException(nameof(statusWriter));
if (progressWriter == null) throw new ArgumentNullException(nameof(progressWriter));
if (dispose == null) throw new ArgumentNullException(nameof(dispose));
_writeCheck = new ISubWriter[] {blockWriter, compilationWriter, testsWriter, flowWriter};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ public void WriteBuildNumber(string buildNumber)
PostMessage(new ValueServiceMessage("buildNumber", buildNumber));
}

public void WriteBuildProblem(string description)
{
if (description == null) throw new ArgumentNullException(nameof(description));
PostMessage(new ServiceMessage("buildProblem") {{"description", description}});
}

public void WriteBuildProblem(string identity, string message)
{
if (identity == null) throw new ArgumentNullException(nameof(identity));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public TCloseBlock OpenFlow()
processor
);

//##teamcity[flowStarted flowId='%lt;new flow id>' parent='current flow id']
//##teamcity[flowStarted flowId='<new flow id>' parent='current flow id']
var flowStartedMessage = new ServiceMessage("flowStarted");
if (myTarget.FlowId != null)
{
Expand Down Expand Up @@ -69,7 +69,7 @@ private void CloseBlock([NotNull] IFlowAwareServiceMessageProcessor flowAwareSer

_openChildFlowIds.Remove(flowAwareServiceMessageProcessor.FlowId);

//##teamcity[flowFinished flowId='%lt;new flow id>']
//##teamcity[flowFinished flowId='<new flow id>']
flowAwareServiceMessageProcessor.AddServiceMessage(new ServiceMessage("flowFinished"));
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace JetBrains.TeamCity.ServiceMessages.Write.Special.Impl.Writer
{
using System;

public class TeamCityProgressWriter : BaseWriter, ITeamCityProgressWriter
{
public TeamCityProgressWriter(IServiceMessageProcessor target)
: base(target)
{
if (target == null) throw new ArgumentNullException(nameof(target));
}

public void WriteProgress(string message)
{
if (message == null) throw new ArgumentNullException(nameof(message));
PostMessage(new ValueServiceMessage("progressMessage", message));
}

public IDisposable OpenProgress(string message)
{
if (message == null) throw new ArgumentNullException(nameof(message));
PostMessage(new ValueServiceMessage("progressStart", message));
return new DisposableDelegate(() => PostMessage(new ValueServiceMessage("progressFinish", message)));
}
}
}