Skip to content

Commit

Permalink
! lib_compiled: Reorganize Pog.Package class hierarchy in preparation…
Browse files Browse the repository at this point in the history
… for remote repository
MatejKafka committed Apr 1, 2024
1 parent 69116c8 commit c715cf3
Showing 12 changed files with 412 additions and 333 deletions.
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@

namespace Pog.Commands;

// TODO: only works on local repository, either document it or extend it to remote repositories (probably don't)
/// <summary>
/// <para type="synopsis">Validates a repository package.</para>
/// <para type="description">
@@ -27,7 +28,7 @@ public sealed class ConfirmPogRepositoryPackageCommand : PogCmdlet {
protected const string DefaultPS = PackageNamePS;

[Parameter(Mandatory = true, Position = 0, ParameterSetName = PackagePS, ValueFromPipeline = true)]
public RepositoryPackage[] Package = null!;
public LocalRepositoryPackage[] Package = null!;

/// <summary><para type="description">Name of the repository package.</para></summary>
[Parameter(Position = 0, ParameterSetName = PackageNamePS, ValueFromPipeline = true)]
@@ -39,12 +40,21 @@ public sealed class ConfirmPogRepositoryPackageCommand : PogCmdlet {
[ArgumentCompleter(typeof(PSAttributes.RepositoryPackageVersionCompleter))]
public PackageVersion? Version;

private readonly Repository _repo = InternalState.Repository;
private readonly LocalRepository _repo;
private bool _noIssues = true;

private static readonly Regex QuoteHighlightRegex = new(@"'([^']+)'",
RegexOptions.Compiled | RegexOptions.CultureInvariant);

public ConfirmPogRepositoryPackageCommand() {
if (InternalState.Repository is LocalRepository r) {
_repo = r;
} else {
// TODO: implement
throw new RuntimeException("Validation of remote repositories is not yet supported");
}
}

private void AddIssue(string message) {
_noIssues = false;
var aligned = message.Replace("\n", "\n ");
@@ -68,9 +78,10 @@ protected override void BeginProcessing() {
"-Version must not be passed when -PackageName contains multiple package names.");
}

RepositoryPackage? package;
LocalRepositoryPackage? package;
try {
package = _repo.GetPackage(PackageName![0], true, true).GetVersionPackage(Version, true);
package = (LocalRepositoryPackage) _repo.GetPackage(PackageName![0], true, true)
.GetVersionPackage(Version, true);
} catch (RepositoryPackageNotFoundException e) {
WriteError(e, "PackageNotFound", ErrorCategory.ObjectNotFound, PackageName![0]);
return;
@@ -111,9 +122,9 @@ protected override void EndProcessing() {
WriteObject(_noIssues);
}

private RepositoryVersionedPackage? ResolvePackage(string packageName) {
private LocalRepositoryVersionedPackage? ResolvePackage(string packageName) {
try {
return _repo.GetPackage(packageName, true, true);
return (LocalRepositoryVersionedPackage) _repo.GetPackage(packageName, true, true);
} catch (RepositoryPackageNotFoundException e) {
WriteError(e, "PackageNotFound", ErrorCategory.ObjectNotFound, packageName);
return null;
@@ -134,16 +145,16 @@ private void ValidateAll() {

// validate all packages
foreach (var vp in _repo.Enumerate()) {
ValidatePackage(vp);
ValidatePackage((LocalRepositoryVersionedPackage) vp);
}
}

private void ValidatePackage(RepositoryVersionedPackage vp) {
private void ValidatePackage(LocalRepositoryVersionedPackage vp) {
if (vp.IsTemplated) ValidateTemplatedPackage(vp);
else ValidateDirectPackage(vp);
}

private void ValidateTemplatedPackage(RepositoryVersionedPackage vp) {
private void ValidateTemplatedPackage(LocalRepositoryVersionedPackage vp) {
if (File.Exists($"{vp.Path}\\.template.psd1")) {
AddIssue($"Package '{vp.PackageName}' contains an invalid version '.template'. " +
$"This version is not allowed, as it leads to ambiguity for direct packages.");
@@ -165,7 +176,7 @@ private void ValidateTemplatedPackage(RepositoryVersionedPackage vp) {
}

// validate .template dir
ValidateManifestDirectory($"'{vp.PackageName}'", templateDirPath);
ValidateManifestDirectory($"package '{vp.PackageName}'", templateDirPath);

// validate that manifest template exists
if (!File.Exists(templatePath)) {
@@ -176,7 +187,7 @@ private void ValidateTemplatedPackage(RepositoryVersionedPackage vp) {
ValidatePackageVersions(vp, false); // manifest dir already validated
}

private void ValidateDirectPackage(RepositoryVersionedPackage vp) {
private void ValidateDirectPackage(LocalRepositoryVersionedPackage vp) {
var extraFiles = GetFileList(Directory.EnumerateFiles(vp.Path));
if (extraFiles != "") {
AddIssue($"Package '{vp.PackageName}' has an incorrect file structure, contains extra files, " +
@@ -186,11 +197,11 @@ private void ValidateDirectPackage(RepositoryVersionedPackage vp) {
ValidatePackageVersions(vp, true);
}

private void ValidatePackageVersions(RepositoryVersionedPackage vp, bool validateManifestDir) {
private void ValidatePackageVersions(LocalRepositoryVersionedPackage vp, bool validateManifestDir) {
var hasVersion = false;
foreach (var p in vp.Enumerate()) {
hasVersion = true;
ValidatePackageVersion(p, validateManifestDir);
ValidatePackageVersion((LocalRepositoryPackage) p, validateManifestDir);
}

if (!hasVersion) {
@@ -199,9 +210,9 @@ private void ValidatePackageVersions(RepositoryVersionedPackage vp, bool validat
}
}

private void ValidatePackageVersion(RepositoryPackage p, bool validateManifestDir = true) {
private void ValidatePackageVersion(LocalRepositoryPackage p, bool validateManifestDir = true) {
if (validateManifestDir) {
ValidateManifestDirectory($"'{p.PackageName}', version '{p.Version}'", p.Path);
ValidateManifestDirectory(p.GetDescriptionString(), p.Path);
}

// validate the manifest
@@ -239,13 +250,13 @@ private void ValidateManifestDirectory(string packageInfoStr, string templateDir
var extraEntries = GetFileList(Directory.EnumerateFileSystemEntries(templateDirPath)
.Where(p => !p.EndsWith(@"\pog.psd1") && !p.EndsWith(@"\.pog")));
if (extraEntries != "") {
AddIssue($"Manifest directory for package {packageInfoStr} at '{templateDirPath}' contains extra " +
AddIssue($"Manifest directory for {packageInfoStr} at '{templateDirPath}' contains extra " +
$"entries: {extraEntries}. Only a 'pog.psd1' manifest file and an optional '.pog' directory for extra " +
$"files is allowed.");
}

if (File.Exists($"{templateDirPath}\\.pog")) {
AddIssue($"Extra resource directory for package {packageInfoStr} must be a directory, " +
AddIssue($"Extra resource directory for {packageInfoStr} must be a directory, " +
$"found a file at '{templateDirPath}\\.pog'.");
}

Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ public sealed class GetPogRepositoryPackage : PogCmdlet {
[Parameter(ParameterSetName = AllVersionsPS)]
public SwitchParameter AllVersions;

private readonly Repository _packages = InternalState.Repository;
private readonly IRepository _packages = InternalState.Repository;

protected override void BeginProcessing() {
base.BeginProcessing();
4 changes: 3 additions & 1 deletion app/Pog/lib_compiled/Pog/src/Commands/ImportPogCommand.cs
Original file line number Diff line number Diff line change
@@ -277,7 +277,7 @@ private void ImportPackage(RepositoryPackage package, ImportedPackage target) {

// FIXME: for templated manifests, `MatchesRepositoryManifest` will build the manifest once,
// and then .ImportTo will build it a second time; figure out how to avoid the duplication
if (!Force && target.MatchesRepositoryManifest(package)) {
if (!Force && package.MatchesImportedManifest(target)) {
WriteInformation($"Skipping import of package '{package.PackageName}', " +
"target already contains this package.");
return;
@@ -319,6 +319,8 @@ private bool ConfirmManifestOverwrite(RepositoryPackage package, ImportedPackage
// either a random folder was erroneously created, or this is a package, but corrupted
WriteWarning($"A package directory already exists at '{target.Path}', but it doesn't seem to contain " +
$"a package manifest. All directories in a package root should be packages with a valid manifest.");
// overwrite without confirmation
return true;
} catch (Exception e) when (e is IPackageManifestException) {
WriteWarning($"Found an existing package manifest at '{target.Path}', but it is not valid.");
}
47 changes: 18 additions & 29 deletions app/Pog/lib_compiled/Pog/src/ImportedPackageTypes.cs
Original file line number Diff line number Diff line change
@@ -3,9 +3,7 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using JetBrains.Annotations;
using Pog.Utils;
using IOPath = System.IO.Path;

namespace Pog;
@@ -118,18 +116,33 @@ public IEnumerable<ImportedPackage> EnumeratePackages(string packageRoot, bool l
/// otherwise an exception is thrown.
/// </summary>
[PublicAPI]
public sealed class ImportedPackage : Package {
public sealed class ImportedPackage : Package, ILocalPackage {
public PackageVersion? Version => Manifest.Version;
public string? ManifestName => Manifest.Name;

internal ImportedPackage(string packageName, string path, bool loadManifest = true) : base(packageName, path) {
public string Path {get;}
public string ManifestPath => IOPath.Combine(Path, PathConfig.PackagePaths.ManifestRelPath);
public string ManifestResourceDirPath => IOPath.Combine(Path, PathConfig.PackagePaths.ManifestResourceRelPath);

public override bool Exists => Directory.Exists(Path);

internal ImportedPackage(string packageName, string path, bool loadManifest = true) : base(packageName, null) {
Verify.Assert.FilePath(path);
Verify.Assert.PackageName(packageName);
Path = path;
if (loadManifest) {
// load the manifest to validate it and ensure the getters won't throw
ReloadManifest();
}
}

protected override PackageManifest LoadManifest() {
if (!Exists) {
throw new PackageNotFoundException($"Tried to read the package manifest of a non-existent package at '{Path}'.");
}
return new PackageManifest(ManifestPath);
}

// called while importing a new manifest
internal void RemoveManifest() {
FsUtils.EnsureDeleteFile(ManifestPath);
@@ -138,26 +151,6 @@ internal void RemoveManifest() {
InvalidateManifest();
}

public bool MatchesRepositoryManifest(RepositoryPackage p) {
// compare resource dirs
if (!FsUtils.DirectoryTreeEqual(ManifestResourceDirPath, p.ManifestResourceDirPath)) {
return false;
}

// compare manifest
var importedManifest = new FileInfo(ManifestPath);
if (!importedManifest.Exists) {
return false;
} else if (p is DirectRepositoryPackage dp) {
return importedManifest.Exists && FsUtils.FileContentEqual(new FileInfo(dp.ManifestPath), importedManifest);
} else if (p is TemplatedRepositoryPackage tp) {
var repoManifest = Encoding.UTF8.GetBytes(tp.GetManifestString());
return FsUtils.FileContentEqual(repoManifest, importedManifest);
} else {
throw new UnreachableException();
}
}

public bool RemoveExportedShortcuts() {
// shortcut dir is the root of the package, delete the shortcuts one-by-one instead of deleting the whole directory
var deleted = false;
@@ -206,11 +199,7 @@ private IEnumerable<FileInfo> EnumerateFilesRel(string relDirPath, string search
}
}

protected override PackageManifest LoadManifest() {
return new PackageManifest(ManifestPath);
}

public string GetDescriptionString() {
public override string GetDescriptionString() {
var versionStr = Manifest.Version != null ? $", version '{Manifest.Version}'" : "";
if (Manifest.Private) {
return $"private package '{PackageName}'{versionStr}";
Loading

0 comments on commit c715cf3

Please sign in to comment.