Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ImageBuilder.Tests/QueueBuildCommandTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ private static bool FilterBuildToParameters(string buildParametersJson, string p
IList<string> paths = pathString
.Split(" ", StringSplitOptions.RemoveEmptyEntries)
.Select(p => p.Trim().Trim('\''))
.Except([ CliHelper.FormatAlias(DockerfileFilterOptionsBuilder.PathOptionName) ])
.Except([ CliHelper.FormatAlias(DockerfileFilterOptions.PathOptionName) ])
.ToList();
return CompareLists(expectedPaths, paths);
}
Expand Down
2 changes: 1 addition & 1 deletion src/ImageBuilder/Commands/AnnotateEolDigestsCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

namespace Microsoft.DotNet.ImageBuilder.Commands
{
public class AnnotateEolDigestsCommand : Command<AnnotateEolDigestsOptions, AnnotateEolDigestsOptionsBuilder>
public class AnnotateEolDigestsCommand : Command<AnnotateEolDigestsOptions>
{
private readonly ILogger<AnnotateEolDigestsCommand> _logger;
private readonly ILifecycleMetadataService _lifecycleMetadataService;
Expand Down
81 changes: 51 additions & 30 deletions src/ImageBuilder/Commands/AnnotateEolDigestsOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,62 @@

using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.Parsing;

namespace Microsoft.DotNet.ImageBuilder.Commands
namespace Microsoft.DotNet.ImageBuilder.Commands;

public class AnnotateEolDigestsOptions : Options
{
public class AnnotateEolDigestsOptions : Options
public RegistryCredentialsOptions CredentialsOptions { get; set; } = new();

public string EolDigestsListPath { get; set; } = string.Empty;
public string AcrName { get; set; } = string.Empty;
public string RepoPrefix { get; set; } = string.Empty;
public string AnnotationDigestsOutputPath { get; set; } = string.Empty;

private static readonly Argument<string> EolDigestsListPathArgument = new(nameof(EolDigestsListPath))
{
public RegistryCredentialsOptions CredentialsOptions { get; set; } = new();
Description = "EOL annotations digests list path"
};

public string EolDigestsListPath { get; set; } = string.Empty;
public string AcrName { get; set; } = string.Empty;
public string RepoPrefix { get; set; } = string.Empty;
public string AnnotationDigestsOutputPath { get; set; } = string.Empty;
}
private static readonly Argument<string> AcrNameArgument = new(nameof(AcrName))
{
Description = "Azure registry name"
};

private static readonly Argument<string> RepoPrefixArgument = new(nameof(RepoPrefix))
{
Description = "Publish prefix of the repo names"
};

private static readonly Argument<string> AnnotationDigestsOutputPathArgument = new(nameof(AnnotationDigestsOutputPath))
{
Description = "Output path of file containing the list of annotation digests that were created"
};

public override IEnumerable<Option> GetCliOptions() =>
[
..base.GetCliOptions(),
..CredentialsOptions.GetCliOptions(),
];

public override IEnumerable<Argument> GetCliArguments() =>
[
..base.GetCliArguments(),
..CredentialsOptions.GetCliArguments(),
EolDigestsListPathArgument,
AcrNameArgument,
RepoPrefixArgument,
AnnotationDigestsOutputPathArgument,
];

public class AnnotateEolDigestsOptionsBuilder : CliOptionsBuilder
public override void Bind(ParseResult result)
{
private readonly RegistryCredentialsOptionsBuilder _registryCredentialsOptionsBuilder = new();

public override IEnumerable<Option> GetCliOptions() =>
[
..base.GetCliOptions(),
.._registryCredentialsOptionsBuilder.GetCliOptions(),
];

public override IEnumerable<Argument> GetCliArguments() =>
[
..base.GetCliArguments(),
.._registryCredentialsOptionsBuilder.GetCliArguments(),
new Argument<string>(nameof(AnnotateEolDigestsOptions.EolDigestsListPath),
"EOL annotations digests list path"),
new Argument<string>(nameof(AnnotateEolDigestsOptions.AcrName),
"Azure registry name"),
new Argument<string>(nameof(AnnotateEolDigestsOptions.RepoPrefix),
"Publish prefix of the repo names"),
new Argument<string>(nameof(AnnotateEolDigestsOptions.AnnotationDigestsOutputPath),
"Output path of file containing the list of annotation digests that were created"),
];
base.Bind(result);
CredentialsOptions.Bind(result);
EolDigestsListPath = result.GetValue(EolDigestsListPathArgument) ?? string.Empty;
AcrName = result.GetValue(AcrNameArgument) ?? string.Empty;
RepoPrefix = result.GetValue(RepoPrefixArgument) ?? string.Empty;
AnnotationDigestsOutputPath = result.GetValue(AnnotationDigestsOutputPathArgument) ?? string.Empty;
}
}
83 changes: 55 additions & 28 deletions src/ImageBuilder/Commands/AzdoOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,72 @@
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.Parsing;
using Microsoft.VisualStudio.Services.Common;
using static Microsoft.DotNet.ImageBuilder.Commands.CliHelper;

namespace Microsoft.DotNet.ImageBuilder.Commands
namespace Microsoft.DotNet.ImageBuilder.Commands;

public class AzdoOptions
{
public class AzdoOptions
public string AccessToken { get; set; } = string.Empty;

public string Organization { get; set; } = string.Empty;

public string Project { get; set; } = string.Empty;

public string? AzdoRepo { get; set; }

public string? AzdoBranch { get; set; }

public string? AzdoPath { get; set; }

private static readonly Argument<string> AccessTokenArgument = new(nameof(AccessToken))
{
public string AccessToken { get; set; } = string.Empty;
Description = "Azure DevOps PAT"
};

public string Organization { get; set; } = string.Empty;
private static readonly Argument<string> OrganizationArgument = new(nameof(Organization))
{
Description = "Azure DevOps organization"
};

public string Project { get; set; } = string.Empty;
private static readonly Argument<string> ProjectArgument = new(nameof(Project))
{
Description = "Azure DevOps project"
};

public string? AzdoRepo { get; set; }
private static readonly Option<string?> AzdoRepoOption = new(CliHelper.FormatAlias("azdo-repo"))
{
Description = "Azure DevOps repo"
};

public string? AzdoBranch { get; set; }
private static readonly Option<string?> AzdoBranchOption = new(CliHelper.FormatAlias("azdo-branch"))
{
Description = "Azure DevOps branch (default: main)",
DefaultValueFactory = _ => "main"
};

public string? AzdoPath { get; set; }
private static readonly Option<string?> AzdoPathOption = new(CliHelper.FormatAlias("azdo-path"))
{
Description = "Azure DevOps path"
};

public (Uri BaseUrl, VssCredentials Credentials) GetConnectionDetails() =>
(new Uri($"https://dev.azure.com/{Organization}"), new VssBasicCredential(string.Empty, AccessToken));
}
public IEnumerable<Argument> GetCliArguments() =>
[AccessTokenArgument, OrganizationArgument, ProjectArgument];

public IEnumerable<Option> GetCliOptions() =>
[AzdoRepoOption, AzdoBranchOption, AzdoPathOption];

public class AzdoOptionsBuilder
public void Bind(ParseResult result)
{
public IEnumerable<Argument> GetCliArguments() =>
new Argument[]
{
new Argument<string>(nameof(AzdoOptions.AccessToken), "Azure DevOps PAT"),
new Argument<string>(nameof(AzdoOptions.Organization), "Azure DevOps organization"),
new Argument<string>(nameof(AzdoOptions.Project), "Azure DevOps project")
};

public IEnumerable<Option> GetCliOptions() =>
new Option[]
{
CreateOption<string?>("azdo-repo", nameof(AzdoOptions.AzdoRepo), "Azure DevOps repo"),
CreateOption<string?>("azdo-branch", nameof(AzdoOptions.AzdoBranch), "Azure DevOps branch (default: main)", "main"),
CreateOption<string?>("azdo-path", nameof(AzdoOptions.AzdoPath), "Azure DevOps path"),
};
AccessToken = result.GetValue(AccessTokenArgument) ?? string.Empty;
Organization = result.GetValue(OrganizationArgument) ?? string.Empty;
Project = result.GetValue(ProjectArgument) ?? string.Empty;
AzdoRepo = result.GetValue(AzdoRepoOption);
AzdoBranch = result.GetValue(AzdoBranchOption);
AzdoPath = result.GetValue(AzdoPathOption);
}

public (Uri BaseUrl, VssCredentials Credentials) GetConnectionDetails() =>
(new Uri($"https://dev.azure.com/{Organization}"), new VssBasicCredential(string.Empty, AccessToken));
}
36 changes: 21 additions & 15 deletions src/ImageBuilder/Commands/BaseImageOverrideOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.Linq;
using System.CommandLine.Parsing;
using System.Text.RegularExpressions;
using static Microsoft.DotNet.ImageBuilder.Commands.CliHelper;

