From 5dfaa84d2ab417879b09996accbc3dd085c26e5e Mon Sep 17 00:00:00 2001 From: ichan-akira <18476854+ichan-akira@users.noreply.github.com> Date: Fri, 30 Jul 2021 21:27:36 +0700 Subject: [PATCH 1/3] Create contfile directive. --- DotnetMakeDeb/Deb/DebPackage.cs | 75 ++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/DotnetMakeDeb/Deb/DebPackage.cs b/DotnetMakeDeb/Deb/DebPackage.cs index ef10b5f..589653f 100644 --- a/DotnetMakeDeb/Deb/DebPackage.cs +++ b/DotnetMakeDeb/Deb/DebPackage.cs @@ -17,6 +17,7 @@ namespace DotnetMakeDeb.Deb internal class DebPackage { private readonly List createdDirs = new List(); + private readonly List controlFileItems = new List(); private readonly List fileItems = new List(); private readonly Dictionary variables = new Dictionary(); @@ -279,6 +280,31 @@ public void ReadSpecification(string fileName) continue; } + m = Regex.Match(line, @"^contfile\s*:\s*(\S+)\s+(\S+)(?:\s+(text))?$", RegexOptions.IgnoreCase); + if (m.Success) + { + // Add data file as control file + var fileItem = new DebControlFileItem + { + SourcePath = ResolveVariables(m.Groups[1].Value.Trim()) + }; + if (!Path.IsPathRooted(fileItem.SourcePath)) + { + // Interpret non-rooted paths relative to the base path + fileItem.SourcePath = Path.Combine(srcBasePath, fileItem.SourcePath); + } + fileItem.IsText = m.Groups[2].Value == "text"; + foreach (var fi in ResolveFileItems(fileItem)) + { + var existingItem = controlFileItems.FirstOrDefault(x => x.SourcePath == fi.SourcePath); + if (existingItem != null) + controlFileItems.Remove(existingItem); + controlFileItems.Add(fi); + } + inDescription = false; + continue; + } + m = Regex.Match(line, @"^file\s*:\s*(\S+)\s+(\S+)(?:\s+(text))?(?:\s+([0-9]+)(?:\s+([0-9]+)\s+([0-9]+))?)?\s*$", RegexOptions.IgnoreCase); if (m.Success) { @@ -468,6 +494,10 @@ public void WritePackage(Stream outStream) { AddFile(postRmFileName, 0, 0, 493 /* 0755 */, postRmIsText); } + foreach (var controlFileItem in controlFileItems) + { + AddFile(controlFileItem.SourcePath, 0, 0, 493 /* 0755 */, controlFileItem.IsText); + } WriteControl(); @@ -767,6 +797,38 @@ private string ResolveVariables(string str) return str; } + private List ResolveFileItems(DebControlFileItem fileItem) + { + var fileItems = new List(); + if (fileItem.SourcePath.Contains("?") || + fileItem.SourcePath.Contains("*")) + { + string path = Path.GetDirectoryName(fileItem.SourcePath); + string searchPattern = Path.GetFileName(fileItem.SourcePath); + var searchOption = SearchOption.TopDirectoryOnly; + if (searchPattern == "**") + { + searchPattern = "*"; + searchOption = SearchOption.AllDirectories; + } + foreach (string fileName in Directory.GetFiles(path, searchPattern, searchOption)) + { + string relFileName = fileName.Substring(path.Length + 1).Replace("\\", "/"); + var fi = new DebControlFileItem + { + SourcePath = fileName, + IsText = fileItem.IsText + }; + fileItems.Add(fi); + } + } + else + { + fileItems.Add(fileItem); + } + return fileItems; + } + private List ResolveFileItems(DebFileItem fileItem) { var fileItems = new List(); @@ -858,7 +920,18 @@ public string ConvertedVersion } /// - /// Contains data about a file in a package. + /// Contains data about a file in a package control.tar.gz. + /// + internal class DebControlFileItem + { + /// The full path of the source file to include. + public string SourcePath { get; set; } + /// Indicates whether the line endings should be converted to Unix format. + public bool IsText { get; set; } + } + + /// + /// Contains data about a file in a package data.tar.gz. /// internal class DebFileItem { From b0dda913d1d2688ad9cb46fcc408f18dc169bb1d Mon Sep 17 00:00:00 2001 From: ichan-akira <18476854+ichan-akira@users.noreply.github.com> Date: Sun, 1 Aug 2021 23:33:49 +0700 Subject: [PATCH 2/3] Change directive from contfile to controlfile. --- DotnetMakeDeb/Deb/DebPackage.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DotnetMakeDeb/Deb/DebPackage.cs b/DotnetMakeDeb/Deb/DebPackage.cs index 589653f..bc46cdb 100644 --- a/DotnetMakeDeb/Deb/DebPackage.cs +++ b/DotnetMakeDeb/Deb/DebPackage.cs @@ -280,7 +280,7 @@ public void ReadSpecification(string fileName) continue; } - m = Regex.Match(line, @"^contfile\s*:\s*(\S+)\s+(\S+)(?:\s+(text))?$", RegexOptions.IgnoreCase); + m = Regex.Match(line, @"^controlfile\s*:\s*(\S+)\s+(\S+)(?:\s+(text))?$", RegexOptions.IgnoreCase); if (m.Success) { // Add data file as control file From db9e5c92ff01b29cb97aee100db02d5673b796b4 Mon Sep 17 00:00:00 2001 From: ichan-akira <18476854+ichan-akira@users.noreply.github.com> Date: Tue, 3 Aug 2021 12:55:30 +0700 Subject: [PATCH 3/3] - Remove DebControlFileItem class for control file item, instead use already existing DebFileItem class. - Adjust regex for controlfile to allow input for SourcePath, IsText, Mode, UserId, and GroupId. - Simplify existing implementation of initializing DebFileItem objects. - Make all properties initialization for DebFileItem more explicit (explicitly initialized) to make code easier to understand. - DebPackage.WritePackage() method now execute AddFile() for control file item with user defined UserId, GroupId, and Mode. - Adjust DebPackage.ResolveFileItems() to allow processing for null DestPath. - Convert pubic fields in DebControlParams and DebFileItem to become property with getter setter (following OOP principle: encapsulation). --- DotnetMakeDeb/Deb/DebPackage.cs | 145 ++++++++++++++------------------ 1 file changed, 62 insertions(+), 83 deletions(-) diff --git a/DotnetMakeDeb/Deb/DebPackage.cs b/DotnetMakeDeb/Deb/DebPackage.cs index bc46cdb..ba9654f 100644 --- a/DotnetMakeDeb/Deb/DebPackage.cs +++ b/DotnetMakeDeb/Deb/DebPackage.cs @@ -17,7 +17,7 @@ namespace DotnetMakeDeb.Deb internal class DebPackage { private readonly List createdDirs = new List(); - private readonly List controlFileItems = new List(); + private readonly List controlFileItems = new List(); private readonly List fileItems = new List(); private readonly Dictionary variables = new Dictionary(); @@ -280,20 +280,29 @@ public void ReadSpecification(string fileName) continue; } - m = Regex.Match(line, @"^controlfile\s*:\s*(\S+)\s+(\S+)(?:\s+(text))?$", RegexOptions.IgnoreCase); + m = Regex.Match(line, @"^controlfile\s*:\s*(\S+)(?:\s+(text))?(?:\s+([0-9]+)(?:\s+([0-9]+)\s+([0-9]+))?)?\s*$", RegexOptions.IgnoreCase); if (m.Success) { // Add data file as control file - var fileItem = new DebControlFileItem + var fileItem = new DebFileItem { - SourcePath = ResolveVariables(m.Groups[1].Value.Trim()) + SourcePath = ResolveVariables(m.Groups[1].Value.Trim()), + DestPath = null, + IsConfig = false, + IsDirectory = false, + IsText = m.Groups[2].Value == "text" }; if (!Path.IsPathRooted(fileItem.SourcePath)) { // Interpret non-rooted paths relative to the base path fileItem.SourcePath = Path.Combine(srcBasePath, fileItem.SourcePath); } - fileItem.IsText = m.Groups[2].Value == "text"; + if (m.Groups[3].Length > 0) + fileItem.Mode = Convert.ToInt32(ResolveVariables(m.Groups[3].Value), 8); + if (m.Groups[4].Length > 0) + fileItem.UserId = Convert.ToInt32(ResolveVariables(m.Groups[4].Value)); + if (m.Groups[5].Length > 0) + fileItem.GroupId = Convert.ToInt32(ResolveVariables(m.Groups[5].Value)); foreach (var fi in ResolveFileItems(fileItem)) { var existingItem = controlFileItems.FirstOrDefault(x => x.SourcePath == fi.SourcePath); @@ -311,15 +320,17 @@ public void ReadSpecification(string fileName) // Add data file var fileItem = new DebFileItem { - SourcePath = ResolveVariables(m.Groups[1].Value.Trim()) + SourcePath = ResolveVariables(m.Groups[1].Value.Trim()), + DestPath = ResolveVariables(m.Groups[2].Value.Trim()), + IsConfig = false, + IsDirectory = false, + IsText = m.Groups[3].Value == "text" }; if (!Path.IsPathRooted(fileItem.SourcePath)) { // Interpret non-rooted paths relative to the base path fileItem.SourcePath = Path.Combine(srcBasePath, fileItem.SourcePath); } - fileItem.DestPath = ResolveVariables(m.Groups[2].Value.Trim()); - fileItem.IsText = m.Groups[3].Value == "text"; if (m.Groups[4].Length > 0) fileItem.Mode = Convert.ToInt32(ResolveVariables(m.Groups[4].Value), 8); if (m.Groups[5].Length > 0) @@ -342,22 +353,23 @@ public void ReadSpecification(string fileName) // Add data file as conffile var fileItem = new DebFileItem { - SourcePath = ResolveVariables(m.Groups[1].Value.Trim()) + SourcePath = ResolveVariables(m.Groups[1].Value.Trim()), + DestPath = ResolveVariables(m.Groups[2].Value.Trim()), + IsConfig = true, + IsDirectory = false, + IsText = m.Groups[3].Value == "text" }; if (!Path.IsPathRooted(fileItem.SourcePath)) { // Interpret non-rooted paths relative to the base path fileItem.SourcePath = Path.Combine(srcBasePath, fileItem.SourcePath); } - fileItem.DestPath = ResolveVariables(m.Groups[2].Value.Trim()); - fileItem.IsText = m.Groups[3].Value == "text"; if (m.Groups[4].Length > 0) fileItem.Mode = Convert.ToInt32(ResolveVariables(m.Groups[4].Value), 8); if (m.Groups[5].Length > 0) fileItem.UserId = Convert.ToInt32(ResolveVariables(m.Groups[5].Value)); if (m.Groups[6].Length > 0) fileItem.GroupId = Convert.ToInt32(ResolveVariables(m.Groups[6].Value)); - fileItem.IsConfig = true; foreach (var fi in ResolveFileItems(fileItem)) { var existingItem = fileItems.FirstOrDefault(x => x.SourcePath == fi.SourcePath); @@ -374,7 +386,11 @@ public void ReadSpecification(string fileName) // Add empty directory var fileItem = new DebFileItem { - DestPath = ResolveVariables(m.Groups[1].Value.Trim()).TrimEnd('/') + SourcePath = null, + DestPath = ResolveVariables(m.Groups[1].Value.Trim()).TrimEnd('/'), + IsConfig = false, + IsDirectory = true, + IsText = false }; if (m.Groups[2].Length > 0) fileItem.Mode = Convert.ToInt32(ResolveVariables(m.Groups[2].Value), 8); @@ -384,7 +400,6 @@ public void ReadSpecification(string fileName) fileItem.UserId = Convert.ToInt32(ResolveVariables(m.Groups[3].Value)); if (m.Groups[4].Length > 0) fileItem.GroupId = Convert.ToInt32(ResolveVariables(m.Groups[4].Value)); - fileItem.IsDirectory = true; fileItems.Add(fileItem); inDescription = false; continue; @@ -496,7 +511,7 @@ public void WritePackage(Stream outStream) } foreach (var controlFileItem in controlFileItems) { - AddFile(controlFileItem.SourcePath, 0, 0, 493 /* 0755 */, controlFileItem.IsText); + AddFile(controlFileItem.SourcePath, controlFileItem.UserId, controlFileItem.GroupId, controlFileItem.Mode, controlFileItem.IsText); } WriteControl(); @@ -797,38 +812,6 @@ private string ResolveVariables(string str) return str; } - private List ResolveFileItems(DebControlFileItem fileItem) - { - var fileItems = new List(); - if (fileItem.SourcePath.Contains("?") || - fileItem.SourcePath.Contains("*")) - { - string path = Path.GetDirectoryName(fileItem.SourcePath); - string searchPattern = Path.GetFileName(fileItem.SourcePath); - var searchOption = SearchOption.TopDirectoryOnly; - if (searchPattern == "**") - { - searchPattern = "*"; - searchOption = SearchOption.AllDirectories; - } - foreach (string fileName in Directory.GetFiles(path, searchPattern, searchOption)) - { - string relFileName = fileName.Substring(path.Length + 1).Replace("\\", "/"); - var fi = new DebControlFileItem - { - SourcePath = fileName, - IsText = fileItem.IsText - }; - fileItems.Add(fi); - } - } - else - { - fileItems.Add(fileItem); - } - return fileItems; - } - private List ResolveFileItems(DebFileItem fileItem) { var fileItems = new List(); @@ -849,18 +832,20 @@ private List ResolveFileItems(DebFileItem fileItem) var fi = new DebFileItem { SourcePath = fileName, - DestPath = fileItem.DestPath.TrimEnd('/') + "/" + relFileName, + DestPath = fileItem.DestPath == null ? null : fileItem.DestPath.TrimEnd('/') + "/" + relFileName, UserId = fileItem.UserId, GroupId = fileItem.GroupId, Mode = fileItem.Mode, - IsConfig = fileItem.IsConfig + IsConfig = fileItem.IsConfig, + IsDirectory = fileItem.IsDirectory, + IsText = fileItem.IsText }; fileItems.Add(fi); } } else { - if (fileItem.DestPath.EndsWith("/")) + if (fileItem.DestPath?.EndsWith("/") ?? false) { fileItem.DestPath += Path.GetFileName(fileItem.SourcePath); } @@ -876,31 +861,31 @@ private List ResolveFileItems(DebFileItem fileItem) internal class DebControlParams { /// The name of the package. - public string Package; + public string Package { get; set; } /// The version of the package. - public string Version; + public string Version { get; set; } /// Convert the specified or overridden version from SemVer to Debian conventions. - public bool ConvertFromSemVer; + public bool ConvertFromSemVer { get; set; } /// The section of the package. - public string Section; + public string Section { get; set; } /// The priority of the package. - public string Priority; + public string Priority { get; set; } /// The hardware architecture of the package. - public string Architecture; + public string Architecture { get; set; } /// The package dependencies of the package. - public string Depends; + public string Depends { get; set; } /// The package pre-dependencies of the package. - public string PreDepends; + public string PreDepends { get; set; } /// The other packages that the package conflicts with. - public string Conflicts; + public string Conflicts { get; set; } /// The total estimated size of the installed package in KiB. - public long InstalledSize; + public long InstalledSize { get; set; } /// The name and e-mail address of the package maintainer in RFC 822 format. - public string Maintainer; + public string Maintainer { get; set; } /// The website URL of the package. - public string Homepage; + public string Homepage { get; set; } /// The description of the package, in the original control file multi-line syntax. - public string Description; + public string Description { get; set; } /// /// Gets the version that was converted from SemVer to Debian, if configured, or the original version. @@ -920,36 +905,30 @@ public string ConvertedVersion } /// - /// Contains data about a file in a package control.tar.gz. - /// - internal class DebControlFileItem - { - /// The full path of the source file to include. - public string SourcePath { get; set; } - /// Indicates whether the line endings should be converted to Unix format. - public bool IsText { get; set; } - } - - /// - /// Contains data about a file in a package data.tar.gz. + /// Contains data about a file in a package. /// internal class DebFileItem { + public DebFileItem() + { + Mode = 420 /* 0644 */; + } + /// The full path of the source file to include. - public string SourcePath; + public string SourcePath { get; set; } /// The full path of the destination file to write, not including the root slash. - public string DestPath; + public string DestPath { get; set; } /// The user ID of the file. - public int UserId; + public int UserId { get; set; } /// The group ID of the file. - public int GroupId; + public int GroupId { get; set; } /// The mode of the file (decimal). - public int Mode = 420 /* 0644 */; + public int Mode { get; set; } /// Indicates whether the file is a configuration file. - public bool IsConfig; + public bool IsConfig { get; set; } /// Indicates whether the file is a directory. - public bool IsDirectory; + public bool IsDirectory { get; set; } /// Indicates whether the line endings should be converted to Unix format. - public bool IsText; + public bool IsText { get; set; } } }