Skip to content

Commit 0725f52

Browse files
authored
Merge pull request #172 from gep13/feature/cake-6
(#155) Cake v6.0.0 catch-up + IEnumerable<string> overloads
2 parents e5e10e4 + 7c7d9bb commit 0725f52

9 files changed

Lines changed: 329 additions & 14 deletions

File tree

.github/workflows/build.yml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,13 @@ jobs:
8484
cake-version: tool-manifest
8585

8686
# The demo/ folders exercise the just-built addin DLL under
87-
# Cake-major-matching cake.tool / Cake.Frosting versions. They run
88-
# in their OWN tool/package context (independent of recipe.cake's
89-
# cake.tool, which is constrained by Cake.Recipe's runtime). Both
87+
# Cake-major-matching cake.tool / Cake.Frosting / Cake.Sdk
88+
# versions. They run in their OWN tool/package context
89+
# (independent of recipe.cake's cake.tool, which is constrained
90+
# by Cake.Recipe's runtime). demo/script and demo/frosting
9091
# consume the addin from BuildArtifacts/temp/_PublishedLibraries/
91-
# populated by DotNetCore-Pack. demo/sdk joins at the Cake 6
92-
# catch-up release.
92+
# populated by DotNetCore-Pack; demo/sdk builds the addin from
93+
# source via the #:project directive in cake.cs.
9394

9495
- name: Run demo/script
9596
if: success()
@@ -101,6 +102,12 @@ jobs:
101102
shell: pwsh
102103
run: ./demo/frosting/build.ps1
103104

105+
- name: Run demo/sdk
106+
if: success()
107+
shell: pwsh
108+
working-directory: ./demo/sdk
109+
run: dotnet cake.cs
110+
104111
- name: Upload Issues-Report
105112
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5
106113
with:

demo/frosting/build/Build.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99
<Reference Include="Cake.FileHelpers">
1010
<HintPath>$(MSBuildProjectDirectory)\..\..\..\BuildArtifacts\temp\_PublishedLibraries\Cake.FileHelpers\net8.0\Cake.FileHelpers.dll</HintPath>
1111
</Reference>
12-
<PackageReference Include="Cake.Frosting" Version="5.1.0" />
12+
<PackageReference Include="Cake.Frosting" Version="6.1.0" />
1313
</ItemGroup>
1414
</Project>

demo/script/.config/dotnet-tools.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"isRoot": true,
44
"tools": {
55
"cake.tool": {
6-
"version": "5.1.0",
6+
"version": "6.1.0",
77
"commands": [
88
"dotnet-cake"
99
]

demo/sdk/cake.cs

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
#!/usr/bin/env dotnet
2+
#:sdk Cake.Sdk@6.1.1
3+
#:project ../../src/Cake.FileHelpers/Cake.FileHelpers.csproj
4+
5+
// Cake SDK consumer demo for Cake.FileHelpers. Runs as a file-based
6+
// .NET program (introduced in .NET 10) using the Cake.Sdk
7+
// directives. The #:project directive above lets the SDK build the
8+
// addin from source rather than referencing a published nupkg.
9+
//
10+
// To run locally:
11+
// cd demo/sdk
12+
// dotnet cake.cs
13+
//
14+
// Mirrors the alias surface exercised by demo/script/filehelpers.cake
15+
// and demo/frosting/, against a temp working directory under
16+
// demo/sdk/BuildArtifacts/ (gitignored). Each task asserts the
17+
// expected outcome and throws on mismatch — the script fails
18+
// (non-zero exit) if any alias misbehaves.
19+
20+
using Cake.FileHelpers;
21+
22+
var workDir = Directory("./BuildArtifacts/temp/test-filehelpers-sdk");
23+
var sampleFile = workDir + File("sample.txt");
24+
var sampleFile2 = workDir + File("sample2.txt");
25+
26+
Task("Default")
27+
.IsDependentOn("Setup")
28+
.IsDependentOn("Read-Operations")
29+
.IsDependentOn("Write-Operations")
30+
.IsDependentOn("Append-Operations")
31+
.IsDependentOn("Touch")
32+
.IsDependentOn("Find-Operations")
33+
.IsDependentOn("Replace-Operations")
34+
.IsDependentOn("Cleanup");
35+
36+
Task("Setup")
37+
.Does(() =>
38+
{
39+
if (DirectoryExists(workDir))
40+
{
41+
DeleteDirectory(workDir, new DeleteDirectorySettings { Recursive = true });
42+
}
43+
44+
EnsureDirectoryExists(workDir);
45+
System.IO.File.WriteAllLines(
46+
sampleFile.Path.FullPath,
47+
new[] { "alpha line 1", "beta line 2", "gamma 42 delta", "alpha line 4" });
48+
System.IO.File.WriteAllText(sampleFile2.Path.FullPath, "second file with the word alpha");
49+
Information("Setup complete.");
50+
});
51+
52+
Task("Read-Operations")
53+
.IsDependentOn("Setup")
54+
.Does(() =>
55+
{
56+
var lines = FileReadLines(sampleFile);
57+
AssertThat(lines.Length == 4, "FileReadLines: expected 4 lines, got " + lines.Length);
58+
AssertThat(lines[0] == "alpha line 1", "FileReadLines: first line mismatch");
59+
AssertThat(lines[3] == "alpha line 4", "FileReadLines: last line mismatch");
60+
Information("FileReadLines OK ({0} lines)", lines.Length);
61+
62+
var text = FileReadText(sampleFile);
63+
AssertThat(text.Contains("gamma 42 delta"), "FileReadText: expected content not found");
64+
Information("FileReadText OK ({0} chars)", text.Length);
65+
});
66+
67+
Task("Write-Operations")
68+
.IsDependentOn("Setup")
69+
.Does(() =>
70+
{
71+
var writeFile = workDir + File("written.txt");
72+
73+
FileWriteText(writeFile, "first text\n");
74+
var afterText = System.IO.File.ReadAllText(writeFile.Path.FullPath);
75+
AssertThat(afterText == "first text\n", "FileWriteText: content mismatch");
76+
Information("FileWriteText OK");
77+
78+
FileWriteLines(writeFile, new[] { "line A", "line B", "line C" });
79+
var afterLines = FileReadLines(writeFile);
80+
AssertThat(afterLines.Length == 3, "FileWriteLines: expected 3 lines, got " + afterLines.Length);
81+
AssertThat(afterLines[1] == "line B", "FileWriteLines: line 2 mismatch");
82+
Information("FileWriteLines OK (overwrote with {0} lines)", afterLines.Length);
83+
});
84+
85+
Task("Append-Operations")
86+
.IsDependentOn("Write-Operations")
87+
.Does(() =>
88+
{
89+
var writeFile = workDir + File("written.txt");
90+
var beforeLines = FileReadLines(writeFile);
91+
92+
FileAppendText(writeFile, "appended text\n");
93+
FileAppendLines(writeFile, new[] { "appended line 1", "appended line 2" });
94+
var afterLines = FileReadLines(writeFile);
95+
96+
AssertThat(afterLines.Length == beforeLines.Length + 3,
97+
$"Append: expected {beforeLines.Length + 3} lines, got {afterLines.Length}");
98+
AssertThat(afterLines[afterLines.Length - 1] == "appended line 2",
99+
"Append: last line mismatch");
100+
Information("FileAppendText + FileAppendLines OK ({0} lines after append)", afterLines.Length);
101+
});
102+
103+
Task("Touch")
104+
.IsDependentOn("Setup")
105+
.Does(() =>
106+
{
107+
var touchFile = workDir + File("touched.txt");
108+
System.IO.File.WriteAllText(touchFile.Path.FullPath, string.Empty);
109+
var beforeUtc = System.IO.File.GetLastWriteTimeUtc(touchFile.Path.FullPath);
110+
System.Threading.Thread.Sleep(10);
111+
FileTouch(touchFile);
112+
var afterUtc = System.IO.File.GetLastWriteTimeUtc(touchFile.Path.FullPath);
113+
114+
AssertThat(afterUtc > beforeUtc,
115+
$"FileTouch: timestamp did not advance (before={beforeUtc:o}, after={afterUtc:o})");
116+
Information("FileTouch OK (advanced from {0:o} to {1:o})", beforeUtc, afterUtc);
117+
});
118+
119+
Task("Find-Operations")
120+
.IsDependentOn("Setup")
121+
.Does(() =>
122+
{
123+
var byText = FindTextInFiles(workDir + File("sample*.txt"), "alpha");
124+
AssertThat(byText.Length == 2, "FindTextInFiles 'alpha': expected 2 files, got " + byText.Length);
125+
Information("FindTextInFiles 'alpha' OK ({0} files)", byText.Length);
126+
127+
var byRegex = FindRegexInFiles(workDir + File("sample*.txt"), @"\d+");
128+
AssertThat(byRegex.Length == 1, "FindRegexInFiles digits: expected 1 file (sample.txt has '42'), got " + byRegex.Length);
129+
Information("FindRegexInFiles digits OK ({0} file)", byRegex.Length);
130+
131+
var single = FindRegexMatchInFile(sampleFile, @"\d+", System.Text.RegularExpressions.RegexOptions.None);
132+
AssertThat(single == "1", "FindRegexMatchInFile: expected first digit run '1' (from 'line 1'), got " + (single ?? "null"));
133+
Information("FindRegexMatchInFile digits OK ('{0}')", single);
134+
135+
var many = FindRegexMatchesInFile(sampleFile, @"alpha", System.Text.RegularExpressions.RegexOptions.None);
136+
AssertThat(many != null && many.Count == 2, $"FindRegexMatchesInFile 'alpha': expected 2 matches, got {many?.Count ?? 0}");
137+
Information("FindRegexMatchesInFile 'alpha' OK ({0} matches)", many.Count);
138+
139+
var group = FindRegexMatchGroupInFile(sampleFile, @"gamma (\d+)", 1, System.Text.RegularExpressions.RegexOptions.None);
140+
AssertThat(group != null && group.Value == "42", "FindRegexMatchGroupInFile: expected group '42', got " + (group?.Value ?? "null"));
141+
Information("FindRegexMatchGroupInFile OK ('{0}')", group.Value);
142+
143+
var groups = FindRegexMatchGroupsInFile(sampleFile, @"(alpha) (line)", System.Text.RegularExpressions.RegexOptions.None);
144+
AssertThat(groups != null && groups.Count == 3, $"FindRegexMatchGroupsInFile: expected 3 groups (full + 2 captures), got {groups?.Count ?? 0}");
145+
Information("FindRegexMatchGroupsInFile OK ({0} groups)", groups.Count);
146+
147+
var allGroups = FindRegexMatchesGroupsInFile(sampleFile, @"(alpha) (line)", System.Text.RegularExpressions.RegexOptions.None);
148+
AssertThat(allGroups != null && allGroups.Count == 2, $"FindRegexMatchesGroupsInFile: expected 2 matches, got {allGroups?.Count ?? 0}");
149+
Information("FindRegexMatchesGroupsInFile OK ({0} matches)", allGroups.Count);
150+
});
151+
152+
Task("Replace-Operations")
153+
.IsDependentOn("Setup")
154+
.Does(() =>
155+
{
156+
var changed = ReplaceTextInFiles(workDir + File("sample*.txt"), "alpha", "ALPHA");
157+
AssertThat(changed.Length == 2, "ReplaceTextInFiles 'alpha'->'ALPHA': expected 2 changed files, got " + changed.Length);
158+
159+
var afterText = FileReadText(sampleFile);
160+
AssertThat(afterText.Contains("ALPHA") && !afterText.Contains("alpha"), "ReplaceTextInFiles: replacement not applied to sample.txt");
161+
Information("ReplaceTextInFiles OK ({0} files modified)", changed.Length);
162+
163+
var changedRx = ReplaceRegexInFiles(workDir + File("sample*.txt"), @"beta", "BETA");
164+
AssertThat(changedRx.Length == 1, "ReplaceRegexInFiles 'beta'->'BETA': expected 1 changed file (only sample.txt has 'beta'), got " + changedRx.Length);
165+
var afterRegex = FileReadText(sampleFile);
166+
AssertThat(afterRegex.Contains("BETA"), "ReplaceRegexInFiles: replacement not applied");
167+
Information("ReplaceRegexInFiles OK ({0} files modified)", changedRx.Length);
168+
});
169+
170+
Task("Cleanup")
171+
.IsDependentOn("Replace-Operations")
172+
.IsDependentOn("Append-Operations")
173+
.IsDependentOn("Touch")
174+
.IsDependentOn("Find-Operations")
175+
.Does(() =>
176+
{
177+
if (DirectoryExists(workDir))
178+
{
179+
DeleteDirectory(workDir, new DeleteDirectorySettings { Recursive = true });
180+
}
181+
182+
Information("Cleanup complete.");
183+
});
184+
185+
RunTarget("Default");
186+
187+
// ----- Helpers (must come AFTER top-level statements per CS8803) -----
188+
189+
static void AssertThat(bool condition, string message)
190+
{
191+
if (!condition)
192+
{
193+
throw new Exception("Assertion failed: " + message);
194+
}
195+
}

global.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"sdk": {
3-
"version": "9.0.100",
3+
"version": "10.0.100",
44
"rollForward": "latestFeature"
55
}
66
}

src/Cake.FileHelpers.Tests/Cake.FileHelpers.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<TargetFramework>net8.0</TargetFramework>
44
</PropertyGroup>
55
<ItemGroup>
6-
<PackageReference Include="Cake.Testing" Version="5.0.0" />
6+
<PackageReference Include="Cake.Testing" Version="6.0.0" />
77
<PackageReference Include="coverlet.msbuild" Version="6.0.4">
88
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
99
<PrivateAssets>all</PrivateAssets>

src/Cake.FileHelpers.Tests/FileHelperTests.cs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Text.RegularExpressions;
34
using Cake.Xamarin.Tests.Fakes;
45
using Cake.Core.IO;
@@ -185,6 +186,64 @@ public void TestAppendLinesToExistingFileAndReadLinesWithUTF8Encoding()
185186
Assert.Equal(contents[i], read[i]);
186187
}
187188

189+
[Fact]
190+
public void TestWriteLinesAcceptsIEnumerable()
191+
{
192+
const string file = "./testdata/Lines.txt";
193+
IEnumerable<string> contents = new List<string> { "This", "is", "a", "test" };
194+
195+
context.CakeContext.FileWriteLines(file, contents);
196+
197+
var read = context.CakeContext.FileReadLines(file);
198+
199+
Assert.Equal(4, read.Length);
200+
Assert.Equal("This", read[0]);
201+
Assert.Equal("test", read[3]);
202+
}
203+
204+
[Fact]
205+
public void TestWriteLinesAcceptsIEnumerableWithUTF8Encoding()
206+
{
207+
const string file = "./testdata/Lines.txt";
208+
IEnumerable<string> contents = new List<string> { "This is a test", "Monkey🐒" };
209+
210+
context.CakeContext.FileWriteLines(file, Encoding.UTF8, contents);
211+
212+
var read = context.CakeContext.FileReadLines(file, Encoding.UTF8);
213+
214+
Assert.Equal(2, read.Length);
215+
Assert.Equal("Monkey🐒", read[1]);
216+
}
217+
218+
[Fact]
219+
public void TestAppendLinesAcceptsIEnumerable()
220+
{
221+
const string file = "./testdata/Text.txt";
222+
IEnumerable<string> contents = new List<string> { "This", "is", "a", "test" };
223+
224+
context.CakeContext.FileAppendLines(file, contents);
225+
226+
var read = context.CakeContext.FileReadLines(file);
227+
228+
Assert.Equal(4, read.Length);
229+
Assert.Equal("This", read[0]);
230+
Assert.Equal("test", read[3]);
231+
}
232+
233+
[Fact]
234+
public void TestAppendLinesAcceptsIEnumerableWithUTF8Encoding()
235+
{
236+
const string file = "./testdata/Text.txt";
237+
IEnumerable<string> contents = new List<string> { "This is a test", "Monkey🐒" };
238+
239+
context.CakeContext.FileAppendLines(file, Encoding.UTF8, contents);
240+
241+
var read = context.CakeContext.FileReadLines(file, Encoding.UTF8);
242+
243+
Assert.Equal(2, read.Length);
244+
Assert.Equal("Monkey🐒", read[1]);
245+
}
246+
188247
[Fact]
189248
public void FindTextInFilesGlob()
190249
{

src/Cake.FileHelpers/Cake.FileHelpers.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3-
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
3+
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
44
<GenerateDocumentationFile>true</GenerateDocumentationFile>
55
<PublishRepositoryUrl>true</PublishRepositoryUrl>
66
<IncludeSymbols>true</IncludeSymbols>
@@ -23,8 +23,8 @@
2323
</PropertyGroup>
2424

2525
<ItemGroup>
26-
<PackageReference Include="Cake.Common" Version="5.0.0" PrivateAssets="All" />
27-
<PackageReference Include="Cake.Core" Version="5.0.0" PrivateAssets="All" />
26+
<PackageReference Include="Cake.Common" Version="6.0.0" PrivateAssets="All" />
27+
<PackageReference Include="Cake.Core" Version="6.0.0" PrivateAssets="All" />
2828

2929
<PackageReference Include="CakeContrib.Guidelines" Version="1.7.0">
3030
<PrivateAssets>all</PrivateAssets>

0 commit comments

Comments
 (0)