Skip to content

Commit 24654e5

Browse files
authored
Merge pull request #67 from Deadpikle/feature/tar-zip-handling
Use .NET built-in Tar and Zip handling
2 parents d142349 + 63f9d63 commit 24654e5

File tree

4 files changed

+172
-5
lines changed

4 files changed

+172
-5
lines changed

src/DotNetReleaser.Tests/BasicTests.cs

+93
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Formats.Tar;
34
using System.IO;
5+
using System.IO.Compression;
46
using System.Linq;
57
using System.Runtime.InteropServices;
68
using System.Text;
@@ -110,6 +112,97 @@ public async Task TestBuild()
110112
File.Delete(_configurationFile);
111113
}
112114

115+
[Test]
116+
public async Task TestMacOSTarZipAreExecutable()
117+
{
118+
EnsureTestsFolder();
119+
120+
File.Delete(_configurationFile);
121+
122+
await CreateConfiguration();
123+
124+
var config = await File.ReadAllTextAsync(_configurationFile);
125+
126+
if (Directory.Exists(_artifactsFolder))
127+
{
128+
Directory.Delete(_artifactsFolder, true);
129+
}
130+
131+
config = "profile = \"custom\"" + Environment.NewLine + config;
132+
config += @"
133+
[msbuild.properties]
134+
SelfContained = false
135+
PublishSingleFile = false
136+
PublishTrimmed = false
137+
[[pack]]
138+
rid = ""osx-x64""
139+
kinds = [""tar"", ""zip""]
140+
[nuget]
141+
publish = false
142+
";
143+
config = config.Replace("\r\n", "\n").Replace("\n", Environment.NewLine);
144+
await File.WriteAllTextAsync(_configurationFile, config);
145+
146+
var resultBuild = await CliWrap.Cli.Wrap(_releaserExe)
147+
.WithArguments("build --force dotnet-releaser.toml")
148+
.WithStandardOutputPipe(PipeTarget.ToDelegate(x => Console.Out.WriteLine(x)))
149+
.WithStandardErrorPipe(PipeTarget.ToDelegate(x => Console.Error.WriteLine(x)))
150+
.WithWorkingDirectory(_helloWorldFolder).ExecuteAsync();
151+
152+
Assert.True(Directory.Exists(_artifactsFolder));
153+
154+
var files = Directory.GetFiles(_artifactsFolder).Select(Path.GetFileName).OrderBy(x => x).ToList();
155+
156+
var expectedFiles = new List<string>()
157+
{
158+
"HelloWorld.0.1.0.osx-x64.tar.gz",
159+
"HelloWorld.0.1.0.osx-x64.zip",
160+
}.OrderBy(x => x).ToList();
161+
162+
foreach (var file in files)
163+
{
164+
Console.WriteLine($"-> {file}");
165+
}
166+
167+
Assert.AreEqual(expectedFiles, files);
168+
169+
if (!OperatingSystem.IsWindows())
170+
{
171+
// ensure files are executable
172+
var tar = Path.Combine(_artifactsFolder, "HelloWorld.0.1.0.osx-x64.tar.gz");
173+
using FileStream fs = new(tar, FileMode.Open, FileAccess.Read);
174+
using var gzip = new GZipStream(fs, CompressionMode.Decompress);
175+
using var unzippedStream = new MemoryStream();
176+
{
177+
await gzip.CopyToAsync(unzippedStream);
178+
unzippedStream.Seek(0, SeekOrigin.Begin);
179+
180+
using var reader = new TarReader(unzippedStream);
181+
182+
while (reader.GetNextEntry() is TarEntry entry)
183+
{
184+
if (entry.Name == "./HelloWorld")
185+
{
186+
Assert.IsTrue(entry.Mode.HasFlag(UnixFileMode.GroupExecute));
187+
Assert.IsTrue(entry.Mode.HasFlag(UnixFileMode.OtherExecute));
188+
Assert.IsTrue(entry.Mode.HasFlag(UnixFileMode.UserExecute));
189+
break;
190+
}
191+
}
192+
}
193+
// extract zip files and check executable
194+
var zippath = Path.Combine(_artifactsFolder, "HelloWorld.0.1.0.osx-x64.zip");
195+
ZipFile.ExtractToDirectory(zippath, _artifactsFolder);
196+
var fileMode = File.GetUnixFileMode(Path.Combine(_artifactsFolder, "HelloWorld"));
197+
Assert.IsTrue(fileMode.HasFlag(UnixFileMode.GroupExecute));
198+
Assert.IsTrue(fileMode.HasFlag(UnixFileMode.OtherExecute));
199+
Assert.IsTrue(fileMode.HasFlag(UnixFileMode.UserExecute));
200+
}
201+
202+
Directory.Delete(_artifactsFolder, true);
203+
File.Delete(_configurationFile);
204+
}
205+
113206
[Test]
114207
public async Task TestBuildService()
115208
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System.Formats.Tar;
2+
using System.IO;
3+
using System.IO.Compression;
4+
5+
namespace DotNetReleaser.Helpers;
6+
7+
internal static class CompressionHelper
8+
{
9+
public static string? MakeTarGz(ProjectPackageInfo projectPackageInfo, string publishDir, string artifactsFolder, string rid)
10+
{
11+
string? outputPath = null;
12+
var publishPath = Path.Combine(Path.GetDirectoryName(projectPackageInfo.ProjectFullPath) ?? "", publishDir);
13+
if (Directory.Exists(publishPath))
14+
{
15+
var gzipPath = Path.GetFullPath(Path.Combine(artifactsFolder,
16+
projectPackageInfo.Name + "." + projectPackageInfo.Version + "." + rid + ".tar.gz"));
17+
if (File.Exists(gzipPath))
18+
{
19+
return null; // file already exists
20+
}
21+
using FileStream fs = new(gzipPath, FileMode.CreateNew, FileAccess.Write);
22+
using GZipStream gz = new(fs, CompressionMode.Compress, leaveOpen: true);
23+
{
24+
TarFile.CreateFromDirectory(publishPath, gz, includeBaseDirectory: false);
25+
}
26+
outputPath = gzipPath;
27+
}
28+
return outputPath;
29+
}
30+
31+
public static string? MakeZip(ProjectPackageInfo projectPackageInfo, string publishDir, string artifactsFolder, string rid)
32+
{
33+
string? outputPath = null;
34+
var publishPath = Path.Combine(Path.GetDirectoryName(projectPackageInfo.ProjectFullPath) ?? "", publishDir);
35+
if (Directory.Exists(publishPath))
36+
{
37+
var zipPath = Path.GetFullPath(Path.Combine(artifactsFolder,
38+
projectPackageInfo.Name + "." + projectPackageInfo.Version + "." + rid + ".zip"));
39+
if (File.Exists(zipPath))
40+
{
41+
return null; // file already exists
42+
}
43+
using FileStream fs = new(zipPath, FileMode.CreateNew, FileAccess.Write);
44+
{
45+
ZipFile.CreateFromDirectory(publishPath, fs, compressionLevel: CompressionLevel.Optimal, includeBaseDirectory: false);
46+
}
47+
outputPath = zipPath;
48+
}
49+
return outputPath;
50+
}
51+
}

