diff --git a/dotnet/Containers.ImageRefs/PartialImageRef.Parsing.cs b/dotnet/Containers.ImageRefs/PartialImageRef.Parsing.cs
index e9f0775..5eedfee 100644
--- a/dotnet/Containers.ImageRefs/PartialImageRef.Parsing.cs
+++ b/dotnet/Containers.ImageRefs/PartialImageRef.Parsing.cs
@@ -10,6 +10,13 @@ public sealed partial record PartialImageRef {
)]
private static partial Regex ImageRefRegex();
+ ///
+ /// Parses a string representation of an image reference.
+ ///
+ /// The string to parse.
+ /// A parsed .
+ /// Thrown when imageReference is null.
+ /// Thrown when imageReference is not in a valid format.
public static PartialImageRef Parse( string imageReference ) {
ArgumentNullException.ThrowIfNull( imageReference );
@@ -33,6 +40,12 @@ public static PartialImageRef Parse( string imageReference ) {
return new PartialImageRef( repository, tag, registry, @namespace, digest );
}
+ ///
+ /// Tries to parse a string representation of an image reference.
+ ///
+ /// The string to parse.
+ /// When this method returns, contains the parsed reference if parsing succeeded, or null if it failed.
+ /// true if parsing succeeded; otherwise, false.
public static bool TryParse( string? input, out PartialImageRef? reference ) {
try {
if ( input is null ) {
diff --git a/dotnet/Containers.ImageRefs/PartialImageRef.cs b/dotnet/Containers.ImageRefs/PartialImageRef.cs
index cda41be..b05da2f 100644
--- a/dotnet/Containers.ImageRefs/PartialImageRef.cs
+++ b/dotnet/Containers.ImageRefs/PartialImageRef.cs
@@ -3,22 +3,24 @@
namespace HLabs.Containers.ImageRefs;
// TODO support platform
-// TODO docs
+// TODO add no-arg Canonicalize?
///
-/// ~~A fully-qualified container image reference.~~
-///
-/// example.com:5000/team/my-app:2.0
-///
-/// Host: example.com:5000
-/// Namespace: team
-/// Repository: my-app
-/// Tag: 2.0
-///
+/// Partial image reference.
+///
+/// -
+///
Use to convert to a fully qualified reference.
+///
+/// -
+///
Use to convert to a canonical reference.
+///
+///
///
public sealed partial record PartialImageRef : ImageRef {
private PartialImageRef(
Repository repository,
+#pragma warning disable S3427
Tag? tag = null,
+#pragma warning restore S3427
Registry? registry = null,
Namespace? @namespace = null,
Digest? digest = null
@@ -35,26 +37,57 @@ private PartialImageRef(
#pragma warning restore SA1124
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The repository name.
public PartialImageRef( Repository repository )
: this( repository, null, null, null, null ) {
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The repository name.
+ /// The tag.
public PartialImageRef( Repository repository, Tag tag )
: this( repository, tag, null, null, null ) {
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The namespace.
+ /// The repository name.
public PartialImageRef( Namespace ns, Repository repository )
: this( repository, null, null, ns, null ) {
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The namespace.
+ /// The repository name.
+ /// The tag.
public PartialImageRef( Namespace ns, Repository repository, Tag tag )
: this( repository, tag, null, ns, null ) {
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The repository name.
+ /// The digest.
public PartialImageRef( Repository repository, Digest digest )
: this( repository, null, null, null, digest ) {
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The repository name.
+ /// The tag.
+ /// The digest.
public PartialImageRef( Repository repository, Tag tag, Digest digest )
: this( repository, tag, null, null, digest ) {
}
@@ -66,6 +99,11 @@ public PartialImageRef( Repository repository, Tag tag, Digest digest )
#region Any registry
#pragma warning restore SA1124
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The registry.
+ /// The repository name.
public PartialImageRef( Registry registry, Repository repository )
: this( repository, null, registry, null, null ) {
}
@@ -73,36 +111,88 @@ public PartialImageRef( Registry registry, Repository repository )
// Overload clashes with Namespace + Repository + Tag when using string literals (implicit conversions), so not included for now.
// The more common use case is probably the other one.
// TODO decide
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The registry.
+ /// The repository name.
+ /// The tag.
public PartialImageRef( Registry registry, Repository repository, Tag tag )
: this( repository, tag, registry, null, null ) {
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The registry.
+ /// The repository name.
+ /// The digest.
public PartialImageRef( Registry registry, Repository repository, Digest digest )
: this( repository, null, registry, null, digest ) {
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The registry.
+ /// The namespace.
+ /// The repository name.
public PartialImageRef( Registry registry, Namespace ns, Repository repository )
: this( repository, null, registry, ns, null ) {
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The registry.
+ /// The namespace.
+ /// The repository name.
+ /// The tag.
public PartialImageRef( Registry registry, Namespace ns, Repository repository, Tag tag )
: this( repository, tag, registry, ns, null ) {
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The registry.
+ /// The namespace.
+ /// The repository name.
+ /// The digest.
public PartialImageRef( Registry registry, Namespace ns, Repository repository, Digest digest )
: this( repository, null, registry, ns, digest ) {
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The registry.
+ /// The repository name.
+ /// The tag.
+ /// The digest.
public PartialImageRef( Registry registry, Repository repository, Tag tag, Digest digest )
: this( repository, tag, registry, null, digest ) {
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The registry.
+ /// The namespace.
+ /// The repository name.
+ /// The tag.
+ /// The digest.
public PartialImageRef( Registry registry, Namespace ns, Repository repository, Tag tag, Digest digest )
: this( repository, tag, registry, ns, digest ) {
}
#endregion
+ ///
+ /// Returns a string representation of this image reference.
+ ///
+ /// A string representation of this image reference.
public override string ToString() {
var reg = Registry is null ? string.Empty : $"{Registry}/";
var ns = Namespace is null ? string.Empty : $"{Namespace}/";
@@ -111,13 +201,21 @@ public override string ToString() {
return $"{reg}{ns}{Repository}{tag}{digest}";
}
+ ///
+ /// Tries to convert this partial reference to a qualified reference by applying default conventions.
+ ///
+ /// When this method returns, contains the qualified reference if qualification succeeded, or null if it failed.
+ /// When this method returns, contains an error message if qualification failed, or null if it succeeded.
+ /// true if qualification succeeded; otherwise, false.
public bool TryQualify( out QualifiedImageRef? canonical, out string? reason ) {
try {
canonical = Qualify();
reason = null;
return true;
}
+#pragma warning disable CA1031
catch ( Exception ex ) {
+#pragma warning restore CA1031
canonical = null;
reason = ex.Message;
return false;
@@ -127,24 +225,33 @@ public bool TryQualify( out QualifiedImageRef? canonical, out string? reason ) {
///
/// Returns a new instance with a different cosmetic tag.
///
+ /// The tag to use, or null to remove the tag.
+ /// A new with the specified tag.
public PartialImageRef With( Tag? tag ) =>
new(Repository, tag, Registry, Namespace, Digest);
///
/// Returns a new instance with a different registry.
///
+ /// The registry to use, or null to remove the registry.
+ /// A new with the specified registry.
public PartialImageRef With( Registry? registry ) =>
new(Repository, Tag, registry, Namespace, Digest);
///
/// Returns a new instance with a different registry.
///
+ /// The registry to use.
+ /// The namespace to use.
+ /// A new with the specified registry and namespace.
public PartialImageRef With( Registry registry, Namespace ns ) =>
new(Repository, Tag, registry, ns, Digest);
///
/// Returns a new instance with a different namespace.
///
+ /// The namespace to use, or null to remove the namespace.
+ /// A new with the specified namespace.
public PartialImageRef With( Namespace? ns ) =>
// TODO remember registry/namespace requirement
new(Repository, Tag, Registry, ns, Digest);
@@ -152,12 +259,20 @@ public PartialImageRef With( Namespace? ns ) =>
///
/// Returns a new instance with a different digest.
///
+ /// The digest to use, or null to remove the digest.
+ /// A new with the specified digest.
public PartialImageRef With( Digest? digest ) =>
new(Repository, Tag, Registry, Namespace, digest);
+ ///
+ /// Gets a value indicating whether this reference has all required components for qualification.
+ ///
public override bool IsQualified => Registry != null && ( !Registry.NamespaceRequired || Namespace != null ) &&
( Tag != null || Digest != null );
+ ///
+ /// Gets a value indicating whether this reference can be qualified using default conventions.
+ ///
public bool CanQualify => TryQualify( out _, out _ );
///
@@ -182,7 +297,6 @@ public QualifiedImageRef Qualify( QualificationMode mode = QualificationMode.Def
return new QualifiedImageRef( registry, ns, repo, tag, Digest );
}
-
///
/// Canonicalizes the image reference using the current digest.
///
@@ -197,7 +311,6 @@ public CanonicalImageRef Canonicalize(
return Qualify( qualificationMode ).Canonicalize( canonicalizationMode );
}
-
///
/// Canonicalizes the image reference with a specific digest.
///
diff --git a/dotnet/Containers.ImageRefs/QualifiedImageRef.cs b/dotnet/Containers.ImageRefs/QualifiedImageRef.cs
index 19b472a..f6de947 100644
--- a/dotnet/Containers.ImageRefs/QualifiedImageRef.cs
+++ b/dotnet/Containers.ImageRefs/QualifiedImageRef.cs
@@ -12,6 +12,9 @@ namespace HLabs.Containers.ImageRefs;
/// Must have either a tag or digest.
///
public sealed record QualifiedImageRef : ImageRef {
+ ///
+ /// Gets the registry for this image reference.
+ ///
public new Registry Registry {
get;
}
@@ -32,12 +35,17 @@ internal QualifiedImageRef( Registry registry, Namespace? ns, Repository reposit
///
/// Returns a new instance with a different tag.
///
+ /// The tag to use.
+ /// A new with the specified tag.
public QualifiedImageRef WithTag( Tag tag ) =>
new(Registry, Namespace, Repository, tag, Digest);
///
/// Returns a new instance with a different registry.
///
+ /// The registry to use.
+ /// Optional namespace to use; if not provided, uses the current namespace.
+ /// A new with the specified registry and namespace.
public QualifiedImageRef On( Registry registry, Namespace? ns = null ) =>
new(registry, ns ?? Namespace, Repository, Tag, Digest);
@@ -59,6 +67,7 @@ public CanonicalImageRef Canonicalize( Digest digest, CanonicalizationMode mode
/// Creates a digest-pinned image reference using the current digest.
///
+ /// Acr("myregistry"); // myregistry.azurecr.io
+ ///
+ ///
+ /// Ecr("aws_account_id", "region"); // aws_account_id.dkr.ecr.region.amazonaws.com
+ ///
+ /// -/// Digests are immutable identifiers that uniquely identify image content i.e., they are content-addressable. -///
+/// Represents a content-addressable digest for a container image (e.g.,
-/// Digest digest = "sha256:abc123";
-///
-/// Using constructor
///
/// var digest = new Digest("sha256:abc123");
-///
-/// Algorithm prefix is optional:
-///
-/// Digest digest1 = "abc123";
+/// Digest digest = "sha256:abc123"; // Implicit conversion from string
+/// Digest digest = "abc123"; // Algorithm prefix optional
///
///
/// var ns = new Namespace("library"); // DockerHub official images
/// var ns = new Namespace("myorg"); // Organization namespace
/// var ns = new Namespace("username"); // User namespace
+/// Namespace ns = "myorg"; // Implicit conversion from string
///
///