namespace Microsoft.DotNet.ImageBuilder.Commands;

/// <summary>
/// Defines options that allow the caller to configure whether and how base image tags defined in a Dockerfile
/// are to be overriden.
/// </summary>
/// <remarks>
/// This allows for images to be sourced from a different location than described in the Dockerfile.
/// For example, the Build command implements this by pulling an image from the overriden location, retagging it with the
/// tag used in the Dockerfile, and continue with the rest of the build.<remarks>
/// tag used in the Dockerfile, and continue with the rest of the build.
/// </remarks>
public class BaseImageOverrideOptions
{
Expand All @@ -27,6 +27,16 @@ public class BaseImageOverrideOptions

public string? Substitution { get; set; }

private static readonly Option<string?> RegexPatternOption = new(CliHelper.FormatAlias(BaseOverrideRegexName))
{
Description = $"Regular expression identifying base image tags to apply string substitution to (requires {BaseOverrideSubName} to be set)"
};

private static readonly Option<string?> SubstitutionOption = new(CliHelper.FormatAlias(BaseOverrideSubName))
{
Description = $"Regular expression substitution that overrides a matching base image tag (requires {BaseOverrideRegexName} to be set)"
};

public void Validate()
{
if ((RegexPattern is null) != (Substitution is null))
Expand All @@ -45,19 +55,15 @@ public string ApplyBaseImageOverride(string imageName)

return imageName;
}
}