src/dotnet-releaser/ReleaserApp.AppPackaging.cs

+23-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Security.Cryptography;
77
using System.Threading.Tasks;
88
using DotNetReleaser.Configuration;
9+
using DotNetReleaser.Helpers;
910
using DotNetReleaser.Logging;
1011
using Spectre.Console;
1112

@@ -225,7 +226,28 @@ private async Task<List<AppPackageInfo>> BuildAppPackages(BuildInformation build
225226

226227
// Copy the file to the output
227228
var path = result[0].ItemSpec;
228-
path = CopyToArtifacts(path);
229+
if (target == ReleaserConstants.DotNetReleaserPublishAndCreateTar)
230+
{
231+
path = CompressionHelper.MakeTarGz(projectPackageInfo, path, _config.ArtifactsFolder, rid);
232+
if (path is null)
233+
{
234+
Error("Unable to make tar file with publish directory " + path + "; does the file already exist?");
235+
break;
236+
}
237+
}
238+
else if (target == ReleaserConstants.DotNetReleaserPublishAndCreateZip)
239+
{
240+
path = CompressionHelper.MakeZip(projectPackageInfo, path, _config.ArtifactsFolder, rid);
241+
if (path is null)
242+
{
243+
Error("Unable to make zip file with publish directory " + path + "; does the file already exist?");
244+
break;
245+
}
246+
}
247+
else
248+
{
249+
path = CopyToArtifacts(path);
250+
}
229251

230252
var sha256 = string.Join("", SHA256.HashData(await File.ReadAllBytesAsync(path)).Select(x => x.ToString("x2")));
231253

src/dotnet-releaser/dotnet-releaser.targets

+5-4
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
<_DotNetReleaserGetPackageInfo Include="$(IsPackable)" Kind="IsNuGetPackable"/>
101101
<_DotNetReleaserGetPackageInfo Include="$(IsTestProject)" Kind="IsTestProject"/>
102102
<_DotNetReleaserGetPackageInfo Include="@(ProjectReference)" Kind="ProjectReference"/>
103+
<_DotNetReleaserGetPackageInfo Include="$([System.IO.Path]::GetFullPath('$(PublishDir)'))" Kind="PublishDir"/>
103104
</ItemGroup>
104105
</Target>
105106

@@ -116,14 +117,14 @@
116117
<_DotNetReleaserPublishAndCreateRpm Include="$(RpmPath)" Kind="RpmPath"/>
117118
</ItemGroup>
118119
</Target>
119-
<Target Name="DotNetReleaserPublishAndCreateZip" Outputs="@(_DotNetReleaserPublishAndCreateZip)" DependsOnTargets="CreateZip">
120+
<Target Name="DotNetReleaserPublishAndCreateZip" Outputs="@(_DotNetReleaserPublishAndCreateZip)" DependsOnTargets="Publish">
120121
<ItemGroup>
121-
<_DotNetReleaserPublishAndCreateZip Include="$(ZipPath)" Kind="ZipPath"/>
122+
<_DotNetReleaserPublishAndCreateZip Include="$(PublishDir)" Kind="PublishDir"/>
122123
</ItemGroup>
123124
</Target>
124-
<Target Name="DotNetReleaserPublishAndCreateTar" Outputs="@(_DotNetReleaserPublishAndCreateTar)" DependsOnTargets="CreateTarball">
125+
<Target Name="DotNetReleaserPublishAndCreateTar" Outputs="@(_DotNetReleaserPublishAndCreateTar)" DependsOnTargets="Publish">
125126
<ItemGroup>
126-
<_DotNetReleaserPublishAndCreateTar Include="$(TarballPath)" Kind="TarballPath"/>
127+
<_DotNetReleaserPublishAndCreateTar Include="$(PublishDir)" Kind="PublishDir"/>
127128
</ItemGroup>
128129
</Target>
129130
</Project>

0 commit comments

Comments
 (0)