public class BaseImageOverrideOptionsBuilder
{
public IEnumerable<Option> GetCliOptions() =>
new Option[]
{
CreateOption<string?>(BaseImageOverrideOptions.BaseOverrideRegexName, nameof(BaseImageOverrideOptions.RegexPattern),
$"Regular expression identifying base image tags to apply string substitution to (requires {BaseImageOverrideOptions.BaseOverrideSubName} to be set)"),
CreateOption<string?>(BaseImageOverrideOptions.BaseOverrideSubName, nameof(BaseImageOverrideOptions.Substitution),
$"Regular expression substitution that overrides a matching base image tag (requires {BaseImageOverrideOptions.BaseOverrideRegexName} to be set)")
};
[RegexPatternOption, SubstitutionOption];

public IEnumerable<Argument> GetCliArguments() => Enumerable.Empty<Argument>();
}
public IEnumerable<Argument> GetCliArguments() => [];

public void Bind(ParseResult result)
{
RegexPattern = result.GetValue(RegexPatternOption);
Substitution = result.GetValue(SubstitutionOption);
}
}
2 changes: 1 addition & 1 deletion src/ImageBuilder/Commands/BuildCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

namespace Microsoft.DotNet.ImageBuilder.Commands
{
public class BuildCommand : ManifestCommand<BuildOptions, BuildOptionsBuilder>
public class BuildCommand : ManifestCommand<BuildOptions>
{
private readonly IDockerService _dockerService;
private readonly ILogger<BuildCommand> _logger;
Expand Down
Loading
Loading